github.com/sijibomii/docker@v0.0.0-20231230191044-5cf6ca554647/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 SIZE\nubuntu 0 B\nubuntu 0 B\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 SIZE\n", 234 }, 235 } 236 237 for _, context := range contexts { 238 context.context.Containers = containers 239 context.context.Write() 240 actual := out.String() 241 if actual != context.expected { 242 t.Fatalf("Expected \n%s, got \n%s", context.expected, actual) 243 } 244 // Clean buffer 245 out.Reset() 246 } 247 } 248 249 func TestImageContextWrite(t *testing.T) { 250 unixTime := time.Now().AddDate(0, 0, -1).Unix() 251 expectedTime := time.Unix(unixTime, 0).String() 252 253 contexts := []struct { 254 context ImageContext 255 expected string 256 }{ 257 // Errors 258 { 259 ImageContext{ 260 Context: Context{ 261 Format: "{{InvalidFunction}}", 262 }, 263 }, 264 `Template parsing error: template: :1: function "InvalidFunction" not defined 265 `, 266 }, 267 { 268 ImageContext{ 269 Context: Context{ 270 Format: "{{nil}}", 271 }, 272 }, 273 `Template parsing error: template: :1:2: executing "" at <nil>: nil is not a command 274 `, 275 }, 276 // Table Format 277 { 278 ImageContext{ 279 Context: Context{ 280 Format: "table", 281 }, 282 }, 283 `REPOSITORY TAG IMAGE ID CREATED SIZE 284 image tag1 imageID1 24 hours ago 0 B 285 image <none> imageID1 24 hours ago 0 B 286 image tag2 imageID2 24 hours ago 0 B 287 <none> <none> imageID3 24 hours ago 0 B 288 `, 289 }, 290 { 291 ImageContext{ 292 Context: Context{ 293 Format: "table {{.Repository}}", 294 }, 295 }, 296 "REPOSITORY\nimage\nimage\nimage\n<none>\n", 297 }, 298 { 299 ImageContext{ 300 Context: Context{ 301 Format: "table {{.Repository}}", 302 }, 303 Digest: true, 304 }, 305 `REPOSITORY DIGEST 306 image <none> 307 image sha256:cbbf2f9a99b47fc460d422812b6a5adff7dfee951d8fa2e4a98caa0382cfbdbf 308 image <none> 309 <none> <none> 310 `, 311 }, 312 { 313 ImageContext{ 314 Context: Context{ 315 Format: "table {{.Repository}}", 316 Quiet: true, 317 }, 318 }, 319 "REPOSITORY\nimage\nimage\nimage\n<none>\n", 320 }, 321 { 322 ImageContext{ 323 Context: Context{ 324 Format: "table", 325 Quiet: true, 326 }, 327 }, 328 "imageID1\nimageID1\nimageID2\nimageID3\n", 329 }, 330 { 331 ImageContext{ 332 Context: Context{ 333 Format: "table", 334 Quiet: false, 335 }, 336 Digest: true, 337 }, 338 `REPOSITORY TAG DIGEST IMAGE ID CREATED SIZE 339 image tag1 <none> imageID1 24 hours ago 0 B 340 image <none> sha256:cbbf2f9a99b47fc460d422812b6a5adff7dfee951d8fa2e4a98caa0382cfbdbf imageID1 24 hours ago 0 B 341 image tag2 <none> imageID2 24 hours ago 0 B 342 <none> <none> <none> imageID3 24 hours ago 0 B 343 `, 344 }, 345 { 346 ImageContext{ 347 Context: Context{ 348 Format: "table", 349 Quiet: true, 350 }, 351 Digest: true, 352 }, 353 "imageID1\nimageID1\nimageID2\nimageID3\n", 354 }, 355 // Raw Format 356 { 357 ImageContext{ 358 Context: Context{ 359 Format: "raw", 360 }, 361 }, 362 fmt.Sprintf(`repository: image 363 tag: tag1 364 image_id: imageID1 365 created_at: %s 366 virtual_size: 0 B 367 368 repository: image 369 tag: <none> 370 image_id: imageID1 371 created_at: %s 372 virtual_size: 0 B 373 374 repository: image 375 tag: tag2 376 image_id: imageID2 377 created_at: %s 378 virtual_size: 0 B 379 380 repository: <none> 381 tag: <none> 382 image_id: imageID3 383 created_at: %s 384 virtual_size: 0 B 385 386 `, expectedTime, expectedTime, expectedTime, expectedTime), 387 }, 388 { 389 ImageContext{ 390 Context: Context{ 391 Format: "raw", 392 }, 393 Digest: true, 394 }, 395 fmt.Sprintf(`repository: image 396 tag: tag1 397 digest: <none> 398 image_id: imageID1 399 created_at: %s 400 virtual_size: 0 B 401 402 repository: image 403 tag: <none> 404 digest: sha256:cbbf2f9a99b47fc460d422812b6a5adff7dfee951d8fa2e4a98caa0382cfbdbf 405 image_id: imageID1 406 created_at: %s 407 virtual_size: 0 B 408 409 repository: image 410 tag: tag2 411 digest: <none> 412 image_id: imageID2 413 created_at: %s 414 virtual_size: 0 B 415 416 repository: <none> 417 tag: <none> 418 digest: <none> 419 image_id: imageID3 420 created_at: %s 421 virtual_size: 0 B 422 423 `, expectedTime, expectedTime, expectedTime, expectedTime), 424 }, 425 { 426 ImageContext{ 427 Context: Context{ 428 Format: "raw", 429 Quiet: true, 430 }, 431 }, 432 `image_id: imageID1 433 image_id: imageID1 434 image_id: imageID2 435 image_id: imageID3 436 `, 437 }, 438 // Custom Format 439 { 440 ImageContext{ 441 Context: Context{ 442 Format: "{{.Repository}}", 443 }, 444 }, 445 "image\nimage\nimage\n<none>\n", 446 }, 447 { 448 ImageContext{ 449 Context: Context{ 450 Format: "{{.Repository}}", 451 }, 452 Digest: true, 453 }, 454 "image\nimage\nimage\n<none>\n", 455 }, 456 } 457 458 for _, context := range contexts { 459 images := []types.Image{ 460 {ID: "imageID1", RepoTags: []string{"image:tag1"}, RepoDigests: []string{"image@sha256:cbbf2f9a99b47fc460d422812b6a5adff7dfee951d8fa2e4a98caa0382cfbdbf"}, Created: unixTime}, 461 {ID: "imageID2", RepoTags: []string{"image:tag2"}, Created: unixTime}, 462 {ID: "imageID3", RepoTags: []string{"<none>:<none>"}, RepoDigests: []string{"<none>@<none>"}, Created: unixTime}, 463 } 464 out := bytes.NewBufferString("") 465 context.context.Output = out 466 context.context.Images = images 467 context.context.Write() 468 actual := out.String() 469 if actual != context.expected { 470 t.Fatalf("Expected \n%s, got \n%s", context.expected, actual) 471 } 472 // Clean buffer 473 out.Reset() 474 } 475 } 476 477 func TestImageContextWriteWithNoImage(t *testing.T) { 478 out := bytes.NewBufferString("") 479 images := []types.Image{} 480 481 contexts := []struct { 482 context ImageContext 483 expected string 484 }{ 485 { 486 ImageContext{ 487 Context: Context{ 488 Format: "{{.Repository}}", 489 Output: out, 490 }, 491 }, 492 "", 493 }, 494 { 495 ImageContext{ 496 Context: Context{ 497 Format: "table {{.Repository}}", 498 Output: out, 499 }, 500 }, 501 "REPOSITORY\n", 502 }, 503 { 504 ImageContext{ 505 Context: Context{ 506 Format: "{{.Repository}}", 507 Output: out, 508 }, 509 Digest: true, 510 }, 511 "", 512 }, 513 { 514 ImageContext{ 515 Context: Context{ 516 Format: "table {{.Repository}}", 517 Output: out, 518 }, 519 Digest: true, 520 }, 521 "REPOSITORY DIGEST\n", 522 }, 523 } 524 525 for _, context := range contexts { 526 context.context.Images = images 527 context.context.Write() 528 actual := out.String() 529 if actual != context.expected { 530 t.Fatalf("Expected \n%s, got \n%s", context.expected, actual) 531 } 532 // Clean buffer 533 out.Reset() 534 } 535 }