github.com/emate/nomad@v0.8.2-wo-binpacking/jobspec/parse_test.go (about) 1 package jobspec 2 3 import ( 4 "path/filepath" 5 "reflect" 6 "strings" 7 "testing" 8 "time" 9 10 "github.com/hashicorp/nomad/api" 11 "github.com/hashicorp/nomad/helper" 12 "github.com/hashicorp/nomad/nomad/structs" 13 "github.com/kr/pretty" 14 15 capi "github.com/hashicorp/consul/api" 16 ) 17 18 func TestParse(t *testing.T) { 19 cases := []struct { 20 File string 21 Result *api.Job 22 Err bool 23 }{ 24 { 25 "basic.hcl", 26 &api.Job{ 27 ID: helper.StringToPtr("binstore-storagelocker"), 28 Name: helper.StringToPtr("binstore-storagelocker"), 29 Type: helper.StringToPtr("batch"), 30 Priority: helper.IntToPtr(52), 31 AllAtOnce: helper.BoolToPtr(true), 32 Datacenters: []string{"us2", "eu1"}, 33 Region: helper.StringToPtr("fooregion"), 34 Namespace: helper.StringToPtr("foonamespace"), 35 VaultToken: helper.StringToPtr("foo"), 36 37 Meta: map[string]string{ 38 "foo": "bar", 39 }, 40 41 Constraints: []*api.Constraint{ 42 { 43 LTarget: "kernel.os", 44 RTarget: "windows", 45 Operand: "=", 46 }, 47 }, 48 49 Update: &api.UpdateStrategy{ 50 Stagger: helper.TimeToPtr(60 * time.Second), 51 MaxParallel: helper.IntToPtr(2), 52 HealthCheck: helper.StringToPtr("manual"), 53 MinHealthyTime: helper.TimeToPtr(10 * time.Second), 54 HealthyDeadline: helper.TimeToPtr(10 * time.Minute), 55 AutoRevert: helper.BoolToPtr(true), 56 Canary: helper.IntToPtr(1), 57 }, 58 59 TaskGroups: []*api.TaskGroup{ 60 { 61 Name: helper.StringToPtr("outside"), 62 Tasks: []*api.Task{ 63 { 64 Name: "outside", 65 Driver: "java", 66 Config: map[string]interface{}{ 67 "jar_path": "s3://my-cool-store/foo.jar", 68 }, 69 Meta: map[string]string{ 70 "my-cool-key": "foobar", 71 }, 72 }, 73 }, 74 }, 75 76 { 77 Name: helper.StringToPtr("binsl"), 78 Count: helper.IntToPtr(5), 79 Constraints: []*api.Constraint{ 80 { 81 LTarget: "kernel.os", 82 RTarget: "linux", 83 Operand: "=", 84 }, 85 }, 86 Meta: map[string]string{ 87 "elb_mode": "tcp", 88 "elb_interval": "10", 89 "elb_checks": "3", 90 }, 91 RestartPolicy: &api.RestartPolicy{ 92 Interval: helper.TimeToPtr(10 * time.Minute), 93 Attempts: helper.IntToPtr(5), 94 Delay: helper.TimeToPtr(15 * time.Second), 95 Mode: helper.StringToPtr("delay"), 96 }, 97 ReschedulePolicy: &api.ReschedulePolicy{ 98 Interval: helper.TimeToPtr(12 * time.Hour), 99 Attempts: helper.IntToPtr(5), 100 }, 101 EphemeralDisk: &api.EphemeralDisk{ 102 Sticky: helper.BoolToPtr(true), 103 SizeMB: helper.IntToPtr(150), 104 }, 105 Update: &api.UpdateStrategy{ 106 MaxParallel: helper.IntToPtr(3), 107 HealthCheck: helper.StringToPtr("checks"), 108 MinHealthyTime: helper.TimeToPtr(1 * time.Second), 109 HealthyDeadline: helper.TimeToPtr(1 * time.Minute), 110 AutoRevert: helper.BoolToPtr(false), 111 Canary: helper.IntToPtr(2), 112 }, 113 Migrate: &api.MigrateStrategy{ 114 MaxParallel: helper.IntToPtr(2), 115 HealthCheck: helper.StringToPtr("task_states"), 116 MinHealthyTime: helper.TimeToPtr(11 * time.Second), 117 HealthyDeadline: helper.TimeToPtr(11 * time.Minute), 118 }, 119 Tasks: []*api.Task{ 120 { 121 Name: "binstore", 122 Driver: "docker", 123 User: "bob", 124 Config: map[string]interface{}{ 125 "image": "hashicorp/binstore", 126 "labels": []map[string]interface{}{ 127 { 128 "FOO": "bar", 129 }, 130 }, 131 }, 132 Services: []*api.Service{ 133 { 134 Tags: []string{"foo", "bar"}, 135 PortLabel: "http", 136 Checks: []api.ServiceCheck{ 137 { 138 Name: "check-name", 139 Type: "tcp", 140 PortLabel: "admin", 141 Interval: 10 * time.Second, 142 Timeout: 2 * time.Second, 143 CheckRestart: &api.CheckRestart{ 144 Limit: 3, 145 Grace: helper.TimeToPtr(10 * time.Second), 146 IgnoreWarnings: true, 147 }, 148 }, 149 }, 150 }, 151 }, 152 Env: map[string]string{ 153 "HELLO": "world", 154 "LOREM": "ipsum", 155 }, 156 Resources: &api.Resources{ 157 CPU: helper.IntToPtr(500), 158 MemoryMB: helper.IntToPtr(128), 159 Networks: []*api.NetworkResource{ 160 { 161 MBits: helper.IntToPtr(100), 162 ReservedPorts: []api.Port{{Label: "one", Value: 1}, {Label: "two", Value: 2}, {Label: "three", Value: 3}}, 163 DynamicPorts: []api.Port{{Label: "http", Value: 0}, {Label: "https", Value: 0}, {Label: "admin", Value: 0}}, 164 }, 165 }, 166 }, 167 KillTimeout: helper.TimeToPtr(22 * time.Second), 168 ShutdownDelay: 11 * time.Second, 169 LogConfig: &api.LogConfig{ 170 MaxFiles: helper.IntToPtr(14), 171 MaxFileSizeMB: helper.IntToPtr(101), 172 }, 173 Artifacts: []*api.TaskArtifact{ 174 { 175 GetterSource: helper.StringToPtr("http://foo.com/artifact"), 176 GetterOptions: map[string]string{ 177 "checksum": "md5:b8a4f3f72ecab0510a6a31e997461c5f", 178 }, 179 }, 180 { 181 GetterSource: helper.StringToPtr("http://bar.com/artifact"), 182 RelativeDest: helper.StringToPtr("test/foo/"), 183 GetterOptions: map[string]string{ 184 "checksum": "md5:ff1cc0d3432dad54d607c1505fb7245c", 185 }, 186 GetterMode: helper.StringToPtr("file"), 187 }, 188 }, 189 Vault: &api.Vault{ 190 Policies: []string{"foo", "bar"}, 191 Env: helper.BoolToPtr(true), 192 ChangeMode: helper.StringToPtr(structs.VaultChangeModeRestart), 193 }, 194 Templates: []*api.Template{ 195 { 196 SourcePath: helper.StringToPtr("foo"), 197 DestPath: helper.StringToPtr("foo"), 198 ChangeMode: helper.StringToPtr("foo"), 199 ChangeSignal: helper.StringToPtr("foo"), 200 Splay: helper.TimeToPtr(10 * time.Second), 201 Perms: helper.StringToPtr("0644"), 202 Envvars: helper.BoolToPtr(true), 203 VaultGrace: helper.TimeToPtr(33 * time.Second), 204 }, 205 { 206 SourcePath: helper.StringToPtr("bar"), 207 DestPath: helper.StringToPtr("bar"), 208 ChangeMode: helper.StringToPtr(structs.TemplateChangeModeRestart), 209 Splay: helper.TimeToPtr(5 * time.Second), 210 Perms: helper.StringToPtr("777"), 211 LeftDelim: helper.StringToPtr("--"), 212 RightDelim: helper.StringToPtr("__"), 213 }, 214 }, 215 Leader: true, 216 KillSignal: "", 217 }, 218 { 219 Name: "storagelocker", 220 Driver: "docker", 221 User: "", 222 Config: map[string]interface{}{ 223 "image": "hashicorp/storagelocker", 224 }, 225 Resources: &api.Resources{ 226 CPU: helper.IntToPtr(500), 227 MemoryMB: helper.IntToPtr(128), 228 IOPS: helper.IntToPtr(30), 229 }, 230 Constraints: []*api.Constraint{ 231 { 232 LTarget: "kernel.arch", 233 RTarget: "amd64", 234 Operand: "=", 235 }, 236 }, 237 Vault: &api.Vault{ 238 Policies: []string{"foo", "bar"}, 239 Env: helper.BoolToPtr(false), 240 ChangeMode: helper.StringToPtr(structs.VaultChangeModeSignal), 241 ChangeSignal: helper.StringToPtr("SIGUSR1"), 242 }, 243 }, 244 }, 245 }, 246 }, 247 }, 248 false, 249 }, 250 251 { 252 "multi-network.hcl", 253 nil, 254 true, 255 }, 256 257 { 258 "multi-resource.hcl", 259 nil, 260 true, 261 }, 262 263 { 264 "multi-vault.hcl", 265 nil, 266 true, 267 }, 268 269 { 270 "default-job.hcl", 271 &api.Job{ 272 ID: helper.StringToPtr("foo"), 273 Name: helper.StringToPtr("foo"), 274 }, 275 false, 276 }, 277 278 { 279 "version-constraint.hcl", 280 &api.Job{ 281 ID: helper.StringToPtr("foo"), 282 Name: helper.StringToPtr("foo"), 283 Constraints: []*api.Constraint{ 284 { 285 LTarget: "$attr.kernel.version", 286 RTarget: "~> 3.2", 287 Operand: structs.ConstraintVersion, 288 }, 289 }, 290 }, 291 false, 292 }, 293 294 { 295 "regexp-constraint.hcl", 296 &api.Job{ 297 ID: helper.StringToPtr("foo"), 298 Name: helper.StringToPtr("foo"), 299 Constraints: []*api.Constraint{ 300 { 301 LTarget: "$attr.kernel.version", 302 RTarget: "[0-9.]+", 303 Operand: structs.ConstraintRegex, 304 }, 305 }, 306 }, 307 false, 308 }, 309 310 { 311 "set-contains-constraint.hcl", 312 &api.Job{ 313 ID: helper.StringToPtr("foo"), 314 Name: helper.StringToPtr("foo"), 315 Constraints: []*api.Constraint{ 316 { 317 LTarget: "$meta.data", 318 RTarget: "foo,bar,baz", 319 Operand: structs.ConstraintSetContains, 320 }, 321 }, 322 }, 323 false, 324 }, 325 326 { 327 "distinctHosts-constraint.hcl", 328 &api.Job{ 329 ID: helper.StringToPtr("foo"), 330 Name: helper.StringToPtr("foo"), 331 Constraints: []*api.Constraint{ 332 { 333 Operand: structs.ConstraintDistinctHosts, 334 }, 335 }, 336 }, 337 false, 338 }, 339 340 { 341 "distinctProperty-constraint.hcl", 342 &api.Job{ 343 ID: helper.StringToPtr("foo"), 344 Name: helper.StringToPtr("foo"), 345 Constraints: []*api.Constraint{ 346 { 347 Operand: structs.ConstraintDistinctProperty, 348 LTarget: "${meta.rack}", 349 }, 350 }, 351 }, 352 false, 353 }, 354 355 { 356 "periodic-cron.hcl", 357 &api.Job{ 358 ID: helper.StringToPtr("foo"), 359 Name: helper.StringToPtr("foo"), 360 Periodic: &api.PeriodicConfig{ 361 SpecType: helper.StringToPtr(api.PeriodicSpecCron), 362 Spec: helper.StringToPtr("*/5 * * *"), 363 ProhibitOverlap: helper.BoolToPtr(true), 364 TimeZone: helper.StringToPtr("Europe/Minsk"), 365 }, 366 }, 367 false, 368 }, 369 370 { 371 "specify-job.hcl", 372 &api.Job{ 373 ID: helper.StringToPtr("job1"), 374 Name: helper.StringToPtr("My Job"), 375 }, 376 false, 377 }, 378 379 { 380 "task-nested-config.hcl", 381 &api.Job{ 382 ID: helper.StringToPtr("foo"), 383 Name: helper.StringToPtr("foo"), 384 TaskGroups: []*api.TaskGroup{ 385 { 386 Name: helper.StringToPtr("bar"), 387 Tasks: []*api.Task{ 388 { 389 Name: "bar", 390 Driver: "docker", 391 Config: map[string]interface{}{ 392 "image": "hashicorp/image", 393 "port_map": []map[string]interface{}{ 394 { 395 "db": 1234, 396 }, 397 }, 398 }, 399 }, 400 }, 401 }, 402 }, 403 }, 404 false, 405 }, 406 407 { 408 "bad-artifact.hcl", 409 nil, 410 true, 411 }, 412 413 { 414 "artifacts.hcl", 415 &api.Job{ 416 ID: helper.StringToPtr("binstore-storagelocker"), 417 Name: helper.StringToPtr("binstore-storagelocker"), 418 TaskGroups: []*api.TaskGroup{ 419 { 420 Name: helper.StringToPtr("binsl"), 421 Tasks: []*api.Task{ 422 { 423 Name: "binstore", 424 Driver: "docker", 425 Artifacts: []*api.TaskArtifact{ 426 { 427 GetterSource: helper.StringToPtr("http://foo.com/bar"), 428 GetterOptions: map[string]string{"foo": "bar"}, 429 RelativeDest: helper.StringToPtr(""), 430 }, 431 { 432 GetterSource: helper.StringToPtr("http://foo.com/baz"), 433 GetterOptions: nil, 434 RelativeDest: nil, 435 }, 436 { 437 GetterSource: helper.StringToPtr("http://foo.com/bam"), 438 GetterOptions: nil, 439 RelativeDest: helper.StringToPtr("var/foo"), 440 }, 441 }, 442 }, 443 }, 444 }, 445 }, 446 }, 447 false, 448 }, 449 { 450 "service-check-initial-status.hcl", 451 &api.Job{ 452 ID: helper.StringToPtr("check_initial_status"), 453 Name: helper.StringToPtr("check_initial_status"), 454 Type: helper.StringToPtr("service"), 455 TaskGroups: []*api.TaskGroup{ 456 { 457 Name: helper.StringToPtr("group"), 458 Count: helper.IntToPtr(1), 459 Tasks: []*api.Task{ 460 { 461 Name: "task", 462 Services: []*api.Service{ 463 { 464 Tags: []string{"foo", "bar"}, 465 PortLabel: "http", 466 Checks: []api.ServiceCheck{ 467 { 468 Name: "check-name", 469 Type: "http", 470 Path: "/", 471 Interval: 10 * time.Second, 472 Timeout: 2 * time.Second, 473 InitialStatus: capi.HealthPassing, 474 Method: "POST", 475 Header: map[string][]string{ 476 "Authorization": {"Basic ZWxhc3RpYzpjaGFuZ2VtZQ=="}, 477 }, 478 }, 479 }, 480 }, 481 }, 482 }, 483 }, 484 }, 485 }, 486 }, 487 false, 488 }, 489 { 490 "service-check-bad-header.hcl", 491 nil, 492 true, 493 }, 494 { 495 "service-check-bad-header-2.hcl", 496 nil, 497 true, 498 }, 499 { 500 // TODO This should be pushed into the API 501 "vault_inheritance.hcl", 502 &api.Job{ 503 ID: helper.StringToPtr("example"), 504 Name: helper.StringToPtr("example"), 505 TaskGroups: []*api.TaskGroup{ 506 { 507 Name: helper.StringToPtr("cache"), 508 Tasks: []*api.Task{ 509 { 510 Name: "redis", 511 Vault: &api.Vault{ 512 Policies: []string{"group"}, 513 Env: helper.BoolToPtr(true), 514 ChangeMode: helper.StringToPtr(structs.VaultChangeModeRestart), 515 }, 516 }, 517 { 518 Name: "redis2", 519 Vault: &api.Vault{ 520 Policies: []string{"task"}, 521 Env: helper.BoolToPtr(false), 522 ChangeMode: helper.StringToPtr(structs.VaultChangeModeRestart), 523 }, 524 }, 525 }, 526 }, 527 { 528 Name: helper.StringToPtr("cache2"), 529 Tasks: []*api.Task{ 530 { 531 Name: "redis", 532 Vault: &api.Vault{ 533 Policies: []string{"job"}, 534 Env: helper.BoolToPtr(true), 535 ChangeMode: helper.StringToPtr(structs.VaultChangeModeRestart), 536 }, 537 }, 538 }, 539 }, 540 }, 541 }, 542 false, 543 }, 544 { 545 "parameterized_job.hcl", 546 &api.Job{ 547 ID: helper.StringToPtr("parameterized_job"), 548 Name: helper.StringToPtr("parameterized_job"), 549 550 ParameterizedJob: &api.ParameterizedJobConfig{ 551 Payload: "required", 552 MetaRequired: []string{"foo", "bar"}, 553 MetaOptional: []string{"baz", "bam"}, 554 }, 555 556 TaskGroups: []*api.TaskGroup{ 557 { 558 Name: helper.StringToPtr("foo"), 559 Tasks: []*api.Task{ 560 { 561 Name: "bar", 562 Driver: "docker", 563 DispatchPayload: &api.DispatchPayloadConfig{ 564 File: "foo/bar", 565 }, 566 }, 567 }, 568 }, 569 }, 570 }, 571 false, 572 }, 573 { 574 "job-with-kill-signal.hcl", 575 &api.Job{ 576 ID: helper.StringToPtr("foo"), 577 Name: helper.StringToPtr("foo"), 578 TaskGroups: []*api.TaskGroup{ 579 { 580 Name: helper.StringToPtr("bar"), 581 Tasks: []*api.Task{ 582 { 583 Name: "bar", 584 Driver: "docker", 585 KillSignal: "SIGQUIT", 586 Config: map[string]interface{}{ 587 "image": "hashicorp/image", 588 }, 589 }, 590 }, 591 }, 592 }, 593 }, 594 false, 595 }, 596 { 597 "service-check-driver-address.hcl", 598 &api.Job{ 599 ID: helper.StringToPtr("address_mode_driver"), 600 Name: helper.StringToPtr("address_mode_driver"), 601 Type: helper.StringToPtr("service"), 602 TaskGroups: []*api.TaskGroup{ 603 { 604 Name: helper.StringToPtr("group"), 605 Tasks: []*api.Task{ 606 { 607 Name: "task", 608 Services: []*api.Service{ 609 { 610 Name: "http-service", 611 PortLabel: "http", 612 AddressMode: "auto", 613 Checks: []api.ServiceCheck{ 614 { 615 Name: "http-check", 616 Type: "http", 617 Path: "/", 618 PortLabel: "http", 619 AddressMode: "driver", 620 }, 621 }, 622 }, 623 { 624 Name: "random-service", 625 PortLabel: "9000", 626 AddressMode: "driver", 627 Checks: []api.ServiceCheck{ 628 { 629 Name: "random-check", 630 Type: "tcp", 631 PortLabel: "9001", 632 AddressMode: "driver", 633 }, 634 }, 635 }, 636 }, 637 }, 638 }, 639 }, 640 }, 641 }, 642 false, 643 }, 644 { 645 "service-check-restart.hcl", 646 &api.Job{ 647 ID: helper.StringToPtr("service_check_restart"), 648 Name: helper.StringToPtr("service_check_restart"), 649 Type: helper.StringToPtr("service"), 650 TaskGroups: []*api.TaskGroup{ 651 { 652 Name: helper.StringToPtr("group"), 653 Tasks: []*api.Task{ 654 { 655 Name: "task", 656 Services: []*api.Service{ 657 { 658 Name: "http-service", 659 CheckRestart: &api.CheckRestart{ 660 Limit: 3, 661 Grace: helper.TimeToPtr(10 * time.Second), 662 IgnoreWarnings: true, 663 }, 664 Checks: []api.ServiceCheck{ 665 { 666 Name: "random-check", 667 Type: "tcp", 668 PortLabel: "9001", 669 }, 670 }, 671 }, 672 }, 673 }, 674 }, 675 }, 676 }, 677 }, 678 false, 679 }, 680 { 681 "reschedule-job.hcl", 682 &api.Job{ 683 ID: helper.StringToPtr("foo"), 684 Name: helper.StringToPtr("foo"), 685 Type: helper.StringToPtr("batch"), 686 Datacenters: []string{"dc1"}, 687 Reschedule: &api.ReschedulePolicy{ 688 Attempts: helper.IntToPtr(15), 689 Interval: helper.TimeToPtr(30 * time.Minute), 690 DelayFunction: helper.StringToPtr("constant"), 691 Delay: helper.TimeToPtr(10 * time.Second), 692 }, 693 TaskGroups: []*api.TaskGroup{ 694 { 695 Name: helper.StringToPtr("bar"), 696 Count: helper.IntToPtr(3), 697 Tasks: []*api.Task{ 698 { 699 Name: "bar", 700 Driver: "raw_exec", 701 Config: map[string]interface{}{ 702 "command": "bash", 703 "args": []interface{}{"-c", "echo hi"}, 704 }, 705 }, 706 }, 707 }, 708 }, 709 }, 710 false, 711 }, 712 { 713 "reschedule-job-unlimited.hcl", 714 &api.Job{ 715 ID: helper.StringToPtr("foo"), 716 Name: helper.StringToPtr("foo"), 717 Type: helper.StringToPtr("batch"), 718 Datacenters: []string{"dc1"}, 719 Reschedule: &api.ReschedulePolicy{ 720 DelayFunction: helper.StringToPtr("exponential"), 721 Delay: helper.TimeToPtr(10 * time.Second), 722 MaxDelay: helper.TimeToPtr(120 * time.Second), 723 Unlimited: helper.BoolToPtr(true), 724 }, 725 TaskGroups: []*api.TaskGroup{ 726 { 727 Name: helper.StringToPtr("bar"), 728 Count: helper.IntToPtr(3), 729 Tasks: []*api.Task{ 730 { 731 Name: "bar", 732 Driver: "raw_exec", 733 Config: map[string]interface{}{ 734 "command": "bash", 735 "args": []interface{}{"-c", "echo hi"}, 736 }, 737 }, 738 }, 739 }, 740 }, 741 }, 742 false, 743 }, 744 { 745 "migrate-job.hcl", 746 &api.Job{ 747 ID: helper.StringToPtr("foo"), 748 Name: helper.StringToPtr("foo"), 749 Type: helper.StringToPtr("batch"), 750 Datacenters: []string{"dc1"}, 751 Migrate: &api.MigrateStrategy{ 752 MaxParallel: helper.IntToPtr(2), 753 HealthCheck: helper.StringToPtr("task_states"), 754 MinHealthyTime: helper.TimeToPtr(11 * time.Second), 755 HealthyDeadline: helper.TimeToPtr(11 * time.Minute), 756 }, 757 TaskGroups: []*api.TaskGroup{ 758 { 759 Name: helper.StringToPtr("bar"), 760 Count: helper.IntToPtr(3), 761 Migrate: &api.MigrateStrategy{ 762 MaxParallel: helper.IntToPtr(3), 763 HealthCheck: helper.StringToPtr("checks"), 764 MinHealthyTime: helper.TimeToPtr(1 * time.Second), 765 HealthyDeadline: helper.TimeToPtr(1 * time.Minute), 766 }, 767 Tasks: []*api.Task{ 768 { 769 Name: "bar", 770 Driver: "raw_exec", 771 Config: map[string]interface{}{ 772 "command": "bash", 773 "args": []interface{}{"-c", "echo hi"}, 774 }, 775 }, 776 }, 777 }, 778 }, 779 }, 780 false, 781 }, 782 } 783 784 for _, tc := range cases { 785 t.Logf("Testing parse: %s", tc.File) 786 787 path, err := filepath.Abs(filepath.Join("./test-fixtures", tc.File)) 788 if err != nil { 789 t.Fatalf("file: %s\n\n%s", tc.File, err) 790 continue 791 } 792 793 actual, err := ParseFile(path) 794 if (err != nil) != tc.Err { 795 t.Fatalf("file: %s\n\n%s", tc.File, err) 796 continue 797 } 798 799 if !reflect.DeepEqual(actual, tc.Result) { 800 for _, d := range pretty.Diff(actual, tc.Result) { 801 t.Logf(d) 802 } 803 t.Fatalf("file: %s", tc.File) 804 } 805 } 806 } 807 808 func TestBadPorts(t *testing.T) { 809 path, err := filepath.Abs(filepath.Join("./test-fixtures", "bad-ports.hcl")) 810 if err != nil { 811 t.Fatalf("Can't get absolute path for file: %s", err) 812 } 813 814 _, err = ParseFile(path) 815 816 if !strings.Contains(err.Error(), errPortLabel.Error()) { 817 t.Fatalf("\nExpected error\n %s\ngot\n %v", errPortLabel, err) 818 } 819 } 820 821 func TestOverlappingPorts(t *testing.T) { 822 path, err := filepath.Abs(filepath.Join("./test-fixtures", "overlapping-ports.hcl")) 823 if err != nil { 824 t.Fatalf("Can't get absolute path for file: %s", err) 825 } 826 827 _, err = ParseFile(path) 828 829 if err == nil { 830 t.Fatalf("Expected an error") 831 } 832 833 if !strings.Contains(err.Error(), "found a port label collision") { 834 t.Fatalf("Expected collision error; got %v", err) 835 } 836 } 837 838 func TestIncorrectKey(t *testing.T) { 839 path, err := filepath.Abs(filepath.Join("./test-fixtures", "basic_wrong_key.hcl")) 840 if err != nil { 841 t.Fatalf("Can't get absolute path for file: %s", err) 842 } 843 844 _, err = ParseFile(path) 845 846 if err == nil { 847 t.Fatalf("Expected an error") 848 } 849 850 if !strings.Contains(err.Error(), "* group: 'binsl', task: 'binstore', service: 'foo', check -> invalid key: nterval") { 851 t.Fatalf("Expected key error; got %v", err) 852 } 853 }