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