diff --git a/.golangci.yml b/.golangci.yml index 7fc6b32f..bf3e1cbc 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -17,6 +17,14 @@ linters: - staticcheck - lll - errorlint + - gocritic + - gosimple + - predeclared + - revive + - thelper + - tparallel + - typecheck + - unused run: deadline: 10m modules-download-mode: readonly diff --git a/cmd/gemini/root.go b/cmd/gemini/root.go index 8f17b49b..bb7fc812 100644 --- a/cmd/gemini/root.go +++ b/cmd/gemini/root.go @@ -140,7 +140,7 @@ func (cb createBuilder) ToCql() (stmt string, names []string) { return cb.stmt, nil } -func run(cmd *cobra.Command, args []string) error { +func run(_ *cobra.Command, _ []string) error { logger := createLogger(level) globalStatus := status.NewGlobalStatus(1000) defer utils.IgnoreError(logger.Sync) diff --git a/pkg/auth/auth_test.go b/pkg/auth/auth_test.go index 24f47645..624cbc29 100644 --- a/pkg/auth/auth_test.go +++ b/pkg/auth/auth_test.go @@ -64,11 +64,12 @@ func TestSetAuthenticator(t *testing.T) { test.input.username, test.input.password, ) - if test.err == "" && err != nil { + switch { + case test.err == "" && err != nil: t.Fatalf("Returned unexpected error '%s'", err.Error()) - } else if test.err != "" && err == nil { + case test.err != "" && err == nil: t.Fatalf("Expected error '%s' but none was returned", test.err) - } else if test.err != "" && err != nil && err.Error() != test.err { + case test.err != "" && err != nil && err.Error() != test.err: t.Fatalf("Returned error '%s' doesn't match expected error '%s'", err.Error(), test.err) } if diff := cmp.Diff(test.want, authenticator); diff != "" { diff --git a/pkg/coltypes/bag.go b/pkg/coltypes/bag.go index dce5127d..06f60dc0 100644 --- a/pkg/coltypes/bag.go +++ b/pkg/coltypes/bag.go @@ -62,19 +62,18 @@ func (ct *BagType) CQLPretty(query string, value []interface{}) (string, int) { if len(value) == 0 { return query, 0 } - switch reflect.TypeOf(value[0]).Kind() { - case reflect.Slice: - s := reflect.ValueOf(value[0]) - vv := "{" - vv += strings.Repeat("?,", s.Len()) - vv = strings.TrimRight(vv, ",") - vv += "}" - for i := 0; i < s.Len(); i++ { - vv, _ = ct.Type.CQLPretty(vv, []interface{}{s.Index(i).Interface()}) - } - return strings.Replace(query, "?", vv, 1), 1 + if reflect.TypeOf(value[0]).Kind() != reflect.Slice { + panic(fmt.Sprintf("set cql pretty, unknown type %v", ct)) } - panic(fmt.Sprintf("set cql pretty, unknown type %v", ct)) + s := reflect.ValueOf(value[0]) + vv := "{" + vv += strings.Repeat("?,", s.Len()) + vv = strings.TrimRight(vv, ",") + vv += "}" + for i := 0; i < s.Len(); i++ { + vv, _ = ct.Type.CQLPretty(vv, []interface{}{s.Index(i).Interface()}) + } + return strings.Replace(query, "?", vv, 1), 1 } func (ct *BagType) GenValue(r *rand.Rand, p *typedef.PartitionRangeConfig) []interface{} { diff --git a/pkg/coltypes/simple_type.go b/pkg/coltypes/simple_type.go index ae8ff2b1..21baee65 100644 --- a/pkg/coltypes/simple_type.go +++ b/pkg/coltypes/simple_type.go @@ -185,7 +185,7 @@ func (st SimpleType) GenValue(r *rand.Rand, p *typedef.PartitionRangeConfig) []i case TYPE_FLOAT: val = r.Float32() case TYPE_INET: - val = net.ParseIP(utils.RandIpV4Address(r, r.Intn(255), 2)).String() + val = net.ParseIP(utils.RandIPV4Address(r, r.Intn(255), 2)).String() case TYPE_INT: val = r.Int31() case TYPE_SMALLINT: diff --git a/pkg/coltypes/types.go b/pkg/coltypes/types.go index 317e43bb..af47bc9f 100644 --- a/pkg/coltypes/types.go +++ b/pkg/coltypes/types.go @@ -27,6 +27,7 @@ import ( "github.com/scylladb/gemini/pkg/utils" ) +// nolint:revive const ( TYPE_ASCII = SimpleType("ascii") TYPE_BIGINT = SimpleType("bigint") @@ -121,19 +122,18 @@ func (mt *MapType) CQLHolder() string { } func (mt *MapType) CQLPretty(query string, value []interface{}) (string, int) { - switch reflect.TypeOf(value[0]).Kind() { - case reflect.Map: - s := reflect.ValueOf(value[0]).MapRange() - vv := "{" - for s.Next() { - vv += fmt.Sprintf("%v:?,", s.Key().Interface()) - vv, _ = mt.ValueType.CQLPretty(vv, []interface{}{s.Value().Interface()}) - } - vv = strings.TrimSuffix(vv, ",") - vv += "}" - return strings.Replace(query, "?", vv, 1), 1 + if reflect.TypeOf(value[0]).Kind() != reflect.Map { + panic(fmt.Sprintf("map cql pretty, unknown type %v", mt)) } - panic(fmt.Sprintf("map cql pretty, unknown type %v", mt)) + s := reflect.ValueOf(value[0]).MapRange() + vv := "{" + for s.Next() { + vv += fmt.Sprintf("%v:?,", s.Key().Interface()) + vv, _ = mt.ValueType.CQLPretty(vv, []interface{}{s.Value().Interface()}) + } + vv = strings.TrimSuffix(vv, ",") + vv += "}" + return strings.Replace(query, "?", vv, 1), 1 } func (mt *MapType) GenValue(r *rand.Rand, p *typedef.PartitionRangeConfig) []interface{} { @@ -180,7 +180,7 @@ func (ct *CounterType) CQLPretty(query string, value []interface{}) (string, int return strings.Replace(query, "?", fmt.Sprintf("%d", value[0]), 1), 1 } -func (ct *CounterType) GenValue(r *rand.Rand, p *typedef.PartitionRangeConfig) []interface{} { +func (ct *CounterType) GenValue(r *rand.Rand, _ *typedef.PartitionRangeConfig) []interface{} { if utils.UnderTest { return []interface{}{r.Int63()} } diff --git a/pkg/generators/column_generator.go b/pkg/generators/column_generator.go index 6b44aab1..9496878c 100644 --- a/pkg/generators/column_generator.go +++ b/pkg/generators/column_generator.go @@ -45,7 +45,7 @@ func GenColumnType(numColumns int, sc *typedef.SchemaConfig) typedef.Type { } } -func GenSimpleType(sc *typedef.SchemaConfig) coltypes.SimpleType { +func GenSimpleType(_ *typedef.SchemaConfig) coltypes.SimpleType { return coltypes.AllTypes[rand.Intn(len(coltypes.AllTypes))] } diff --git a/pkg/generators/generator.go b/pkg/generators/generator.go index 60356f57..98a6b1b7 100644 --- a/pkg/generators/generator.go +++ b/pkg/generators/generator.go @@ -163,7 +163,7 @@ func (g *Generator) start() { } grp.Go(func() error { g.logger.Info("starting partition key generation loop") - routingKeyCreator := &routingkey.RoutingKeyCreator{} + routingKeyCreator := &routingkey.Creator{} r := rand.New(rand.NewSource(g.seed)) var ( cntCreated uint64 diff --git a/pkg/generators/statement_generator.go b/pkg/generators/statement_generator.go index 134a0fcd..7412e30a 100644 --- a/pkg/generators/statement_generator.go +++ b/pkg/generators/statement_generator.go @@ -353,7 +353,7 @@ func genMultiplePartitionClusteringRangeQuery( func genSingleIndexQuery( s *testschema.Schema, t *testschema.Table, - g GeneratorInterface, + _ GeneratorInterface, r *rand.Rand, p *typedef.PartitionRangeConfig, idxCount int, @@ -398,7 +398,7 @@ func genInsertOrUpdateStmt( return genInsertStmt(s, t, valuesWithToken, r, p, useLWT) } -func genUpdateStmt(s *testschema.Schema, t *testschema.Table, valuesWithToken *typedef.ValueWithToken, r *rand.Rand, p *typedef.PartitionRangeConfig) (*typedef.Stmt, error) { +func genUpdateStmt(_ *testschema.Schema, t *testschema.Table, valuesWithToken *typedef.ValueWithToken, r *rand.Rand, p *typedef.PartitionRangeConfig) (*typedef.Stmt, error) { stmtCache := t.GetQueryCache(typedef.CacheUpdate) nonCounters := t.Columns.NonCounters() values := make(typedef.Values, 0, t.PartitionKeys.LenValues()+t.ClusteringKeys.LenValues()+nonCounters.LenValues()) @@ -417,7 +417,7 @@ func genUpdateStmt(s *testschema.Schema, t *testschema.Table, valuesWithToken *t } func genInsertStmt( - s *testschema.Schema, + _ *testschema.Schema, t *testschema.Table, valuesWithToken *typedef.ValueWithToken, r *rand.Rand, @@ -507,7 +507,7 @@ func genInsertJSONStmt( }, nil } -func genDeleteRows(s *testschema.Schema, t *testschema.Table, valuesWithToken *typedef.ValueWithToken, r *rand.Rand, p *typedef.PartitionRangeConfig) (*typedef.Stmt, error) { +func genDeleteRows(_ *testschema.Schema, t *testschema.Table, valuesWithToken *typedef.ValueWithToken, r *rand.Rand, p *typedef.PartitionRangeConfig) (*typedef.Stmt, error) { stmtCache := t.GetQueryCache(typedef.CacheDelete) values := valuesWithToken.Value.Copy() if len(t.ClusteringKeys) > 0 { @@ -522,7 +522,7 @@ func genDeleteRows(s *testschema.Schema, t *testschema.Table, valuesWithToken *t }, nil } -func GenDDLStmt(s *testschema.Schema, t *testschema.Table, r *rand.Rand, p *typedef.PartitionRangeConfig, sc *typedef.SchemaConfig) (*typedef.Stmts, error) { +func GenDDLStmt(s *testschema.Schema, t *testschema.Table, r *rand.Rand, _ *typedef.PartitionRangeConfig, sc *typedef.SchemaConfig) (*typedef.Stmts, error) { maxVariant := 1 if len(t.Columns) > 0 { maxVariant = 2 @@ -730,7 +730,7 @@ func GetCreateSchema(s *testschema.Schema) []string { } else { createMaterializedView = "CREATE MATERIALIZED VIEW IF NOT EXISTS %s.%s AS SELECT * FROM %s.%s WHERE %s PRIMARY KEY ((%s)" } - createMaterializedView = createMaterializedView + ",%s)" + createMaterializedView += ",%s)" stmts = append(stmts, fmt.Sprintf(createMaterializedView, s.Keyspace.Name, mv.Name, s.Keyspace.Name, t.Name, strings.Join(mvPrimaryKeysNotNull, " AND "), diff --git a/pkg/generators/table.go b/pkg/generators/table.go index cc90c3d0..fe111cf2 100644 --- a/pkg/generators/table.go +++ b/pkg/generators/table.go @@ -64,15 +64,16 @@ func GetCreateTypes(t *testschema.Table, keyspace typedef.Keyspace) []string { var stmts []string for _, column := range t.Columns { - switch c := column.Type.(type) { - case *coltypes.UDTType: - createType := "CREATE TYPE IF NOT EXISTS %s.%s (%s)" - var typs []string - for name, typ := range c.Types { - typs = append(typs, name+" "+typ.CQLDef()) - } - stmts = append(stmts, fmt.Sprintf(createType, keyspace.Name, c.TypeName, strings.Join(typs, ","))) + c, ok := column.Type.(*coltypes.UDTType) + if !ok { + continue } + createType := "CREATE TYPE IF NOT EXISTS %s.%s (%s)" + var typs []string + for name, typ := range c.Types { + typs = append(typs, name+" "+typ.CQLDef()) + } + stmts = append(stmts, fmt.Sprintf(createType, keyspace.Name, c.TypeName, strings.Join(typs, ","))) } return stmts } diff --git a/pkg/generators/test_generator.go b/pkg/generators/test_generator.go index fca84f1e..a0675aff 100644 --- a/pkg/generators/test_generator.go +++ b/pkg/generators/test_generator.go @@ -28,14 +28,14 @@ type MockGenerator struct { table *testschema.Table rand *rand.Rand partitionsConfig *typedef.PartitionRangeConfig - routingKeyCreator *routingkey.RoutingKeyCreator + routingKeyCreator *routingkey.Creator } func NewTestGenerator( table *testschema.Table, rnd *rand.Rand, partitionsConfig *typedef.PartitionRangeConfig, - routingKeyCreator *routingkey.RoutingKeyCreator, + routingKeyCreator *routingkey.Creator, ) *MockGenerator { return &MockGenerator{table: table, rand: rnd, partitionsConfig: partitionsConfig, routingKeyCreator: routingKeyCreator} } diff --git a/pkg/jobs/jobs.go b/pkg/jobs/jobs.go index 4a013ae8..08cb45ea 100644 --- a/pkg/jobs/jobs.go +++ b/pkg/jobs/jobs.go @@ -56,7 +56,7 @@ var ( errorJobTerminated = errors.New("job terminated") ) -type list struct { +type List struct { name string jobs []job duration time.Duration @@ -83,7 +83,7 @@ type job struct { name string } -func ListFromMode(mode string, duration time.Duration, workers uint64) list { +func ListFromMode(mode string, duration time.Duration, workers uint64) List { jobs := make([]job, 0, 2) name := "work cycle" switch mode { @@ -97,7 +97,7 @@ func ListFromMode(mode string, duration time.Duration, workers uint64) list { default: jobs = append(jobs, mutate, validate) } - return list{ + return List{ name: name, jobs: jobs, duration: duration, @@ -105,7 +105,7 @@ func ListFromMode(mode string, duration time.Duration, workers uint64) list { } } -func (l list) Run( +func (l List) Run( ctx context.Context, schema *testschema.Schema, schemaConfig typedef.SchemaConfig, diff --git a/pkg/murmur/murmur_test.go b/pkg/murmur/murmur_test.go index 560698a7..b91a7216 100644 --- a/pkg/murmur/murmur_test.go +++ b/pkg/murmur/murmur_test.go @@ -110,7 +110,7 @@ func TestMurmur3H1(t *testing.T) { for i, expected := range seriesExpected { assertMurmur3H1(t, []byte(sample), expected) - sample = sample + strconv.Itoa(i%10) + sample += strconv.Itoa(i % 10) } // Here are some test examples from other driver implementations @@ -122,6 +122,7 @@ func TestMurmur3H1(t *testing.T) { // helper function for testing the murmur3 implementation func assertMurmur3H1(t *testing.T, data []byte, expected uint64) { + t.Helper() actual := Murmur3H1(data) if actual != int64(expected) { t.Errorf("Expected h1 = %x for data = %x, but was %x", int64(expected), data, actual) diff --git a/pkg/routingkey/routing_key.go b/pkg/routingkey/routing_key.go index a0f5999e..2fbd8e77 100644 --- a/pkg/routingkey/routing_key.go +++ b/pkg/routingkey/routing_key.go @@ -26,11 +26,11 @@ import ( "github.com/gocql/gocql" ) -type RoutingKeyCreator struct { +type Creator struct { routingKeyBuffer []byte } -func (rc *RoutingKeyCreator) CreateRoutingKey(table *testschema.Table, values []interface{}) ([]byte, error) { +func (rc *Creator) CreateRoutingKey(table *testschema.Table, values []interface{}) ([]byte, error) { partitionKeys := table.PartitionKeys if len(partitionKeys) == 1 { // single column routing key @@ -68,7 +68,7 @@ func (rc *RoutingKeyCreator) CreateRoutingKey(table *testschema.Table, values [] return routingKey, nil } -func (rc *RoutingKeyCreator) GetHash(t *testschema.Table, values typedef.Values) (uint64, error) { +func (rc *Creator) GetHash(t *testschema.Table, values typedef.Values) (uint64, error) { b, err := rc.CreateRoutingKey(t, values) if err != nil { return 0, err diff --git a/pkg/routingkey/routing_key_test.go b/pkg/routingkey/routing_key_test.go index 99cdf85f..37f2b395 100644 --- a/pkg/routingkey/routing_key_test.go +++ b/pkg/routingkey/routing_key_test.go @@ -32,7 +32,7 @@ func TestRoutingKey(t *testing.T) { values typedef.Values want []byte } - rkc := &routingkey.RoutingKeyCreator{} + rkc := &routingkey.Creator{} tests := map[string]struct { table *testschema.Table data []data diff --git a/pkg/stop/flag_test.go b/pkg/stop/flag_test.go index 9fad3265..8d5dbd6f 100644 --- a/pkg/stop/flag_test.go +++ b/pkg/stop/flag_test.go @@ -30,7 +30,7 @@ func TestHardStop(t *testing.T) { testFlag, ctx, workersDone := initVars() workers := 30 - testSignals(workersDone, workers, testFlag.IsHard, testFlag.SetHard, t) + testSignals(t, workersDone, workers, testFlag.IsHard, testFlag.SetHard) if ctx.Err() == nil { t.Error("Error:SetHard function does not apply hardStopHandler") } @@ -40,7 +40,7 @@ func TestSoftStop(t *testing.T) { testFlag, ctx, workersDone := initVars() workers := 30 - testSignals(workersDone, workers, testFlag.IsSoft, testFlag.SetSoft, t) + testSignals(t, workersDone, workers, testFlag.IsSoft, testFlag.SetSoft) if ctx.Err() != nil { t.Error("Error:SetSoft function apply hardStopHandler") } @@ -50,13 +50,13 @@ func TestSoftOrHardStop(t *testing.T) { testFlag, ctx, workersDone := initVars() workers := 30 - testSignals(workersDone, workers, testFlag.IsHardOrSoft, testFlag.SetSoft, t) + testSignals(t, workersDone, workers, testFlag.IsHardOrSoft, testFlag.SetSoft) if ctx.Err() != nil { t.Error("Error:SetSoft function apply hardStopHandler") } workersDone.Store(uint32(0)) - testSignals(workersDone, workers, testFlag.IsHardOrSoft, testFlag.SetHard, t) + testSignals(t, workersDone, workers, testFlag.IsHardOrSoft, testFlag.SetHard) if ctx.Err() != nil { t.Error("Error:SetHard function apply hardStopHandler after SetSoft") } @@ -64,7 +64,7 @@ func TestSoftOrHardStop(t *testing.T) { testFlag, ctx, workersDone = initVars() workersDone.Store(uint32(0)) - testSignals(workersDone, workers, testFlag.IsHardOrSoft, testFlag.SetHard, t) + testSignals(t, workersDone, workers, testFlag.IsHardOrSoft, testFlag.SetHard) if ctx.Err() == nil { t.Error("Error:SetHard function does not apply hardStopHandler") } @@ -78,12 +78,14 @@ func initVars() (testFlag *stop.Flag, ctx context.Context, workersDone *atomic.U return &testFlagOut, ctx, workersDone } -func testSignals(workersDone *atomic.Uint32, +func testSignals( + t *testing.T, + workersDone *atomic.Uint32, workers int, checkFunc func() bool, setFunc func() bool, - t *testing.T, ) { + t.Helper() for i := 0; i != workers; i++ { go func() { for { diff --git a/pkg/testschema/columns.go b/pkg/testschema/columns.go index 70960178..5093fcaf 100644 --- a/pkg/testschema/columns.go +++ b/pkg/testschema/columns.go @@ -147,11 +147,9 @@ func (c Columns) LenValues() int { func (c Columns) NonCounters() Columns { out := make(Columns, 0, len(c)) for _, col := range c { - switch col.Type.(type) { - case *coltypes.CounterType: - continue + if _, ok := col.Type.(*coltypes.CounterType); !ok { + out = append(out, col) } - out = append(out, col) } return out } diff --git a/pkg/typedef/const.go b/pkg/typedef/const.go index 94f2b099..5534b4ca 100644 --- a/pkg/typedef/const.go +++ b/pkg/typedef/const.go @@ -36,6 +36,7 @@ const ( DropColumnStatementType ) +//nolint:revive const ( CQL_FEATURE_BASIC CQLFeature = iota + 1 CQL_FEATURE_NORMAL diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index c8fb1cd1..463003ff 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -37,7 +37,7 @@ func RandTime(rnd *rand.Rand) time.Time { return time.Unix(sec, 0).UTC() } -func RandIpV4Address(rnd *rand.Rand, v, pos int) string { +func RandIPV4Address(rnd *rand.Rand, v, pos int) string { if pos < 0 || pos > 4 { panic(fmt.Sprintf("invalid position for the desired value of the IP part %d, 0-3 supported", pos)) }