github.com/pingcap/tidb-lightning@v5.0.0-rc.0.20210428090220-84b649866577+incompatible/lightning/config/config_test.go (about) 1 // Copyright 2019 PingCAP, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package config_test 15 16 import ( 17 "bytes" 18 "context" 19 "flag" 20 "fmt" 21 "net" 22 "net/http" 23 "net/http/httptest" 24 "net/url" 25 "path/filepath" 26 "regexp" 27 "strconv" 28 "testing" 29 "time" 30 31 "github.com/BurntSushi/toml" 32 . "github.com/pingcap/check" 33 "github.com/pingcap/parser/mysql" 34 35 "github.com/pingcap/tidb-lightning/lightning/config" 36 ) 37 38 func Test(t *testing.T) { 39 TestingT(t) 40 } 41 42 var _ = Suite(&configTestSuite{}) 43 44 type configTestSuite struct{} 45 46 func startMockServer(c *C, statusCode int, content string) (*httptest.Server, string, int) { 47 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 48 w.WriteHeader(statusCode) 49 fmt.Fprint(w, content) 50 })) 51 52 url, err := url.Parse(ts.URL) 53 c.Assert(err, IsNil) 54 host, portString, err := net.SplitHostPort(url.Host) 55 c.Assert(err, IsNil) 56 port, err := strconv.Atoi(portString) 57 c.Assert(err, IsNil) 58 59 return ts, host, port 60 } 61 62 func assignMinimalLegalValue(cfg *config.Config) { 63 cfg.TiDB.Host = "123.45.67.89" 64 cfg.TiDB.Port = 4567 65 cfg.TiDB.StatusPort = 8901 66 cfg.TiDB.PdAddr = "234.56.78.90:12345" 67 cfg.Mydumper.SourceDir = "file://." 68 cfg.TikvImporter.DiskQuota = 1 69 } 70 71 func (s *configTestSuite) TestAdjustPdAddrAndPort(c *C) { 72 ts, host, port := startMockServer(c, http.StatusOK, 73 `{"port":4444,"advertise-address":"","path":"123.45.67.89:1234,56.78.90.12:3456"}`, 74 ) 75 defer ts.Close() 76 77 cfg := config.NewConfig() 78 cfg.TiDB.Host = host 79 cfg.TiDB.StatusPort = port 80 cfg.Mydumper.SourceDir = "." 81 82 err := cfg.Adjust(context.Background()) 83 c.Assert(err, IsNil) 84 c.Assert(cfg.TiDB.Port, Equals, 4444) 85 c.Assert(cfg.TiDB.PdAddr, Equals, "123.45.67.89:1234") 86 } 87 88 func (s *configTestSuite) TestAdjustPdAddrAndPortViaAdvertiseAddr(c *C) { 89 ts, host, port := startMockServer(c, http.StatusOK, 90 `{"port":6666,"advertise-address":"121.212.121.212:5555","path":"34.34.34.34:3434"}`, 91 ) 92 defer ts.Close() 93 94 cfg := config.NewConfig() 95 cfg.TiDB.Host = host 96 cfg.TiDB.StatusPort = port 97 cfg.Mydumper.SourceDir = "." 98 99 err := cfg.Adjust(context.Background()) 100 c.Assert(err, IsNil) 101 c.Assert(cfg.TiDB.Port, Equals, 6666) 102 c.Assert(cfg.TiDB.PdAddr, Equals, "34.34.34.34:3434") 103 } 104 105 func (s *configTestSuite) TestAdjustPageNotFound(c *C) { 106 ts, host, port := startMockServer(c, http.StatusNotFound, "{}") 107 defer ts.Close() 108 109 cfg := config.NewConfig() 110 cfg.TiDB.Host = host 111 cfg.TiDB.StatusPort = port 112 113 err := cfg.Adjust(context.Background()) 114 c.Assert(err, ErrorMatches, "cannot fetch settings from TiDB.*") 115 } 116 117 func (s *configTestSuite) TestAdjustConnectRefused(c *C) { 118 ts, host, port := startMockServer(c, http.StatusOK, "{}") 119 120 cfg := config.NewConfig() 121 cfg.TiDB.Host = host 122 cfg.TiDB.StatusPort = port 123 124 ts.Close() // immediately close to ensure connection refused. 125 126 err := cfg.Adjust(context.Background()) 127 c.Assert(err, ErrorMatches, "cannot fetch settings from TiDB.*") 128 } 129 130 func (s *configTestSuite) TestAdjustInvalidBackend(c *C) { 131 cfg := config.NewConfig() 132 cfg.TikvImporter.Backend = "no_such_backend" 133 err := cfg.Adjust(context.Background()) 134 c.Assert(err, ErrorMatches, "invalid config: unsupported `tikv-importer\\.backend` \\(no_such_backend\\)") 135 } 136 137 func (s *configTestSuite) TestAdjustFileRoutePath(c *C) { 138 cfg := config.NewConfig() 139 assignMinimalLegalValue(cfg) 140 141 ctx := context.Background() 142 tmpDir := c.MkDir() 143 cfg.Mydumper.SourceDir = tmpDir 144 invalidPath := filepath.Join(tmpDir, "../test123/1.sql") 145 rule := &config.FileRouteRule{Path: invalidPath, Type: "sql", Schema: "test", Table: "tbl"} 146 cfg.Mydumper.FileRouters = []*config.FileRouteRule{rule} 147 err := cfg.Adjust(ctx) 148 c.Assert(err, ErrorMatches, fmt.Sprintf("\\Qfile route path '%s' is not in source dir '%s'\\E", invalidPath, tmpDir)) 149 150 relPath := filepath.FromSlash("test_dir/1.sql") 151 rule.Path = filepath.Join(tmpDir, relPath) 152 err = cfg.Adjust(ctx) 153 c.Assert(err, IsNil) 154 c.Assert(cfg.Mydumper.FileRouters[0].Path, Equals, relPath) 155 } 156 157 func (s *configTestSuite) TestDecodeError(c *C) { 158 ts, host, port := startMockServer(c, http.StatusOK, "invalid-string") 159 defer ts.Close() 160 161 cfg := config.NewConfig() 162 cfg.TiDB.Host = host 163 cfg.TiDB.StatusPort = port 164 165 err := cfg.Adjust(context.Background()) 166 c.Assert(err, ErrorMatches, "cannot fetch settings from TiDB.*") 167 } 168 169 func (s *configTestSuite) TestInvalidSetting(c *C) { 170 ts, host, port := startMockServer(c, http.StatusOK, `{"port": 0}`) 171 defer ts.Close() 172 173 cfg := config.NewConfig() 174 cfg.TiDB.Host = host 175 cfg.TiDB.StatusPort = port 176 177 err := cfg.Adjust(context.Background()) 178 c.Assert(err, ErrorMatches, "invalid `tidb.port` setting") 179 } 180 181 func (s *configTestSuite) TestInvalidPDAddr(c *C) { 182 ts, host, port := startMockServer(c, http.StatusOK, `{"port": 1234, "path": ",,"}`) 183 defer ts.Close() 184 185 cfg := config.NewConfig() 186 cfg.TiDB.Host = host 187 cfg.TiDB.StatusPort = port 188 189 err := cfg.Adjust(context.Background()) 190 c.Assert(err, ErrorMatches, "invalid `tidb.pd-addr` setting") 191 } 192 193 func (s *configTestSuite) TestAdjustWillNotContactServerIfEverythingIsDefined(c *C) { 194 cfg := config.NewConfig() 195 assignMinimalLegalValue(cfg) 196 197 err := cfg.Adjust(context.Background()) 198 c.Assert(err, IsNil) 199 c.Assert(cfg.TiDB.Port, Equals, 4567) 200 c.Assert(cfg.TiDB.PdAddr, Equals, "234.56.78.90:12345") 201 } 202 203 func (s *configTestSuite) TestAdjustWillBatchImportRatioInvalid(c *C) { 204 cfg := config.NewConfig() 205 assignMinimalLegalValue(cfg) 206 cfg.Mydumper.BatchImportRatio = -1 207 err := cfg.Adjust(context.Background()) 208 c.Assert(err, IsNil) 209 c.Assert(cfg.Mydumper.BatchImportRatio, Equals, 0.75) 210 } 211 212 func (s *configTestSuite) TestAdjustSecuritySection(c *C) { 213 testCases := []struct { 214 input string 215 expectedCA string 216 expectedTLS string 217 }{ 218 { 219 input: ``, 220 expectedCA: "", 221 expectedTLS: "false", 222 }, 223 { 224 input: ` 225 [security] 226 `, 227 expectedCA: "", 228 expectedTLS: "false", 229 }, 230 { 231 input: ` 232 [security] 233 ca-path = "/path/to/ca.pem" 234 `, 235 expectedCA: "/path/to/ca.pem", 236 expectedTLS: "cluster", 237 }, 238 { 239 input: ` 240 [security] 241 ca-path = "/path/to/ca.pem" 242 [tidb.security] 243 `, 244 expectedCA: "", 245 expectedTLS: "false", 246 }, 247 { 248 input: ` 249 [security] 250 ca-path = "/path/to/ca.pem" 251 [tidb.security] 252 ca-path = "/path/to/ca2.pem" 253 `, 254 expectedCA: "/path/to/ca2.pem", 255 expectedTLS: "cluster", 256 }, 257 { 258 input: ` 259 [security] 260 [tidb.security] 261 ca-path = "/path/to/ca2.pem" 262 `, 263 expectedCA: "/path/to/ca2.pem", 264 expectedTLS: "cluster", 265 }, 266 { 267 input: ` 268 [security] 269 [tidb] 270 tls = "skip-verify" 271 [tidb.security] 272 `, 273 expectedCA: "", 274 expectedTLS: "skip-verify", 275 }, 276 } 277 278 for _, tc := range testCases { 279 comment := Commentf("input = %s", tc.input) 280 281 cfg := config.NewConfig() 282 assignMinimalLegalValue(cfg) 283 err := cfg.LoadFromTOML([]byte(tc.input)) 284 c.Assert(err, IsNil, comment) 285 286 err = cfg.Adjust(context.Background()) 287 c.Assert(err, IsNil, comment) 288 c.Assert(cfg.TiDB.Security.CAPath, Equals, tc.expectedCA, comment) 289 c.Assert(cfg.TiDB.TLS, Equals, tc.expectedTLS, comment) 290 } 291 } 292 293 func (s *configTestSuite) TestInvalidCSV(c *C) { 294 testCases := []struct { 295 input string 296 err string 297 }{ 298 { 299 input: ` 300 [mydumper.csv] 301 separator = '' 302 `, 303 err: "invalid config: `mydumper.csv.separator` must not be empty", 304 }, 305 { 306 input: ` 307 [mydumper.csv] 308 separator = 'hello' 309 delimiter = 'hel' 310 `, 311 err: "invalid config: `mydumper.csv.separator` and `mydumper.csv.delimiter` must not be prefix of each other", 312 }, 313 { 314 input: ` 315 [mydumper.csv] 316 separator = 'hel' 317 delimiter = 'hello' 318 `, 319 err: "invalid config: `mydumper.csv.separator` and `mydumper.csv.delimiter` must not be prefix of each other", 320 }, 321 { 322 input: ` 323 [mydumper.csv] 324 separator = '\' 325 backslash-escape = false 326 `, 327 err: "", 328 }, 329 { 330 input: ` 331 [mydumper.csv] 332 separator = ',' 333 `, 334 err: "", 335 }, 336 { 337 input: ` 338 [mydumper.csv] 339 delimiter = '' 340 `, 341 err: "", 342 }, 343 { 344 input: ` 345 [mydumper.csv] 346 delimiter = 'hello' 347 `, 348 err: "", 349 }, 350 { 351 input: ` 352 [mydumper.csv] 353 delimiter = '\' 354 backslash-escape = false 355 `, 356 err: "", 357 }, 358 { 359 input: ` 360 [mydumper.csv] 361 separator = '\s' 362 delimiter = '\d' 363 `, 364 err: "", 365 }, 366 { 367 input: ` 368 [mydumper.csv] 369 separator = '|' 370 delimiter = '|' 371 `, 372 err: "invalid config: `mydumper.csv.separator` and `mydumper.csv.delimiter` must not be prefix of each other", 373 }, 374 { 375 input: ` 376 [mydumper.csv] 377 separator = '\' 378 backslash-escape = true 379 `, 380 err: "invalid config: cannot use '\\' as CSV separator when `mydumper.csv.backslash-escape` is true", 381 }, 382 { 383 input: ` 384 [mydumper.csv] 385 delimiter = '\' 386 backslash-escape = true 387 `, 388 err: "invalid config: cannot use '\\' as CSV delimiter when `mydumper.csv.backslash-escape` is true", 389 }, 390 { 391 input: ` 392 [tidb] 393 sql-mode = "invalid-sql-mode" 394 `, 395 err: "invalid config: `mydumper.tidb.sql_mode` must be a valid SQL_MODE: ERROR 1231 (42000): Variable 'sql_mode' can't be set to the value of 'invalid-sql-mode'", 396 }, 397 { 398 input: ` 399 [[routes]] 400 schema-pattern = "" 401 table-pattern = "shard_table_*" 402 `, 403 err: "schema pattern of table route rule should not be empty", 404 }, 405 { 406 input: ` 407 [[routes]] 408 schema-pattern = "schema_*" 409 table-pattern = "" 410 `, 411 err: "target schema of table route rule should not be empty", 412 }, 413 } 414 415 for _, tc := range testCases { 416 comment := Commentf("input = %s", tc.input) 417 418 cfg := config.NewConfig() 419 cfg.Mydumper.SourceDir = "file://." 420 cfg.TiDB.Port = 4000 421 cfg.TiDB.PdAddr = "test.invalid:2379" 422 err := cfg.LoadFromTOML([]byte(tc.input)) 423 c.Assert(err, IsNil) 424 425 err = cfg.Adjust(context.Background()) 426 if tc.err != "" { 427 c.Assert(err, ErrorMatches, regexp.QuoteMeta(tc.err), comment) 428 } else { 429 c.Assert(err, IsNil, comment) 430 } 431 } 432 } 433 434 func (s *configTestSuite) TestInvalidTOML(c *C) { 435 cfg := &config.Config{} 436 err := cfg.LoadFromTOML([]byte(` 437 invalid[mydumper.csv] 438 delimiter = '\' 439 backslash-escape = true 440 `)) 441 c.Assert(err, ErrorMatches, regexp.QuoteMeta("Near line 0 (last key parsed ''): bare keys cannot contain '['")) 442 } 443 444 func (s *configTestSuite) TestTOMLUnusedKeys(c *C) { 445 cfg := &config.Config{} 446 err := cfg.LoadFromTOML([]byte(` 447 [lightning] 448 typo = 123 449 `)) 450 c.Assert(err, ErrorMatches, regexp.QuoteMeta("config file contained unknown configuration options: lightning.typo")) 451 } 452 453 func (s *configTestSuite) TestDurationUnmarshal(c *C) { 454 duration := config.Duration{} 455 err := duration.UnmarshalText([]byte("13m20s")) 456 c.Assert(err, IsNil) 457 c.Assert(duration.Duration.Seconds(), Equals, 13*60+20.0) 458 err = duration.UnmarshalText([]byte("13x20s")) 459 c.Assert(err, ErrorMatches, "time: unknown unit .?x.? in duration .?13x20s.?") 460 } 461 462 func (s *configTestSuite) TestDurationMarshalJSON(c *C) { 463 duration := config.Duration{} 464 err := duration.UnmarshalText([]byte("13m20s")) 465 c.Assert(err, IsNil) 466 c.Assert(duration.Duration.Seconds(), Equals, 13*60+20.0) 467 result, err := duration.MarshalJSON() 468 c.Assert(err, IsNil) 469 c.Assert(string(result), Equals, `"13m20s"`) 470 } 471 472 func (s *configTestSuite) TestLoadConfig(c *C) { 473 cfg, err := config.LoadGlobalConfig([]string{"-tidb-port", "sss"}, nil) 474 c.Assert(err, ErrorMatches, `invalid value "sss" for flag -tidb-port: parse error`) 475 c.Assert(cfg, IsNil) 476 477 cfg, err = config.LoadGlobalConfig([]string{"-V"}, nil) 478 c.Assert(err, Equals, flag.ErrHelp) 479 c.Assert(cfg, IsNil) 480 481 cfg, err = config.LoadGlobalConfig([]string{"-config", "not-exists"}, nil) 482 c.Assert(err, ErrorMatches, ".*(no such file or directory|The system cannot find the file specified).*") 483 c.Assert(cfg, IsNil) 484 485 cfg, err = config.LoadGlobalConfig([]string{"--server-mode"}, nil) 486 c.Assert(err, ErrorMatches, "If server-mode is enabled, the status-addr must be a valid listen address") 487 c.Assert(cfg, IsNil) 488 489 path, _ := filepath.Abs(".") 490 cfg, err = config.LoadGlobalConfig([]string{ 491 "-L", "debug", 492 "-log-file", "/path/to/file.log", 493 "-tidb-host", "172.16.30.11", 494 "-tidb-port", "4001", 495 "-tidb-user", "guest", 496 "-tidb-password", "12345", 497 "-pd-urls", "172.16.30.11:2379,172.16.30.12:2379", 498 "-d", path, 499 "-importer", "172.16.30.11:23008", 500 "-checksum=false", 501 }, nil) 502 c.Assert(err, IsNil) 503 c.Assert(cfg.App.Config.Level, Equals, "debug") 504 c.Assert(cfg.App.Config.File, Equals, "/path/to/file.log") 505 c.Assert(cfg.TiDB.Host, Equals, "172.16.30.11") 506 c.Assert(cfg.TiDB.Port, Equals, 4001) 507 c.Assert(cfg.TiDB.User, Equals, "guest") 508 c.Assert(cfg.TiDB.Psw, Equals, "12345") 509 c.Assert(cfg.TiDB.PdAddr, Equals, "172.16.30.11:2379,172.16.30.12:2379") 510 c.Assert(cfg.Mydumper.SourceDir, Equals, path) 511 c.Assert(cfg.TikvImporter.Addr, Equals, "172.16.30.11:23008") 512 c.Assert(cfg.PostRestore.Checksum, Equals, config.OpLevelOff) 513 c.Assert(cfg.PostRestore.Analyze, Equals, config.OpLevelOptional) 514 515 taskCfg := config.NewConfig() 516 err = taskCfg.LoadFromGlobal(cfg) 517 c.Assert(err, IsNil) 518 c.Assert(taskCfg.PostRestore.Checksum, Equals, config.OpLevelOff) 519 c.Assert(taskCfg.PostRestore.Analyze, Equals, config.OpLevelOptional) 520 521 taskCfg.Checkpoint.DSN = "" 522 taskCfg.Checkpoint.Driver = config.CheckpointDriverMySQL 523 err = taskCfg.Adjust(context.Background()) 524 c.Assert(err, IsNil) 525 c.Assert(taskCfg.Checkpoint.DSN, Equals, "guest:12345@tcp(172.16.30.11:4001)/?charset=utf8mb4&sql_mode='"+mysql.DefaultSQLMode+"'&maxAllowedPacket=67108864&tls=false") 526 527 result := taskCfg.String() 528 c.Assert(result, Matches, `.*"pd-addr":"172.16.30.11:2379,172.16.30.12:2379".*`) 529 } 530 531 func (s *configTestSuite) TestDefaultImporterBackendValue(c *C) { 532 cfg := config.NewConfig() 533 assignMinimalLegalValue(cfg) 534 cfg.TikvImporter.Backend = "importer" 535 err := cfg.Adjust(context.Background()) 536 c.Assert(err, IsNil) 537 c.Assert(cfg.App.IndexConcurrency, Equals, 2) 538 c.Assert(cfg.App.TableConcurrency, Equals, 6) 539 } 540 541 func (s *configTestSuite) TestDefaultTidbBackendValue(c *C) { 542 cfg := config.NewConfig() 543 assignMinimalLegalValue(cfg) 544 cfg.TikvImporter.Backend = "tidb" 545 cfg.App.RegionConcurrency = 123 546 err := cfg.Adjust(context.Background()) 547 c.Assert(err, IsNil) 548 c.Assert(cfg.App.IndexConcurrency, Equals, 123) 549 c.Assert(cfg.App.TableConcurrency, Equals, 123) 550 } 551 552 func (s *configTestSuite) TestDefaultCouldBeOverwritten(c *C) { 553 cfg := config.NewConfig() 554 assignMinimalLegalValue(cfg) 555 cfg.TikvImporter.Backend = "importer" 556 cfg.App.IndexConcurrency = 20 557 cfg.App.TableConcurrency = 60 558 err := cfg.Adjust(context.Background()) 559 c.Assert(err, IsNil) 560 c.Assert(cfg.App.IndexConcurrency, Equals, 20) 561 c.Assert(cfg.App.TableConcurrency, Equals, 60) 562 } 563 564 func (s *configTestSuite) TestLoadFromInvalidConfig(c *C) { 565 taskCfg := config.NewConfig() 566 err := taskCfg.LoadFromGlobal(&config.GlobalConfig{ 567 ConfigFileContent: []byte("invalid toml"), 568 }) 569 c.Assert(err, ErrorMatches, "Near line 1.*") 570 } 571 572 func (s *configTestSuite) TestTomlPostRestore(c *C) { 573 cfg := &config.Config{} 574 err := cfg.LoadFromTOML([]byte(` 575 [post-restore] 576 checksum = "req" 577 `)) 578 c.Assert(err, ErrorMatches, regexp.QuoteMeta("invalid op level 'req', please choose valid option between ['off', 'optional', 'required']")) 579 580 err = cfg.LoadFromTOML([]byte(` 581 [post-restore] 582 analyze = 123 583 `)) 584 c.Assert(err, ErrorMatches, regexp.QuoteMeta("invalid op level '123', please choose valid option between ['off', 'optional', 'required']")) 585 586 kvMap := map[string]config.PostOpLevel{ 587 `"off"`: config.OpLevelOff, 588 `"required"`: config.OpLevelRequired, 589 `"optional"`: config.OpLevelOptional, 590 "true": config.OpLevelRequired, 591 "false": config.OpLevelOff, 592 } 593 594 var b bytes.Buffer 595 enc := toml.NewEncoder(&b) 596 597 for k, v := range kvMap { 598 cfg := &config.Config{} 599 confStr := fmt.Sprintf("[post-restore]\r\nchecksum= %s\r\n", k) 600 err := cfg.LoadFromTOML([]byte(confStr)) 601 c.Assert(err, IsNil) 602 c.Assert(cfg.PostRestore.Checksum, Equals, v) 603 604 b.Reset() 605 c.Assert(enc.Encode(cfg.PostRestore), IsNil) 606 c.Assert(&b, Matches, fmt.Sprintf(`(?s).*checksum = "\Q%s\E".*`, v)) 607 } 608 609 for k, v := range kvMap { 610 cfg := &config.Config{} 611 confStr := fmt.Sprintf("[post-restore]\r\nanalyze= %s\r\n", k) 612 err := cfg.LoadFromTOML([]byte(confStr)) 613 c.Assert(err, IsNil) 614 c.Assert(cfg.PostRestore.Analyze, Equals, v) 615 616 b.Reset() 617 c.Assert(enc.Encode(cfg.PostRestore), IsNil) 618 c.Assert(&b, Matches, fmt.Sprintf(`(?s).*analyze = "\Q%s\E".*`, v)) 619 } 620 } 621 622 func (s *configTestSuite) TestCronEncodeDecode(c *C) { 623 cfg := &config.Config{} 624 cfg.Cron.SwitchMode.Duration = 1 * time.Minute 625 cfg.Cron.LogProgress.Duration = 2 * time.Minute 626 cfg.Cron.CheckDiskQuota.Duration = 3 * time.Second 627 var b bytes.Buffer 628 c.Assert(toml.NewEncoder(&b).Encode(cfg.Cron), IsNil) 629 c.Assert(b.String(), Equals, "switch-mode = \"1m0s\"\nlog-progress = \"2m0s\"\ncheck-disk-quota = \"3s\"\n") 630 631 confStr := "[cron]\r\n" + b.String() 632 cfg2 := &config.Config{} 633 c.Assert(cfg2.LoadFromTOML([]byte(confStr)), IsNil) 634 c.Assert(cfg2.Cron, DeepEquals, cfg.Cron) 635 } 636 637 func (s *configTestSuite) TestAdjustWithLegacyBlackWhiteList(c *C) { 638 cfg := config.NewConfig() 639 assignMinimalLegalValue(cfg) 640 c.Assert(cfg.Mydumper.Filter, DeepEquals, config.DefaultFilter) 641 c.Assert(cfg.HasLegacyBlackWhiteList(), IsFalse) 642 643 ctx := context.Background() 644 cfg.Mydumper.Filter = []string{"test.*"} 645 c.Assert(cfg.Adjust(ctx), IsNil) 646 c.Assert(cfg.HasLegacyBlackWhiteList(), IsFalse) 647 648 cfg.BWList.DoDBs = []string{"test"} 649 c.Assert(cfg.Adjust(ctx), ErrorMatches, "invalid config: `mydumper\\.filter` and `black-white-list` cannot be simultaneously defined") 650 651 cfg.Mydumper.Filter = config.DefaultFilter 652 c.Assert(cfg.Adjust(ctx), IsNil) 653 c.Assert(cfg.HasLegacyBlackWhiteList(), IsTrue) 654 }