diff --git a/.github/workflows/static_checks_etc.yml b/.github/workflows/static_checks_etc.yml index 3084991410b..7a45a544260 100644 --- a/.github/workflows/static_checks_etc.yml +++ b/.github/workflows/static_checks_etc.yml @@ -90,7 +90,8 @@ jobs: - 'Makefile' - 'bootstrap.sh' - '.github/workflows/static_checks_etc.yml' - + ci_config: + - 'test/config.json' - name: Set up Go if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.go_files == 'true' || steps.changes.outputs.parser_changes == 'true' || steps.changes.outputs.proto_changes == 'true' @@ -195,3 +196,8 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.proto_changes == 'true' run: | tools/check_make_proto.sh || exit 1 + + - name: Check test/config.json + if: steps.skip-workflow.outputs.skip-workflow == 'false' && (steps.changes.outputs.go_files == 'true' || steps.changes.outputs.ci_config == 'true') + run: | + go run ./go/tools/ci-config/main.go || exit 1 diff --git a/go.sum b/go.sum index a0ed58c44de..7dae9fb5119 100644 --- a/go.sum +++ b/go.sum @@ -128,8 +128,6 @@ github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdn github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/bndr/gotabulate v1.1.2 h1:yC9izuZEphojb9r+KYL4W9IJKO/ceIO8HDwxMA24U4c= github.com/bndr/gotabulate v1.1.2/go.mod h1:0+8yUgaPTtLRTjf49E8oju7ojpU11YmXyvq1LbPAb3U= -github.com/buger/jsonparser v0.0.0-20200322175846-f7e751efca13 h1:+qUNY4VRkEH46bLUwxCyUU+iOGJMQBVibAaYzWiwWcg= -github.com/buger/jsonparser v0.0.0-20200322175846-f7e751efca13/go.mod h1:tgcrVJ81GPSF0mz+0nu1Xaz0fazGPrmmJfJtxjbHhUQ= github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= diff --git a/go/test/endtoend/utils/cmp.go b/go/test/endtoend/utils/cmp.go index 89e51c1e665..a377ed777c8 100644 --- a/go/test/endtoend/utils/cmp.go +++ b/go/test/endtoend/utils/cmp.go @@ -85,6 +85,39 @@ func (mcmp *MySQLCompare) AssertMatchesAny(query string, expected ...string) { mcmp.t.Errorf("Query: %s (-want +got):\n%v\nGot:%s", query, expected, got) } +// AssertMatchesAnyNoCompare ensures the given query produces any one of the expected results. +// This method does not compare the mysql and vitess results together +func (mcmp *MySQLCompare) AssertMatchesAnyNoCompare(query string, expected ...string) { + mcmp.t.Helper() + + mQr, vQr := mcmp.execNoCompare(query) + got := fmt.Sprintf("%v", mQr.Rows) + valid := false + for _, e := range expected { + diff := cmp.Diff(e, got) + if diff == "" { + valid = true + break + } + } + if !valid { + mcmp.t.Errorf("MySQL Query: %s (-want +got):\n%v\nGot:%s", query, expected, got) + } + valid = false + + got = fmt.Sprintf("%v", vQr.Rows) + for _, e := range expected { + diff := cmp.Diff(e, got) + if diff == "" { + valid = true + break + } + } + if !valid { + mcmp.t.Errorf("Vitess Query: %s (-want +got):\n%v\nGot:%s", query, expected, got) + } +} + // AssertContainsError executes the query on both Vitess and MySQL. // Both clients need to return an error. The error of Vitess must be matching the given expectation. func (mcmp *MySQLCompare) AssertContainsError(query, expected string) { diff --git a/go/test/endtoend/vtgate/queries/derived/derived_test.go b/go/test/endtoend/vtgate/queries/derived/derived_test.go index 5da8d8bac9b..62601ed528d 100644 --- a/go/test/endtoend/vtgate/queries/derived/derived_test.go +++ b/go/test/endtoend/vtgate/queries/derived/derived_test.go @@ -30,7 +30,7 @@ func start(t *testing.T) (utils.MySQLCompare, func()) { require.NoError(t, err) deleteAll := func() { - tables := []string{"music"} + tables := []string{"music", "user"} for _, table := range tables { _, _ = mcmp.ExecAndIgnore("delete from " + table) } @@ -56,6 +56,7 @@ func TestDerivedTableWithOrderByLimit(t *testing.T) { } func TestDerivedAggregationOnRHS(t *testing.T) { + t.Skip("skipped for now, issue: https://github.com/vitessio/vitess/issues/11703") mcmp, closer := start(t) defer closer() @@ -84,10 +85,7 @@ func TestDerivedTableWithHaving(t *testing.T) { mcmp.Exec("insert into user(id, name) values(1,'toto'), (2,'tata'), (3,'titi'), (4,'tete'), (5,'foo')") mcmp.Exec("set sql_mode = ''") - - // this is probably flaky? the id returned from the derived table could be any of the ids from user. - // works on my machine (TM) - mcmp.Exec("select /*vt+ PLANNER=Gen4 */ * from (select id from user having count(*) >= 1) s") + mcmp.AssertMatchesAnyNoCompare("select /*vt+ PLANNER=Gen4 */ * from (select id from user having count(*) >= 1) s", "[[INT64(1)]]", "[[INT64(4)]]") } func TestDerivedTableColumns(t *testing.T) { diff --git a/go/tools/ci-config/main.go b/go/tools/ci-config/main.go new file mode 100644 index 00000000000..d767b6f4d32 --- /dev/null +++ b/go/tools/ci-config/main.go @@ -0,0 +1,74 @@ +/* +Copyright 2022 The Vitess Authors. + +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 main + +import ( + "encoding/json" + "fmt" + "log" + "os" + "strings" +) + +type Test struct { + Args []string +} + +type Config struct { + Tests map[string]*Test +} + +func main() { + content, err := os.ReadFile("./test/config.json") + if err != nil { + log.Fatal(err) + } + + tests := &Config{} + err = json.Unmarshal(content, tests) + if err != nil { + log.Fatal(err) + } + + var failedConfig []string + for name, test := range tests.Tests { + if len(test.Args) == 0 { + continue + } + path := test.Args[0] + if !strings.HasPrefix(path, "vitess.io/vitess/") { + continue + } + path = path[len("vitess.io/vitess/"):] + + stat, err := os.Stat(path) + if err != nil || !stat.IsDir() { + failedConfig = append(failedConfig, fmt.Sprintf("%s: %s", name, path)) + continue + } + } + + if len(failedConfig) > 0 { + fmt.Println("Some packages in test/config.json were not found in the codebase:") + for _, failed := range failedConfig { + fmt.Println("\t" + failed) + } + fmt.Println("\nYou must remove them from test/config.json to avoid unnecessary CI load.") + os.Exit(1) + } + fmt.Println("The file: test/config.json is clean.") +} diff --git a/test/config.json b/test/config.json index 7b0b8245f14..cb2dbf14c78 100644 --- a/test/config.json +++ b/test/config.json @@ -520,6 +520,15 @@ "RetryMax": 2, "Tags": [] }, + "vtgate_queries_derived": { + "File": "unused.go", + "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/queries/derived"], + "Command": [], + "Manual": false, + "Shard": "vtgate_queries", + "RetryMax": 1, + "Tags": [] + }, "vtgate_queries_aggregation": { "File": "unused.go", "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/queries/aggregation"], @@ -691,15 +700,6 @@ "RetryMax": 1, "Tags": [] }, - "vtgate_mysql80_derived": { - "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/mysql80/derived"], - "Command": [], - "Manual": false, - "Shard": "mysql80", - "RetryMax": 1, - "Tags": [] - }, "vtgate_sequence": { "File": "unused.go", "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/sequence"],