diff --git a/cmd/helper/error.go b/cmd/helper/error.go index ff9f84af6c..aafd30088f 100644 --- a/cmd/helper/error.go +++ b/cmd/helper/error.go @@ -25,10 +25,12 @@ import ( "google.golang.org/grpc/status" ) +var osexit = os.Exit + // QuitToStdErr prints an error on stderr and closes func QuitToStdErr(msg interface{}) { _, _ = fmt.Fprintln(os.Stderr, msg) - os.Exit(1) + osexit(1) } // QuitWithUserError ... @@ -42,3 +44,7 @@ func QuitWithUserError(err error) { } QuitToStdErr(err) } + +func OverrideQuitter(quitter func(int)) { + osexit=quitter +} diff --git a/cmd/immudb/command/cmd_test.go b/cmd/immudb/command/cmd_test.go index 9b67a67087..ae9e57901e 100644 --- a/cmd/immudb/command/cmd_test.go +++ b/cmd/immudb/command/cmd_test.go @@ -28,6 +28,7 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" "github.com/stretchr/testify/assert" + "github.com/codenotary/immudb/cmd/helper" ) func DefaultTestOptions() (o *server.Options) { @@ -66,6 +67,37 @@ func TestImmudbCommandFlagParser(t *testing.T) { assert.Equal(t, o.Logfile, options.Logfile) } +func TestImmudbCommandFlagParserWrongTLS(t *testing.T) { + viper.Set("mtls", true) + o := DefaultTestOptions() + + var err error + cmd := &cobra.Command{ + Use: "immudb", + RunE: func(cmd *cobra.Command, args []string) (err error) { + _, err = parseOptions() + if err != nil { + return err + } + return nil + }, + } + cl := Commandline{} + cl.setupFlags(cmd, server.DefaultOptions()) + + err = viper.BindPFlags(cmd.Flags()) + assert.Nil(t, err) + + setupDefaults(server.DefaultOptions()) + + _, err = executeCommand(cmd, "--logfile="+o.Logfile) + + assert.Error(t, err) + viper.Set("mtls", false) +} + + + //Priority: // 1. overrides // 2. flags @@ -210,3 +242,13 @@ func TestNewCommand(t *testing.T) { _, err := newCommand(server.DefaultServer()) require.NoError(t, err) } + +func TestExecute(t * testing.T) { + quitCode := 0 + os.Setenv("IMMUDB_ADDRESS","999.999.999.999") + helper.OverrideQuitter(func(q int) { + quitCode=q + }) + Execute() + assert.Equal(t, quitCode,1) +} diff --git a/cmd/immudb/command/tls_config_test.go b/cmd/immudb/command/tls_config_test.go new file mode 100644 index 0000000000..3679613125 --- /dev/null +++ b/cmd/immudb/command/tls_config_test.go @@ -0,0 +1,75 @@ +/* +Copyright 2021 CodeNotary, Inc. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package immudb + +import ( + "fmt" + "github.com/stretchr/testify/require" + "os" + "testing" +) + +var key = ` +-----BEGIN PRIVATE KEY----- +MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEApIGvkc3ROIC18zdL +K3I4VhKmY7gq1YU53dIwikrd5uy/fjUTmW73rLlthkV1zPvG/34rsW9kMDanmndb +QENmHwIDAQABAkEAkOW9vCJaP3d3TCQO7NStdHr23eywpeO0BYMGyDiLXcMOcjaT +MrkeCMyXsgtIaoh/sPFO356z2DXjz8Z4PY53EQIhANPSp0dOKi4OeqHdSsj8wjwt +eeAxCcASe3cz18gnBUB5AiEAxtDJ3spTLNogOoOzQA8g7rVT8xW5R5xQwfmvZwQx +JVcCICAIkGGZMYnLiMInzCJ/DwS4v+CmqdnRMbjCL1TGieXJAiBvQXNWCx6UYNPc +KsrqNA0Xx7zcsPFn01+VzOWM3lmqLQIgdUukJDJHjdX203wOJMd51jq3I+c1n09A +SXr+Ea7CjsE= +-----END PRIVATE KEY----- +` + +var cert = ` +-----BEGIN CERTIFICATE----- +MIIB4TCCAYugAwIBAgIUIZwZa1cYqrwK+McrPStDwFD+e1AwDQYJKoZIhvcNAQEL +BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMTA3MTYxNDMwMThaFw0yMjA3 +MTYxNDMwMThaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw +HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwXDANBgkqhkiG9w0BAQEF +AANLADBIAkEApIGvkc3ROIC18zdLK3I4VhKmY7gq1YU53dIwikrd5uy/fjUTmW73 +rLlthkV1zPvG/34rsW9kMDanmndbQENmHwIDAQABo1MwUTAdBgNVHQ4EFgQU+ENZ +1LFa7+HsPySAYZuPgz2tufkwHwYDVR0jBBgwFoAU+ENZ1LFa7+HsPySAYZuPgz2t +ufkwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAANBAHnfiyFv0PYoCCIW +d/ax/lUR3RCVV6A+hzTgOhYKvoV1U6iX21hUarcm6MB6qaeORCHfQzQpn62nRe6X +4LbTf3k= +-----END CERTIFICATE----- +` + +func TestSetUpTLS(t *testing.T) { + _, err := setUpTLS("banana", "banana", "banana", false) + require.Error(t, err) + _, err = setUpTLS("", "", "", true) + require.Error(t, err) + _, err = setUpTLS("banana", "", "", true) + require.Error(t, err) + + defer os.Remove("xxkey.pem") + f, _ := os.Create("xxkey.pem") + fmt.Fprintf(f, key) + f.Close() + + defer os.Remove("xxcert.pem") + f, _ = os.Create("xxcert.pem") + fmt.Fprintf(f, cert) + f.Close() + + _, err = setUpTLS("xxkey.pem", "xxcert.pem", "banana", true) + require.Error(t, err) +} diff --git a/embedded/ahtree/ahtree_test.go b/embedded/ahtree/ahtree_test.go index d9b01d4763..7a0a6efa89 100644 --- a/embedded/ahtree/ahtree_test.go +++ b/embedded/ahtree/ahtree_test.go @@ -23,6 +23,7 @@ import ( "github.com/codenotary/immudb/embedded/appendable" "github.com/codenotary/immudb/embedded/appendable/mocked" + "github.com/codenotary/immudb/embedded/appendable/multiapp" "github.com/stretchr/testify/require" ) @@ -340,6 +341,33 @@ func TestIntegrity(t *testing.T) { } } +func TestOpenFail(t *testing.T) { + _, err := Open("/dev/null", DefaultOptions().WithSynced(false)) + require.Error(t, err) + os.Mkdir("ro_dir1", 0500) + defer os.RemoveAll("ro_dir1") + _, err = Open("ro_dir/bla", DefaultOptions().WithSynced(false)) + require.Error(t, err) + _, err = Open("wrongdir\000", DefaultOptions().WithSynced(false)) + require.Error(t, err) + defer os.RemoveAll("tt1") + _, err = Open("tt1", DefaultOptions().WithSynced(false).WithAppFactory( + func (rootPath, subPath string, opts *multiapp.Options) (a appendable.Appendable, e error) { + if subPath=="tree" { + e = errors.New("simulated error") + } + return + } )) + _, err = Open("tt1", DefaultOptions().WithSynced(false).WithAppFactory( + func (rootPath, subPath string, opts *multiapp.Options) (a appendable.Appendable, e error) { + if subPath=="commit" { + e = errors.New("simulated error") + } + return + } )) + require.Error(t, err) +} + func TestInclusionAndConsistencyProofs(t *testing.T) { tree, err := Open("ahtree_test", DefaultOptions().WithSynced(false)) require.NoError(t, err) diff --git a/embedded/store/indexer_test.go b/embedded/store/indexer_test.go index c071b5a7a5..8efd8c40f0 100644 --- a/embedded/store/indexer_test.go +++ b/embedded/store/indexer_test.go @@ -24,6 +24,7 @@ import ( "github.com/codenotary/immudb/embedded/tbtree" "github.com/codenotary/immudb/embedded/watchers" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -174,5 +175,38 @@ func TestReplaceIndexCornerCases(t *testing.T) { c.fn(t, d, store) }) } +} + +func TestClosedIndexer(t *testing.T) { + i := indexer{closed: true} + var err error + dummy := []byte("dummy") + + _, _, _, err = i.Get(dummy) + assert.Error(t, err) + assert.Equal(t, err, ErrAlreadyClosed) + + _, err = i.History(dummy, 0, false, 0) + assert.Error(t, err) + assert.Equal(t, err, ErrAlreadyClosed) + + _, err = i.Snapshot() + assert.Error(t, err) + assert.Equal(t, err, ErrAlreadyClosed) + + _, err = i.SnapshotSince(0) + assert.Error(t, err) + assert.Equal(t, err, ErrAlreadyClosed) + + _, err = i.ExistKeyWith(dummy, dummy, false) + assert.Error(t, err) + assert.Equal(t, err, ErrAlreadyClosed) + + err = i.Sync() + assert.Error(t, err) + assert.Equal(t, err, ErrAlreadyClosed) + err = i.Close() + assert.Error(t, err) + assert.Equal(t, err, ErrAlreadyClosed) } diff --git a/pkg/client/sql_test.go b/pkg/client/sql_test.go index d02b6a7826..0d60206af0 100644 --- a/pkg/client/sql_test.go +++ b/pkg/client/sql_test.go @@ -29,6 +29,24 @@ import ( "google.golang.org/grpc/metadata" ) +func TestDisconnectedImmuClient(t *testing.T) { + options := server.DefaultOptions().WithAuth(true) + bs := servertest.NewBufconnServer(options) + + defer os.RemoveAll(options.Dir) + defer os.Remove(".state-") + + bs.Start() + defer bs.Stop() + + client, err := NewImmuClient(DefaultOptions().WithDialOptions(&[]grpc.DialOption{grpc.WithContextDialer(bs.Dialer), grpc.WithInsecure()})) + client.Disconnect() + _,err = client.SQLExec(context.Background(), "SELECT 1", nil) + require.Error(t, err) + _,err = client.SQLQuery(context.Background(), "SELECT 1", nil, true) + require.Error(t, err) +} + func TestImmuClient_SQL(t *testing.T) { options := server.DefaultOptions().WithAuth(true) bs := servertest.NewBufconnServer(options) @@ -48,10 +66,10 @@ func TestImmuClient_SQL(t *testing.T) { ctx := metadata.NewOutgoingContext(context.Background(), md) _, err = client.SQLExec(ctx, `CREATE TABLE table1( - id INTEGER, - title VARCHAR, - active BOOLEAN, - payload BLOB, + id INTEGER, + title VARCHAR, + active BOOLEAN, + payload BLOB, PRIMARY KEY id );`, nil) require.NoError(t, err)