github.com/pingcap/tiup@v1.15.1/components/dm/spec/topology_dm_test.go (about) 1 // Copyright 2020 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 spec 15 16 import ( 17 "fmt" 18 "os" 19 "testing" 20 21 . "github.com/pingcap/check" 22 "github.com/pingcap/tiup/pkg/cluster/spec" 23 "github.com/stretchr/testify/assert" 24 "gopkg.in/yaml.v2" 25 ) 26 27 type metaSuiteDM struct { 28 } 29 30 var _ = Suite(&metaSuiteDM{}) 31 32 func TestDefaultDataDir(t *testing.T) { 33 // Test with without global DataDir. 34 topo := new(Specification) 35 topo.Masters = append(topo.Masters, &MasterSpec{Host: "1.1.1.1", Port: 1111}) 36 topo.Workers = append(topo.Workers, &WorkerSpec{Host: "1.1.2.1", Port: 2221}) 37 data, err := yaml.Marshal(topo) 38 assert.Nil(t, err) 39 40 // Check default value. 41 topo = new(Specification) 42 err = yaml.Unmarshal(data, topo) 43 assert.Nil(t, err) 44 assert.Equal(t, "data", topo.GlobalOptions.DataDir) 45 assert.Equal(t, "data", topo.Masters[0].DataDir) 46 assert.Equal(t, "data", topo.Workers[0].DataDir) 47 48 // Can keep the default value. 49 data, err = yaml.Marshal(topo) 50 assert.Nil(t, err) 51 topo = new(Specification) 52 err = yaml.Unmarshal(data, topo) 53 assert.Nil(t, err) 54 assert.Equal(t, "data", topo.GlobalOptions.DataDir) 55 assert.Equal(t, "data", topo.Masters[0].DataDir) 56 assert.Equal(t, "data", topo.Workers[0].DataDir) 57 58 // Test with global DataDir. 59 topo = new(Specification) 60 topo.GlobalOptions.DataDir = "/gloable_data" 61 topo.Masters = append(topo.Masters, &MasterSpec{Host: "1.1.1.1", Port: 1111}) 62 topo.Masters = append(topo.Masters, &MasterSpec{Host: "1.1.1.2", Port: 1112, DataDir: "/my_data"}) 63 topo.Workers = append(topo.Workers, &WorkerSpec{Host: "1.1.2.1", Port: 2221}) 64 topo.Workers = append(topo.Workers, &WorkerSpec{Host: "1.1.2.2", Port: 2222, DataDir: "/my_data"}) 65 data, err = yaml.Marshal(topo) 66 assert.Nil(t, err) 67 68 topo = new(Specification) 69 err = yaml.Unmarshal(data, topo) 70 71 assert.Nil(t, err) 72 assert.Equal(t, "/gloable_data", topo.GlobalOptions.DataDir) 73 assert.Equal(t, "/gloable_data/dm-master-1111", topo.Masters[0].DataDir) 74 assert.Equal(t, "/my_data", topo.Masters[1].DataDir) 75 assert.Equal(t, "/gloable_data/dm-worker-2221", topo.Workers[0].DataDir) 76 assert.Equal(t, "/my_data", topo.Workers[1].DataDir) 77 } 78 79 func TestGlobalOptions(t *testing.T) { 80 topo := Specification{} 81 err := yaml.Unmarshal([]byte(` 82 global: 83 user: "test1" 84 ssh_port: 220 85 deploy_dir: "test-deploy" 86 data_dir: "test-data" 87 master_servers: 88 - host: 172.16.5.138 89 deploy_dir: "master-deploy" 90 worker_servers: 91 - host: 172.16.5.53 92 data_dir: "worker-data" 93 `), &topo) 94 assert.Nil(t, err) 95 assert.Equal(t, "test1", topo.GlobalOptions.User) 96 97 assert.Equal(t, 220, topo.GlobalOptions.SSHPort) 98 assert.Equal(t, 220, topo.Masters[0].SSHPort) 99 assert.Equal(t, "master-deploy", topo.Masters[0].DeployDir) 100 101 assert.Equal(t, 220, topo.Workers[0].SSHPort) 102 assert.Equal(t, "test-deploy/dm-worker-8262", topo.Workers[0].DeployDir) 103 assert.Equal(t, "worker-data", topo.Workers[0].DataDir) 104 } 105 106 func TestDirectoryConflicts(t *testing.T) { 107 topo := Specification{} 108 err := yaml.Unmarshal([]byte(` 109 global: 110 user: "test1" 111 ssh_port: 220 112 deploy_dir: "test-deploy" 113 data_dir: "test-data" 114 master_servers: 115 - host: 172.16.5.138 116 deploy_dir: "/test-1" 117 worker_servers: 118 - host: 172.16.5.138 119 data_dir: "/test-1" 120 `), &topo) 121 assert.NotNil(t, err) 122 assert.Equal(t, "directory conflict for '/test-1' between 'master_servers:172.16.5.138.deploy_dir' and 'worker_servers:172.16.5.138.data_dir'", err.Error()) 123 124 err = yaml.Unmarshal([]byte(` 125 global: 126 user: "test1" 127 ssh_port: 220 128 deploy_dir: "test-deploy" 129 data_dir: "/test-data" 130 master_servers: 131 - host: 172.16.5.138 132 data_dir: "test-1" 133 worker_servers: 134 - host: 172.16.5.138 135 data_dir: "test-1" 136 `), &topo) 137 assert.Nil(t, err) 138 } 139 140 func TestPortConflicts(t *testing.T) { 141 topo := Specification{} 142 err := yaml.Unmarshal([]byte(` 143 global: 144 user: "test1" 145 ssh_port: 220 146 deploy_dir: "test-deploy" 147 data_dir: "test-data" 148 master_servers: 149 - host: 172.16.5.138 150 peer_port: 1234 151 worker_servers: 152 - host: 172.16.5.138 153 port: 1234 154 `), &topo) 155 assert.NotNil(t, err) 156 assert.Equal(t, "port conflict for '1234' between 'master_servers:172.16.5.138.peer_port,omitempty' and 'worker_servers:172.16.5.138.port,omitempty'", err.Error()) 157 } 158 159 func TestPlatformConflicts(t *testing.T) { 160 // aarch64 and arm64 are equal 161 topo := Specification{} 162 err := yaml.Unmarshal([]byte(` 163 global: 164 os: "linux" 165 arch: "aarch64" 166 master_servers: 167 - host: 172.16.5.138 168 arch: "arm64" 169 worker_servers: 170 - host: 172.16.5.138 171 arch: "aarch64" 172 `), &topo) 173 assert.Nil(t, err) 174 175 // different arch defined for the same host 176 topo = Specification{} 177 err = yaml.Unmarshal([]byte(` 178 global: 179 os: "linux" 180 master_servers: 181 - host: 172.16.5.138 182 arch: "aarch64" 183 os: "linux" 184 worker_servers: 185 - host: 172.16.5.138 186 arch: "amd64" 187 os: "linux" 188 `), &topo) 189 assert.NotNil(t, err) 190 assert.Equal(t, "platform mismatch for '172.16.5.138' between 'master_servers:linux/arm64' and 'worker_servers:linux/amd64'", err.Error()) 191 192 // different os defined for the same host 193 topo = Specification{} 194 err = yaml.Unmarshal([]byte(` 195 global: 196 os: "linux" 197 arch: "aarch64" 198 master_servers: 199 - host: 172.16.5.138 200 os: "darwin" 201 arch: "aarch64" 202 worker_servers: 203 - host: 172.16.5.138 204 os: "linux" 205 arch: "aarch64" 206 `), &topo) 207 assert.NotNil(t, err) 208 assert.Equal(t, "platform mismatch for '172.16.5.138' between 'master_servers:darwin/arm64' and 'worker_servers:linux/arm64'", err.Error()) 209 } 210 211 func TestCountDir(t *testing.T) { 212 topo := Specification{} 213 214 err := yaml.Unmarshal([]byte(` 215 global: 216 user: "test1" 217 ssh_port: 220 218 deploy_dir: "test-deploy" 219 master_servers: 220 - host: 172.16.5.138 221 deploy_dir: "master-deploy" 222 data_dir: "/test-data/data-1" 223 worker_servers: 224 - host: 172.16.5.53 225 data_dir: "test-1" 226 `), &topo) 227 assert.Nil(t, err) 228 cnt := topo.CountDir("172.16.5.53", "test-deploy/dm-worker-8262") 229 assert.Equal(t, 3, cnt) 230 cnt = topo.CountDir("172.16.5.138", "/test-data/data") 231 assert.Equal(t, 0, cnt) // should not match partial path 232 233 err = yaml.Unmarshal([]byte(` 234 global: 235 user: "test1" 236 ssh_port: 220 237 deploy_dir: "/test-deploy" 238 master_servers: 239 - host: 172.16.5.138 240 deploy_dir: "master-deploy" 241 data_dir: "/test-data/data-1" 242 worker_servers: 243 - host: 172.16.5.138 244 data_dir: "/test-data/data-2" 245 `), &topo) 246 assert.Nil(t, err) 247 cnt = topo.CountDir("172.16.5.138", "/test-deploy/dm-worker-8262") 248 assert.Equal(t, 2, cnt) 249 cnt = topo.CountDir("172.16.5.138", "") 250 assert.Equal(t, 2, cnt) 251 cnt = topo.CountDir("172.16.5.138", "test-data") 252 assert.Equal(t, 0, cnt) 253 cnt = topo.CountDir("172.16.5.138", "/test-data") 254 assert.Equal(t, 2, cnt) 255 256 err = yaml.Unmarshal([]byte(` 257 global: 258 user: "test1" 259 ssh_port: 220 260 deploy_dir: "/test-deploy" 261 data_dir: "/test-data" 262 master_servers: 263 - host: 172.16.5.138 264 data_dir: "data-1" 265 worker_servers: 266 - host: 172.16.5.138 267 data_dir: "data-2" 268 - host: 172.16.5.53 269 `), &topo) 270 assert.Nil(t, err) 271 // if per-instance data_dir is set, the global data_dir is ignored, and if it 272 // is a relative path, it will be under the instance's deploy_dir 273 cnt = topo.CountDir("172.16.5.138", "/test-deploy/dm-worker-8262") 274 assert.Equal(t, 3, cnt) 275 cnt = topo.CountDir("172.16.5.138", "") 276 assert.Equal(t, 0, cnt) 277 cnt = topo.CountDir("172.16.5.53", "/test-data") 278 assert.Equal(t, 1, cnt) 279 } 280 281 func withTempFile(content string, fn func(string)) { 282 file, err := os.CreateTemp("/tmp", "topology-test") 283 if err != nil { 284 panic(fmt.Sprintf("create temp file: %s", err)) 285 } 286 defer os.Remove(file.Name()) 287 288 _, err = file.WriteString(content) 289 if err != nil { 290 panic(fmt.Sprintf("write temp file: %s", err)) 291 } 292 file.Close() 293 294 fn(file.Name()) 295 } 296 297 func with2TempFile(content1, content2 string, fn func(string, string)) { 298 withTempFile(content1, func(file1 string) { 299 withTempFile(content2, func(file2 string) { 300 fn(file1, file2) 301 }) 302 }) 303 } 304 305 func merge4test(base, scale string) (*Specification, error) { 306 baseTopo := Specification{} 307 if err := spec.ParseTopologyYaml(base, &baseTopo); err != nil { 308 return nil, err 309 } 310 311 scaleTopo := baseTopo.NewPart() 312 if err := spec.ParseTopologyYaml(scale, scaleTopo); err != nil { 313 return nil, err 314 } 315 316 mergedTopo := baseTopo.MergeTopo(scaleTopo) 317 if err := mergedTopo.Validate(); err != nil { 318 return nil, err 319 } 320 321 return mergedTopo.(*Specification), nil 322 } 323 324 func TestRelativePath(t *testing.T) { 325 // base test 326 withTempFile(` 327 master_servers: 328 - host: 172.16.5.140 329 worker_servers: 330 - host: 172.16.5.140 331 `, func(file string) { 332 topo := Specification{} 333 err := spec.ParseTopologyYaml(file, &topo) 334 assert.Nil(t, err) 335 spec.ExpandRelativeDir(&topo) 336 assert.Equal(t, "/home/tidb/deploy/dm-master-8261", topo.Masters[0].DeployDir) 337 assert.Equal(t, "/home/tidb/deploy/dm-worker-8262", topo.Workers[0].DeployDir) 338 }) 339 340 // test data dir & log dir 341 withTempFile(` 342 master_servers: 343 - host: 172.16.5.140 344 deploy_dir: my-deploy 345 data_dir: my-data 346 log_dir: my-log 347 `, func(file string) { 348 topo := Specification{} 349 err := spec.ParseTopologyYaml(file, &topo) 350 assert.Nil(t, err) 351 spec.ExpandRelativeDir(&topo) 352 353 assert.Equal(t, "/home/tidb/my-deploy", topo.Masters[0].DeployDir) 354 assert.Equal(t, "/home/tidb/my-deploy/my-data", topo.Masters[0].DataDir) 355 assert.Equal(t, "/home/tidb/my-deploy/my-log", topo.Masters[0].LogDir) 356 }) 357 358 // test global options, case 1 359 withTempFile(` 360 global: 361 deploy_dir: my-deploy 362 master_servers: 363 - host: 172.16.5.140 364 `, func(file string) { 365 topo := Specification{} 366 err := spec.ParseTopologyYaml(file, &topo) 367 assert.Nil(t, err) 368 spec.ExpandRelativeDir(&topo) 369 370 assert.Equal(t, "/home/tidb/my-deploy/dm-master-8261", topo.Masters[0].DeployDir) 371 assert.Equal(t, "/home/tidb/my-deploy/dm-master-8261/data", topo.Masters[0].DataDir) 372 assert.Equal(t, "", topo.Masters[0].LogDir) 373 }) 374 375 // test global options, case 2 376 withTempFile(` 377 global: 378 deploy_dir: my-deploy 379 master_servers: 380 - host: 172.16.5.140 381 worker_servers: 382 - host: 172.16.5.140 383 port: 20160 384 - host: 172.16.5.140 385 port: 20161 386 `, func(file string) { 387 topo := Specification{} 388 err := spec.ParseTopologyYaml(file, &topo) 389 assert.Nil(t, err) 390 spec.ExpandRelativeDir(&topo) 391 392 assert.Equal(t, "my-deploy", topo.GlobalOptions.DeployDir) 393 assert.Equal(t, "data", topo.GlobalOptions.DataDir) 394 395 assert.Equal(t, "/home/tidb/my-deploy/dm-worker-20160", topo.Workers[0].DeployDir) 396 assert.Equal(t, "/home/tidb/my-deploy/dm-worker-20160/data", topo.Workers[0].DataDir) 397 398 assert.Equal(t, "/home/tidb/my-deploy/dm-worker-20161", topo.Workers[1].DeployDir) 399 assert.Equal(t, "/home/tidb/my-deploy/dm-worker-20161/data", topo.Workers[1].DataDir) 400 }) 401 402 // test global options, case 3 403 withTempFile(` 404 global: 405 deploy_dir: my-deploy 406 master_servers: 407 - host: 172.16.5.140 408 worker_servers: 409 - host: 172.16.5.140 410 port: 20160 411 data_dir: my-data 412 log_dir: my-log 413 - host: 172.16.5.140 414 port: 20161 415 `, func(file string) { 416 topo := Specification{} 417 err := spec.ParseTopologyYaml(file, &topo) 418 assert.Nil(t, err) 419 spec.ExpandRelativeDir(&topo) 420 421 assert.Equal(t, "my-deploy", topo.GlobalOptions.DeployDir) 422 assert.Equal(t, "data", topo.GlobalOptions.DataDir) 423 424 assert.Equal(t, "/home/tidb/my-deploy/dm-worker-20160", topo.Workers[0].DeployDir) 425 assert.Equal(t, "/home/tidb/my-deploy/dm-worker-20160/my-data", topo.Workers[0].DataDir) 426 assert.Equal(t, "/home/tidb/my-deploy/dm-worker-20160/my-log", topo.Workers[0].LogDir) 427 428 assert.Equal(t, "/home/tidb/my-deploy/dm-worker-20161", topo.Workers[1].DeployDir) 429 assert.Equal(t, "/home/tidb/my-deploy/dm-worker-20161/data", topo.Workers[1].DataDir) 430 assert.Equal(t, "", topo.Workers[1].LogDir) 431 }) 432 433 // test global options, case 4 434 withTempFile(` 435 global: 436 data_dir: my-global-data 437 log_dir: my-global-log 438 master_servers: 439 - host: 172.16.5.140 440 worker_servers: 441 - host: 172.16.5.140 442 port: 20160 443 data_dir: my-local-data 444 log_dir: my-local-log 445 - host: 172.16.5.140 446 port: 20161 447 `, func(file string) { 448 topo := Specification{} 449 err := spec.ParseTopologyYaml(file, &topo) 450 assert.Nil(t, err) 451 spec.ExpandRelativeDir(&topo) 452 453 assert.Equal(t, "deploy", topo.GlobalOptions.DeployDir) 454 assert.Equal(t, "my-global-data", topo.GlobalOptions.DataDir) 455 assert.Equal(t, "my-global-log", topo.GlobalOptions.LogDir) 456 457 assert.Equal(t, "/home/tidb/deploy/dm-worker-20160", topo.Workers[0].DeployDir) 458 assert.Equal(t, "/home/tidb/deploy/dm-worker-20160/my-local-data", topo.Workers[0].DataDir) 459 assert.Equal(t, "/home/tidb/deploy/dm-worker-20160/my-local-log", topo.Workers[0].LogDir) 460 461 assert.Equal(t, "/home/tidb/deploy/dm-worker-20161", topo.Workers[1].DeployDir) 462 assert.Equal(t, "/home/tidb/deploy/dm-worker-20161/my-global-data", topo.Workers[1].DataDir) 463 assert.Equal(t, "/home/tidb/deploy/dm-worker-20161/my-global-log", topo.Workers[1].LogDir) 464 }) 465 } 466 467 func TestTopologyMerge(t *testing.T) { 468 // base test 469 with2TempFile(` 470 master_servers: 471 - host: 172.16.5.140 472 worker_servers: 473 - host: 172.16.5.140 474 `, ` 475 worker_servers: 476 - host: 172.16.5.139 477 `, func(base, scale string) { 478 topo, err := merge4test(base, scale) 479 assert.Nil(t, err) 480 spec.ExpandRelativeDir(topo) 481 482 assert.Equal(t, "/home/tidb/deploy/dm-worker-8262", topo.Workers[0].DeployDir) 483 assert.Equal(t, "/home/tidb/deploy/dm-worker-8262/data", topo.Workers[0].DataDir) 484 assert.Equal(t, "", topo.Workers[0].LogDir) 485 486 assert.Equal(t, "/home/tidb/deploy/dm-worker-8262", topo.Workers[1].DeployDir) 487 assert.Equal(t, "/home/tidb/deploy/dm-worker-8262/data", topo.Workers[1].DataDir) 488 assert.Equal(t, "", topo.Workers[1].LogDir) 489 }) 490 491 // test global option overwrite 492 with2TempFile(` 493 global: 494 user: test 495 deploy_dir: /my-global-deploy 496 master_servers: 497 - host: 172.16.5.140 498 worker_servers: 499 - host: 172.16.5.140 500 log_dir: my-local-log 501 data_dir: my-local-data 502 - host: 172.16.5.175 503 deploy_dir: flash-deploy 504 - host: 172.16.5.141 505 `, ` 506 worker_servers: 507 - host: 172.16.5.139 508 deploy_dir: flash-deploy 509 - host: 172.16.5.134 510 `, func(base, scale string) { 511 topo, err := merge4test(base, scale) 512 assert.Nil(t, err) 513 514 spec.ExpandRelativeDir(topo) 515 516 assert.Equal(t, "/my-global-deploy/dm-worker-8262", topo.Workers[0].DeployDir) 517 assert.Equal(t, "/my-global-deploy/dm-worker-8262/my-local-data", topo.Workers[0].DataDir) 518 assert.Equal(t, "/my-global-deploy/dm-worker-8262/my-local-log", topo.Workers[0].LogDir) 519 520 assert.Equal(t, "/home/test/flash-deploy", topo.Workers[1].DeployDir) 521 assert.Equal(t, "/home/test/flash-deploy/data", topo.Workers[1].DataDir) 522 assert.Equal(t, "/home/test/flash-deploy", topo.Workers[3].DeployDir) 523 assert.Equal(t, "/home/test/flash-deploy/data", topo.Workers[3].DataDir) 524 525 assert.Equal(t, "/my-global-deploy/dm-worker-8262", topo.Workers[2].DeployDir) 526 assert.Equal(t, "/my-global-deploy/dm-worker-8262/data", topo.Workers[2].DataDir) 527 assert.Equal(t, "/my-global-deploy/dm-worker-8262", topo.Workers[4].DeployDir) 528 assert.Equal(t, "/my-global-deploy/dm-worker-8262/data", topo.Workers[4].DataDir) 529 }) 530 } 531 532 func TestMonitorLogDir(t *testing.T) { 533 withTempFile(` 534 monitored: 535 node_exporter_port: 39100 536 blackbox_exporter_port: 39115 537 deploy_dir: "test-deploy" 538 log_dir: "test-deploy/log" 539 `, func(file string) { 540 topo := Specification{} 541 err := spec.ParseTopologyYaml(file, &topo) 542 assert.Nil(t, err) 543 assert.Equal(t, 39100, topo.MonitoredOptions.NodeExporterPort) 544 assert.Equal(t, 39115, topo.MonitoredOptions.BlackboxExporterPort) 545 assert.Equal(t, "test-deploy/log", topo.MonitoredOptions.LogDir) 546 assert.Equal(t, "test-deploy", topo.MonitoredOptions.DeployDir) 547 }) 548 }