vitess.io/vitess@v0.16.2/go/vt/vttablet/tabletmanager/vreplication/engine_test.go (about) 1 /* 2 Copyright 2019 The Vitess Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package vreplication 18 19 import ( 20 "context" 21 "errors" 22 "fmt" 23 "reflect" 24 "strings" 25 "testing" 26 "time" 27 28 "github.com/stretchr/testify/assert" 29 "github.com/stretchr/testify/require" 30 31 "vitess.io/vitess/go/sqltypes" 32 "vitess.io/vitess/go/sync2" 33 "vitess.io/vitess/go/vt/binlog/binlogplayer" 34 "vitess.io/vitess/go/vt/mysqlctl/fakemysqldaemon" 35 ) 36 37 func TestEngineOpen(t *testing.T) { 38 defer func() { globalStats = &vrStats{} }() 39 40 defer deleteTablet(addTablet(100)) 41 resetBinlogClient() 42 dbClient := binlogplayer.NewMockDBClient(t) 43 dbClientFactory := func() binlogplayer.DBClient { return dbClient } 44 mysqld := &fakemysqldaemon.FakeMysqlDaemon{MysqlPort: sync2.NewAtomicInt32(3306)} 45 46 vre := NewTestEngine(env.TopoServ, env.Cells[0], mysqld, dbClientFactory, dbClientFactory, dbClient.DBName(), nil) 47 require.False(t, vre.IsOpen()) 48 49 dbClient.ExpectRequest("select * from _vt.vreplication where db_name='db'", sqltypes.MakeTestResult( 50 sqltypes.MakeTestFields( 51 "id|state|source|tablet_types", 52 "int64|varchar|varchar|varbinary", 53 ), 54 fmt.Sprintf(`1|Running|keyspace:"%s" shard:"0" key_range:{end:"\x80"}|PRIMARY,REPLICA`, env.KeyspaceName), 55 ), nil) 56 dbClient.ExpectRequestRE("update _vt.vreplication set message='Picked source tablet.*", testDMLResponse, nil) 57 dbClient.ExpectRequest("update _vt.vreplication set state='Running', message='' where id=1", testDMLResponse, nil) 58 dbClient.ExpectRequest("select pos, stop_pos, max_tps, max_replication_lag, state, workflow_type, workflow, workflow_sub_type, defer_secondary_keys from _vt.vreplication where id=1", testSettingsResponse, nil) 59 dbClient.ExpectRequest("begin", nil, nil) 60 dbClient.ExpectRequest("insert into t values(1)", testDMLResponse, nil) 61 dbClient.ExpectRequestRE("update _vt.vreplication set pos='MariaDB/0-1-1235', time_updated=.*", testDMLResponse, nil) 62 dbClient.ExpectRequest("commit", nil, nil) 63 vre.Open(context.Background()) 64 defer vre.Close() 65 assert.True(t, vre.IsOpen()) 66 67 // Verify stats 68 assert.Equal(t, globalStats.controllers, vre.controllers) 69 70 ct := vre.controllers[1] 71 assert.True(t, ct != nil && ct.id == 1) 72 } 73 74 func TestEngineOpenRetry(t *testing.T) { 75 defer func() { globalStats = &vrStats{} }() 76 77 defer func(saved time.Duration) { openRetryInterval.Set(saved) }(openRetryInterval.Get()) 78 openRetryInterval.Set(10 * time.Millisecond) 79 80 defer deleteTablet(addTablet(100)) 81 resetBinlogClient() 82 dbClient := binlogplayer.NewMockDBClient(t) 83 dbClientFactory := func() binlogplayer.DBClient { return dbClient } 84 mysqld := &fakemysqldaemon.FakeMysqlDaemon{MysqlPort: sync2.NewAtomicInt32(3306)} 85 86 vre := NewTestEngine(env.TopoServ, env.Cells[0], mysqld, dbClientFactory, dbClientFactory, dbClient.DBName(), nil) 87 88 // Fail twice to ensure the retry retries at least once. 89 dbClient.ExpectRequest("select * from _vt.vreplication where db_name='db'", nil, errors.New("err")) 90 dbClient.ExpectRequest("select * from _vt.vreplication where db_name='db'", nil, errors.New("err")) 91 dbClient.ExpectRequest("select * from _vt.vreplication where db_name='db'", sqltypes.MakeTestResult( 92 sqltypes.MakeTestFields( 93 "id|state|source", 94 "int64|varchar|varchar", 95 ), 96 ), nil) 97 98 isRetrying := func() bool { 99 vre.mu.Lock() 100 defer vre.mu.Unlock() 101 return vre.cancelRetry != nil 102 } 103 104 vre.Open(context.Background()) 105 106 assert.True(t, isRetrying()) 107 func() { 108 for i := 0; i < 10; i++ { 109 time.Sleep(10 * time.Millisecond) 110 if !isRetrying() { 111 return 112 } 113 } 114 t.Error("retrying did not become false") 115 }() 116 117 // Open is idempotent. 118 assert.True(t, vre.IsOpen()) 119 vre.Open(context.Background()) 120 121 vre.Close() 122 assert.False(t, vre.IsOpen()) 123 124 dbClient.ExpectRequest("select * from _vt.vreplication where db_name='db'", nil, errors.New("err")) 125 vre.Open(context.Background()) 126 127 // A second Open should cancel the existing retry and start a new one. 128 dbClient.ExpectRequest("select * from _vt.vreplication where db_name='db'", nil, errors.New("err")) 129 vre.Open(context.Background()) 130 131 start := time.Now() 132 // Close should cause the retry to exit. 133 vre.Close() 134 elapsed := time.Since(start) 135 assert.Greater(t, int64(openRetryInterval.Get()), int64(elapsed)) 136 } 137 138 func TestEngineExec(t *testing.T) { 139 defer func() { globalStats = &vrStats{} }() 140 141 defer deleteTablet(addTablet(100)) 142 resetBinlogClient() 143 dbClient := binlogplayer.NewMockDBClient(t) 144 dbClientFactory := func() binlogplayer.DBClient { return dbClient } 145 mysqld := &fakemysqldaemon.FakeMysqlDaemon{MysqlPort: sync2.NewAtomicInt32(3306)} 146 147 // Test Insert 148 149 vre := NewTestEngine(env.TopoServ, env.Cells[0], mysqld, dbClientFactory, dbClientFactory, dbClient.DBName(), nil) 150 151 dbClient.ExpectRequest("select * from _vt.vreplication where db_name='db'", &sqltypes.Result{}, nil) 152 vre.Open(context.Background()) 153 defer vre.Close() 154 155 dbClient.ExpectRequest("use _vt", &sqltypes.Result{}, nil) 156 dbClient.ExpectRequest("insert into _vt.vreplication values(null)", &sqltypes.Result{InsertID: 1}, nil) 157 dbClient.ExpectRequest("select * from _vt.vreplication where id = 1", sqltypes.MakeTestResult( 158 sqltypes.MakeTestFields( 159 "id|state|source|tablet_types", 160 "int64|varchar|varchar|varbinary", 161 ), 162 fmt.Sprintf(`1|Running|keyspace:"%s" shard:"0" key_range:{end:"\x80"}|PRIMARY,REPLICA`, env.KeyspaceName), 163 ), nil) 164 dbClient.ExpectRequestRE("update _vt.vreplication set message='Picked source tablet.*", testDMLResponse, nil) 165 dbClient.ExpectRequest("update _vt.vreplication set state='Running', message='' where id=1", testDMLResponse, nil) 166 dbClient.ExpectRequest("select pos, stop_pos, max_tps, max_replication_lag, state, workflow_type, workflow, workflow_sub_type, defer_secondary_keys from _vt.vreplication where id=1", testSettingsResponse, nil) 167 dbClient.ExpectRequest("begin", nil, nil) 168 dbClient.ExpectRequest("insert into t values(1)", testDMLResponse, nil) 169 dbClient.ExpectRequestRE("update _vt.vreplication set pos='MariaDB/0-1-1235', time_updated=.*", testDMLResponse, nil) 170 dbClient.ExpectRequest("commit", nil, nil) 171 172 qr, err := vre.Exec("insert into _vt.vreplication values(null)") 173 if err != nil { 174 t.Fatal(err) 175 } 176 wantqr := &sqltypes.Result{InsertID: 1} 177 if !qr.Equal(wantqr) { 178 t.Errorf("Exec: %v, want %v", qr, wantqr) 179 } 180 dbClient.Wait() 181 182 ct := vre.controllers[1] 183 if ct == nil || ct.id != 1 { 184 t.Errorf("ct: %v, id should be 1", ct) 185 } 186 187 // Verify stats 188 if !reflect.DeepEqual(globalStats.controllers, vre.controllers) { 189 t.Errorf("stats are mismatched: %v, want %v", globalStats.controllers, vre.controllers) 190 } 191 192 // Test Update 193 194 savedBlp := ct.blpStats 195 196 dbClient.ExpectRequest("use _vt", &sqltypes.Result{}, nil) 197 dbClient.ExpectRequest("select id from _vt.vreplication where id = 1", testSelectorResponse1, nil) 198 dbClient.ExpectRequest("update _vt.vreplication set pos = 'MariaDB/0-1-1084', state = 'Running' where id in (1)", testDMLResponse, nil) 199 dbClient.ExpectRequest("select * from _vt.vreplication where id = 1", sqltypes.MakeTestResult( 200 sqltypes.MakeTestFields( 201 "id|state|source", 202 "int64|varchar|varchar", 203 ), 204 fmt.Sprintf(`1|Running|keyspace:"%s" shard:"0" key_range:{end:"\x80"}`, env.KeyspaceName), 205 ), nil) 206 dbClient.ExpectRequestRE("update _vt.vreplication set message='Picked source tablet.*", testDMLResponse, nil) 207 dbClient.ExpectRequest("update _vt.vreplication set state='Running', message='' where id=1", testDMLResponse, nil) 208 dbClient.ExpectRequest("select pos, stop_pos, max_tps, max_replication_lag, state, workflow_type, workflow, workflow_sub_type, defer_secondary_keys from _vt.vreplication where id=1", testSettingsResponse, nil) 209 dbClient.ExpectRequest("begin", nil, nil) 210 dbClient.ExpectRequest("insert into t values(1)", testDMLResponse, nil) 211 dbClient.ExpectRequestRE("update _vt.vreplication set pos='MariaDB/0-1-1235', time_updated=.*", testDMLResponse, nil) 212 dbClient.ExpectRequest("commit", nil, nil) 213 214 qr, err = vre.Exec("update _vt.vreplication set pos = 'MariaDB/0-1-1084', state = 'Running' where id = 1") 215 if err != nil { 216 t.Fatal(err) 217 } 218 wantqr = &sqltypes.Result{RowsAffected: 1} 219 if !qr.Equal(wantqr) { 220 t.Errorf("Exec: %v, want %v", qr, wantqr) 221 } 222 dbClient.Wait() 223 224 ct = vre.controllers[1] 225 226 // Verify that the new controller has reused the previous blpStats. 227 if ct.blpStats != savedBlp { 228 t.Errorf("BlpStats: %v and %v, must be same", ct.blpStats, savedBlp) 229 } 230 231 // Verify stats 232 if !reflect.DeepEqual(globalStats.controllers, vre.controllers) { 233 t.Errorf("stats are mismatched: %v, want %v", globalStats.controllers, vre.controllers) 234 } 235 236 // Test no update 237 dbClient.ExpectRequest("use _vt", &sqltypes.Result{}, nil) 238 dbClient.ExpectRequest("select id from _vt.vreplication where id = 2", &sqltypes.Result{}, nil) 239 _, err = vre.Exec("update _vt.vreplication set pos = 'MariaDB/0-1-1084', state = 'Running' where id = 2") 240 if err != nil { 241 t.Fatal(err) 242 } 243 dbClient.Wait() 244 245 // Test Delete 246 247 dbClient.ExpectRequest("use _vt", &sqltypes.Result{}, nil) 248 dbClient.ExpectRequest("select id from _vt.vreplication where id = 1", testSelectorResponse1, nil) 249 dbClient.ExpectRequest("begin", nil, nil) 250 dbClient.ExpectRequest("delete from _vt.vreplication where id in (1)", testDMLResponse, nil) 251 dbClient.ExpectRequest("delete from _vt.copy_state where vrepl_id in (1)", nil, nil) 252 dbClient.ExpectRequest("delete from _vt.post_copy_action where vrepl_id in (1)", nil, nil) 253 dbClient.ExpectRequest("commit", nil, nil) 254 255 qr, err = vre.Exec("delete from _vt.vreplication where id = 1") 256 if err != nil { 257 t.Fatal(err) 258 } 259 wantqr = &sqltypes.Result{RowsAffected: 1} 260 if !qr.Equal(wantqr) { 261 t.Errorf("Exec: %v, want %v", qr, wantqr) 262 } 263 dbClient.Wait() 264 265 ct = vre.controllers[1] 266 if ct != nil { 267 t.Errorf("ct: %v, want nil", ct) 268 } 269 270 // Verify stats 271 if !reflect.DeepEqual(globalStats.controllers, vre.controllers) { 272 t.Errorf("stats are mismatched: %v, want %v", globalStats.controllers, vre.controllers) 273 } 274 275 // Test Delete of multiple rows 276 277 dbClient.ExpectRequest("use _vt", &sqltypes.Result{}, nil) 278 dbClient.ExpectRequest("select id from _vt.vreplication where id > 1", testSelectorResponse2, nil) 279 dbClient.ExpectRequest("begin", nil, nil) 280 dbClient.ExpectRequest("delete from _vt.vreplication where id in (1, 2)", testDMLResponse, nil) 281 dbClient.ExpectRequest("delete from _vt.copy_state where vrepl_id in (1, 2)", nil, nil) 282 dbClient.ExpectRequest("delete from _vt.post_copy_action where vrepl_id in (1, 2)", nil, nil) 283 dbClient.ExpectRequest("commit", nil, nil) 284 285 _, err = vre.Exec("delete from _vt.vreplication where id > 1") 286 if err != nil { 287 t.Fatal(err) 288 } 289 dbClient.Wait() 290 291 // Test no delete 292 dbClient.ExpectRequest("use _vt", &sqltypes.Result{}, nil) 293 dbClient.ExpectRequest("select id from _vt.vreplication where id = 3", &sqltypes.Result{}, nil) 294 _, err = vre.Exec("delete from _vt.vreplication where id = 3") 295 if err != nil { 296 t.Fatal(err) 297 } 298 dbClient.Wait() 299 } 300 301 func TestEngineBadInsert(t *testing.T) { 302 defer func() { globalStats = &vrStats{} }() 303 304 defer deleteTablet(addTablet(100)) 305 resetBinlogClient() 306 307 dbClient := binlogplayer.NewMockDBClient(t) 308 dbClientFactory := func() binlogplayer.DBClient { return dbClient } 309 mysqld := &fakemysqldaemon.FakeMysqlDaemon{MysqlPort: sync2.NewAtomicInt32(3306)} 310 311 vre := NewTestEngine(env.TopoServ, env.Cells[0], mysqld, dbClientFactory, dbClientFactory, dbClient.DBName(), nil) 312 313 dbClient.ExpectRequest("select * from _vt.vreplication where db_name='db'", &sqltypes.Result{}, nil) 314 vre.Open(context.Background()) 315 defer vre.Close() 316 317 dbClient.ExpectRequest("use _vt", &sqltypes.Result{}, nil) 318 dbClient.ExpectRequest("insert into _vt.vreplication values(null)", &sqltypes.Result{}, nil) 319 _, err := vre.Exec("insert into _vt.vreplication values(null)") 320 want := "insert failed to generate an id" 321 if err == nil || err.Error() != want { 322 t.Errorf("vre.Exec err: %v, want %v", err, want) 323 } 324 325 // Verify stats 326 if !reflect.DeepEqual(globalStats.controllers, vre.controllers) { 327 t.Errorf("stats are mismatched: %v, want %v", globalStats.controllers, vre.controllers) 328 } 329 } 330 331 func TestEngineSelect(t *testing.T) { 332 defer deleteTablet(addTablet(100)) 333 resetBinlogClient() 334 dbClient := binlogplayer.NewMockDBClient(t) 335 336 dbClientFactory := func() binlogplayer.DBClient { return dbClient } 337 mysqld := &fakemysqldaemon.FakeMysqlDaemon{MysqlPort: sync2.NewAtomicInt32(3306)} 338 339 vre := NewTestEngine(env.TopoServ, env.Cells[0], mysqld, dbClientFactory, dbClientFactory, dbClient.DBName(), nil) 340 341 dbClient.ExpectRequest("select * from _vt.vreplication where db_name='db'", &sqltypes.Result{}, nil) 342 vre.Open(context.Background()) 343 defer vre.Close() 344 345 dbClient.ExpectRequest("use _vt", &sqltypes.Result{}, nil) 346 wantQuery := "select * from _vt.vreplication where workflow = 'x'" 347 wantResult := sqltypes.MakeTestResult( 348 sqltypes.MakeTestFields( 349 "id|state|source|pos", 350 "int64|varchar|varchar|varchar", 351 ), 352 fmt.Sprintf(`1|Running|keyspace:"%s" shard:"0" key_range:{end:"\x80"}|MariaDB/0-1-1083`, env.KeyspaceName), 353 ) 354 dbClient.ExpectRequest(wantQuery, wantResult, nil) 355 qr, err := vre.Exec(wantQuery) 356 if err != nil { 357 t.Fatal(err) 358 } 359 if !qr.Equal(wantResult) { 360 t.Errorf("Exec: %v, want %v", qr, wantResult) 361 } 362 } 363 364 func TestWaitForPos(t *testing.T) { 365 savedRetryTime := waitRetryTime 366 defer func() { waitRetryTime = savedRetryTime }() 367 waitRetryTime = 10 * time.Millisecond 368 369 dbClient := binlogplayer.NewMockDBClient(t) 370 mysqld := &fakemysqldaemon.FakeMysqlDaemon{MysqlPort: sync2.NewAtomicInt32(3306)} 371 dbClientFactory := func() binlogplayer.DBClient { return dbClient } 372 vre := NewTestEngine(env.TopoServ, env.Cells[0], mysqld, dbClientFactory, dbClientFactory, dbClient.DBName(), nil) 373 374 dbClient.ExpectRequest("select * from _vt.vreplication where db_name='db'", &sqltypes.Result{}, nil) 375 vre.Open(context.Background()) 376 377 dbClient.ExpectRequest("select pos, state, message from _vt.vreplication where id=1", &sqltypes.Result{Rows: [][]sqltypes.Value{{ 378 sqltypes.NewVarBinary("MariaDB/0-1-1083"), 379 sqltypes.NewVarBinary("Running"), 380 sqltypes.NewVarBinary(""), 381 }}}, nil) 382 dbClient.ExpectRequest("select pos, state, message from _vt.vreplication where id=1", &sqltypes.Result{Rows: [][]sqltypes.Value{{ 383 sqltypes.NewVarBinary("MariaDB/0-1-1084"), 384 sqltypes.NewVarBinary("Running"), 385 sqltypes.NewVarBinary(""), 386 }}}, nil) 387 start := time.Now() 388 if err := vre.WaitForPos(context.Background(), 1, "MariaDB/0-1-1084"); err != nil { 389 t.Fatal(err) 390 } 391 if duration := time.Since(start); duration < 10*time.Microsecond { 392 t.Errorf("duration: %v, want < 10ms", duration) 393 } 394 } 395 396 func TestWaitForPosError(t *testing.T) { 397 dbClient := binlogplayer.NewMockDBClient(t) 398 mysqld := &fakemysqldaemon.FakeMysqlDaemon{MysqlPort: sync2.NewAtomicInt32(3306)} 399 dbClientFactory := func() binlogplayer.DBClient { return dbClient } 400 vre := NewTestEngine(env.TopoServ, env.Cells[0], mysqld, dbClientFactory, dbClientFactory, dbClient.DBName(), nil) 401 402 err := vre.WaitForPos(context.Background(), 1, "MariaDB/0-1-1084") 403 want := `vreplication engine is closed` 404 if err == nil || err.Error() != want { 405 t.Errorf("WaitForPos: %v, want %v", err, want) 406 } 407 408 dbClient.ExpectRequest("select * from _vt.vreplication where db_name='db'", &sqltypes.Result{}, nil) 409 vre.Open(context.Background()) 410 411 err = vre.WaitForPos(context.Background(), 1, "BadFlavor/0-1-1084") 412 want = `parse error: unknown GTIDSet flavor "BadFlavor"` 413 if err == nil || err.Error() != want { 414 t.Errorf("WaitForPos: %v, want %v", err, want) 415 } 416 417 dbClient.ExpectRequest("select pos, state, message from _vt.vreplication where id=1", &sqltypes.Result{Rows: [][]sqltypes.Value{{}}}, nil) 418 err = vre.WaitForPos(context.Background(), 1, "MariaDB/0-1-1084") 419 want = "unexpected result: &{[] 0 0 [[]] 0 }" 420 assert.EqualError(t, err, want, "WaitForPos:") 421 422 dbClient.ExpectRequest("select pos, state, message from _vt.vreplication where id=1", &sqltypes.Result{Rows: [][]sqltypes.Value{{ 423 sqltypes.NewVarBinary("MariaDB/0-1-1083"), 424 }, { 425 sqltypes.NewVarBinary("MariaDB/0-1-1083"), 426 }}}, nil) 427 err = vre.WaitForPos(context.Background(), 1, "MariaDB/0-1-1084") 428 want = `unexpected result: &{[] 0 0 [[VARBINARY("MariaDB/0-1-1083")] [VARBINARY("MariaDB/0-1-1083")]] 0 }` 429 assert.EqualError(t, err, want, "WaitForPos:") 430 } 431 432 func TestWaitForPosCancel(t *testing.T) { 433 dbClient := binlogplayer.NewMockDBClient(t) 434 mysqld := &fakemysqldaemon.FakeMysqlDaemon{MysqlPort: sync2.NewAtomicInt32(3306)} 435 dbClientFactory := func() binlogplayer.DBClient { return dbClient } 436 vre := NewTestEngine(env.TopoServ, env.Cells[0], mysqld, dbClientFactory, dbClientFactory, dbClient.DBName(), nil) 437 438 dbClient.ExpectRequest("select * from _vt.vreplication where db_name='db'", &sqltypes.Result{}, nil) 439 vre.Open(context.Background()) 440 441 dbClient.ExpectRequest("select pos, state, message from _vt.vreplication where id=1", &sqltypes.Result{Rows: [][]sqltypes.Value{{ 442 sqltypes.NewVarBinary("MariaDB/0-1-1083"), 443 sqltypes.NewVarBinary("Running"), 444 sqltypes.NewVarBinary(""), 445 }}}, nil) 446 ctx, cancel := context.WithCancel(context.Background()) 447 cancel() 448 err := vre.WaitForPos(ctx, 1, "MariaDB/0-1-1084") 449 want := "error waiting for pos: MariaDB/0-1-1084, last pos: MariaDB/0-1-1083: context canceled" 450 if err == nil || !strings.Contains(err.Error(), want) { 451 t.Errorf("WaitForPos: %v, must contain %v", err, want) 452 } 453 dbClient.Wait() 454 455 go func() { 456 time.Sleep(5 * time.Millisecond) 457 vre.Close() 458 }() 459 dbClient.ExpectRequest("select pos, state, message from _vt.vreplication where id=1", &sqltypes.Result{Rows: [][]sqltypes.Value{{ 460 sqltypes.NewVarBinary("MariaDB/0-1-1083"), 461 sqltypes.NewVarBinary("Running"), 462 sqltypes.NewVarBinary(""), 463 }}}, nil) 464 err = vre.WaitForPos(context.Background(), 1, "MariaDB/0-1-1084") 465 want = "vreplication is closing: context canceled" 466 if err == nil || err.Error() != want { 467 t.Errorf("WaitForPos: %v, want %v", err, want) 468 } 469 } 470 471 func TestGetDBClient(t *testing.T) { 472 dbClientDba := binlogplayer.NewMockDbaClient(t) 473 dbClientFiltered := binlogplayer.NewMockDBClient(t) 474 dbClientFactoryDba := func() binlogplayer.DBClient { return dbClientDba } 475 dbClientFactoryFiltered := func() binlogplayer.DBClient { return dbClientFiltered } 476 477 mysqld := &fakemysqldaemon.FakeMysqlDaemon{MysqlPort: sync2.NewAtomicInt32(3306)} 478 vre := NewTestEngine(env.TopoServ, env.Cells[0], mysqld, dbClientFactoryFiltered, dbClientFactoryDba, dbClientDba.DBName(), nil) 479 480 shouldBeDbaClient := vre.getDBClient(true /*runAsAdmin*/) 481 assert.Equal(t, shouldBeDbaClient, dbClientDba) 482 483 shouldBeFilteredClient := vre.getDBClient(false /*runAsAdmin*/) 484 assert.Equal(t, shouldBeFilteredClient, dbClientFiltered) 485 }