From 0bd81634cfb3c351ba544d2c3dbe067adc18f15e Mon Sep 17 00:00:00 2001 From: kevindiu Date: Thu, 29 Oct 2020 17:16:15 +0900 Subject: [PATCH 1/6] add cassandra test --- internal/db/nosql/cassandra/cassandra.go | 47 +- internal/db/nosql/cassandra/cassandra_test.go | 1677 +++++++++++------ 2 files changed, 1128 insertions(+), 596 deletions(-) diff --git a/internal/db/nosql/cassandra/cassandra.go b/internal/db/nosql/cassandra/cassandra.go index 05876a4186..9ffbade918 100644 --- a/internal/db/nosql/cassandra/cassandra.go +++ b/internal/db/nosql/cassandra/cassandra.go @@ -83,6 +83,11 @@ type ( dcHost string whiteList []string } + events struct { + DisableNodeStatusEvents bool + DisableTopologyEvents bool + DisableSchemaEvents bool + } client struct { hosts []string cqlVersion string @@ -216,19 +221,21 @@ func New(opts ...Option) (Cassandra, error) { ReconnectInterval: c.reconnectInterval, MaxWaitSchemaAgreement: c.maxWaitSchemaAgreement, HostFilter: func() (hf gocql.HostFilter) { - if c.hostFilter.enable { - if len(c.hostFilter.dcHost) != 0 { - hf = gocql.DataCentreHostFilter(c.poolConfig.dataCenterName) - } - if len(c.hostFilter.whiteList) != 0 { - if hf == nil { - hf = gocql.WhiteListHostFilter(c.hostFilter.whiteList...) - } else { - hf = gocql.HostFilterFunc(func(host *gocql.HostInfo) bool { - return hf.Accept(host) || - gocql.WhiteListHostFilter(c.hostFilter.whiteList...).Accept(host) - }) - } + if !c.hostFilter.enable { + return nil + } + + if len(c.hostFilter.dcHost) != 0 { + hf = gocql.DataCentreHostFilter(c.hostFilter.dcHost) + } + if len(c.hostFilter.whiteList) != 0 { + wlhf := gocql.WhiteListHostFilter(c.hostFilter.whiteList...) + if hf == nil { + hf = wlhf + } else { + hf = gocql.HostFilterFunc(func(host *gocql.HostInfo) bool { + return hf.Accept(host) || wlhf.Accept(host) + }) } } return hf @@ -236,11 +243,7 @@ func New(opts ...Option) (Cassandra, error) { // AddressTranslator IgnorePeerAddr: c.ignorePeerAddr, DisableInitialHostLookup: c.disableInitialHostLookup, - Events: struct { - DisableNodeStatusEvents bool - DisableTopologyEvents bool - DisableSchemaEvents bool - }{ + Events: events{ DisableNodeStatusEvents: c.disableNodeStatusEvents, DisableTopologyEvents: c.disableTopologyEvents, DisableSchemaEvents: c.disableSchemaEvents, @@ -269,14 +272,10 @@ func New(opts ...Option) (Cassandra, error) { return c, nil } -func (c *client) Open(ctx context.Context) error { - session, err := c.cluster.CreateSession() - if err != nil { +func (c *client) Open(ctx context.Context) (err error) { + if c.session, err = c.cluster.CreateSession(); err != nil { return err } - - c.session = session - return nil } diff --git a/internal/db/nosql/cassandra/cassandra_test.go b/internal/db/nosql/cassandra/cassandra_test.go index 63d930c67b..89bfeed7c6 100644 --- a/internal/db/nosql/cassandra/cassandra_test.go +++ b/internal/db/nosql/cassandra/cassandra_test.go @@ -19,16 +19,74 @@ package cassandra import ( "context" "crypto/tls" + "os" "reflect" "testing" "time" "github.com/gocql/gocql" + "github.com/scylladb/gocqlx" + "github.com/scylladb/gocqlx/qb" "github.com/vdaas/vald/internal/errors" + "github.com/vdaas/vald/internal/log" + "github.com/vdaas/vald/internal/test/comparator" "go.uber.org/goleak" ) +var ( + // default comparator option for client + clientComparatorOpts = []comparator.Option{ + comparator.AllowUnexported(client{}), + comparator.AllowUnexported(gocql.ClusterConfig{}), + comparator.Comparer(func(x, y retryPolicy) bool { + return reflect.DeepEqual(x, y) + }), + comparator.Comparer(func(x, y reconnectionPolicy) bool { + return reflect.DeepEqual(x, y) + }), + comparator.Comparer(func(x, y poolConfig) bool { + return reflect.DeepEqual(x, y) + }), + comparator.Comparer(func(x, y hostFilter) bool { + return reflect.DeepEqual(x, y) + }), + comparator.Comparer(func(x, y gocql.PoolConfig) bool { + return reflect.DeepEqual(x, y) + }), + comparator.Comparer(func(x, y gocql.HostSelectionPolicy) bool { + return reflect.DeepEqual(x, y) + }), + comparator.Comparer(func(x, y func(h *gocql.HostInfo) (gocql.Authenticator, error)) bool { + if (x == nil && y != nil) || (x != nil && y == nil) { + return false + } + if x == nil && y == nil { + return true + } + return reflect.ValueOf(x).Pointer() == reflect.ValueOf(y).Pointer() + }), + comparator.Comparer(func(x, y gocql.HostFilter) bool { + if (x == nil && y != nil) || (x != nil && y == nil) { + return false + } + if x == nil && y == nil { + return true + } + return reflect.ValueOf(x).Pointer() == reflect.ValueOf(y).Pointer() + }), + + comparator.Comparer(func(x, y tls.Config) bool { + return reflect.DeepEqual(x, y) + }), + } +) + +func TestMain(m *testing.M) { + log.Init() + os.Exit(m.Run()) +} + func TestNew(t *testing.T) { type args struct { opts []Option @@ -49,42 +107,926 @@ func TestNew(t *testing.T) { if !errors.Is(err, w.err) { return errors.Errorf("got_error: \"%#v\",\n\t\t\t\twant: \"%#v\"", err, w.err) } - if !reflect.DeepEqual(got, w.want) { - return errors.Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", got, w.want) + if diff := comparator.Diff(got, w.want, clientComparatorOpts...); diff != "" { + return errors.New(diff) } return nil } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - args: args { - opts: nil, - }, - want: want{}, - checkFunc: defaultCheckFunc, - }, - */ - - // TODO test cases + { + name: "New returns default cassandra", + args: args{ + opts: nil, + }, + want: want{ + want: &client{ + cqlVersion: "3.0.0", + connectTimeout: 600 * time.Millisecond, + consistency: gocql.Quorum, + defaultIdempotence: false, + defaultTimestamp: true, + disableInitialHostLookup: false, + disableNodeStatusEvents: false, + disableSkipMetadata: false, + disableTopologyEvents: false, + enableHostVerification: false, + ignorePeerAddr: false, + maxPreparedStmts: 1000, + maxRoutingKeyInfo: 1000, + maxWaitSchemaAgreement: 1 * time.Minute, + numConns: 2, + pageSize: 5000, + port: 9042, + protoVersion: 0, + reconnectInterval: time.Minute, + serialConsistency: gocql.LocalSerial, + timeout: 600 * time.Millisecond, + writeCoalesceWaitTime: 200 * time.Microsecond, + cluster: &gocql.ClusterConfig{ + Authenticator: func() *gocql.PasswordAuthenticator { + return nil + }(), + RetryPolicy: func() *gocql.ExponentialBackoffRetryPolicy { + return nil + }(), + ConvictionPolicy: NewConvictionPolicy(), + ReconnectionPolicy: &gocql.ExponentialReconnectionPolicy{}, + PoolConfig: gocql.PoolConfig{ + HostSelectionPolicy: func() gocql.HostSelectionPolicy { + return gocql.TokenAwareHostPolicy(gocql.RoundRobinHostPolicy()) + }(), + }, + + CQLVersion: "3.0.0", + ConnectTimeout: 600 * time.Millisecond, + Consistency: gocql.Quorum, + DefaultIdempotence: false, + DefaultTimestamp: true, + DisableInitialHostLookup: false, + Events: events{ + DisableNodeStatusEvents: false, + DisableTopologyEvents: false, + }, + DisableSkipMetadata: false, + IgnorePeerAddr: false, + MaxPreparedStmts: 1000, + MaxRoutingKeyInfo: 1000, + MaxWaitSchemaAgreement: 1 * time.Minute, + NumConns: 2, + PageSize: 5000, + Port: 9042, + ProtoVersion: 0, + ReconnectInterval: time.Minute, + SerialConsistency: gocql.LocalSerial, + Timeout: 600 * time.Millisecond, + WriteCoalesceWaitTime: 200 * time.Microsecond, + }, + poolConfig: poolConfig{ + enableDCAwareRouting: false, + enableNonLocalReplicasFallback: false, + enableShuffleReplicas: false, + enableTokenAwareHostPolicy: true, + }, + }, + }, + }, + { + name: "New returns cassandra with and username password", + args: args{ + opts: []Option{ + WithUsername("un"), + WithPassword("p"), + }, + }, + want: want{ + want: &client{ + username: "un", + password: "p", + cqlVersion: "3.0.0", + connectTimeout: 600 * time.Millisecond, + consistency: gocql.Quorum, + defaultIdempotence: false, + defaultTimestamp: true, + disableInitialHostLookup: false, + disableNodeStatusEvents: false, + disableSkipMetadata: false, + disableTopologyEvents: false, + enableHostVerification: false, + ignorePeerAddr: false, + maxPreparedStmts: 1000, + maxRoutingKeyInfo: 1000, + maxWaitSchemaAgreement: 1 * time.Minute, + numConns: 2, + pageSize: 5000, + port: 9042, + protoVersion: 0, + reconnectInterval: time.Minute, + serialConsistency: gocql.LocalSerial, + timeout: 600 * time.Millisecond, + writeCoalesceWaitTime: 200 * time.Microsecond, + cluster: &gocql.ClusterConfig{ + Authenticator: func() *gocql.PasswordAuthenticator { + return &gocql.PasswordAuthenticator{ + Username: "un", + Password: "p", + } + }(), + RetryPolicy: func() *gocql.ExponentialBackoffRetryPolicy { + return nil + }(), + ConvictionPolicy: NewConvictionPolicy(), + ReconnectionPolicy: &gocql.ExponentialReconnectionPolicy{}, + PoolConfig: gocql.PoolConfig{ + HostSelectionPolicy: func() gocql.HostSelectionPolicy { + return gocql.TokenAwareHostPolicy(gocql.RoundRobinHostPolicy()) + }(), + }, + + CQLVersion: "3.0.0", + ConnectTimeout: 600 * time.Millisecond, + Consistency: gocql.Quorum, + DefaultIdempotence: false, + DefaultTimestamp: true, + DisableInitialHostLookup: false, + Events: events{ + DisableNodeStatusEvents: false, + DisableTopologyEvents: false, + }, + DisableSkipMetadata: false, + IgnorePeerAddr: false, + MaxPreparedStmts: 1000, + MaxRoutingKeyInfo: 1000, + MaxWaitSchemaAgreement: 1 * time.Minute, + NumConns: 2, + PageSize: 5000, + Port: 9042, + ProtoVersion: 0, + ReconnectInterval: time.Minute, + SerialConsistency: gocql.LocalSerial, + Timeout: 600 * time.Millisecond, + WriteCoalesceWaitTime: 200 * time.Microsecond, + }, + poolConfig: poolConfig{ + enableDCAwareRouting: false, + enableNonLocalReplicasFallback: false, + enableShuffleReplicas: false, + enableTokenAwareHostPolicy: true, + }, + }, + }, + }, + { + name: "New returns cassandra with backoff", + args: args{ + opts: []Option{ + WithRetryPolicyNumRetries(5), + WithRetryPolicyMinDuration("1s"), + WithRetryPolicyMaxDuration("5s"), + }, + }, + want: want{ + want: &client{ + cqlVersion: "3.0.0", + connectTimeout: 600 * time.Millisecond, + consistency: gocql.Quorum, + defaultIdempotence: false, + defaultTimestamp: true, + disableInitialHostLookup: false, + disableNodeStatusEvents: false, + disableSkipMetadata: false, + disableTopologyEvents: false, + enableHostVerification: false, + ignorePeerAddr: false, + maxPreparedStmts: 1000, + maxRoutingKeyInfo: 1000, + maxWaitSchemaAgreement: 1 * time.Minute, + numConns: 2, + pageSize: 5000, + port: 9042, + protoVersion: 0, + reconnectInterval: time.Minute, + serialConsistency: gocql.LocalSerial, + timeout: 600 * time.Millisecond, + writeCoalesceWaitTime: 200 * time.Microsecond, + retryPolicy: retryPolicy{ + numRetries: 5, + minDuration: time.Second, + maxDuration: 5 * time.Second, + }, + cluster: &gocql.ClusterConfig{ + Authenticator: func() *gocql.PasswordAuthenticator { + return nil + }(), + RetryPolicy: func() *gocql.ExponentialBackoffRetryPolicy { + return &gocql.ExponentialBackoffRetryPolicy{ + NumRetries: 5, + Min: time.Second, + Max: 5 * time.Second, + } + }(), + ConvictionPolicy: NewConvictionPolicy(), + ReconnectionPolicy: &gocql.ExponentialReconnectionPolicy{}, + PoolConfig: gocql.PoolConfig{ + HostSelectionPolicy: func() gocql.HostSelectionPolicy { + return gocql.TokenAwareHostPolicy(gocql.RoundRobinHostPolicy()) + }(), + }, + + CQLVersion: "3.0.0", + ConnectTimeout: 600 * time.Millisecond, + Consistency: gocql.Quorum, + DefaultIdempotence: false, + DefaultTimestamp: true, + DisableInitialHostLookup: false, + Events: events{ + DisableNodeStatusEvents: false, + DisableTopologyEvents: false, + }, + DisableSkipMetadata: false, + IgnorePeerAddr: false, + MaxPreparedStmts: 1000, + MaxRoutingKeyInfo: 1000, + MaxWaitSchemaAgreement: 1 * time.Minute, + NumConns: 2, + PageSize: 5000, + Port: 9042, + ProtoVersion: 0, + ReconnectInterval: time.Minute, + SerialConsistency: gocql.LocalSerial, + Timeout: 600 * time.Millisecond, + WriteCoalesceWaitTime: 200 * time.Microsecond, + }, + poolConfig: poolConfig{ + enableDCAwareRouting: false, + enableNonLocalReplicasFallback: false, + enableShuffleReplicas: false, + enableTokenAwareHostPolicy: true, + }, + }, + }, + }, + { + name: "New returns cassandra with DC aware poll config", + args: args{ + opts: []Option{ + WithDCAwareRouting(true), + WithDC("dc"), + WithTokenAwareHostPolicy(false), + }, + }, + want: want{ + want: &client{ + cqlVersion: "3.0.0", + connectTimeout: 600 * time.Millisecond, + consistency: gocql.Quorum, + defaultIdempotence: false, + defaultTimestamp: true, + disableInitialHostLookup: false, + disableNodeStatusEvents: false, + disableSkipMetadata: false, + disableTopologyEvents: false, + enableHostVerification: false, + ignorePeerAddr: false, + maxPreparedStmts: 1000, + maxRoutingKeyInfo: 1000, + maxWaitSchemaAgreement: 1 * time.Minute, + numConns: 2, + pageSize: 5000, + port: 9042, + protoVersion: 0, + reconnectInterval: time.Minute, + serialConsistency: gocql.LocalSerial, + timeout: 600 * time.Millisecond, + writeCoalesceWaitTime: 200 * time.Microsecond, + cluster: &gocql.ClusterConfig{ + Authenticator: func() *gocql.PasswordAuthenticator { + return nil + }(), + RetryPolicy: func() *gocql.ExponentialBackoffRetryPolicy { + return nil + }(), + ConvictionPolicy: NewConvictionPolicy(), + ReconnectionPolicy: &gocql.ExponentialReconnectionPolicy{}, + PoolConfig: gocql.PoolConfig{ + HostSelectionPolicy: func() gocql.HostSelectionPolicy { + return gocql.DCAwareRoundRobinPolicy("dc") + }(), + }, + + CQLVersion: "3.0.0", + ConnectTimeout: 600 * time.Millisecond, + Consistency: gocql.Quorum, + DefaultIdempotence: false, + DefaultTimestamp: true, + DisableInitialHostLookup: false, + Events: events{ + DisableNodeStatusEvents: false, + DisableTopologyEvents: false, + }, + DisableSkipMetadata: false, + IgnorePeerAddr: false, + MaxPreparedStmts: 1000, + MaxRoutingKeyInfo: 1000, + MaxWaitSchemaAgreement: 1 * time.Minute, + NumConns: 2, + PageSize: 5000, + Port: 9042, + ProtoVersion: 0, + ReconnectInterval: time.Minute, + SerialConsistency: gocql.LocalSerial, + Timeout: 600 * time.Millisecond, + WriteCoalesceWaitTime: 200 * time.Microsecond, + }, + poolConfig: poolConfig{ + enableDCAwareRouting: true, + dataCenterName: "dc", + enableNonLocalReplicasFallback: false, + enableShuffleReplicas: false, + enableTokenAwareHostPolicy: false, + }, + }, + }, + }, + { + name: "New returns cassandra with shuffle replica", + args: args{ + opts: []Option{ + WithShuffleReplicas(true), + }, + }, + want: want{ + want: &client{ + cqlVersion: "3.0.0", + connectTimeout: 600 * time.Millisecond, + consistency: gocql.Quorum, + defaultIdempotence: false, + defaultTimestamp: true, + disableInitialHostLookup: false, + disableNodeStatusEvents: false, + disableSkipMetadata: false, + disableTopologyEvents: false, + enableHostVerification: false, + ignorePeerAddr: false, + maxPreparedStmts: 1000, + maxRoutingKeyInfo: 1000, + maxWaitSchemaAgreement: 1 * time.Minute, + numConns: 2, + pageSize: 5000, + port: 9042, + protoVersion: 0, + reconnectInterval: time.Minute, + serialConsistency: gocql.LocalSerial, + timeout: 600 * time.Millisecond, + writeCoalesceWaitTime: 200 * time.Microsecond, + cluster: &gocql.ClusterConfig{ + Authenticator: func() *gocql.PasswordAuthenticator { + return nil + }(), + RetryPolicy: func() *gocql.ExponentialBackoffRetryPolicy { + return nil + }(), + ConvictionPolicy: NewConvictionPolicy(), + ReconnectionPolicy: &gocql.ExponentialReconnectionPolicy{}, + PoolConfig: gocql.PoolConfig{ + HostSelectionPolicy: func() gocql.HostSelectionPolicy { + return gocql.TokenAwareHostPolicy(gocql.RoundRobinHostPolicy(), gocql.ShuffleReplicas()) + }(), + }, + + CQLVersion: "3.0.0", + ConnectTimeout: 600 * time.Millisecond, + Consistency: gocql.Quorum, + DefaultIdempotence: false, + DefaultTimestamp: true, + DisableInitialHostLookup: false, + Events: events{ + DisableNodeStatusEvents: false, + DisableTopologyEvents: false, + }, + DisableSkipMetadata: false, + IgnorePeerAddr: false, + MaxPreparedStmts: 1000, + MaxRoutingKeyInfo: 1000, + MaxWaitSchemaAgreement: 1 * time.Minute, + NumConns: 2, + PageSize: 5000, + Port: 9042, + ProtoVersion: 0, + ReconnectInterval: time.Minute, + SerialConsistency: gocql.LocalSerial, + Timeout: 600 * time.Millisecond, + WriteCoalesceWaitTime: 200 * time.Microsecond, + }, + poolConfig: poolConfig{ + enableDCAwareRouting: false, + enableNonLocalReplicasFallback: false, + enableShuffleReplicas: true, + enableTokenAwareHostPolicy: true, + }, + }, + }, + }, + { + name: "New returns cassandra with non local replicas fallback pool", + args: args{ + opts: []Option{ + WithNonLocalReplicasFallback(true), + }, + }, + want: want{ + want: &client{ + cqlVersion: "3.0.0", + connectTimeout: 600 * time.Millisecond, + consistency: gocql.Quorum, + defaultIdempotence: false, + defaultTimestamp: true, + disableInitialHostLookup: false, + disableNodeStatusEvents: false, + disableSkipMetadata: false, + disableTopologyEvents: false, + enableHostVerification: false, + ignorePeerAddr: false, + maxPreparedStmts: 1000, + maxRoutingKeyInfo: 1000, + maxWaitSchemaAgreement: 1 * time.Minute, + numConns: 2, + pageSize: 5000, + port: 9042, + protoVersion: 0, + reconnectInterval: time.Minute, + serialConsistency: gocql.LocalSerial, + timeout: 600 * time.Millisecond, + writeCoalesceWaitTime: 200 * time.Microsecond, + cluster: &gocql.ClusterConfig{ + Authenticator: func() *gocql.PasswordAuthenticator { + return nil + }(), + RetryPolicy: func() *gocql.ExponentialBackoffRetryPolicy { + return nil + }(), + ConvictionPolicy: NewConvictionPolicy(), + ReconnectionPolicy: &gocql.ExponentialReconnectionPolicy{}, + PoolConfig: gocql.PoolConfig{ + HostSelectionPolicy: func() gocql.HostSelectionPolicy { + return gocql.TokenAwareHostPolicy(gocql.RoundRobinHostPolicy(), gocql.NonLocalReplicasFallback()) + }(), + }, + + CQLVersion: "3.0.0", + ConnectTimeout: 600 * time.Millisecond, + Consistency: gocql.Quorum, + DefaultIdempotence: false, + DefaultTimestamp: true, + DisableInitialHostLookup: false, + Events: events{ + DisableNodeStatusEvents: false, + DisableTopologyEvents: false, + }, + DisableSkipMetadata: false, + IgnorePeerAddr: false, + MaxPreparedStmts: 1000, + MaxRoutingKeyInfo: 1000, + MaxWaitSchemaAgreement: 1 * time.Minute, + NumConns: 2, + PageSize: 5000, + Port: 9042, + ProtoVersion: 0, + ReconnectInterval: time.Minute, + SerialConsistency: gocql.LocalSerial, + Timeout: 600 * time.Millisecond, + WriteCoalesceWaitTime: 200 * time.Microsecond, + }, + poolConfig: poolConfig{ + enableDCAwareRouting: false, + enableNonLocalReplicasFallback: true, + enableShuffleReplicas: false, + enableTokenAwareHostPolicy: true, + }, + }, + }, + }, + { + name: "New default cassandra with shuffle replicas and non local replicas fallback", + args: args{ + opts: []Option{ + WithShuffleReplicas(true), + WithNonLocalReplicasFallback(true), + }, + }, + want: want{ + want: &client{ + cqlVersion: "3.0.0", + connectTimeout: 600 * time.Millisecond, + consistency: gocql.Quorum, + defaultIdempotence: false, + defaultTimestamp: true, + disableInitialHostLookup: false, + disableNodeStatusEvents: false, + disableSkipMetadata: false, + disableTopologyEvents: false, + enableHostVerification: false, + ignorePeerAddr: false, + maxPreparedStmts: 1000, + maxRoutingKeyInfo: 1000, + maxWaitSchemaAgreement: 1 * time.Minute, + numConns: 2, + pageSize: 5000, + port: 9042, + protoVersion: 0, + reconnectInterval: time.Minute, + serialConsistency: gocql.LocalSerial, + timeout: 600 * time.Millisecond, + writeCoalesceWaitTime: 200 * time.Microsecond, + cluster: &gocql.ClusterConfig{ + Authenticator: func() *gocql.PasswordAuthenticator { + return nil + }(), + RetryPolicy: func() *gocql.ExponentialBackoffRetryPolicy { + return nil + }(), + ConvictionPolicy: NewConvictionPolicy(), + ReconnectionPolicy: &gocql.ExponentialReconnectionPolicy{}, + PoolConfig: gocql.PoolConfig{ + HostSelectionPolicy: func() gocql.HostSelectionPolicy { + return gocql.TokenAwareHostPolicy(gocql.RoundRobinHostPolicy(), gocql.ShuffleReplicas(), gocql.NonLocalReplicasFallback()) + }(), + }, + + CQLVersion: "3.0.0", + ConnectTimeout: 600 * time.Millisecond, + Consistency: gocql.Quorum, + DefaultIdempotence: false, + DefaultTimestamp: true, + DisableInitialHostLookup: false, + Events: events{ + DisableNodeStatusEvents: false, + DisableTopologyEvents: false, + }, + DisableSkipMetadata: false, + IgnorePeerAddr: false, + MaxPreparedStmts: 1000, + MaxRoutingKeyInfo: 1000, + MaxWaitSchemaAgreement: 1 * time.Minute, + NumConns: 2, + PageSize: 5000, + Port: 9042, + ProtoVersion: 0, + ReconnectInterval: time.Minute, + SerialConsistency: gocql.LocalSerial, + Timeout: 600 * time.Millisecond, + WriteCoalesceWaitTime: 200 * time.Microsecond, + }, + poolConfig: poolConfig{ + enableDCAwareRouting: false, + enableNonLocalReplicasFallback: true, + enableShuffleReplicas: true, + enableTokenAwareHostPolicy: true, + }, + }, + }, + }, + { + name: "New returns cassandra with host filter enable", + args: args{ + opts: []Option{ + WithHostFilter(true), + WithDCHostFilter("dc"), + }, + }, + want: want{ + want: &client{ + cqlVersion: "3.0.0", + connectTimeout: 600 * time.Millisecond, + consistency: gocql.Quorum, + defaultIdempotence: false, + defaultTimestamp: true, + disableInitialHostLookup: false, + disableNodeStatusEvents: false, + disableSkipMetadata: false, + disableTopologyEvents: false, + enableHostVerification: false, + ignorePeerAddr: false, + maxPreparedStmts: 1000, + maxRoutingKeyInfo: 1000, + maxWaitSchemaAgreement: 1 * time.Minute, + numConns: 2, + pageSize: 5000, + port: 9042, + protoVersion: 0, + reconnectInterval: time.Minute, + serialConsistency: gocql.LocalSerial, + timeout: 600 * time.Millisecond, + writeCoalesceWaitTime: 200 * time.Microsecond, + hostFilter: hostFilter{ + enable: true, + dcHost: "dc", + }, + cluster: &gocql.ClusterConfig{ + Authenticator: func() *gocql.PasswordAuthenticator { + return nil + }(), + RetryPolicy: func() *gocql.ExponentialBackoffRetryPolicy { + return nil + }(), + ConvictionPolicy: NewConvictionPolicy(), + ReconnectionPolicy: &gocql.ExponentialReconnectionPolicy{}, + PoolConfig: gocql.PoolConfig{ + HostSelectionPolicy: func() gocql.HostSelectionPolicy { + return gocql.TokenAwareHostPolicy(gocql.RoundRobinHostPolicy()) + }(), + }, + HostFilter: gocql.DataCentreHostFilter("dc"), + + CQLVersion: "3.0.0", + ConnectTimeout: 600 * time.Millisecond, + Consistency: gocql.Quorum, + DefaultIdempotence: false, + DefaultTimestamp: true, + DisableInitialHostLookup: false, + Events: events{ + DisableNodeStatusEvents: false, + DisableTopologyEvents: false, + }, + DisableSkipMetadata: false, + IgnorePeerAddr: false, + MaxPreparedStmts: 1000, + MaxRoutingKeyInfo: 1000, + MaxWaitSchemaAgreement: 1 * time.Minute, + NumConns: 2, + PageSize: 5000, + Port: 9042, + ProtoVersion: 0, + ReconnectInterval: time.Minute, + SerialConsistency: gocql.LocalSerial, + Timeout: 600 * time.Millisecond, + WriteCoalesceWaitTime: 200 * time.Microsecond, + }, + poolConfig: poolConfig{ + enableDCAwareRouting: false, + enableNonLocalReplicasFallback: false, + enableShuffleReplicas: false, + enableTokenAwareHostPolicy: true, + }, + }, + }, + }, + { + name: "New returns cassandra with whitelist enable", + args: args{ + opts: []Option{ + WithHostFilter(true), + WithWhiteListHostFilter([]string{"localhost"}), + }, + }, + want: want{ + want: &client{ + cqlVersion: "3.0.0", + connectTimeout: 600 * time.Millisecond, + consistency: gocql.Quorum, + defaultIdempotence: false, + defaultTimestamp: true, + disableInitialHostLookup: false, + disableNodeStatusEvents: false, + disableSkipMetadata: false, + disableTopologyEvents: false, + enableHostVerification: false, + ignorePeerAddr: false, + maxPreparedStmts: 1000, + maxRoutingKeyInfo: 1000, + maxWaitSchemaAgreement: 1 * time.Minute, + numConns: 2, + pageSize: 5000, + port: 9042, + protoVersion: 0, + reconnectInterval: time.Minute, + serialConsistency: gocql.LocalSerial, + timeout: 600 * time.Millisecond, + writeCoalesceWaitTime: 200 * time.Microsecond, + hostFilter: hostFilter{ + enable: true, + whiteList: []string{"localhost"}, + }, + cluster: &gocql.ClusterConfig{ + Authenticator: func() *gocql.PasswordAuthenticator { + return nil + }(), + RetryPolicy: func() *gocql.ExponentialBackoffRetryPolicy { + return nil + }(), + ConvictionPolicy: NewConvictionPolicy(), + ReconnectionPolicy: &gocql.ExponentialReconnectionPolicy{}, + PoolConfig: gocql.PoolConfig{ + HostSelectionPolicy: func() gocql.HostSelectionPolicy { + return gocql.TokenAwareHostPolicy(gocql.RoundRobinHostPolicy()) + }(), + }, + HostFilter: gocql.WhiteListHostFilter("localhost"), + + CQLVersion: "3.0.0", + ConnectTimeout: 600 * time.Millisecond, + Consistency: gocql.Quorum, + DefaultIdempotence: false, + DefaultTimestamp: true, + DisableInitialHostLookup: false, + Events: events{ + DisableNodeStatusEvents: false, + DisableTopologyEvents: false, + }, + DisableSkipMetadata: false, + IgnorePeerAddr: false, + MaxPreparedStmts: 1000, + MaxRoutingKeyInfo: 1000, + MaxWaitSchemaAgreement: 1 * time.Minute, + NumConns: 2, + PageSize: 5000, + Port: 9042, + ProtoVersion: 0, + ReconnectInterval: time.Minute, + SerialConsistency: gocql.LocalSerial, + Timeout: 600 * time.Millisecond, + WriteCoalesceWaitTime: 200 * time.Microsecond, + }, + poolConfig: poolConfig{ + enableDCAwareRouting: false, + enableNonLocalReplicasFallback: false, + enableShuffleReplicas: false, + enableTokenAwareHostPolicy: true, + }, + }, + }, + }, /* - func() test { - return test { - name: "test_case_2", - args: args { - opts: nil, - }, - want: want{}, - checkFunc: defaultCheckFunc, - } - }(), + { + name: "New returns cassandra with host filter and whitelist enabled", + args: args{ + opts: []Option{ + WithHostFilter(true), + WithDCHostFilter("dc"), + WithWhiteListHostFilter("localhost"), + }, + }, + want: want{ + want: &client{ + cqlVersion: "3.0.0", + connectTimeout: 600 * time.Millisecond, + consistency: gocql.Quorum, + defaultIdempotence: false, + defaultTimestamp: true, + disableInitialHostLookup: false, + disableNodeStatusEvents: false, + disableSkipMetadata: false, + disableTopologyEvents: false, + enableHostVerification: false, + ignorePeerAddr: false, + maxPreparedStmts: 1000, + maxRoutingKeyInfo: 1000, + maxWaitSchemaAgreement: 1 * time.Minute, + numConns: 2, + pageSize: 5000, + port: 9042, + protoVersion: 0, + reconnectInterval: time.Minute, + serialConsistency: gocql.LocalSerial, + timeout: 600 * time.Millisecond, + writeCoalesceWaitTime: 200 * time.Microsecond, + cluster: &gocql.ClusterConfig{ + Authenticator: func() *gocql.PasswordAuthenticator { + return nil + }(), + RetryPolicy: func() *gocql.ExponentialBackoffRetryPolicy { + return nil + }(), + ConvictionPolicy: NewConvictionPolicy(), + ReconnectionPolicy: &gocql.ExponentialReconnectionPolicy{}, + PoolConfig: gocql.PoolConfig{ + HostSelectionPolicy: func() gocql.HostSelectionPolicy { + return gocql.TokenAwareHostPolicy(gocql.RoundRobinHostPolicy()) + }(), + }, + HostFilter: , + + CQLVersion: "3.0.0", + ConnectTimeout: 600 * time.Millisecond, + Consistency: gocql.Quorum, + DefaultIdempotence: false, + DefaultTimestamp: true, + DisableInitialHostLookup: false, + Events: events{ + DisableNodeStatusEvents: false, + DisableTopologyEvents: false, + }, + DisableSkipMetadata: false, + IgnorePeerAddr: false, + MaxPreparedStmts: 1000, + MaxRoutingKeyInfo: 1000, + MaxWaitSchemaAgreement: 1 * time.Minute, + NumConns: 2, + PageSize: 5000, + Port: 9042, + ProtoVersion: 0, + ReconnectInterval: time.Minute, + SerialConsistency: gocql.LocalSerial, + Timeout: 600 * time.Millisecond, + WriteCoalesceWaitTime: 200 * time.Microsecond, + }, + poolConfig: poolConfig{ + enableDCAwareRouting: false, + enableNonLocalReplicasFallback: false, + enableShuffleReplicas: false, + enableTokenAwareHostPolicy: true, + }, + }, + }, + }, */ + { + name: "New returns cassandra with tls", + args: args{ + opts: []Option{ + WithTLS(&tls.Config{}), + }, + }, + want: want{ + want: &client{ + cqlVersion: "3.0.0", + connectTimeout: 600 * time.Millisecond, + consistency: gocql.Quorum, + defaultIdempotence: false, + defaultTimestamp: true, + disableInitialHostLookup: false, + disableNodeStatusEvents: false, + disableSkipMetadata: false, + disableTopologyEvents: false, + enableHostVerification: false, + ignorePeerAddr: false, + maxPreparedStmts: 1000, + maxRoutingKeyInfo: 1000, + maxWaitSchemaAgreement: 1 * time.Minute, + numConns: 2, + pageSize: 5000, + port: 9042, + protoVersion: 0, + reconnectInterval: time.Minute, + serialConsistency: gocql.LocalSerial, + timeout: 600 * time.Millisecond, + writeCoalesceWaitTime: 200 * time.Microsecond, + cluster: &gocql.ClusterConfig{ + Authenticator: func() *gocql.PasswordAuthenticator { + return nil + }(), + RetryPolicy: func() *gocql.ExponentialBackoffRetryPolicy { + return nil + }(), + ConvictionPolicy: NewConvictionPolicy(), + ReconnectionPolicy: &gocql.ExponentialReconnectionPolicy{}, + PoolConfig: gocql.PoolConfig{ + HostSelectionPolicy: func() gocql.HostSelectionPolicy { + return gocql.TokenAwareHostPolicy(gocql.RoundRobinHostPolicy()) + }(), + }, + + CQLVersion: "3.0.0", + ConnectTimeout: 600 * time.Millisecond, + Consistency: gocql.Quorum, + DefaultIdempotence: false, + DefaultTimestamp: true, + DisableInitialHostLookup: false, + Events: events{ + DisableNodeStatusEvents: false, + DisableTopologyEvents: false, + }, + DisableSkipMetadata: false, + IgnorePeerAddr: false, + MaxPreparedStmts: 1000, + MaxRoutingKeyInfo: 1000, + MaxWaitSchemaAgreement: 1 * time.Minute, + NumConns: 2, + PageSize: 5000, + Port: 9042, + ProtoVersion: 0, + ReconnectInterval: time.Minute, + SerialConsistency: gocql.LocalSerial, + Timeout: 600 * time.Millisecond, + WriteCoalesceWaitTime: 200 * time.Microsecond, + SslOpts: &gocql.SslOptions{ + Config: &tls.Config{}, + }, + }, + poolConfig: poolConfig{ + enableDCAwareRouting: false, + enableNonLocalReplicasFallback: false, + enableShuffleReplicas: false, + enableTokenAwareHostPolicy: true, + }, + tls: &tls.Config{}, + }, + }, + }, } for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt, goleakIgnoreOptions...) if test.beforeFunc != nil { test.beforeFunc(test.args) } @@ -187,122 +1129,37 @@ func Test_client_Open(t *testing.T) { return nil } tests := []test{ - // TODO test cases /* - { - name: "test_case_1", - args: args { - ctx: nil, - }, - fields: fields { - hosts: nil, - cqlVersion: "", - protoVersion: 0, - timeout: nil, - connectTimeout: nil, - port: 0, - keyspace: "", - numConns: 0, - consistency: nil, - compressor: nil, - username: "", - password: "", - authProvider: nil, - retryPolicy: struct{numRetries int; minDuration time.Duration; maxDuration time.Duration}{}, - reconnectionPolicy: struct{initialInterval time.Duration; maxRetries int}{}, - poolConfig: struct{dataCenterName string; enableDCAwareRouting bool; enableShuffleReplicas bool; enableNonLocalReplicasFallback bool; enableTokenAwareHostPolicy bool}{}, - hostFilter: struct{enable bool; dcHost string; whiteList []string}{}, - socketKeepalive: nil, - maxPreparedStmts: 0, - maxRoutingKeyInfo: 0, - pageSize: 0, - serialConsistency: nil, - tls: nil, - tlsCertPath: "", - tlsKeyPath: "", - tlsCAPath: "", - enableHostVerification: false, - defaultTimestamp: false, - reconnectInterval: nil, - maxWaitSchemaAgreement: nil, - ignorePeerAddr: false, - disableInitialHostLookup: false, - disableNodeStatusEvents: false, - disableTopologyEvents: false, - disableSchemaEvents: false, - disableSkipMetadata: false, - defaultIdempotence: false, - dialer: nil, - writeCoalesceWaitTime: nil, - cluster: nil, - session: nil, - }, - want: want{}, - checkFunc: defaultCheckFunc, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - args: args { - ctx: nil, - }, - fields: fields { - hosts: nil, - cqlVersion: "", - protoVersion: 0, - timeout: nil, - connectTimeout: nil, - port: 0, - keyspace: "", - numConns: 0, - consistency: nil, - compressor: nil, - username: "", - password: "", - authProvider: nil, - retryPolicy: struct{numRetries int; minDuration time.Duration; maxDuration time.Duration}{}, - reconnectionPolicy: struct{initialInterval time.Duration; maxRetries int}{}, - poolConfig: struct{dataCenterName string; enableDCAwareRouting bool; enableShuffleReplicas bool; enableNonLocalReplicasFallback bool; enableTokenAwareHostPolicy bool}{}, - hostFilter: struct{enable bool; dcHost string; whiteList []string}{}, - socketKeepalive: nil, - maxPreparedStmts: 0, - maxRoutingKeyInfo: 0, - pageSize: 0, - serialConsistency: nil, - tls: nil, - tlsCertPath: "", - tlsKeyPath: "", - tlsCAPath: "", - enableHostVerification: false, - defaultTimestamp: false, - reconnectInterval: nil, - maxWaitSchemaAgreement: nil, - ignorePeerAddr: false, - disableInitialHostLookup: false, - disableNodeStatusEvents: false, - disableTopologyEvents: false, - disableSchemaEvents: false, - disableSkipMetadata: false, - defaultIdempotence: false, - dialer: nil, - writeCoalesceWaitTime: nil, - cluster: nil, - session: nil, - }, - want: want{}, - checkFunc: defaultCheckFunc, - } - }(), + { + name: "open create session success", + args: args{ + ctx: context.Background(), + }, + fields: fields{ + cluster: &gocql.ClusterConfig{ + Hosts: []string{"127.0.0.1"}, + }, + }, + want: want{}, + }, */ + { + name: "open create session and return any error if occured", + args: args{ + ctx: context.Background(), + }, + fields: fields{ + cluster: &gocql.ClusterConfig{}, + }, + want: want{ + err: gocql.ErrNoHosts, + }, + }, } for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt, goleakIgnoreOptions...) if test.beforeFunc != nil { test.beforeFunc(test.args) } @@ -448,122 +1305,21 @@ func Test_client_Close(t *testing.T) { return nil } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - args: args { - ctx: nil, - }, - fields: fields { - hosts: nil, - cqlVersion: "", - protoVersion: 0, - timeout: nil, - connectTimeout: nil, - port: 0, - keyspace: "", - numConns: 0, - consistency: nil, - compressor: nil, - username: "", - password: "", - authProvider: nil, - retryPolicy: struct{numRetries int; minDuration time.Duration; maxDuration time.Duration}{}, - reconnectionPolicy: struct{initialInterval time.Duration; maxRetries int}{}, - poolConfig: struct{dataCenterName string; enableDCAwareRouting bool; enableShuffleReplicas bool; enableNonLocalReplicasFallback bool; enableTokenAwareHostPolicy bool}{}, - hostFilter: struct{enable bool; dcHost string; whiteList []string}{}, - socketKeepalive: nil, - maxPreparedStmts: 0, - maxRoutingKeyInfo: 0, - pageSize: 0, - serialConsistency: nil, - tls: nil, - tlsCertPath: "", - tlsKeyPath: "", - tlsCAPath: "", - enableHostVerification: false, - defaultTimestamp: false, - reconnectInterval: nil, - maxWaitSchemaAgreement: nil, - ignorePeerAddr: false, - disableInitialHostLookup: false, - disableNodeStatusEvents: false, - disableTopologyEvents: false, - disableSchemaEvents: false, - disableSkipMetadata: false, - defaultIdempotence: false, - dialer: nil, - writeCoalesceWaitTime: nil, - cluster: nil, - session: nil, - }, - want: want{}, - checkFunc: defaultCheckFunc, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - args: args { - ctx: nil, - }, - fields: fields { - hosts: nil, - cqlVersion: "", - protoVersion: 0, - timeout: nil, - connectTimeout: nil, - port: 0, - keyspace: "", - numConns: 0, - consistency: nil, - compressor: nil, - username: "", - password: "", - authProvider: nil, - retryPolicy: struct{numRetries int; minDuration time.Duration; maxDuration time.Duration}{}, - reconnectionPolicy: struct{initialInterval time.Duration; maxRetries int}{}, - poolConfig: struct{dataCenterName string; enableDCAwareRouting bool; enableShuffleReplicas bool; enableNonLocalReplicasFallback bool; enableTokenAwareHostPolicy bool}{}, - hostFilter: struct{enable bool; dcHost string; whiteList []string}{}, - socketKeepalive: nil, - maxPreparedStmts: 0, - maxRoutingKeyInfo: 0, - pageSize: 0, - serialConsistency: nil, - tls: nil, - tlsCertPath: "", - tlsKeyPath: "", - tlsCAPath: "", - enableHostVerification: false, - defaultTimestamp: false, - reconnectInterval: nil, - maxWaitSchemaAgreement: nil, - ignorePeerAddr: false, - disableInitialHostLookup: false, - disableNodeStatusEvents: false, - disableTopologyEvents: false, - disableSchemaEvents: false, - disableSkipMetadata: false, - defaultIdempotence: false, - dialer: nil, - writeCoalesceWaitTime: nil, - cluster: nil, - session: nil, - }, - want: want{}, - checkFunc: defaultCheckFunc, - } - }(), - */ + { + name: "close return nil", + args: args{ + ctx: context.Background(), + }, + fields: fields{ + session: &gocql.Session{}, + }, + want: want{}, + }, } for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt, goleakIgnoreOptions...) if test.beforeFunc != nil { test.beforeFunc(test.args) } @@ -710,124 +1466,24 @@ func Test_client_Query(t *testing.T) { return nil } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - args: args { - stmt: "", - names: nil, - }, - fields: fields { - hosts: nil, - cqlVersion: "", - protoVersion: 0, - timeout: nil, - connectTimeout: nil, - port: 0, - keyspace: "", - numConns: 0, - consistency: nil, - compressor: nil, - username: "", - password: "", - authProvider: nil, - retryPolicy: struct{numRetries int; minDuration time.Duration; maxDuration time.Duration}{}, - reconnectionPolicy: struct{initialInterval time.Duration; maxRetries int}{}, - poolConfig: struct{dataCenterName string; enableDCAwareRouting bool; enableShuffleReplicas bool; enableNonLocalReplicasFallback bool; enableTokenAwareHostPolicy bool}{}, - hostFilter: struct{enable bool; dcHost string; whiteList []string}{}, - socketKeepalive: nil, - maxPreparedStmts: 0, - maxRoutingKeyInfo: 0, - pageSize: 0, - serialConsistency: nil, - tls: nil, - tlsCertPath: "", - tlsKeyPath: "", - tlsCAPath: "", - enableHostVerification: false, - defaultTimestamp: false, - reconnectInterval: nil, - maxWaitSchemaAgreement: nil, - ignorePeerAddr: false, - disableInitialHostLookup: false, - disableNodeStatusEvents: false, - disableTopologyEvents: false, - disableSchemaEvents: false, - disableSkipMetadata: false, - defaultIdempotence: false, - dialer: nil, - writeCoalesceWaitTime: nil, - cluster: nil, - session: nil, - }, - want: want{}, - checkFunc: defaultCheckFunc, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - args: args { - stmt: "", - names: nil, - }, - fields: fields { - hosts: nil, - cqlVersion: "", - protoVersion: 0, - timeout: nil, - connectTimeout: nil, - port: 0, - keyspace: "", - numConns: 0, - consistency: nil, - compressor: nil, - username: "", - password: "", - authProvider: nil, - retryPolicy: struct{numRetries int; minDuration time.Duration; maxDuration time.Duration}{}, - reconnectionPolicy: struct{initialInterval time.Duration; maxRetries int}{}, - poolConfig: struct{dataCenterName string; enableDCAwareRouting bool; enableShuffleReplicas bool; enableNonLocalReplicasFallback bool; enableTokenAwareHostPolicy bool}{}, - hostFilter: struct{enable bool; dcHost string; whiteList []string}{}, - socketKeepalive: nil, - maxPreparedStmts: 0, - maxRoutingKeyInfo: 0, - pageSize: 0, - serialConsistency: nil, - tls: nil, - tlsCertPath: "", - tlsKeyPath: "", - tlsCAPath: "", - enableHostVerification: false, - defaultTimestamp: false, - reconnectInterval: nil, - maxWaitSchemaAgreement: nil, - ignorePeerAddr: false, - disableInitialHostLookup: false, - disableNodeStatusEvents: false, - disableTopologyEvents: false, - disableSchemaEvents: false, - disableSkipMetadata: false, - defaultIdempotence: false, - dialer: nil, - writeCoalesceWaitTime: nil, - cluster: nil, - session: nil, - }, - want: want{}, - checkFunc: defaultCheckFunc, - } - }(), - */ + { + name: "query return gocqlx.Query", + args: args{ + stmt: "stmt", + names: []string{"n"}, + }, + fields: fields{ + session: &gocql.Session{}, + }, + want: want{ + gocqlx.Query(new(gocql.Session).Query("stmt"), []string{"n"}), + }, + }, } for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt, goleakIgnoreOptions...) if test.beforeFunc != nil { test.beforeFunc(test.args) } @@ -918,40 +1574,26 @@ func TestSelect(t *testing.T) { return nil } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - args: args { - table: "", - columns: nil, - cmps: nil, - }, - want: want{}, - checkFunc: defaultCheckFunc, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - args: args { - table: "", - columns: nil, - cmps: nil, - }, - want: want{}, - checkFunc: defaultCheckFunc, - } - }(), - */ + func() test { + stmt, names := qb.Select("t").Columns("col").Where(Eq("col")).ToCql() + return test{ + name: "selete return qb.select", + args: args{ + table: "t", + columns: []string{"col"}, + cmps: []Cmp{Eq("col")}, + }, + want: want{ + wantStmt: stmt, + wantNames: names, + }, + } + }(), } for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt, goleakIgnoreOptions...) if test.beforeFunc != nil { test.beforeFunc(test.args) } @@ -994,38 +1636,23 @@ func TestDelete(t *testing.T) { return nil } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - args: args { - table: "", - cmps: nil, - }, - want: want{}, - checkFunc: defaultCheckFunc, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - args: args { - table: "", - cmps: nil, - }, - want: want{}, - checkFunc: defaultCheckFunc, - } - }(), - */ + { + name: "delete returns qb.delete", + args: args{ + table: "t", + cmps: []Cmp{ + Eq("col"), + }, + }, + want: want{ + want: qb.Delete("t").Where(qb.Eq("col")), + }, + }, } for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt, goleakIgnoreOptions...) if test.beforeFunc != nil { test.beforeFunc(test.args) } @@ -1068,38 +1695,21 @@ func TestInsert(t *testing.T) { return nil } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - args: args { - table: "", - columns: nil, - }, - want: want{}, - checkFunc: defaultCheckFunc, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - args: args { - table: "", - columns: nil, - }, - want: want{}, - checkFunc: defaultCheckFunc, - } - }(), - */ + { + name: "insert return qb.insert", + args: args{ + table: "t", + columns: []string{"col"}, + }, + want: want{ + want: qb.Insert("t").Columns("col"), + }, + }, } for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt, goleakIgnoreOptions...) if test.beforeFunc != nil { test.beforeFunc(test.args) } @@ -1141,36 +1751,20 @@ func TestUpdate(t *testing.T) { return nil } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - args: args { - table: "", - }, - want: want{}, - checkFunc: defaultCheckFunc, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - args: args { - table: "", - }, - want: want{}, - checkFunc: defaultCheckFunc, - } - }(), - */ + { + name: "update return qb.update", + args: args{ + table: "t", + }, + want: want{ + want: qb.Update("t"), + }, + }, } for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt, goleakIgnoreOptions...) if test.beforeFunc != nil { test.beforeFunc(test.args) } @@ -1208,30 +1802,17 @@ func TestBatch(t *testing.T) { return nil } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - want: want{}, - checkFunc: defaultCheckFunc, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - want: want{}, - checkFunc: defaultCheckFunc, - } - }(), - */ + { + name: "bath return qb.batch", + want: want{ + want: qb.Batch(), + }, + }, } for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt, goleakIgnoreOptions...) if test.beforeFunc != nil { test.beforeFunc() } @@ -1273,36 +1854,20 @@ func TestEq(t *testing.T) { return nil } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - args: args { - column: "", - }, - want: want{}, - checkFunc: defaultCheckFunc, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - args: args { - column: "", - }, - want: want{}, - checkFunc: defaultCheckFunc, - } - }(), - */ + { + name: "eq return qb.eq", + args: args{ + column: "col", + }, + want: want{ + want: qb.Eq("col"), + }, + }, } for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt, goleakIgnoreOptions...) if test.beforeFunc != nil { test.beforeFunc(test.args) } @@ -1344,36 +1909,20 @@ func TestIn(t *testing.T) { return nil } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - args: args { - column: "", - }, - want: want{}, - checkFunc: defaultCheckFunc, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - args: args { - column: "", - }, - want: want{}, - checkFunc: defaultCheckFunc, - } - }(), - */ + { + name: "in return qb.in", + args: args{ + column: "col", + }, + want: want{ + want: qb.In("col"), + }, + }, } for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt, goleakIgnoreOptions...) if test.beforeFunc != nil { test.beforeFunc(test.args) } @@ -1415,36 +1964,20 @@ func TestContains(t *testing.T) { return nil } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - args: args { - column: "", - }, - want: want{}, - checkFunc: defaultCheckFunc, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - args: args { - column: "", - }, - want: want{}, - checkFunc: defaultCheckFunc, - } - }(), - */ + { + name: "contains return qb.contains", + args: args{ + column: "col", + }, + want: want{ + want: qb.Contains("col"), + }, + }, } for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt, goleakIgnoreOptions...) if test.beforeFunc != nil { test.beforeFunc(test.args) } From 6ec70a737d381fa224eff5db1850a306626a1460 Mon Sep 17 00:00:00 2001 From: kevindiu Date: Fri, 30 Oct 2020 16:30:27 +0900 Subject: [PATCH 2/6] add test --- internal/db/nosql/cassandra/cassandra.go | 6 +- internal/db/nosql/cassandra/cassandra_mock.go | 11 + internal/db/nosql/cassandra/cassandra_test.go | 444 +++++++++++++----- internal/db/nosql/cassandra/option_test.go | 20 - 4 files changed, 342 insertions(+), 139 deletions(-) create mode 100644 internal/db/nosql/cassandra/cassandra_mock.go diff --git a/internal/db/nosql/cassandra/cassandra.go b/internal/db/nosql/cassandra/cassandra.go index 9ffbade918..959c912a82 100644 --- a/internal/db/nosql/cassandra/cassandra.go +++ b/internal/db/nosql/cassandra/cassandra.go @@ -51,6 +51,10 @@ type Cassandra interface { Query(stmt string, names []string) *Queryx } +type ClusterConfig interface { + CreateSession() (*gocql.Session, error) +} + type ( Session = gocql.Session Cmp = qb.Cmp @@ -133,7 +137,7 @@ type ( dialer gocql.Dialer writeCoalesceWaitTime time.Duration - cluster *gocql.ClusterConfig + cluster ClusterConfig session *gocql.Session } ) diff --git a/internal/db/nosql/cassandra/cassandra_mock.go b/internal/db/nosql/cassandra/cassandra_mock.go new file mode 100644 index 0000000000..8a741d4e01 --- /dev/null +++ b/internal/db/nosql/cassandra/cassandra_mock.go @@ -0,0 +1,11 @@ +package cassandra + +import "github.com/gocql/gocql" + +type MockClusterConfig struct { + CreateSessionFunc func() (*gocql.Session, error) +} + +func (m *MockClusterConfig) CreateSession() (*gocql.Session, error) { + return m.CreateSessionFunc() +} diff --git a/internal/db/nosql/cassandra/cassandra_test.go b/internal/db/nosql/cassandra/cassandra_test.go index 89bfeed7c6..1f85187c8e 100644 --- a/internal/db/nosql/cassandra/cassandra_test.go +++ b/internal/db/nosql/cassandra/cassandra_test.go @@ -73,6 +73,11 @@ var ( if x == nil && y == nil { return true } + + switch x.(type) { + case gocql.HostFilterFunc: + return true + } return reflect.ValueOf(x).Pointer() == reflect.ValueOf(y).Pointer() }), @@ -855,90 +860,99 @@ func TestNew(t *testing.T) { }, }, }, - /* - { - name: "New returns cassandra with host filter and whitelist enabled", - args: args{ - opts: []Option{ - WithHostFilter(true), - WithDCHostFilter("dc"), - WithWhiteListHostFilter("localhost"), - }, + { + name: "New returns cassandra with host filter and whitelist enabled", + args: args{ + opts: []Option{ + WithHostFilter(true), + WithDCHostFilter("dc"), + WithWhiteListHostFilter([]string{"localhost"}), }, - want: want{ - want: &client{ - cqlVersion: "3.0.0", - connectTimeout: 600 * time.Millisecond, - consistency: gocql.Quorum, - defaultIdempotence: false, - defaultTimestamp: true, - disableInitialHostLookup: false, - disableNodeStatusEvents: false, - disableSkipMetadata: false, - disableTopologyEvents: false, - enableHostVerification: false, - ignorePeerAddr: false, - maxPreparedStmts: 1000, - maxRoutingKeyInfo: 1000, - maxWaitSchemaAgreement: 1 * time.Minute, - numConns: 2, - pageSize: 5000, - port: 9042, - protoVersion: 0, - reconnectInterval: time.Minute, - serialConsistency: gocql.LocalSerial, - timeout: 600 * time.Millisecond, - writeCoalesceWaitTime: 200 * time.Microsecond, - cluster: &gocql.ClusterConfig{ - Authenticator: func() *gocql.PasswordAuthenticator { - return nil - }(), - RetryPolicy: func() *gocql.ExponentialBackoffRetryPolicy { - return nil + }, + want: want{ + want: &client{ + cqlVersion: "3.0.0", + connectTimeout: 600 * time.Millisecond, + consistency: gocql.Quorum, + defaultIdempotence: false, + defaultTimestamp: true, + disableInitialHostLookup: false, + disableNodeStatusEvents: false, + disableSkipMetadata: false, + disableTopologyEvents: false, + enableHostVerification: false, + ignorePeerAddr: false, + maxPreparedStmts: 1000, + maxRoutingKeyInfo: 1000, + maxWaitSchemaAgreement: 1 * time.Minute, + numConns: 2, + pageSize: 5000, + port: 9042, + protoVersion: 0, + reconnectInterval: time.Minute, + serialConsistency: gocql.LocalSerial, + timeout: 600 * time.Millisecond, + writeCoalesceWaitTime: 200 * time.Microsecond, + hostFilter: hostFilter{ + enable: true, + dcHost: "dc", + whiteList: []string{"localhost"}, + }, + cluster: &gocql.ClusterConfig{ + Authenticator: func() *gocql.PasswordAuthenticator { + return nil + }(), + RetryPolicy: func() *gocql.ExponentialBackoffRetryPolicy { + return nil + }(), + ConvictionPolicy: NewConvictionPolicy(), + ReconnectionPolicy: &gocql.ExponentialReconnectionPolicy{}, + PoolConfig: gocql.PoolConfig{ + HostSelectionPolicy: func() gocql.HostSelectionPolicy { + return gocql.TokenAwareHostPolicy(gocql.RoundRobinHostPolicy()) }(), - ConvictionPolicy: NewConvictionPolicy(), - ReconnectionPolicy: &gocql.ExponentialReconnectionPolicy{}, - PoolConfig: gocql.PoolConfig{ - HostSelectionPolicy: func() gocql.HostSelectionPolicy { - return gocql.TokenAwareHostPolicy(gocql.RoundRobinHostPolicy()) - }(), - }, - HostFilter: , - - CQLVersion: "3.0.0", - ConnectTimeout: 600 * time.Millisecond, - Consistency: gocql.Quorum, - DefaultIdempotence: false, - DefaultTimestamp: true, - DisableInitialHostLookup: false, - Events: events{ - DisableNodeStatusEvents: false, - DisableTopologyEvents: false, - }, - DisableSkipMetadata: false, - IgnorePeerAddr: false, - MaxPreparedStmts: 1000, - MaxRoutingKeyInfo: 1000, - MaxWaitSchemaAgreement: 1 * time.Minute, - NumConns: 2, - PageSize: 5000, - Port: 9042, - ProtoVersion: 0, - ReconnectInterval: time.Minute, - SerialConsistency: gocql.LocalSerial, - Timeout: 600 * time.Millisecond, - WriteCoalesceWaitTime: 200 * time.Microsecond, }, - poolConfig: poolConfig{ - enableDCAwareRouting: false, - enableNonLocalReplicasFallback: false, - enableShuffleReplicas: false, - enableTokenAwareHostPolicy: true, + HostFilter: func() gocql.HostFilter { + dchf := gocql.DataCentreHostFilter("dc") + wlhf := gocql.WhiteListHostFilter("localhost") + return gocql.HostFilterFunc(func(host *gocql.HostInfo) bool { + return dchf.Accept(host) || wlhf.Accept(host) + }) + }(), + + CQLVersion: "3.0.0", + ConnectTimeout: 600 * time.Millisecond, + Consistency: gocql.Quorum, + DefaultIdempotence: false, + DefaultTimestamp: true, + DisableInitialHostLookup: false, + Events: events{ + DisableNodeStatusEvents: false, + DisableTopologyEvents: false, }, + DisableSkipMetadata: false, + IgnorePeerAddr: false, + MaxPreparedStmts: 1000, + MaxRoutingKeyInfo: 1000, + MaxWaitSchemaAgreement: 1 * time.Minute, + NumConns: 2, + PageSize: 5000, + Port: 9042, + ProtoVersion: 0, + ReconnectInterval: time.Minute, + SerialConsistency: gocql.LocalSerial, + Timeout: 600 * time.Millisecond, + WriteCoalesceWaitTime: 200 * time.Microsecond, + }, + poolConfig: poolConfig{ + enableDCAwareRouting: false, + enableNonLocalReplicasFallback: false, + enableShuffleReplicas: false, + enableTokenAwareHostPolicy: true, }, }, }, - */ + }, { name: "New returns cassandra with tls", args: args{ @@ -1022,6 +1036,100 @@ func TestNew(t *testing.T) { }, }, }, + { + name: "New failed to init cassandra and return error", + args: args{ + opts: []Option{ + func(*client) error { + return errors.NewErrCriticalOption("n", 1) + }, + }, + }, + want: want{ + err: errors.NewErrCriticalOption("n", 1), + }, + }, + { + name: "New returns default cassandra with option fail", + args: args{ + opts: []Option{ + func(*client) error { + return errors.New("err") + }, + }, + }, + want: want{ + want: &client{ + cqlVersion: "3.0.0", + connectTimeout: 600 * time.Millisecond, + consistency: gocql.Quorum, + defaultIdempotence: false, + defaultTimestamp: true, + disableInitialHostLookup: false, + disableNodeStatusEvents: false, + disableSkipMetadata: false, + disableTopologyEvents: false, + enableHostVerification: false, + ignorePeerAddr: false, + maxPreparedStmts: 1000, + maxRoutingKeyInfo: 1000, + maxWaitSchemaAgreement: 1 * time.Minute, + numConns: 2, + pageSize: 5000, + port: 9042, + protoVersion: 0, + reconnectInterval: time.Minute, + serialConsistency: gocql.LocalSerial, + timeout: 600 * time.Millisecond, + writeCoalesceWaitTime: 200 * time.Microsecond, + cluster: &gocql.ClusterConfig{ + Authenticator: func() *gocql.PasswordAuthenticator { + return nil + }(), + RetryPolicy: func() *gocql.ExponentialBackoffRetryPolicy { + return nil + }(), + ConvictionPolicy: NewConvictionPolicy(), + ReconnectionPolicy: &gocql.ExponentialReconnectionPolicy{}, + PoolConfig: gocql.PoolConfig{ + HostSelectionPolicy: func() gocql.HostSelectionPolicy { + return gocql.TokenAwareHostPolicy(gocql.RoundRobinHostPolicy()) + }(), + }, + + CQLVersion: "3.0.0", + ConnectTimeout: 600 * time.Millisecond, + Consistency: gocql.Quorum, + DefaultIdempotence: false, + DefaultTimestamp: true, + DisableInitialHostLookup: false, + Events: events{ + DisableNodeStatusEvents: false, + DisableTopologyEvents: false, + }, + DisableSkipMetadata: false, + IgnorePeerAddr: false, + MaxPreparedStmts: 1000, + MaxRoutingKeyInfo: 1000, + MaxWaitSchemaAgreement: 1 * time.Minute, + NumConns: 2, + PageSize: 5000, + Port: 9042, + ProtoVersion: 0, + ReconnectInterval: time.Minute, + SerialConsistency: gocql.LocalSerial, + Timeout: 600 * time.Millisecond, + WriteCoalesceWaitTime: 200 * time.Microsecond, + }, + poolConfig: poolConfig{ + enableDCAwareRouting: false, + enableNonLocalReplicasFallback: false, + enableShuffleReplicas: false, + enableTokenAwareHostPolicy: true, + }, + }, + }, + }, } for _, test := range tests { @@ -1107,7 +1215,7 @@ func Test_client_Open(t *testing.T) { defaultIdempotence bool dialer gocql.Dialer writeCoalesceWaitTime time.Duration - cluster *gocql.ClusterConfig + cluster ClusterConfig session *gocql.Session } type want struct { @@ -1129,20 +1237,20 @@ func Test_client_Open(t *testing.T) { return nil } tests := []test{ - /* - { - name: "open create session success", - args: args{ - ctx: context.Background(), - }, - fields: fields{ - cluster: &gocql.ClusterConfig{ - Hosts: []string{"127.0.0.1"}, + { + name: "open create session success", + args: args{ + ctx: context.Background(), + }, + fields: fields{ + cluster: &MockClusterConfig{ + CreateSessionFunc: func() (*gocql.Session, error) { + return nil, nil }, }, - want: want{}, }, - */ + want: want{}, + }, { name: "open create session and return any error if occured", args: args{ @@ -1159,7 +1267,7 @@ func Test_client_Open(t *testing.T) { for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(tt, goleakIgnoreOptions...) + defer goleak.VerifyNone(tt, append(goleakIgnoreOptions, goleak.IgnoreTopFunction("github.com/gocql/gocql.(*eventDebouncer).flusher"))...) if test.beforeFunc != nil { test.beforeFunc(test.args) } @@ -2020,38 +2128,138 @@ func TestWrapErrorWithKeys(t *testing.T) { return nil } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - args: args { - err: nil, - keys: nil, - }, - want: want{}, - checkFunc: defaultCheckFunc, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - args: args { - err: nil, - keys: nil, - }, - want: want{}, - checkFunc: defaultCheckFunc, - } - }(), - */ + { + name: "return error not found", + args: args{ + err: ErrNotFound, + keys: []string{"k1"}, + }, + want: want{ + err: errors.ErrCassandraNotFound("k1"), + }, + }, + { + name: "return unavilable error", + args: args{ + err: ErrUnavailable, + }, + want: want{ + err: errors.ErrCassandraUnavailable(), + }, + }, + { + name: "return unsupported error", + args: args{ + err: ErrUnsupported, + }, + want: want{ + err: ErrUnsupported, + }, + }, + { + name: "return too many stmts error", + args: args{ + err: ErrTooManyStmts, + }, + want: want{ + err: ErrTooManyStmts, + }, + }, + { + name: "return use stmt error", + args: args{ + err: ErrUseStmt, + }, + want: want{ + err: ErrUseStmt, + }, + }, + { + name: "return session closed error", + args: args{ + err: ErrSessionClosed, + }, + want: want{ + err: ErrSessionClosed, + }, + }, + { + name: "return no connection error", + args: args{ + err: ErrNoConnections, + }, + want: want{ + err: ErrNoConnections, + }, + }, + { + name: "return no keyspace error", + args: args{ + err: ErrNoKeyspace, + }, + want: want{ + err: ErrNoKeyspace, + }, + }, + { + name: "return keyspace does not exist error", + args: args{ + err: ErrKeyspaceDoesNotExist, + }, + want: want{ + err: ErrKeyspaceDoesNotExist, + }, + }, + { + name: "return no metadata error", + args: args{ + err: ErrNoMetadata, + }, + want: want{ + err: ErrNoMetadata, + }, + }, + { + name: "return no hosts error", + args: args{ + err: ErrNoHosts, + }, + want: want{ + err: ErrNoHosts, + }, + }, + { + name: "return no connection started error", + args: args{ + err: ErrNoConnectionsStarted, + }, + want: want{ + err: ErrNoConnectionsStarted, + }, + }, + { + name: "return host query failed error", + args: args{ + err: ErrHostQueryFailed, + }, + want: want{ + err: ErrHostQueryFailed, + }, + }, + { + name: "return other error", + args: args{ + err: errors.New("err"), + }, + want: want{ + err: errors.New("err"), + }, + }, } for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt, goleakIgnoreOptions...) if test.beforeFunc != nil { test.beforeFunc(test.args) } diff --git a/internal/db/nosql/cassandra/option_test.go b/internal/db/nosql/cassandra/option_test.go index df92c779bd..bb285a74f8 100644 --- a/internal/db/nosql/cassandra/option_test.go +++ b/internal/db/nosql/cassandra/option_test.go @@ -35,26 +35,6 @@ var ( goleakIgnoreOptions = []goleak.Option{ goleak.IgnoreTopFunction("github.com/kpango/fastime.(*Fastime).StartTimerD.func1"), } - - // default comparator option for client - clientComparatorOpts = []comparator.Option{ - comparator.AllowUnexported(client{}), - comparator.Comparer(func(x, y retryPolicy) bool { - return reflect.DeepEqual(x, y) - }), - comparator.Comparer(func(x, y reconnectionPolicy) bool { - return reflect.DeepEqual(x, y) - }), - comparator.Comparer(func(x, y poolConfig) bool { - return reflect.DeepEqual(x, y) - }), - comparator.Comparer(func(x, y hostFilter) bool { - return reflect.DeepEqual(x, y) - }), - comparator.Comparer(func(x, y func(h *gocql.HostInfo) (gocql.Authenticator, error)) bool { - return reflect.ValueOf(x).Pointer() == reflect.ValueOf(y).Pointer() - }), - } ) func TestWithHosts(t *testing.T) { From 2fe3fd9ce1316e84c72b79f93545dd84b1b4169d Mon Sep 17 00:00:00 2001 From: kevindiu Date: Fri, 30 Oct 2020 16:38:06 +0900 Subject: [PATCH 3/6] fix --- internal/db/nosql/cassandra/conviction_test.go | 7 ------- 1 file changed, 7 deletions(-) diff --git a/internal/db/nosql/cassandra/conviction_test.go b/internal/db/nosql/cassandra/conviction_test.go index c232fe70b0..773ad49049 100644 --- a/internal/db/nosql/cassandra/conviction_test.go +++ b/internal/db/nosql/cassandra/conviction_test.go @@ -18,22 +18,15 @@ package cassandra import ( "net" - "os" "reflect" "testing" "github.com/gocql/gocql" "github.com/vdaas/vald/internal/errors" - "github.com/vdaas/vald/internal/log" "go.uber.org/goleak" ) -func TestMain(m *testing.M) { - log.Init() - os.Exit(m.Run()) -} - func TestNewConvictionPolicy(t *testing.T) { type want struct { want gocql.ConvictionPolicy From b7c24d923c2cbca9067204c10fe6b13edc3d929a Mon Sep 17 00:00:00 2001 From: kevindiu Date: Fri, 30 Oct 2020 16:53:29 +0900 Subject: [PATCH 4/6] fix typo --- internal/db/nosql/cassandra/cassandra_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/db/nosql/cassandra/cassandra_test.go b/internal/db/nosql/cassandra/cassandra_test.go index 1f85187c8e..aaec05089c 100644 --- a/internal/db/nosql/cassandra/cassandra_test.go +++ b/internal/db/nosql/cassandra/cassandra_test.go @@ -1252,7 +1252,7 @@ func Test_client_Open(t *testing.T) { want: want{}, }, { - name: "open create session and return any error if occured", + name: "open create session and return any error if occurred", args: args{ ctx: context.Background(), }, From 3c4dfed231e65174e89d0444a489595f2836622e Mon Sep 17 00:00:00 2001 From: kevindiu Date: Fri, 30 Oct 2020 17:31:09 +0900 Subject: [PATCH 5/6] add comment --- internal/db/nosql/cassandra/cassandra.go | 65 ++++++++++++++++++------ 1 file changed, 50 insertions(+), 15 deletions(-) diff --git a/internal/db/nosql/cassandra/cassandra.go b/internal/db/nosql/cassandra/cassandra.go index 959c912a82..6a53e4912e 100644 --- a/internal/db/nosql/cassandra/cassandra.go +++ b/internal/db/nosql/cassandra/cassandra.go @@ -30,39 +30,61 @@ import ( ) var ( - ErrNotFound = gocql.ErrNotFound - ErrUnavailable = gocql.ErrUnavailable - ErrUnsupported = gocql.ErrUnsupported - ErrTooManyStmts = gocql.ErrTooManyStmts - ErrUseStmt = gocql.ErrUseStmt - ErrSessionClosed = gocql.ErrSessionClosed - ErrNoConnections = gocql.ErrNoConnections - ErrNoKeyspace = gocql.ErrNoKeyspace + // ErrNotFound is a alias of gocql.ErrNotFound + ErrNotFound = gocql.ErrNotFound + // ErrUnavailable is a alias of gocql.ErrUnavailable + ErrUnavailable = gocql.ErrUnavailable + // ErrUnsupported is a alias of gocql.ErrUnsupported + ErrUnsupported = gocql.ErrUnsupported + // ErrTooManyStmts is a alias of gocql.ErrTooManyStmts + ErrTooManyStmts = gocql.ErrTooManyStmts + // ErrUseStmt is a alias of gocql.ErrUseStmt + ErrUseStmt = gocql.ErrUseStmt + // ErrSessionClosed is a alias of gocql.ErrSessionClosed + ErrSessionClosed = gocql.ErrSessionClosed + // ErrNoConnections is a alias of gocql.ErrNoConnections + ErrNoConnections = gocql.ErrNoConnections + // ErrNoKeyspace is a alias of gocql.ErrNoKeyspace + ErrNoKeyspace = gocql.ErrNoKeyspace + // ErrKeyspaceDoesNotExist is a alias of gocql.ErrKeyspaceDoesNotExist ErrKeyspaceDoesNotExist = gocql.ErrKeyspaceDoesNotExist - ErrNoMetadata = gocql.ErrNoMetadata - ErrNoHosts = gocql.ErrNoHosts + // ErrNoMetadata is a alias of gocql.ErrNoMetadata + ErrNoMetadata = gocql.ErrNoMetadata + // ErrNoHosts is a alias of gocql.ErrNoHosts + ErrNoHosts = gocql.ErrNoHosts + // ErrNoConnectionsStarted is a alias of gocql.ErrNoConnectionsStarted ErrNoConnectionsStarted = gocql.ErrNoConnectionsStarted - ErrHostQueryFailed = gocql.ErrHostQueryFailed + // ErrHostQueryFailed is a alias of gocql.ErrHostQueryFailed + ErrHostQueryFailed = gocql.ErrHostQueryFailed ) +// Cassandra represent an interface to query on cassandra type Cassandra interface { Open(ctx context.Context) error Close(ctx context.Context) error Query(stmt string, names []string) *Queryx } +// ClusterConfig represent an interface of cassandra cluster configuation type ClusterConfig interface { CreateSession() (*gocql.Session, error) } type ( - Session = gocql.Session - Cmp = qb.Cmp - BatchBuilder = qb.BatchBuilder + // Session is a alias of gocql.Session + Session = gocql.Session + // Cmp is a alias of qb.Cmp + Cmp = qb.Cmp + // BatchBuilder is a alias of qb.BatchBuilder + BatchBuilder = qb.BatchBuilder + // InsertBuilder is a alias of qb.InsertBuilder InsertBuilder = qb.InsertBuilder + // DeleteBuilder is a alias of qb.DeleteBuilder DeleteBuilder = qb.DeleteBuilder + // UpdateBuilder is a alias of qb.UpdateBuilder UpdateBuilder = qb.UpdateBuilder - Queryx = gocqlx.Queryx + // Queryx is a alias of gocqlx.Queryx + Queryx = gocqlx.Queryx ) type ( @@ -142,6 +164,7 @@ type ( } ) +// New initialize and return the cassandra client, or any error occurred. func New(opts ...Option) (Cassandra, error) { c := new(client) for _, opt := range append(defaultOpts, opts...) { @@ -276,6 +299,7 @@ func New(opts ...Option) (Cassandra, error) { return c, nil } +// Open creates a session to cassandra and return any error occurred func (c *client) Open(ctx context.Context) (err error) { if c.session, err = c.cluster.CreateSession(); err != nil { return err @@ -283,15 +307,18 @@ func (c *client) Open(ctx context.Context) (err error) { return nil } +// Close closes the session to cassandra func (c *client) Close(ctx context.Context) error { c.session.Close() return nil } +// Query creates an query that can be executed on cassandra func (c *client) Query(stmt string, names []string) *Queryx { return gocqlx.Query(c.session.Query(stmt), names) } +// Select build and returns the cql string and the named args func Select(table string, columns []string, cmps ...Cmp) (stmt string, names []string) { sb := qb.Select(table).Columns(columns...) for _, cmp := range cmps { @@ -300,6 +327,7 @@ func Select(table string, columns []string, cmps ...Cmp) (stmt string, names []s return sb.ToCql() } +// Delete returns the delete builder func Delete(table string, cmps ...Cmp) *DeleteBuilder { db := qb.Delete(table) for _, cmp := range cmps { @@ -308,30 +336,37 @@ func Delete(table string, cmps ...Cmp) *DeleteBuilder { return db } +// Insert returns the insert builder func Insert(table string, columns ...string) *InsertBuilder { return qb.Insert(table).Columns(columns...) } +// Update returns the update builder func Update(table string) *UpdateBuilder { return qb.Update(table) } +// Batch returns the batch builder func Batch() *BatchBuilder { return qb.Batch() } +// Eq returns the equal comparator func Eq(column string) Cmp { return qb.Eq(column) } +// In returns the in comparator func In(column string) Cmp { return qb.In(column) } +// Contains return the contains comparator func Contains(column string) Cmp { return qb.Contains(column) } +// WrapErrorWithKeys wraps the cassandra error to Vald internal error func WrapErrorWithKeys(err error, keys ...string) error { switch err { case ErrNotFound: From 8e4d82c5724b277f7ff144ab96f41f4d4d393b0d Mon Sep 17 00:00:00 2001 From: kevindiu Date: Wed, 4 Nov 2020 18:19:57 +0900 Subject: [PATCH 6/6] fix --- internal/db/nosql/cassandra/cassandra_test.go | 113 +++++++++++++----- 1 file changed, 86 insertions(+), 27 deletions(-) diff --git a/internal/db/nosql/cassandra/cassandra_test.go b/internal/db/nosql/cassandra/cassandra_test.go index aaec05089c..90ca6e7622 100644 --- a/internal/db/nosql/cassandra/cassandra_test.go +++ b/internal/db/nosql/cassandra/cassandra_test.go @@ -1219,6 +1219,7 @@ func Test_client_Open(t *testing.T) { session *gocql.Session } type want struct { + c *client err error } type test struct { @@ -1226,43 +1227,60 @@ func Test_client_Open(t *testing.T) { args args fields fields want want - checkFunc func(want, error) error + checkFunc func(*client, want, error) error beforeFunc func(args) afterFunc func(args) } - defaultCheckFunc := func(w want, err error) error { + defaultCheckFunc := func(c *client, w want, err error) error { if !errors.Is(err, w.err) { return errors.Errorf("got_error: \"%#v\",\n\t\t\t\twant: \"%#v\"", err, w.err) } + if !reflect.DeepEqual(c, w.c) { + return errors.New("client is not equal") + } return nil } tests := []test{ - { - name: "open create session success", - args: args{ - ctx: context.Background(), - }, - fields: fields{ - cluster: &MockClusterConfig{ - CreateSessionFunc: func() (*gocql.Session, error) { - return nil, nil + func() test { + cf := &MockClusterConfig{ + CreateSessionFunc: func() (*gocql.Session, error) { + return &gocql.Session{}, nil + }, + } + + return test{ + name: "open create session success", + args: args{ + ctx: context.Background(), + }, + fields: fields{ + cluster: cf, + }, + want: want{ + c: &client{ + cluster: cf, + session: &gocql.Session{}, }, }, - }, - want: want{}, - }, - { - name: "open create session and return any error if occurred", - args: args{ - ctx: context.Background(), - }, - fields: fields{ - cluster: &gocql.ClusterConfig{}, - }, - want: want{ - err: gocql.ErrNoHosts, - }, - }, + } + }(), + func() test { + return test{ + name: "open create session and return any error if occurred", + args: args{ + ctx: context.Background(), + }, + fields: fields{ + cluster: &gocql.ClusterConfig{}, + }, + want: want{ + err: gocql.ErrNoHosts, + c: &client{ + cluster: &gocql.ClusterConfig{}, + }, + }, + } + }(), } for _, test := range tests { @@ -1322,7 +1340,7 @@ func Test_client_Open(t *testing.T) { } err := c.Open(test.args.ctx) - if err := test.checkFunc(test.want, err); err != nil { + if err := test.checkFunc(c, test.want, err); err != nil { tt.Errorf("error = %v", err) } @@ -1587,6 +1605,19 @@ func Test_client_Query(t *testing.T) { gocqlx.Query(new(gocql.Session).Query("stmt"), []string{"n"}), }, }, + { + name: "query return gocqlx.Query with names", + args: args{ + stmt: "stmt", + names: []string{"n", "n1"}, + }, + fields: fields{ + session: &gocql.Session{}, + }, + want: want{ + gocqlx.Query(new(gocql.Session).Query("stmt"), []string{"n", "n1"}), + }, + }, } for _, test := range tests { @@ -1697,6 +1728,21 @@ func TestSelect(t *testing.T) { }, } }(), + func() test { + stmt, names := qb.Select("t").Columns("col", "col1").Where(Eq("cmp")).Where(Eq("cmp1")).ToCql() + return test{ + name: "selete return qb.select with cols and cmps", + args: args{ + table: "t", + columns: []string{"col", "col1"}, + cmps: []Cmp{Eq("cmp"), Eq("cmp1")}, + }, + want: want{ + wantStmt: stmt, + wantNames: names, + }, + } + }(), } for _, test := range tests { @@ -1756,6 +1802,19 @@ func TestDelete(t *testing.T) { want: qb.Delete("t").Where(qb.Eq("col")), }, }, + { + name: "delete returns qb.delete with cmps", + args: args{ + table: "t", + cmps: []Cmp{ + Eq("col"), + Eq("col1"), + }, + }, + want: want{ + want: qb.Delete("t").Where(qb.Eq("col")).Where(qb.Eq("col1")), + }, + }, } for _, test := range tests {