diff --git a/go/test/endtoend/vtgate/queries/misc/main_test.go b/go/test/endtoend/vtgate/queries/misc/main_test.go index d71dc55ef46..a3858284884 100644 --- a/go/test/endtoend/vtgate/queries/misc/main_test.go +++ b/go/test/endtoend/vtgate/queries/misc/main_test.go @@ -62,9 +62,7 @@ func TestMain(m *testing.M) { } clusterInstance.VtTabletExtraArgs = append(clusterInstance.VtTabletExtraArgs, - "--queryserver-config-max-result-size", "1000000", - "--queryserver-config-query-timeout", "200", - "--queryserver-config-query-pool-timeout", "200") + "--queryserver-config-max-result-size", "1000000") // Start Unsharded keyspace ukeyspace := &cluster.Keyspace{ Name: uks, @@ -86,8 +84,6 @@ func TestMain(m *testing.M) { return 1 } - clusterInstance.VtGateExtraArgs = append(clusterInstance.VtGateExtraArgs, - "--query-timeout", "100") // Start vtgate err = clusterInstance.StartVtgate() if err != nil { diff --git a/go/test/endtoend/vtgate/queries/misc/misc_test.go b/go/test/endtoend/vtgate/queries/misc/misc_test.go index 0d66315bd1e..afe30e9024d 100644 --- a/go/test/endtoend/vtgate/queries/misc/misc_test.go +++ b/go/test/endtoend/vtgate/queries/misc/misc_test.go @@ -97,58 +97,6 @@ func TestInvalidDateTimeTimestampVals(t *testing.T) { require.Error(t, err) } -func TestQueryTimeoutWithDual(t *testing.T) { - mcmp, closer := start(t) - defer closer() - - _, err := utils.ExecAllowError(t, mcmp.VtConn, "select sleep(0.04) from dual") - assert.NoError(t, err) - _, err = utils.ExecAllowError(t, mcmp.VtConn, "select sleep(0.24) from dual") - assert.Error(t, err) - _, err = utils.ExecAllowError(t, mcmp.VtConn, "set @@session.query_timeout=20") - require.NoError(t, err) - _, err = utils.ExecAllowError(t, mcmp.VtConn, "select sleep(0.04) from dual") - assert.Error(t, err) - _, err = utils.ExecAllowError(t, mcmp.VtConn, "select sleep(0.01) from dual") - assert.NoError(t, err) - _, err = utils.ExecAllowError(t, mcmp.VtConn, "select /*vt+ QUERY_TIMEOUT_MS=500 */ sleep(0.24) from dual") - assert.NoError(t, err) - _, err = utils.ExecAllowError(t, mcmp.VtConn, "select /*vt+ QUERY_TIMEOUT_MS=10 */ sleep(0.04) from dual") - assert.Error(t, err) - _, err = utils.ExecAllowError(t, mcmp.VtConn, "select /*vt+ QUERY_TIMEOUT_MS=15 */ sleep(0.001) from dual") - assert.NoError(t, err) -} - -func TestQueryTimeoutWithTables(t *testing.T) { - mcmp, closer := start(t) - defer closer() - - // unsharded - utils.Exec(t, mcmp.VtConn, "insert /*vt+ QUERY_TIMEOUT_MS=1000 */ into uks.unsharded(id1) values (1),(2),(3),(4),(5)") - for i := 0; i < 12; i++ { - utils.Exec(t, mcmp.VtConn, "insert /*vt+ QUERY_TIMEOUT_MS=1000 */ into uks.unsharded(id1) select id1+5 from uks.unsharded") - } - - utils.Exec(t, mcmp.VtConn, "select count(*) from uks.unsharded where id1 > 31") - utils.Exec(t, mcmp.VtConn, "select /*vt+ PLANNER=gen4 QUERY_TIMEOUT_MS=100 */ count(*) from uks.unsharded where id1 > 31") - - // the query usually takes more than 5ms to return. So this should fail. - _, err := utils.ExecAllowError(t, mcmp.VtConn, "select /*vt+ PLANNER=gen4 QUERY_TIMEOUT_MS=1 */ count(*) from uks.unsharded where id1 > 31") - require.Error(t, err) - assert.Contains(t, err.Error(), "context deadline exceeded") - assert.Contains(t, err.Error(), "(errno 1317) (sqlstate 70100)") - - // sharded - utils.Exec(t, mcmp.VtConn, "insert /*vt+ QUERY_TIMEOUT_MS=1000 */ into ks_misc.t1(id1, id2) values (1,2),(2,4),(3,6),(4,8),(5,10)") - - // sleep take in seconds, so 0.1 is 100ms - utils.Exec(t, mcmp.VtConn, "select /*vt+ PLANNER=gen4 QUERY_TIMEOUT_MS=500 */ sleep(0.1) from t1 where id1 = 1") - _, err = utils.ExecAllowError(t, mcmp.VtConn, "select /*vt+ PLANNER=gen4 QUERY_TIMEOUT_MS=20 */ sleep(0.1) from t1 where id1 = 1") - require.Error(t, err) - assert.Contains(t, err.Error(), "context deadline exceeded") - assert.Contains(t, err.Error(), "(errno 1317) (sqlstate 70100)") -} - // TestIntervalWithMathFunctions tests that the Interval keyword can be used with math functions. func TestIntervalWithMathFunctions(t *testing.T) { mcmp, closer := start(t) @@ -214,7 +162,7 @@ func TestHighNumberOfParams(t *testing.T) { require.NoError(t, err) // run the query - r, err := db.Query(fmt.Sprintf("SELECT /*vt+ QUERY_TIMEOUT_MS=10000 */ id1 FROM t1 WHERE id1 in (%s) ORDER BY id1 ASC", strings.Join(params, ", ")), vals...) + r, err := db.Query(fmt.Sprintf("SELECT id1 FROM t1 WHERE id1 in (%s) ORDER BY id1 ASC", strings.Join(params, ", ")), vals...) require.NoError(t, err) // check the results we got, we should get 5 rows with each: 0, 1, 2, 3, 4 diff --git a/go/test/endtoend/vtgate/queries/timeout/main_test.go b/go/test/endtoend/vtgate/queries/timeout/main_test.go new file mode 100644 index 00000000000..d71dc55ef46 --- /dev/null +++ b/go/test/endtoend/vtgate/queries/timeout/main_test.go @@ -0,0 +1,110 @@ +/* +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 misc + +import ( + _ "embed" + "flag" + "fmt" + "os" + "testing" + + "vitess.io/vitess/go/test/endtoend/utils" + + "vitess.io/vitess/go/mysql" + "vitess.io/vitess/go/test/endtoend/cluster" +) + +var ( + clusterInstance *cluster.LocalProcessCluster + vtParams mysql.ConnParams + mysqlParams mysql.ConnParams + keyspaceName = "ks_misc" + uks = "uks" + cell = "test_misc" + + //go:embed uschema.sql + uschemaSQL string + + //go:embed schema.sql + schemaSQL string + + //go:embed vschema.json + vschema string +) + +func TestMain(m *testing.M) { + defer cluster.PanicHandler(nil) + flag.Parse() + + exitCode := func() int { + clusterInstance = cluster.NewCluster(cell, "localhost") + defer clusterInstance.Teardown() + + // Start topo server + err := clusterInstance.StartTopo() + if err != nil { + return 1 + } + + clusterInstance.VtTabletExtraArgs = append(clusterInstance.VtTabletExtraArgs, + "--queryserver-config-max-result-size", "1000000", + "--queryserver-config-query-timeout", "200", + "--queryserver-config-query-pool-timeout", "200") + // Start Unsharded keyspace + ukeyspace := &cluster.Keyspace{ + Name: uks, + SchemaSQL: uschemaSQL, + } + err = clusterInstance.StartUnshardedKeyspace(*ukeyspace, 0, false) + if err != nil { + return 1 + } + + // Start keyspace + keyspace := &cluster.Keyspace{ + Name: keyspaceName, + SchemaSQL: schemaSQL, + VSchema: vschema, + } + err = clusterInstance.StartKeyspace(*keyspace, []string{"-80", "80-"}, 0, false) + if err != nil { + return 1 + } + + clusterInstance.VtGateExtraArgs = append(clusterInstance.VtGateExtraArgs, + "--query-timeout", "100") + // Start vtgate + err = clusterInstance.StartVtgate() + if err != nil { + return 1 + } + + vtParams = clusterInstance.GetVTParams(keyspaceName) + + // create mysql instance and connection parameters + conn, closer, err := utils.NewMySQL(clusterInstance, keyspaceName, schemaSQL) + if err != nil { + fmt.Println(err) + return 1 + } + defer closer() + mysqlParams = conn + return m.Run() + }() + os.Exit(exitCode) +} diff --git a/go/test/endtoend/vtgate/queries/timeout/schema.sql b/go/test/endtoend/vtgate/queries/timeout/schema.sql new file mode 100644 index 00000000000..ceac0c07e6d --- /dev/null +++ b/go/test/endtoend/vtgate/queries/timeout/schema.sql @@ -0,0 +1,5 @@ +create table if not exists t1( + id1 bigint, + id2 bigint, + primary key(id1) +) Engine=InnoDB; \ No newline at end of file diff --git a/go/test/endtoend/vtgate/queries/timeout/timeout_test.go b/go/test/endtoend/vtgate/queries/timeout/timeout_test.go new file mode 100644 index 00000000000..b6c7a0bc7f5 --- /dev/null +++ b/go/test/endtoend/vtgate/queries/timeout/timeout_test.go @@ -0,0 +1,100 @@ +/* +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 misc + +import ( + "testing" + + _ "github.com/go-sql-driver/mysql" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "vitess.io/vitess/go/test/endtoend/cluster" + "vitess.io/vitess/go/test/endtoend/utils" +) + +func start(t *testing.T) (utils.MySQLCompare, func()) { + mcmp, err := utils.NewMySQLCompare(t, vtParams, mysqlParams) + require.NoError(t, err) + + deleteAll := func() { + tables := []string{"t1", "uks.unsharded"} + for _, table := range tables { + _, _ = mcmp.ExecAndIgnore("delete from " + table) + } + } + + deleteAll() + + return mcmp, func() { + deleteAll() + mcmp.Close() + cluster.PanicHandler(t) + } +} + +func TestQueryTimeoutWithDual(t *testing.T) { + mcmp, closer := start(t) + defer closer() + + _, err := utils.ExecAllowError(t, mcmp.VtConn, "select sleep(0.04) from dual") + assert.NoError(t, err) + _, err = utils.ExecAllowError(t, mcmp.VtConn, "select sleep(0.24) from dual") + assert.Error(t, err) + _, err = utils.ExecAllowError(t, mcmp.VtConn, "set @@session.query_timeout=20") + require.NoError(t, err) + _, err = utils.ExecAllowError(t, mcmp.VtConn, "select sleep(0.04) from dual") + assert.Error(t, err) + _, err = utils.ExecAllowError(t, mcmp.VtConn, "select sleep(0.01) from dual") + assert.NoError(t, err) + _, err = utils.ExecAllowError(t, mcmp.VtConn, "select /*vt+ QUERY_TIMEOUT_MS=500 */ sleep(0.24) from dual") + assert.NoError(t, err) + _, err = utils.ExecAllowError(t, mcmp.VtConn, "select /*vt+ QUERY_TIMEOUT_MS=10 */ sleep(0.04) from dual") + assert.Error(t, err) + _, err = utils.ExecAllowError(t, mcmp.VtConn, "select /*vt+ QUERY_TIMEOUT_MS=15 */ sleep(0.001) from dual") + assert.NoError(t, err) +} + +func TestQueryTimeoutWithTables(t *testing.T) { + mcmp, closer := start(t) + defer closer() + + // unsharded + utils.Exec(t, mcmp.VtConn, "insert /*vt+ QUERY_TIMEOUT_MS=1000 */ into uks.unsharded(id1) values (1),(2),(3),(4),(5)") + for i := 0; i < 12; i++ { + utils.Exec(t, mcmp.VtConn, "insert /*vt+ QUERY_TIMEOUT_MS=1000 */ into uks.unsharded(id1) select id1+5 from uks.unsharded") + } + + utils.Exec(t, mcmp.VtConn, "select count(*) from uks.unsharded where id1 > 31") + utils.Exec(t, mcmp.VtConn, "select /*vt+ PLANNER=gen4 QUERY_TIMEOUT_MS=100 */ count(*) from uks.unsharded where id1 > 31") + + // the query usually takes more than 5ms to return. So this should fail. + _, err := utils.ExecAllowError(t, mcmp.VtConn, "select /*vt+ PLANNER=gen4 QUERY_TIMEOUT_MS=1 */ count(*) from uks.unsharded where id1 > 31") + require.Error(t, err) + assert.Contains(t, err.Error(), "context deadline exceeded") + assert.Contains(t, err.Error(), "(errno 1317) (sqlstate 70100)") + + // sharded + utils.Exec(t, mcmp.VtConn, "insert /*vt+ QUERY_TIMEOUT_MS=1000 */ into ks_misc.t1(id1, id2) values (1,2),(2,4),(3,6),(4,8),(5,10)") + + // sleep take in seconds, so 0.1 is 100ms + utils.Exec(t, mcmp.VtConn, "select /*vt+ PLANNER=gen4 QUERY_TIMEOUT_MS=500 */ sleep(0.1) from t1 where id1 = 1") + _, err = utils.ExecAllowError(t, mcmp.VtConn, "select /*vt+ PLANNER=gen4 QUERY_TIMEOUT_MS=20 */ sleep(0.1) from t1 where id1 = 1") + require.Error(t, err) + assert.Contains(t, err.Error(), "context deadline exceeded") + assert.Contains(t, err.Error(), "(errno 1317) (sqlstate 70100)") +} diff --git a/go/test/endtoend/vtgate/queries/timeout/uschema.sql b/go/test/endtoend/vtgate/queries/timeout/uschema.sql new file mode 100644 index 00000000000..6ba158b134e --- /dev/null +++ b/go/test/endtoend/vtgate/queries/timeout/uschema.sql @@ -0,0 +1,5 @@ +create table unsharded( + id1 bigint, + id2 bigint, + key(id1) +) Engine=InnoDB; \ No newline at end of file diff --git a/go/test/endtoend/vtgate/queries/timeout/vschema.json b/go/test/endtoend/vtgate/queries/timeout/vschema.json new file mode 100644 index 00000000000..60aa2bc9c07 --- /dev/null +++ b/go/test/endtoend/vtgate/queries/timeout/vschema.json @@ -0,0 +1,18 @@ +{ + "sharded": true, + "vindexes": { + "hash": { + "type": "hash" + } + }, + "tables": { + "t1": { + "column_vindexes": [ + { + "column": "id1", + "name": "hash" + } + ] + } + } +} \ No newline at end of file diff --git a/test/config.json b/test/config.json index 0070720f1a0..82157e2ae05 100644 --- a/test/config.json +++ b/test/config.json @@ -558,6 +558,15 @@ "RetryMax": 1, "Tags": [] }, + "vtgate_queries_timeout": { + "File": "unused.go", + "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/queries/timeout"], + "Command": [], + "Manual": false, + "Shard": "vtgate_queries", + "RetryMax": 1, + "Tags": [] + }, "vtgate_queries_normalize": { "File": "unused.go", "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/queries/normalize"],