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  })