github.com/portworx/docker@v1.12.1/api/client/formatter/formatter_test.go (about) 1 package formatter 2 3 import ( 4 "bytes" 5 "fmt" 6 "testing" 7 "time" 8 9 "github.com/docker/engine-api/types" 10 ) 11 12 func TestContainerContextWrite(t *testing.T) { 13 unixTime := time.Now().AddDate(0, 0, -1).Unix() 14 expectedTime := time.Unix(unixTime, 0).String() 15 16 contexts := []struct { 17 context ContainerContext 18 expected string 19 }{ 20 // Errors 21 { 22 ContainerContext{ 23 Context: Context{ 24 Format: "{{InvalidFunction}}", 25 }, 26 }, 27 `Template parsing error: template: :1: function "InvalidFunction" not defined 28 `, 29 }, 30 { 31 ContainerContext{ 32 Context: Context{ 33 Format: "{{nil}}", 34 }, 35 }, 36 `Template parsing error: template: :1:2: executing "" at <nil>: nil is not a command 37 `, 38 }, 39 // Table Format 40 { 41 ContainerContext{ 42 Context: Context{ 43 Format: "table", 44 }, 45 }, 46 `CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 47 containerID1 ubuntu "" 24 hours ago foobar_baz 48 containerID2 ubuntu "" 24 hours ago foobar_bar 49 `, 50 }, 51 { 52 ContainerContext{ 53 Context: Context{ 54 Format: "table {{.Image}}", 55 }, 56 }, 57 "IMAGE\nubuntu\nubuntu\n", 58 }, 59 { 60 ContainerContext{ 61 Context: Context{ 62 Format: "table {{.Image}}", 63 }, 64 Size: true, 65 }, 66 "IMAGE\nubuntu\nubuntu\n", 67 }, 68 { 69 ContainerContext{ 70 Context: Context{ 71 Format: "table {{.Image}}", 72 Quiet: true, 73 }, 74 }, 75 "IMAGE\nubuntu\nubuntu\n", 76 }, 77 { 78 ContainerContext{ 79 Context: Context{ 80 Format: "table", 81 Quiet: true, 82 }, 83 }, 84 "containerID1\ncontainerID2\n", 85 }, 86 // Raw Format 87 { 88 ContainerContext{ 89 Context: Context{ 90 Format: "raw", 91 }, 92 }, 93 fmt.Sprintf(`container_id: containerID1 94 image: ubuntu 95 command: "" 96 created_at: %s 97 status: 98 names: foobar_baz 99 labels: 100 ports: 101 102 container_id: containerID2 103 image: ubuntu 104 command: "" 105 created_at: %s 106 status: 107 names: foobar_bar 108 labels: 109 ports: 110 111 `, expectedTime, expectedTime), 112 }, 113 { 114 ContainerContext{ 115 Context: Context{ 116 Format: "raw", 117 }, 118 Size: true, 119 }, 120 fmt.Sprintf(`container_id: containerID1 121 image: ubuntu 122 command: "" 123 created_at: %s 124 status: 125 names: foobar_baz 126 labels: 127 ports: 128 size: 0 B 129 130 container_id: containerID2 131 image: ubuntu 132 command: "" 133 created_at: %s 134 status: 135 names: foobar_bar 136 labels: 137 ports: 138 size: 0 B 139 140 `, expectedTime, expectedTime), 141 }, 142 { 143 ContainerContext{ 144 Context: Context{ 145 Format: "raw", 146 Quiet: true, 147 }, 148 }, 149 "container_id: containerID1\ncontainer_id: containerID2\n", 150 }, 151 // Custom Format 152 { 153 ContainerContext{ 154 Context: Context{ 155 Format: "{{.Image}}", 156 }, 157 }, 158 "ubuntu\nubuntu\n", 159 }, 160 { 161 ContainerContext{ 162 Context: Context{ 163 Format: "{{.Image}}", 164 }, 165 Size: true, 166 }, 167 "ubuntu\nubuntu\n", 168 }, 169 } 170 171 for _, context := range contexts { 172 containers := []types.Container{ 173 {ID: "containerID1", Names: []string{"/foobar_baz"}, Image: "ubuntu", Created: unixTime}, 174 {ID: "containerID2", Names: []string{"/foobar_bar"}, Image: "ubuntu", Created: unixTime}, 175 } 176 out := bytes.NewBufferString("") 177 context.context.Output = out 178 context.context.Containers = containers 179 context.context.Write() 180 actual := out.String() 181 if actual != context.expected { 182 t.Fatalf("Expected \n%s, got \n%s", context.expected, actual) 183 } 184 // Clean buffer 185 out.Reset() 186 } 187 } 188 189 func TestContainerContextWriteWithNoContainers(t *testing.T) { 190 out := bytes.NewBufferString("") 191 containers := []types.Container{} 192 193 contexts := []struct { 194 context ContainerContext 195 expected string 196 }{ 197 { 198 ContainerContext{ 199 Context: Context{ 200 Format: "{{.Image}}", 201 Output: out, 202 }, 203 }, 204 "", 205 }, 206 { 207 ContainerContext{ 208 Context: Context{ 209 Format: "table {{.Image}}", 210 Output: out, 211 }, 212 }, 213 "IMAGE\n", 214 }, 215 { 216 ContainerContext{ 217 Context: Context{ 218 Format: "{{.Image}}", 219 Output: out, 220 }, 221 Size: true, 222 }, 223 "", 224 }, 225 { 226 ContainerContext{ 227 Context: Context{ 228 Format: "table {{.Image}}", 229 Output: out, 230 }, 231 Size: true, 232 }, 233 "IMAGE\n", 234 }, 235 { 236 ContainerContext{ 237 Context: Context{ 238 Format: "table {{.Image}}\t{{.Size}}", 239 Output: out, 240 }, 241 }, 242 "IMAGE SIZE\n", 243 }, 244 { 245 ContainerContext{ 246 Context: Context{ 247 Format: "table {{.Image}}\t{{.Size}}", 248 Output: out, 249 }, 250 Size: true, 251 }, 252 "IMAGE SIZE\n", 253 }, 254 } 255 256 for _, context := range contexts { 257 context.context.Containers = containers 258 context.context.Write() 259 actual := out.String() 260 if actual != context.expected { 261 t.Fatalf("Expected \n%s, got \n%s", context.expected, actual) 262 } 263 // Clean buffer 264 out.Reset() 265 } 266 } 267 268 func TestImageContextWrite(t *testing.T) { 269 unixTime := time.Now().AddDate(0, 0, -1).Unix() 270 expectedTime := time.Unix(unixTime, 0).String() 271 272 contexts := []struct { 273 context ImageContext 274 expected string 275 }{ 276 // Errors 277 { 278 ImageContext{ 279 Context: Context{ 280 Format: "{{InvalidFunction}}", 281 }, 282 }, 283 `Template parsing error: template: :1: function "InvalidFunction" not defined 284 `, 285 }, 286 { 287 ImageContext{ 288 Context: Context{ 289 Format: "{{nil}}", 290 }, 291 }, 292 `Template parsing error: template: :1:2: executing "" at <nil>: nil is not a command 293 `, 294 }, 295 // Table Format 296 { 297 ImageContext{ 298 Context: Context{ 299 Format: "table", 300 }, 301 }, 302 `REPOSITORY TAG IMAGE ID CREATED SIZE 303 image tag1 imageID1 24 hours ago 0 B 304 image tag2 imageID2 24 hours ago 0 B 305 <none> <none> imageID3 24 hours ago 0 B 306 `, 307 }, 308 { 309 ImageContext{ 310 Context: Context{ 311 Format: "table {{.Repository}}", 312 }, 313 }, 314 "REPOSITORY\nimage\nimage\n<none>\n", 315 }, 316 { 317 ImageContext{ 318 Context: Context{ 319 Format: "table {{.Repository}}", 320 }, 321 Digest: true, 322 }, 323 `REPOSITORY DIGEST 324 image sha256:cbbf2f9a99b47fc460d422812b6a5adff7dfee951d8fa2e4a98caa0382cfbdbf 325 image <none> 326 <none> <none> 327 `, 328 }, 329 { 330 ImageContext{ 331 Context: Context{ 332 Format: "table {{.Repository}}", 333 Quiet: true, 334 }, 335 }, 336 "REPOSITORY\nimage\nimage\n<none>\n", 337 }, 338 { 339 ImageContext{ 340 Context: Context{ 341 Format: "table", 342 Quiet: true, 343 }, 344 }, 345 "imageID1\nimageID2\nimageID3\n", 346 }, 347 { 348 ImageContext{ 349 Context: Context{ 350 Format: "table", 351 Quiet: false, 352 }, 353 Digest: true, 354 }, 355 `REPOSITORY TAG DIGEST IMAGE ID CREATED SIZE 356 image tag1 sha256:cbbf2f9a99b47fc460d422812b6a5adff7dfee951d8fa2e4a98caa0382cfbdbf imageID1 24 hours ago 0 B 357 image tag2 <none> imageID2 24 hours ago 0 B 358 <none> <none> <none> imageID3 24 hours ago 0 B 359 `, 360 }, 361 { 362 ImageContext{ 363 Context: Context{ 364 Format: "table", 365 Quiet: true, 366 }, 367 Digest: true, 368 }, 369 "imageID1\nimageID2\nimageID3\n", 370 }, 371 // Raw Format 372 { 373 ImageContext{ 374 Context: Context{ 375 Format: "raw", 376 }, 377 }, 378 fmt.Sprintf(`repository: image 379 tag: tag1 380 image_id: imageID1 381 created_at: %s 382 virtual_size: 0 B 383 384 repository: image 385 tag: tag2 386 image_id: imageID2 387 created_at: %s 388 virtual_size: 0 B 389 390 repository: <none> 391 tag: <none> 392 image_id: imageID3 393 created_at: %s 394 virtual_size: 0 B 395 396 `, expectedTime, expectedTime, expectedTime), 397 }, 398 { 399 ImageContext{ 400 Context: Context{ 401 Format: "raw", 402 }, 403 Digest: true, 404 }, 405 fmt.Sprintf(`repository: image 406 tag: tag1 407 digest: sha256:cbbf2f9a99b47fc460d422812b6a5adff7dfee951d8fa2e4a98caa0382cfbdbf 408 image_id: imageID1 409 created_at: %s 410 virtual_size: 0 B 411 412 repository: image 413 tag: tag2 414 digest: <none> 415 image_id: imageID2 416 created_at: %s 417 virtual_size: 0 B 418 419 repository: <none> 420 tag: <none> 421 digest: <none> 422 image_id: imageID3 423 created_at: %s 424 virtual_size: 0 B 425 426 `, expectedTime, expectedTime, expectedTime), 427 }, 428 { 429 ImageContext{ 430 Context: Context{ 431 Format: "raw", 432 Quiet: true, 433 }, 434 }, 435 `image_id: imageID1 436 image_id: imageID2 437 image_id: imageID3 438 `, 439 }, 440 // Custom Format 441 { 442 ImageContext{ 443 Context: Context{ 444 Format: "{{.Repository}}", 445 }, 446 }, 447 "image\nimage\n<none>\n", 448 }, 449 { 450 ImageContext{ 451 Context: Context{ 452 Format: "{{.Repository}}", 453 }, 454 Digest: true, 455 }, 456 "image\nimage\n<none>\n", 457 }, 458 } 459 460 for _, context := range contexts { 461 images := []types.Image{ 462 {ID: "imageID1", RepoTags: []string{"image:tag1"}, RepoDigests: []string{"image@sha256:cbbf2f9a99b47fc460d422812b6a5adff7dfee951d8fa2e4a98caa0382cfbdbf"}, Created: unixTime}, 463 {ID: "imageID2", RepoTags: []string{"image:tag2"}, Created: unixTime}, 464 {ID: "imageID3", RepoTags: []string{"<none>:<none>"}, RepoDigests: []string{"<none>@<none>"}, Created: unixTime}, 465 } 466 out := bytes.NewBufferString("") 467 context.context.Output = out 468 context.context.Images = images 469 context.context.Write() 470 actual := out.String() 471 if actual != context.expected { 472 t.Fatalf("Expected \n%s, got \n%s", context.expected, actual) 473 } 474 // Clean buffer 475 out.Reset() 476 } 477 } 478 479 func TestImageContextWriteWithNoImage(t *testing.T) { 480 out := bytes.NewBufferString("") 481 images := []types.Image{} 482 483 contexts := []struct { 484 context ImageContext 485 expected string 486 }{ 487 { 488 ImageContext{ 489 Context: Context{ 490 Format: "{{.Repository}}", 491 Output: out, 492 }, 493 }, 494 "", 495 }, 496 { 497 ImageContext{ 498 Context: Context{ 499 Format: "table {{.Repository}}", 500 Output: out, 501 }, 502 }, 503 "REPOSITORY\n", 504 }, 505 { 506 ImageContext{ 507 Context: Context{ 508 Format: "{{.Repository}}", 509 Output: out, 510 }, 511 Digest: true, 512 }, 513 "", 514 }, 515 { 516 ImageContext{ 517 Context: Context{ 518 Format: "table {{.Repository}}", 519 Output: out, 520 }, 521 Digest: true, 522 }, 523 "REPOSITORY DIGEST\n", 524 }, 525 } 526 527 for _, context := range contexts { 528 context.context.Images = images 529 context.context.Write() 530 actual := out.String() 531 if actual != context.expected { 532 t.Fatalf("Expected \n%s, got \n%s", context.expected, actual) 533 } 534 // Clean buffer 535 out.Reset() 536 } 537 }