github.com/kjdelisle/consul@v1.4.5/command/kv/put/kv_put_test.go (about) 1 package put 2 3 import ( 4 "bytes" 5 "encoding/base64" 6 "io" 7 "os" 8 "strconv" 9 "strings" 10 "testing" 11 12 "github.com/hashicorp/consul/agent" 13 "github.com/hashicorp/consul/api" 14 "github.com/hashicorp/consul/testutil" 15 "github.com/mitchellh/cli" 16 ) 17 18 func TestKVPutCommand_noTabs(t *testing.T) { 19 t.Parallel() 20 if strings.ContainsRune(New(nil).Help(), '\t') { 21 t.Fatal("help has tabs") 22 } 23 } 24 25 func TestKVPutCommand_Validation(t *testing.T) { 26 t.Parallel() 27 ui := cli.NewMockUi() 28 c := New(ui) 29 30 cases := map[string]struct { 31 args []string 32 output string 33 }{ 34 "-acquire without -session": { 35 []string{"-acquire", "foo"}, 36 "Missing -session", 37 }, 38 "-release without -session": { 39 []string{"-release", "foo"}, 40 "Missing -session", 41 }, 42 "-cas no -modify-index": { 43 []string{"-cas", "foo"}, 44 "Must specify -modify-index", 45 }, 46 "no key": { 47 []string{}, 48 "Missing KEY argument", 49 }, 50 "extra args": { 51 []string{"foo", "bar", "baz"}, 52 "Too many arguments", 53 }, 54 } 55 56 for name, tc := range cases { 57 c.init() 58 // Ensure our buffer is always clear 59 if ui.ErrorWriter != nil { 60 ui.ErrorWriter.Reset() 61 } 62 if ui.OutputWriter != nil { 63 ui.OutputWriter.Reset() 64 } 65 66 code := c.Run(tc.args) 67 if code == 0 { 68 t.Errorf("%s: expected non-zero exit", name) 69 } 70 71 output := ui.ErrorWriter.String() 72 if !strings.Contains(output, tc.output) { 73 t.Errorf("%s: expected %q to contain %q", name, output, tc.output) 74 } 75 } 76 } 77 78 func TestKVPutCommand(t *testing.T) { 79 t.Parallel() 80 a := agent.NewTestAgent(t, t.Name(), ``) 81 defer a.Shutdown() 82 client := a.Client() 83 84 ui := cli.NewMockUi() 85 c := New(ui) 86 87 args := []string{ 88 "-http-addr=" + a.HTTPAddr(), 89 "foo", "bar", 90 } 91 92 code := c.Run(args) 93 if code != 0 { 94 t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String()) 95 } 96 97 data, _, err := client.KV().Get("foo", nil) 98 if err != nil { 99 t.Fatal(err) 100 } 101 102 if !bytes.Equal(data.Value, []byte("bar")) { 103 t.Errorf("bad: %#v", data.Value) 104 } 105 } 106 107 func TestKVPutCommand_EmptyDataQuoted(t *testing.T) { 108 t.Parallel() 109 a := agent.NewTestAgent(t, t.Name(), ``) 110 defer a.Shutdown() 111 client := a.Client() 112 113 ui := cli.NewMockUi() 114 c := New(ui) 115 116 args := []string{ 117 "-http-addr=" + a.HTTPAddr(), 118 "foo", "", 119 } 120 121 code := c.Run(args) 122 if code != 0 { 123 t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String()) 124 } 125 126 data, _, err := client.KV().Get("foo", nil) 127 if err != nil { 128 t.Fatal(err) 129 } 130 131 if data.Value != nil { 132 t.Errorf("bad: %#v", data.Value) 133 } 134 } 135 136 func TestKVPutCommand_Base64(t *testing.T) { 137 t.Parallel() 138 a := agent.NewTestAgent(t, t.Name(), ``) 139 defer a.Shutdown() 140 client := a.Client() 141 142 ui := cli.NewMockUi() 143 c := New(ui) 144 145 const encodedString = "aGVsbG8gd29ybGQK" 146 147 args := []string{ 148 "-http-addr=" + a.HTTPAddr(), 149 "-base64", 150 "foo", encodedString, 151 } 152 153 code := c.Run(args) 154 if code != 0 { 155 t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String()) 156 } 157 158 data, _, err := client.KV().Get("foo", nil) 159 if err != nil { 160 t.Fatal(err) 161 } 162 163 expected, err := base64.StdEncoding.DecodeString(encodedString) 164 if err != nil { 165 t.Fatal(err) 166 } 167 168 if !bytes.Equal(data.Value, []byte(expected)) { 169 t.Errorf("bad: %#v, %s", data.Value, data.Value) 170 } 171 } 172 173 func TestKVPutCommand_File(t *testing.T) { 174 t.Parallel() 175 a := agent.NewTestAgent(t, t.Name(), ``) 176 defer a.Shutdown() 177 client := a.Client() 178 179 ui := cli.NewMockUi() 180 c := New(ui) 181 182 f := testutil.TempFile(t, "kv-put-command-file") 183 defer os.Remove(f.Name()) 184 if _, err := f.WriteString("bar"); err != nil { 185 t.Fatalf("err: %#v", err) 186 } 187 188 args := []string{ 189 "-http-addr=" + a.HTTPAddr(), 190 "foo", "@" + f.Name(), 191 } 192 193 code := c.Run(args) 194 if code != 0 { 195 t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String()) 196 } 197 198 data, _, err := client.KV().Get("foo", nil) 199 if err != nil { 200 t.Fatal(err) 201 } 202 203 if !bytes.Equal(data.Value, []byte("bar")) { 204 t.Errorf("bad: %#v", data.Value) 205 } 206 } 207 208 func TestKVPutCommand_FileNoExist(t *testing.T) { 209 t.Parallel() 210 ui := cli.NewMockUi() 211 c := New(ui) 212 213 args := []string{ 214 "foo", "@/nope/definitely/not-a-real-file.txt", 215 } 216 217 code := c.Run(args) 218 if code == 0 { 219 t.Fatal("bad: expected error") 220 } 221 222 output := ui.ErrorWriter.String() 223 if !strings.Contains(output, "Failed to read file") { 224 t.Errorf("bad: %#v", output) 225 } 226 } 227 228 func TestKVPutCommand_Stdin(t *testing.T) { 229 t.Parallel() 230 a := agent.NewTestAgent(t, t.Name(), ``) 231 defer a.Shutdown() 232 client := a.Client() 233 234 stdinR, stdinW := io.Pipe() 235 236 ui := cli.NewMockUi() 237 c := New(ui) 238 c.testStdin = stdinR 239 240 go func() { 241 stdinW.Write([]byte("bar")) 242 stdinW.Close() 243 }() 244 245 args := []string{ 246 "-http-addr=" + a.HTTPAddr(), 247 "foo", "-", 248 } 249 250 code := c.Run(args) 251 if code != 0 { 252 t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String()) 253 } 254 255 data, _, err := client.KV().Get("foo", nil) 256 if err != nil { 257 t.Fatal(err) 258 } 259 260 if !bytes.Equal(data.Value, []byte("bar")) { 261 t.Errorf("bad: %#v", data.Value) 262 } 263 } 264 265 func TestKVPutCommand_NegativeVal(t *testing.T) { 266 t.Parallel() 267 a := agent.NewTestAgent(t, t.Name(), ``) 268 defer a.Shutdown() 269 client := a.Client() 270 271 ui := cli.NewMockUi() 272 c := New(ui) 273 274 args := []string{ 275 "-http-addr=" + a.HTTPAddr(), 276 "foo", "-2", 277 } 278 279 code := c.Run(args) 280 if code != 0 { 281 t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String()) 282 } 283 284 data, _, err := client.KV().Get("foo", nil) 285 if err != nil { 286 t.Fatal(err) 287 } 288 289 if !bytes.Equal(data.Value, []byte("-2")) { 290 t.Errorf("bad: %#v", data.Value) 291 } 292 } 293 294 func TestKVPutCommand_Flags(t *testing.T) { 295 t.Parallel() 296 a := agent.NewTestAgent(t, t.Name(), ``) 297 defer a.Shutdown() 298 client := a.Client() 299 300 ui := cli.NewMockUi() 301 c := New(ui) 302 303 args := []string{ 304 "-http-addr=" + a.HTTPAddr(), 305 "-flags", "12345", 306 "foo", 307 } 308 309 code := c.Run(args) 310 if code != 0 { 311 t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String()) 312 } 313 314 data, _, err := client.KV().Get("foo", nil) 315 if err != nil { 316 t.Fatal(err) 317 } 318 319 if data.Flags != 12345 { 320 t.Errorf("bad: %#v", data.Flags) 321 } 322 } 323 324 func TestKVPutCommand_CAS(t *testing.T) { 325 t.Parallel() 326 a := agent.NewTestAgent(t, t.Name(), ``) 327 defer a.Shutdown() 328 client := a.Client() 329 330 // Create the initial pair so it has a ModifyIndex. 331 pair := &api.KVPair{ 332 Key: "foo", 333 Value: []byte("bar"), 334 } 335 if _, err := client.KV().Put(pair, nil); err != nil { 336 t.Fatalf("err: %#v", err) 337 } 338 339 ui := cli.NewMockUi() 340 c := New(ui) 341 342 args := []string{ 343 "-http-addr=" + a.HTTPAddr(), 344 "-cas", 345 "-modify-index", "123", 346 "foo", "a", 347 } 348 349 code := c.Run(args) 350 if code == 0 { 351 t.Fatalf("bad: expected error") 352 } 353 354 data, _, err := client.KV().Get("foo", nil) 355 if err != nil { 356 t.Fatal(err) 357 } 358 359 // Reset buffers 360 ui.OutputWriter.Reset() 361 ui.ErrorWriter.Reset() 362 363 args = []string{ 364 "-http-addr=" + a.HTTPAddr(), 365 "-cas", 366 "-modify-index", strconv.FormatUint(data.ModifyIndex, 10), 367 "foo", "a", 368 } 369 370 code = c.Run(args) 371 if code != 0 { 372 t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String()) 373 } 374 375 data, _, err = client.KV().Get("foo", nil) 376 if err != nil { 377 t.Fatal(err) 378 } 379 380 if !bytes.Equal(data.Value, []byte("a")) { 381 t.Errorf("bad: %#v", data.Value) 382 } 383 }