github.com/ferranbt/nomad@v0.9.3-0.20190607002617-85c449b7667c/command/agent/command_test.go (about) 1 package agent 2 3 import ( 4 "io/ioutil" 5 "os" 6 "path/filepath" 7 "strings" 8 "testing" 9 10 "github.com/hashicorp/nomad/version" 11 "github.com/mitchellh/cli" 12 ) 13 14 func TestCommand_Implements(t *testing.T) { 15 t.Parallel() 16 var _ cli.Command = &Command{} 17 } 18 19 func TestCommand_Args(t *testing.T) { 20 t.Parallel() 21 tmpDir, err := ioutil.TempDir("", "nomad") 22 if err != nil { 23 t.Fatalf("err: %s", err) 24 } 25 defer os.RemoveAll(tmpDir) 26 27 type tcase struct { 28 args []string 29 errOut string 30 } 31 tcases := []tcase{ 32 { 33 []string{}, 34 "Must specify either server, client or dev mode for the agent.", 35 }, 36 { 37 []string{"-client", "-data-dir=" + tmpDir, "-bootstrap-expect=1"}, 38 "Bootstrap requires server mode to be enabled", 39 }, 40 { 41 []string{"-data-dir=" + tmpDir, "-server", "-bootstrap-expect=1"}, 42 "WARNING: Bootstrap mode enabled!", 43 }, 44 { 45 []string{"-server"}, 46 "Must specify data directory", 47 }, 48 { 49 []string{"-client", "-alloc-dir="}, 50 "Must specify the state, alloc dir, and plugin dir if data-dir is omitted.", 51 }, 52 { 53 []string{"-client", "-data-dir=" + tmpDir, "-meta=invalid..key=inaccessible-value"}, 54 "Invalid Client.Meta key: invalid..key", 55 }, 56 { 57 []string{"-client", "-data-dir=" + tmpDir, "-meta=.invalid=inaccessible-value"}, 58 "Invalid Client.Meta key: .invalid", 59 }, 60 { 61 []string{"-client", "-data-dir=" + tmpDir, "-meta=invalid.=inaccessible-value"}, 62 "Invalid Client.Meta key: invalid.", 63 }, 64 } 65 for _, tc := range tcases { 66 // Make a new command. We preemptively close the shutdownCh 67 // so that the command exits immediately instead of blocking. 68 ui := new(cli.MockUi) 69 shutdownCh := make(chan struct{}) 70 close(shutdownCh) 71 cmd := &Command{ 72 Version: version.GetVersion(), 73 Ui: ui, 74 ShutdownCh: shutdownCh, 75 } 76 77 // To prevent test failures on hosts whose hostname resolves to 78 // a loopback address, we must append a bind address 79 tc.args = append(tc.args, "-bind=169.254.0.1") 80 if code := cmd.Run(tc.args); code != 1 { 81 t.Fatalf("args: %v\nexit: %d\n", tc.args, code) 82 } 83 84 if expect := tc.errOut; expect != "" { 85 out := ui.ErrorWriter.String() 86 if !strings.Contains(out, expect) { 87 t.Fatalf("expect to find %q\n\n%s", expect, out) 88 } 89 } 90 } 91 } 92 93 func TestCommand_MetaConfigValidation(t *testing.T) { 94 tmpDir, err := ioutil.TempDir("", "nomad") 95 if err != nil { 96 t.Fatalf("err: %s", err) 97 } 98 defer os.RemoveAll(tmpDir) 99 100 tcases := []string{ 101 "foo..invalid", 102 ".invalid", 103 "invalid.", 104 } 105 for _, tc := range tcases { 106 configFile := filepath.Join(tmpDir, "conf1.hcl") 107 err = ioutil.WriteFile(configFile, []byte(`client{ 108 enabled = true 109 meta = { 110 "valid" = "yes" 111 "`+tc+`" = "kaboom!" 112 "nested.var" = "is nested" 113 "deeply.nested.var" = "is deeply nested" 114 } 115 }`), 0600) 116 if err != nil { 117 t.Fatalf("err: %s", err) 118 } 119 120 // Make a new command. We preemptively close the shutdownCh 121 // so that the command exits immediately instead of blocking. 122 ui := new(cli.MockUi) 123 shutdownCh := make(chan struct{}) 124 close(shutdownCh) 125 cmd := &Command{ 126 Version: version.GetVersion(), 127 Ui: ui, 128 ShutdownCh: shutdownCh, 129 } 130 131 // To prevent test failures on hosts whose hostname resolves to 132 // a loopback address, we must append a bind address 133 args := []string{"-client", "-data-dir=" + tmpDir, "-config=" + configFile, "-bind=169.254.0.1"} 134 if code := cmd.Run(args); code != 1 { 135 t.Fatalf("args: %v\nexit: %d\n", args, code) 136 } 137 138 expect := "Invalid Client.Meta key: " + tc 139 out := ui.ErrorWriter.String() 140 if !strings.Contains(out, expect) { 141 t.Fatalf("expect to find %q\n\n%s", expect, out) 142 } 143 } 144 }