github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/command/job_scale_test.go (about) 1 package command 2 3 import ( 4 "fmt" 5 "strings" 6 "testing" 7 8 "github.com/hashicorp/nomad/api" 9 "github.com/hashicorp/nomad/ci" 10 "github.com/hashicorp/nomad/helper/pointer" 11 "github.com/hashicorp/nomad/testutil" 12 "github.com/mitchellh/cli" 13 ) 14 15 func TestJobScaleCommand_SingleGroup(t *testing.T) { 16 ci.Parallel(t) 17 srv, client, url := testServer(t, true, nil) 18 defer srv.Shutdown() 19 testutil.WaitForResult(func() (bool, error) { 20 nodes, _, err := client.Nodes().List(nil) 21 if err != nil { 22 return false, err 23 } 24 if len(nodes) == 0 { 25 return false, fmt.Errorf("missing node") 26 } 27 if _, ok := nodes[0].Drivers["mock_driver"]; !ok { 28 return false, fmt.Errorf("mock_driver not ready") 29 } 30 return true, nil 31 }, func(err error) { 32 t.Fatalf("err: %s", err) 33 }) 34 35 ui := cli.NewMockUi() 36 cmd := &JobScaleCommand{Meta: Meta{Ui: ui}} 37 38 // Register a test job and ensure it is running before moving on. 39 resp, _, err := client.Jobs().Register(testJob("scale_cmd_single_group"), nil) 40 if err != nil { 41 t.Fatalf("err: %s", err) 42 } 43 if code := waitForSuccess(ui, client, fullId, t, resp.EvalID); code != 0 { 44 t.Fatalf("expected waitForSuccess exit code 0, got: %d", code) 45 } 46 47 // Perform the scaling action. 48 if code := cmd.Run([]string{"-address=" + url, "-detach", "scale_cmd_single_group", "2"}); code != 0 { 49 t.Fatalf("expected cmd run exit code 0, got: %d", code) 50 } 51 if out := ui.OutputWriter.String(); !strings.Contains(out, "Evaluation ID:") { 52 t.Fatalf("Expected Evaluation ID within output: %v", out) 53 } 54 } 55 56 func TestJobScaleCommand_MultiGroup(t *testing.T) { 57 ci.Parallel(t) 58 srv, client, url := testServer(t, true, nil) 59 defer srv.Shutdown() 60 testutil.WaitForResult(func() (bool, error) { 61 nodes, _, err := client.Nodes().List(nil) 62 if err != nil { 63 return false, err 64 } 65 if len(nodes) == 0 { 66 return false, fmt.Errorf("missing node") 67 } 68 if _, ok := nodes[0].Drivers["mock_driver"]; !ok { 69 return false, fmt.Errorf("mock_driver not ready") 70 } 71 return true, nil 72 }, func(err error) { 73 t.Fatalf("err: %s", err) 74 }) 75 76 ui := cli.NewMockUi() 77 cmd := &JobScaleCommand{Meta: Meta{Ui: ui}} 78 79 // Create a job with two task groups. 80 job := testJob("scale_cmd_multi_group") 81 task := api.NewTask("task2", "mock_driver"). 82 SetConfig("kill_after", "1s"). 83 SetConfig("run_for", "5s"). 84 SetConfig("exit_code", 0). 85 Require(&api.Resources{ 86 MemoryMB: pointer.Of(256), 87 CPU: pointer.Of(100), 88 }). 89 SetLogConfig(&api.LogConfig{ 90 MaxFiles: pointer.Of(1), 91 MaxFileSizeMB: pointer.Of(2), 92 }) 93 group2 := api.NewTaskGroup("group2", 1). 94 AddTask(task). 95 RequireDisk(&api.EphemeralDisk{ 96 SizeMB: pointer.Of(20), 97 }) 98 job.AddTaskGroup(group2) 99 100 // Register a test job and ensure it is running before moving on. 101 resp, _, err := client.Jobs().Register(job, nil) 102 if err != nil { 103 t.Fatalf("err: %s", err) 104 } 105 if code := waitForSuccess(ui, client, fullId, t, resp.EvalID); code != 0 { 106 t.Fatalf("expected waitForSuccess exit code 0, got: %d", code) 107 } 108 109 // Attempt to scale without specifying the task group which should fail. 110 if code := cmd.Run([]string{"-address=" + url, "-detach", "scale_cmd_multi_group", "2"}); code != 1 { 111 t.Fatalf("expected cmd run exit code 1, got: %d", code) 112 } 113 if out := ui.ErrorWriter.String(); !strings.Contains(out, "Group name required") { 114 t.Fatalf("unexpected error message: %v", out) 115 } 116 117 // Specify the target group which should be successful. 118 if code := cmd.Run([]string{"-address=" + url, "-detach", "scale_cmd_multi_group", "group1", "2"}); code != 0 { 119 t.Fatalf("expected cmd run exit code 0, got: %d", code) 120 } 121 if out := ui.OutputWriter.String(); !strings.Contains(out, "Evaluation ID:") { 122 t.Fatalf("Expected Evaluation ID within output: %v", out) 123 } 124 }