github.com/containers/podman/v4@v4.9.4/pkg/bindings/test/containers_test.go (about) 1 package bindings_test 2 3 import ( 4 "net/http" 5 "strings" 6 "time" 7 8 "github.com/containers/podman/v4/libpod/define" 9 "github.com/containers/podman/v4/pkg/bindings" 10 "github.com/containers/podman/v4/pkg/bindings/containers" 11 "github.com/containers/podman/v4/pkg/domain/entities/reports" 12 "github.com/containers/podman/v4/pkg/specgen" 13 . "github.com/onsi/ginkgo/v2" 14 . "github.com/onsi/gomega" 15 "github.com/onsi/gomega/gexec" 16 ) 17 18 var _ = Describe("Podman containers ", func() { 19 var ( 20 bt *bindingTest 21 s *gexec.Session 22 err error 23 ) 24 25 BeforeEach(func() { 26 bt = newBindingTest() 27 bt.RestoreImagesFromCache() 28 s = bt.startAPIService() 29 time.Sleep(1 * time.Second) 30 err := bt.NewConnection() 31 Expect(err).ToNot(HaveOccurred()) 32 }) 33 34 AfterEach(func() { 35 s.Kill() 36 bt.cleanup() 37 }) 38 39 It("podman pause a bogus container", func() { 40 // Pausing bogus container should return 404 41 err = containers.Pause(bt.conn, "foobar", nil) 42 Expect(err).To(HaveOccurred()) 43 code, _ := bindings.CheckResponseCode(err) 44 Expect(code).To(BeNumerically("==", http.StatusNotFound)) 45 }) 46 47 It("podman unpause a bogus container", func() { 48 // Unpausing bogus container should return 404 49 err = containers.Unpause(bt.conn, "foobar", nil) 50 Expect(err).To(HaveOccurred()) 51 code, _ := bindings.CheckResponseCode(err) 52 Expect(code).To(BeNumerically("==", http.StatusNotFound)) 53 }) 54 55 It("podman pause a running container by name", func() { 56 // Pausing by name should work 57 var name = "top" 58 _, err := bt.RunTopContainer(&name, nil) 59 Expect(err).ToNot(HaveOccurred()) 60 err = containers.Pause(bt.conn, name, nil) 61 Expect(err).ToNot(HaveOccurred()) 62 63 // Ensure container is paused 64 data, err := containers.Inspect(bt.conn, name, nil) 65 Expect(err).ToNot(HaveOccurred()) 66 Expect(data.State.Status).To(Equal("paused")) 67 }) 68 69 It("podman pause a running container by id", func() { 70 // Pausing by id should work 71 var name = "top" 72 cid, err := bt.RunTopContainer(&name, nil) 73 Expect(err).ToNot(HaveOccurred()) 74 err = containers.Pause(bt.conn, cid, nil) 75 Expect(err).ToNot(HaveOccurred()) 76 77 // Ensure container is paused 78 data, err := containers.Inspect(bt.conn, cid, nil) 79 Expect(err).ToNot(HaveOccurred()) 80 Expect(data.State.Status).To(Equal("paused")) 81 }) 82 83 It("podman unpause a running container by name", func() { 84 // Unpausing by name should work 85 var name = "top" 86 _, err := bt.RunTopContainer(&name, nil) 87 Expect(err).ToNot(HaveOccurred()) 88 err = containers.Pause(bt.conn, name, nil) 89 Expect(err).ToNot(HaveOccurred()) 90 err = containers.Unpause(bt.conn, name, nil) 91 Expect(err).ToNot(HaveOccurred()) 92 93 // Ensure container is unpaused 94 data, err := containers.Inspect(bt.conn, name, nil) 95 Expect(err).ToNot(HaveOccurred()) 96 Expect(data.State.Status).To(Equal("running")) 97 }) 98 99 It("podman unpause a running container by ID", func() { 100 // Unpausing by ID should work 101 var name = "top" 102 _, err := bt.RunTopContainer(&name, nil) 103 Expect(err).ToNot(HaveOccurred()) 104 // Pause by name 105 err = containers.Pause(bt.conn, name, nil) 106 Expect(err).ToNot(HaveOccurred(), "error from containers.Pause()") 107 // paused := "paused" 108 // _, err = containers.Wait(bt.conn, cid, &paused) 109 // Expect(err).To(BeNil()) 110 err = containers.Unpause(bt.conn, name, nil) 111 Expect(err).ToNot(HaveOccurred()) 112 113 // Ensure container is unpaused 114 data, err := containers.Inspect(bt.conn, name, nil) 115 Expect(err).ToNot(HaveOccurred()) 116 Expect(data.State.Status).To(Equal("running")) 117 }) 118 119 It("podman pause a paused container by name", func() { 120 // Pausing a paused container by name should fail 121 var name = "top" 122 _, err := bt.RunTopContainer(&name, nil) 123 Expect(err).ToNot(HaveOccurred()) 124 err = containers.Pause(bt.conn, name, nil) 125 Expect(err).ToNot(HaveOccurred()) 126 err = containers.Pause(bt.conn, name, nil) 127 Expect(err).To(HaveOccurred()) 128 code, _ := bindings.CheckResponseCode(err) 129 Expect(code).To(BeNumerically("==", http.StatusInternalServerError)) 130 }) 131 132 It("podman pause a paused container by id", func() { 133 // Pausing a paused container by id should fail 134 var name = "top" 135 cid, err := bt.RunTopContainer(&name, nil) 136 Expect(err).ToNot(HaveOccurred()) 137 err = containers.Pause(bt.conn, cid, nil) 138 Expect(err).ToNot(HaveOccurred()) 139 err = containers.Pause(bt.conn, cid, nil) 140 Expect(err).To(HaveOccurred()) 141 code, _ := bindings.CheckResponseCode(err) 142 Expect(code).To(BeNumerically("==", http.StatusInternalServerError)) 143 }) 144 145 It("podman pause a stopped container by name", func() { 146 // Pausing a stopped container by name should fail 147 var name = "top" 148 _, err := bt.RunTopContainer(&name, nil) 149 Expect(err).ToNot(HaveOccurred()) 150 err = containers.Stop(bt.conn, name, nil) 151 Expect(err).ToNot(HaveOccurred()) 152 err = containers.Pause(bt.conn, name, nil) 153 Expect(err).To(HaveOccurred()) 154 code, _ := bindings.CheckResponseCode(err) 155 Expect(code).To(BeNumerically("==", http.StatusInternalServerError)) 156 }) 157 158 It("podman pause a stopped container by id", func() { 159 // Pausing a stopped container by id should fail 160 var name = "top" 161 cid, err := bt.RunTopContainer(&name, nil) 162 Expect(err).ToNot(HaveOccurred()) 163 err = containers.Stop(bt.conn, cid, nil) 164 Expect(err).ToNot(HaveOccurred()) 165 err = containers.Pause(bt.conn, cid, nil) 166 Expect(err).To(HaveOccurred()) 167 code, _ := bindings.CheckResponseCode(err) 168 Expect(code).To(BeNumerically("==", http.StatusInternalServerError)) 169 }) 170 171 It("podman remove a paused container by id without force", func() { 172 // Removing a paused container without force should fail 173 var name = "top" 174 cid, err := bt.RunTopContainer(&name, nil) 175 Expect(err).ToNot(HaveOccurred()) 176 err = containers.Pause(bt.conn, cid, nil) 177 Expect(err).ToNot(HaveOccurred()) 178 _, err = containers.Remove(bt.conn, cid, nil) 179 Expect(err).To(HaveOccurred()) 180 code, _ := bindings.CheckResponseCode(err) 181 Expect(code).To(BeNumerically("==", http.StatusInternalServerError)) 182 }) 183 184 It("podman remove a paused container by id with force", func() { 185 // Removing a paused container with force should work 186 var name = "top" 187 cid, err := bt.RunTopContainer(&name, nil) 188 Expect(err).ToNot(HaveOccurred()) 189 err = containers.Pause(bt.conn, cid, nil) 190 Expect(err).ToNot(HaveOccurred()) 191 rmResponse, err := containers.Remove(bt.conn, cid, new(containers.RemoveOptions).WithForce(true)) 192 Expect(err).ToNot(HaveOccurred()) 193 Expect(reports.RmReportsErrs(rmResponse)).To(BeEmpty()) 194 Expect(reports.RmReportsIds(rmResponse)).To(HaveLen(1)) 195 }) 196 197 It("podman stop a paused container by name", func() { 198 // Stopping a paused container by name should fail 199 var name = "top" 200 _, err := bt.RunTopContainer(&name, nil) 201 Expect(err).ToNot(HaveOccurred()) 202 err = containers.Pause(bt.conn, name, nil) 203 Expect(err).ToNot(HaveOccurred()) 204 err = containers.Stop(bt.conn, name, nil) 205 Expect(err).To(HaveOccurred()) 206 code, _ := bindings.CheckResponseCode(err) 207 Expect(code).To(BeNumerically("==", http.StatusInternalServerError)) 208 }) 209 210 It("podman stop a paused container by id", func() { 211 // Stopping a paused container by id should fail 212 var name = "top" 213 cid, err := bt.RunTopContainer(&name, nil) 214 Expect(err).ToNot(HaveOccurred()) 215 err = containers.Pause(bt.conn, cid, nil) 216 Expect(err).ToNot(HaveOccurred()) 217 err = containers.Stop(bt.conn, cid, nil) 218 Expect(err).To(HaveOccurred()) 219 code, _ := bindings.CheckResponseCode(err) 220 Expect(code).To(BeNumerically("==", http.StatusInternalServerError)) 221 }) 222 223 It("podman stop a running container by name", func() { 224 // Stopping a running container by name should work 225 var name = "top" 226 _, err := bt.RunTopContainer(&name, nil) 227 Expect(err).ToNot(HaveOccurred()) 228 err = containers.Stop(bt.conn, name, nil) 229 Expect(err).ToNot(HaveOccurred()) 230 231 // Ensure container is stopped 232 data, err := containers.Inspect(bt.conn, name, nil) 233 Expect(err).ToNot(HaveOccurred()) 234 Expect(isStopped(data.State.Status)).To(BeTrue()) 235 }) 236 237 It("podman stop a running container by ID", func() { 238 // Stopping a running container by ID should work 239 var name = "top" 240 cid, err := bt.RunTopContainer(&name, nil) 241 Expect(err).ToNot(HaveOccurred()) 242 err = containers.Stop(bt.conn, cid, nil) 243 Expect(err).ToNot(HaveOccurred()) 244 245 // Ensure container is stopped 246 data, err := containers.Inspect(bt.conn, name, nil) 247 Expect(err).ToNot(HaveOccurred()) 248 Expect(isStopped(data.State.Status)).To(BeTrue()) 249 }) 250 251 It("podman wait no condition", func() { 252 var ( 253 name = "top" 254 exitCode int32 = -1 255 ) 256 _, err := containers.Wait(bt.conn, "foobar", nil) 257 Expect(err).To(HaveOccurred()) 258 code, _ := bindings.CheckResponseCode(err) 259 Expect(code).To(BeNumerically("==", http.StatusNotFound)) 260 261 errChan := make(chan error) 262 _, err = bt.RunTopContainer(&name, nil) 263 Expect(err).ToNot(HaveOccurred()) 264 go func() { 265 defer GinkgoRecover() 266 exitCode, err = containers.Wait(bt.conn, name, nil) 267 errChan <- err 268 close(errChan) 269 }() 270 err = containers.Stop(bt.conn, name, nil) 271 Expect(err).ToNot(HaveOccurred()) 272 wait := <-errChan 273 Expect(wait).ToNot(HaveOccurred()) 274 Expect(exitCode).To(BeNumerically("==", 143)) 275 }) 276 277 It("podman wait to pause|unpause condition", func() { 278 var ( 279 name = "top" 280 exitCode int32 = -1 281 pause = define.ContainerStatePaused 282 running = define.ContainerStateRunning 283 ) 284 errChan := make(chan error) 285 _, err := bt.RunTopContainer(&name, nil) 286 Expect(err).ToNot(HaveOccurred()) 287 go func() { 288 defer GinkgoRecover() 289 exitCode, err = containers.Wait(bt.conn, name, new(containers.WaitOptions).WithCondition([]define.ContainerStatus{pause})) 290 errChan <- err 291 close(errChan) 292 }() 293 err = containers.Pause(bt.conn, name, nil) 294 Expect(err).ToNot(HaveOccurred()) 295 wait := <-errChan 296 Expect(wait).ToNot(HaveOccurred()) 297 Expect(exitCode).To(BeNumerically("==", -1)) 298 299 unpauseErrChan := make(chan error) 300 go func() { 301 defer GinkgoRecover() 302 303 _, waitErr := containers.Wait(bt.conn, name, new(containers.WaitOptions).WithCondition([]define.ContainerStatus{running})) 304 unpauseErrChan <- waitErr 305 close(unpauseErrChan) 306 }() 307 err = containers.Unpause(bt.conn, name, nil) 308 Expect(err).ToNot(HaveOccurred()) 309 unPausewait := <-unpauseErrChan 310 Expect(unPausewait).ToNot(HaveOccurred()) 311 Expect(exitCode).To(BeNumerically("==", -1)) 312 }) 313 314 It("run healthcheck", func() { 315 bt.runPodman([]string{"run", "-d", "--name", "hc", "--health-interval", "disable", "--health-retries", "2", "--health-cmd", "ls / || exit 1", alpine.name, "top"}) 316 317 // bogus name should result in 404 318 _, err := containers.RunHealthCheck(bt.conn, "foobar", nil) 319 Expect(err).To(HaveOccurred()) 320 code, _ := bindings.CheckResponseCode(err) 321 Expect(code).To(BeNumerically("==", http.StatusNotFound)) 322 323 // a container that has no healthcheck should be a 409 324 var name = "top" 325 _, err = bt.RunTopContainer(&name, nil) 326 Expect(err).ToNot(HaveOccurred()) 327 _, err = containers.RunHealthCheck(bt.conn, name, nil) 328 Expect(err).To(HaveOccurred()) 329 code, _ = bindings.CheckResponseCode(err) 330 Expect(code).To(BeNumerically("==", http.StatusConflict)) 331 332 // TODO for the life of me, i cannot get this to work. maybe another set 333 // of eyes will 334 // successful healthcheck 335 // status := define.HealthCheckHealthy 336 // for i:=0; i < 10; i++ { 337 // result, err := containers.RunHealthCheck(connText, "hc") 338 // Expect(err).To(BeNil()) 339 // if result.Status != define.HealthCheckHealthy { 340 // fmt.Println("Healthcheck container still starting, retrying in 1 second") 341 // time.Sleep(1 * time.Second) 342 // continue 343 // } 344 // status = result.Status 345 // break 346 // } 347 // Expect(status).To(Equal(define.HealthCheckHealthy)) 348 349 // TODO enable this when wait is working 350 // healthcheck on a stopped container should be a 409 351 // err = containers.Stop(connText, "hc", nil) 352 // Expect(err).To(BeNil()) 353 // _, err = containers.Wait(connText, "hc") 354 // Expect(err).To(BeNil()) 355 // _, err = containers.RunHealthCheck(connText, "hc") 356 // code, _ = bindings.CheckResponseCode(err) 357 // Expect(code).To(BeNumerically("==", http.StatusConflict)) 358 }) 359 360 It("logging", func() { 361 stdoutChan := make(chan string, 10) 362 s := specgen.NewSpecGenerator(alpine.name, false) 363 s.Terminal = true 364 s.Command = []string{"date", "-R"} 365 r, err := containers.CreateWithSpec(bt.conn, s, nil) 366 Expect(err).ToNot(HaveOccurred()) 367 err = containers.Start(bt.conn, r.ID, nil) 368 Expect(err).ToNot(HaveOccurred()) 369 370 _, err = containers.Wait(bt.conn, r.ID, nil) 371 Expect(err).ToNot(HaveOccurred()) 372 373 opts := new(containers.LogOptions).WithStdout(true).WithFollow(true) 374 go func() { 375 defer GinkgoRecover() 376 err := containers.Logs(bt.conn, r.ID, opts, stdoutChan, nil) 377 close(stdoutChan) 378 Expect(err).ShouldNot(HaveOccurred()) 379 }() 380 o := <-stdoutChan 381 o = strings.TrimSpace(o) 382 _, err = time.Parse(time.RFC1123Z, o) 383 Expect(err).ShouldNot(HaveOccurred()) 384 }) 385 386 It("podman top", func() { 387 var name = "top" 388 cid, err := bt.RunTopContainer(&name, nil) 389 Expect(err).ToNot(HaveOccurred()) 390 391 // By name 392 _, err = containers.Top(bt.conn, name, nil) 393 Expect(err).ToNot(HaveOccurred()) 394 395 // By id 396 _, err = containers.Top(bt.conn, cid, nil) 397 Expect(err).ToNot(HaveOccurred()) 398 399 // With descriptors 400 output, err := containers.Top(bt.conn, cid, new(containers.TopOptions).WithDescriptors([]string{"user", "pid", "hpid"})) 401 Expect(err).ToNot(HaveOccurred()) 402 header := strings.Split(output[0], "\t") 403 for _, d := range []string{"USER", "PID", "HPID"} { 404 Expect(d).To(BeElementOf(header)) 405 } 406 407 // With bogus ID 408 _, err = containers.Top(bt.conn, "IdoNotExist", nil) 409 Expect(err).To(HaveOccurred()) 410 411 // With bogus descriptors 412 _, err = containers.Top(bt.conn, cid, new(containers.TopOptions).WithDescriptors([]string{"Me,Neither"})) 413 Expect(err).To(HaveOccurred()) 414 }) 415 416 It("podman bogus container does not exist in local storage", func() { 417 // Bogus container existence check should fail 418 containerExists, err := containers.Exists(bt.conn, "foobar", nil) 419 Expect(err).ToNot(HaveOccurred()) 420 Expect(containerExists).To(BeFalse()) 421 }) 422 423 It("podman container exists in local storage by name", func() { 424 // Container existence check by name should work 425 var name = "top" 426 _, err := bt.RunTopContainer(&name, nil) 427 Expect(err).ToNot(HaveOccurred()) 428 containerExists, err := containers.Exists(bt.conn, name, nil) 429 Expect(err).ToNot(HaveOccurred()) 430 Expect(containerExists).To(BeTrue()) 431 }) 432 433 It("podman container exists in local storage by ID", func() { 434 // Container existence check by ID should work 435 var name = "top" 436 cid, err := bt.RunTopContainer(&name, nil) 437 Expect(err).ToNot(HaveOccurred()) 438 containerExists, err := containers.Exists(bt.conn, cid, nil) 439 Expect(err).ToNot(HaveOccurred()) 440 Expect(containerExists).To(BeTrue()) 441 }) 442 443 It("podman container exists in local storage by short ID", func() { 444 // Container existence check by short ID should work 445 var name = "top" 446 cid, err := bt.RunTopContainer(&name, nil) 447 Expect(err).ToNot(HaveOccurred()) 448 containerExists, err := containers.Exists(bt.conn, cid[0:12], nil) 449 Expect(err).ToNot(HaveOccurred()) 450 Expect(containerExists).To(BeTrue()) 451 }) 452 453 It("podman kill bogus container", func() { 454 // Killing bogus container should return 404 455 err := containers.Kill(bt.conn, "foobar", new(containers.KillOptions).WithSignal("SIGTERM")) 456 Expect(err).To(HaveOccurred()) 457 code, _ := bindings.CheckResponseCode(err) 458 Expect(code).To(BeNumerically("==", http.StatusNotFound)) 459 }) 460 461 It("podman kill a running container by name with SIGINT", func() { 462 // Killing a running container should work 463 var name = "top" 464 _, err := bt.RunTopContainer(&name, nil) 465 Expect(err).ToNot(HaveOccurred()) 466 err = containers.Kill(bt.conn, name, new(containers.KillOptions).WithSignal("SIGINT")) 467 Expect(err).ToNot(HaveOccurred()) 468 _, err = containers.Exists(bt.conn, name, nil) 469 Expect(err).ToNot(HaveOccurred()) 470 }) 471 472 It("podman kill a running container by ID with SIGTERM", func() { 473 // Killing a running container by ID should work 474 var name = "top" 475 cid, err := bt.RunTopContainer(&name, nil) 476 Expect(err).ToNot(HaveOccurred()) 477 err = containers.Kill(bt.conn, cid, new(containers.KillOptions).WithSignal("SIGTERM")) 478 Expect(err).ToNot(HaveOccurred()) 479 _, err = containers.Exists(bt.conn, cid, nil) 480 Expect(err).ToNot(HaveOccurred()) 481 }) 482 483 It("podman kill a running container by ID with SIGKILL", func() { 484 // Killing a running container by ID with TERM should work 485 var name = "top" 486 cid, err := bt.RunTopContainer(&name, nil) 487 Expect(err).ToNot(HaveOccurred()) 488 err = containers.Kill(bt.conn, cid, new(containers.KillOptions).WithSignal("SIGKILL")) 489 Expect(err).ToNot(HaveOccurred()) 490 }) 491 492 It("podman kill a running container by bogus signal", func() { 493 // Killing a running container by bogus signal should fail 494 var name = "top" 495 cid, err := bt.RunTopContainer(&name, nil) 496 Expect(err).ToNot(HaveOccurred()) 497 err = containers.Kill(bt.conn, cid, new(containers.KillOptions).WithSignal("foobar")) 498 Expect(err).To(HaveOccurred()) 499 code, _ := bindings.CheckResponseCode(err) 500 Expect(code).To(BeNumerically("==", http.StatusInternalServerError)) 501 }) 502 503 It("podman kill latest container with SIGTERM", func() { 504 // Killing latest container should work 505 var name1 = "first" 506 var name2 = "second" 507 _, err := bt.RunTopContainer(&name1, nil) 508 Expect(err).ToNot(HaveOccurred()) 509 _, err = bt.RunTopContainer(&name2, nil) 510 Expect(err).ToNot(HaveOccurred()) 511 containerLatestList, err := containers.List(bt.conn, new(containers.ListOptions).WithLast(1)) 512 Expect(err).ToNot(HaveOccurred()) 513 err = containers.Kill(bt.conn, containerLatestList[0].Names[0], new(containers.KillOptions).WithSignal("SIGTERM")) 514 Expect(err).ToNot(HaveOccurred()) 515 }) 516 517 It("container init on a bogus container", func() { 518 err := containers.ContainerInit(bt.conn, "doesnotexist", nil) 519 Expect(err).To(HaveOccurred()) 520 code, _ := bindings.CheckResponseCode(err) 521 Expect(code).To(BeNumerically("==", http.StatusNotFound)) 522 }) 523 524 It("container init", func() { 525 s := specgen.NewSpecGenerator(alpine.name, false) 526 ctr, err := containers.CreateWithSpec(bt.conn, s, nil) 527 Expect(err).ToNot(HaveOccurred()) 528 err = containers.ContainerInit(bt.conn, ctr.ID, nil) 529 Expect(err).ToNot(HaveOccurred()) 530 // trying to init again should be an error 531 err = containers.ContainerInit(bt.conn, ctr.ID, nil) 532 Expect(err).To(HaveOccurred()) 533 }) 534 535 It("podman prune stopped containers", func() { 536 // Start and stop a container to enter in exited state. 537 var name = "top" 538 _, err := bt.RunTopContainer(&name, nil) 539 Expect(err).ToNot(HaveOccurred()) 540 err = containers.Stop(bt.conn, name, nil) 541 Expect(err).ToNot(HaveOccurred()) 542 543 // Prune container should return no errors and one pruned container ID. 544 pruneResponse, err := containers.Prune(bt.conn, nil) 545 Expect(err).ToNot(HaveOccurred()) 546 Expect(reports.PruneReportsErrs(pruneResponse)).To(BeEmpty()) 547 Expect(reports.PruneReportsIds(pruneResponse)).To(HaveLen(1)) 548 }) 549 550 It("podman prune stopped containers with filters", func() { 551 // Start and stop a container to enter in exited state. 552 var name = "top" 553 _, err := bt.RunTopContainer(&name, nil) 554 Expect(err).ToNot(HaveOccurred()) 555 err = containers.Stop(bt.conn, name, nil) 556 Expect(err).ToNot(HaveOccurred()) 557 558 // Invalid filter keys should return error. 559 filtersIncorrect := map[string][]string{ 560 "status": {"dummy"}, 561 } 562 _, err = containers.Prune(bt.conn, new(containers.PruneOptions).WithFilters(filtersIncorrect)) 563 Expect(err).To(HaveOccurred()) 564 565 // List filter params should not work with prune. 566 filtersIncorrect = map[string][]string{ 567 "name": {"top"}, 568 } 569 _, err = containers.Prune(bt.conn, new(containers.PruneOptions).WithFilters(filtersIncorrect)) 570 Expect(err).To(HaveOccurred()) 571 572 // Mismatched filter params no container should be pruned. 573 filtersIncorrect = map[string][]string{ 574 "label": {"xyz"}, 575 } 576 pruneResponse, err := containers.Prune(bt.conn, new(containers.PruneOptions).WithFilters(filtersIncorrect)) 577 Expect(err).ToNot(HaveOccurred()) 578 Expect(reports.PruneReportsIds(pruneResponse)).To(BeEmpty()) 579 Expect(reports.PruneReportsErrs(pruneResponse)).To(BeEmpty()) 580 581 // Valid filter params container should be pruned now. 582 filters := map[string][]string{ 583 "until": {"5000000000"}, // Friday, June 11, 2128 584 } 585 pruneResponse, err = containers.Prune(bt.conn, new(containers.PruneOptions).WithFilters(filters)) 586 Expect(err).ToNot(HaveOccurred()) 587 Expect(reports.PruneReportsErrs(pruneResponse)).To(BeEmpty()) 588 Expect(reports.PruneReportsIds(pruneResponse)).To(HaveLen(1)) 589 }) 590 591 It("podman list containers with until filter", func() { 592 var name = "top" 593 _, err := bt.RunTopContainer(&name, nil) 594 Expect(err).ToNot(HaveOccurred()) 595 596 filters := map[string][]string{ 597 "until": {"5000000000"}, // Friday, June 11, 2128 598 } 599 c, err := containers.List(bt.conn, new(containers.ListOptions).WithFilters(filters).WithAll(true)) 600 Expect(err).ToNot(HaveOccurred()) 601 Expect(c).To(HaveLen(1)) 602 603 filters = map[string][]string{ 604 "until": {"500000"}, // Tuesday, January 6, 1970 605 } 606 c, err = containers.List(bt.conn, new(containers.ListOptions).WithFilters(filters).WithAll(true)) 607 Expect(err).ToNot(HaveOccurred()) 608 Expect(c).To(BeEmpty()) 609 }) 610 611 It("podman prune running containers", func() { 612 // Start the container. 613 var name = "top" 614 _, err := bt.RunTopContainer(&name, nil) 615 Expect(err).ToNot(HaveOccurred()) 616 617 // Check if the container is running. 618 data, err := containers.Inspect(bt.conn, name, nil) 619 Expect(err).ToNot(HaveOccurred()) 620 Expect(data.State.Status).To(Equal("running")) 621 622 // Prune. Should return no error no prune response ID. 623 pruneResponse, err := containers.Prune(bt.conn, nil) 624 Expect(err).ToNot(HaveOccurred()) 625 Expect(pruneResponse).To(BeEmpty()) 626 }) 627 628 It("podman inspect bogus container", func() { 629 _, err := containers.Inspect(bt.conn, "foobar", nil) 630 Expect(err).To(HaveOccurred()) 631 code, _ := bindings.CheckResponseCode(err) 632 Expect(code).To(BeNumerically("==", http.StatusNotFound)) 633 }) 634 635 It("podman inspect running container", func() { 636 var name = "top" 637 _, err := bt.RunTopContainer(&name, nil) 638 Expect(err).ToNot(HaveOccurred()) 639 // Inspecting running container should succeed 640 _, err = containers.Inspect(bt.conn, name, nil) 641 Expect(err).ToNot(HaveOccurred()) 642 }) 643 644 It("podman inspect stopped container", func() { 645 var name = "top" 646 _, err := bt.RunTopContainer(&name, nil) 647 Expect(err).ToNot(HaveOccurred()) 648 err = containers.Stop(bt.conn, name, nil) 649 Expect(err).ToNot(HaveOccurred()) 650 // Inspecting stopped container should succeed 651 _, err = containers.Inspect(bt.conn, name, nil) 652 Expect(err).ToNot(HaveOccurred()) 653 }) 654 655 It("podman inspect running container with size", func() { 656 var name = "top" 657 _, err := bt.RunTopContainer(&name, nil) 658 Expect(err).ToNot(HaveOccurred()) 659 _, err = containers.Inspect(bt.conn, name, new(containers.InspectOptions).WithSize(true)) 660 Expect(err).ToNot(HaveOccurred()) 661 }) 662 663 It("podman inspect stopped container with size", func() { 664 var name = "top" 665 _, err := bt.RunTopContainer(&name, nil) 666 Expect(err).ToNot(HaveOccurred()) 667 err = containers.Stop(bt.conn, name, nil) 668 Expect(err).ToNot(HaveOccurred()) 669 // Inspecting stopped container with size should succeed 670 _, err = containers.Inspect(bt.conn, name, new(containers.InspectOptions).WithSize(true)) 671 Expect(err).ToNot(HaveOccurred()) 672 }) 673 674 It("podman remove bogus container", func() { 675 _, err := containers.Remove(bt.conn, "foobar", nil) 676 Expect(err).To(HaveOccurred()) 677 code, _ := bindings.CheckResponseCode(err) 678 Expect(code).To(BeNumerically("==", http.StatusNotFound)) 679 }) 680 681 It("podman remove running container by name", func() { 682 var name = "top" 683 _, err := bt.RunTopContainer(&name, nil) 684 Expect(err).ToNot(HaveOccurred()) 685 // Removing running container should fail 686 _, err = containers.Remove(bt.conn, name, nil) 687 Expect(err).To(HaveOccurred()) 688 code, _ := bindings.CheckResponseCode(err) 689 Expect(code).To(BeNumerically("==", http.StatusInternalServerError)) 690 }) 691 692 It("podman remove running container by ID", func() { 693 var name = "top" 694 cid, err := bt.RunTopContainer(&name, nil) 695 Expect(err).ToNot(HaveOccurred()) 696 // Removing running container should fail 697 _, err = containers.Remove(bt.conn, cid, nil) 698 Expect(err).To(HaveOccurred()) 699 code, _ := bindings.CheckResponseCode(err) 700 Expect(code).To(BeNumerically("==", http.StatusInternalServerError)) 701 }) 702 703 It("podman forcibly remove running container by name", func() { 704 var name = "top" 705 _, err := bt.RunTopContainer(&name, nil) 706 Expect(err).ToNot(HaveOccurred()) 707 // Removing running container should succeed 708 rmResponse, err := containers.Remove(bt.conn, name, new(containers.RemoveOptions).WithForce(true)) 709 Expect(err).ToNot(HaveOccurred()) 710 Expect(reports.RmReportsErrs(rmResponse)).To(BeEmpty()) 711 Expect(reports.RmReportsIds(rmResponse)).To(HaveLen(1)) 712 }) 713 714 It("podman forcibly remove running container by ID", func() { 715 var name = "top" 716 cid, err := bt.RunTopContainer(&name, nil) 717 Expect(err).ToNot(HaveOccurred()) 718 // Forcibly Removing running container should succeed 719 rmResponse, err := containers.Remove(bt.conn, cid, new(containers.RemoveOptions).WithForce(true)) 720 Expect(err).ToNot(HaveOccurred()) 721 Expect(reports.RmReportsErrs(rmResponse)).To(BeEmpty()) 722 Expect(reports.RmReportsIds(rmResponse)).To(HaveLen(1)) 723 }) 724 725 It("podman remove running container and volume by name", func() { 726 var name = "top" 727 _, err := bt.RunTopContainer(&name, nil) 728 Expect(err).ToNot(HaveOccurred()) 729 // Removing running container should fail 730 _, err = containers.Remove(bt.conn, name, new(containers.RemoveOptions).WithVolumes(true)) 731 Expect(err).To(HaveOccurred()) 732 code, _ := bindings.CheckResponseCode(err) 733 Expect(code).To(BeNumerically("==", http.StatusInternalServerError)) 734 }) 735 736 It("podman remove running container and volume by ID", func() { 737 var name = "top" 738 cid, err := bt.RunTopContainer(&name, nil) 739 Expect(err).ToNot(HaveOccurred()) 740 // Removing running container should fail 741 _, err = containers.Remove(bt.conn, cid, new(containers.RemoveOptions).WithVolumes(true)) 742 Expect(err).To(HaveOccurred()) 743 code, _ := bindings.CheckResponseCode(err) 744 Expect(code).To(BeNumerically("==", http.StatusInternalServerError)) 745 }) 746 747 It("podman forcibly remove running container and volume by name", func() { 748 var name = "top" 749 _, err := bt.RunTopContainer(&name, nil) 750 Expect(err).ToNot(HaveOccurred()) 751 // Forcibly Removing running container should succeed 752 rmResponse, err := containers.Remove(bt.conn, name, new(containers.RemoveOptions).WithVolumes(true).WithForce(true)) 753 Expect(err).ToNot(HaveOccurred()) 754 Expect(reports.RmReportsErrs(rmResponse)).To(BeEmpty()) 755 Expect(reports.RmReportsIds(rmResponse)).To(HaveLen(1)) 756 }) 757 758 It("podman forcibly remove running container and volume by ID", func() { 759 var name = "top" 760 cid, err := bt.RunTopContainer(&name, nil) 761 Expect(err).ToNot(HaveOccurred()) 762 // Removing running container should fail 763 rmResponse, err := containers.Remove(bt.conn, cid, new(containers.RemoveOptions).WithForce(true).WithVolumes(true)) 764 Expect(err).ToNot(HaveOccurred()) 765 Expect(reports.RmReportsErrs(rmResponse)).To(BeEmpty()) 766 Expect(reports.RmReportsIds(rmResponse)).To(HaveLen(1)) 767 }) 768 769 It("List containers with filters", func() { 770 var name = "top" 771 var name2 = "top2" 772 cid, err := bt.RunTopContainer(&name, nil) 773 Expect(err).ToNot(HaveOccurred()) 774 _, err = bt.RunTopContainer(&name2, nil) 775 Expect(err).ToNot(HaveOccurred()) 776 s := specgen.NewSpecGenerator(alpine.name, false) 777 s.Terminal = true 778 s.Command = []string{"date", "-R"} 779 _, err = containers.CreateWithSpec(bt.conn, s, nil) 780 Expect(err).ToNot(HaveOccurred()) 781 // Validate list container with id filter 782 filters := make(map[string][]string) 783 filters["id"] = []string{cid} 784 c, err := containers.List(bt.conn, new(containers.ListOptions).WithFilters(filters).WithAll(true)) 785 Expect(err).ToNot(HaveOccurred()) 786 Expect(c).To(HaveLen(1)) 787 }) 788 789 It("List containers always includes pod information", func() { 790 podName := "testpod" 791 ctrName := "testctr" 792 bt.Podcreate(&podName) 793 _, err := bt.RunTopContainer(&ctrName, &podName) 794 Expect(err).ToNot(HaveOccurred()) 795 796 lastNum := 1 797 798 c, err := containers.List(bt.conn, new(containers.ListOptions).WithAll(true).WithLast(lastNum)) 799 Expect(err).ToNot(HaveOccurred()) 800 Expect(c).To(HaveLen(1)) 801 Expect(c[0].PodName).To(Equal(podName)) 802 }) 803 })