github.com/containers/libpod@v1.9.4-0.20220419124438-4284fd425507/pkg/bindings/test/pods_test.go (about)

     1  package test_bindings
     2  
     3  import (
     4  	"net/http"
     5  	"strings"
     6  	"time"
     7  
     8  	"github.com/containers/libpod/libpod/define"
     9  	"github.com/containers/libpod/pkg/bindings"
    10  	"github.com/containers/libpod/pkg/bindings/pods"
    11  	"github.com/containers/libpod/pkg/specgen"
    12  	. "github.com/onsi/ginkgo"
    13  	. "github.com/onsi/gomega"
    14  	"github.com/onsi/gomega/gexec"
    15  )
    16  
    17  var _ = Describe("Podman pods", func() {
    18  	var (
    19  		bt     *bindingTest
    20  		s      *gexec.Session
    21  		newpod string
    22  		err    error
    23  	)
    24  
    25  	BeforeEach(func() {
    26  		bt = newBindingTest()
    27  		newpod = "newpod"
    28  		bt.RestoreImagesFromCache()
    29  		bt.Podcreate(&newpod)
    30  		s = bt.startAPIService()
    31  		time.Sleep(1 * time.Second)
    32  		err := bt.NewConnection()
    33  		Expect(err).To(BeNil())
    34  	})
    35  
    36  	AfterEach(func() {
    37  		s.Kill()
    38  		bt.cleanup()
    39  	})
    40  
    41  	It("inspect pod", func() {
    42  		//Inspect an invalid pod name
    43  		_, err := pods.Inspect(bt.conn, "dummyname")
    44  		Expect(err).ToNot(BeNil())
    45  		code, _ := bindings.CheckResponseCode(err)
    46  		Expect(code).To(BeNumerically("==", http.StatusNotFound))
    47  
    48  		//Inspect an valid pod name
    49  		response, err := pods.Inspect(bt.conn, newpod)
    50  		Expect(err).To(BeNil())
    51  		Expect(response.Config.Name).To(Equal(newpod))
    52  	})
    53  
    54  	// Test validates the list all api returns
    55  	It("list pod", func() {
    56  		//List all the pods in the current instance
    57  		podSummary, err := pods.List(bt.conn, nil)
    58  		Expect(err).To(BeNil())
    59  		Expect(len(podSummary)).To(Equal(1))
    60  		// Adding an alpine container to the existing pod
    61  		_, err = bt.RunTopContainer(nil, &bindings.PTrue, &newpod)
    62  		Expect(err).To(BeNil())
    63  		podSummary, err = pods.List(bt.conn, nil)
    64  		// Verify no errors.
    65  		Expect(err).To(BeNil())
    66  		// Verify number of containers in the pod.
    67  		Expect(len(podSummary[0].Containers)).To(Equal(2))
    68  
    69  		// Add multiple pods and verify them by name and size.
    70  		var newpod2 string = "newpod2"
    71  		bt.Podcreate(&newpod2)
    72  		podSummary, err = pods.List(bt.conn, nil)
    73  		Expect(len(podSummary)).To(Equal(2))
    74  		var names []string
    75  		for _, i := range podSummary {
    76  			names = append(names, i.Name)
    77  		}
    78  		Expect(StringInSlice(newpod, names)).To(BeTrue())
    79  		Expect(StringInSlice("newpod2", names)).To(BeTrue())
    80  	})
    81  
    82  	// The test validates the list pod endpoint with passing filters as the params.
    83  	It("List pods with filters", func() {
    84  		newpod2 := "newpod2"
    85  		bt.Podcreate(&newpod2)
    86  		_, err = bt.RunTopContainer(nil, &bindings.PTrue, &newpod)
    87  		Expect(err).To(BeNil())
    88  
    89  		// Expected err with invalid filter params
    90  		filters := make(map[string][]string)
    91  		filters["dummy"] = []string{"dummy"}
    92  		filteredPods, err := pods.List(bt.conn, filters)
    93  		Expect(err).ToNot(BeNil())
    94  		code, _ := bindings.CheckResponseCode(err)
    95  		Expect(code).To(BeNumerically("==", http.StatusInternalServerError))
    96  
    97  		// Expected empty response with invalid filters
    98  		filters = make(map[string][]string)
    99  		filters["name"] = []string{"dummy"}
   100  		filteredPods, err = pods.List(bt.conn, filters)
   101  		Expect(err).To(BeNil())
   102  		Expect(len(filteredPods)).To(BeNumerically("==", 0))
   103  
   104  		// Validate list pod with name filter
   105  		filters = make(map[string][]string)
   106  		filters["name"] = []string{newpod2}
   107  		filteredPods, err = pods.List(bt.conn, filters)
   108  		Expect(err).To(BeNil())
   109  		Expect(len(filteredPods)).To(BeNumerically("==", 1))
   110  		var names []string
   111  		for _, i := range filteredPods {
   112  			names = append(names, i.Name)
   113  		}
   114  		Expect(StringInSlice("newpod2", names)).To(BeTrue())
   115  
   116  		// Validate list pod with id filter
   117  		filters = make(map[string][]string)
   118  		response, err := pods.Inspect(bt.conn, newpod)
   119  		Expect(err).To(BeNil())
   120  		id := response.Config.ID
   121  		filters["id"] = []string{id}
   122  		filteredPods, err = pods.List(bt.conn, filters)
   123  		Expect(err).To(BeNil())
   124  		Expect(len(filteredPods)).To(BeNumerically("==", 1))
   125  		names = names[:0]
   126  		for _, i := range filteredPods {
   127  			names = append(names, i.Name)
   128  		}
   129  		Expect(StringInSlice("newpod", names)).To(BeTrue())
   130  
   131  		// Using multiple filters
   132  		filters["name"] = []string{newpod}
   133  		filteredPods, err = pods.List(bt.conn, filters)
   134  		Expect(err).To(BeNil())
   135  		Expect(len(filteredPods)).To(BeNumerically("==", 1))
   136  		names = names[:0]
   137  		for _, i := range filteredPods {
   138  			names = append(names, i.Name)
   139  		}
   140  		Expect(StringInSlice("newpod", names)).To(BeTrue())
   141  	})
   142  
   143  	// The test validates if the exists responds
   144  	It("exists pod", func() {
   145  		response, err := pods.Exists(bt.conn, "dummyName")
   146  		Expect(err).To(BeNil())
   147  		Expect(response).To(BeFalse())
   148  
   149  		// Should exit with no error and response should be true
   150  		response, err = pods.Exists(bt.conn, "newpod")
   151  		Expect(err).To(BeNil())
   152  		Expect(response).To(BeTrue())
   153  	})
   154  
   155  	// This test validates if All running containers within
   156  	// each specified pod are paused and unpaused
   157  	It("pause upause pod", func() {
   158  		// TODO fix this
   159  		Skip("Pod behavior is jacked right now.")
   160  		// Pause invalid container
   161  		_, err := pods.Pause(bt.conn, "dummyName")
   162  		Expect(err).ToNot(BeNil())
   163  		code, _ := bindings.CheckResponseCode(err)
   164  		Expect(code).To(BeNumerically("==", http.StatusNotFound))
   165  
   166  		// Adding an alpine container to the existing pod
   167  		_, err = bt.RunTopContainer(nil, &bindings.PTrue, &newpod)
   168  		Expect(err).To(BeNil())
   169  
   170  		// Binding needs to be modified to inspect the pod state.
   171  		// Since we don't have a pod state we inspect the states of the containers within the pod.
   172  		// Pause a valid container
   173  		_, err = pods.Pause(bt.conn, newpod)
   174  		Expect(err).To(BeNil())
   175  		response, err := pods.Inspect(bt.conn, newpod)
   176  		Expect(err).To(BeNil())
   177  		Expect(response.State.Status).To(Equal(define.PodStatePaused))
   178  		for _, i := range response.Containers {
   179  			Expect(define.StringToContainerStatus(i.State)).
   180  				To(Equal(define.ContainerStatePaused))
   181  		}
   182  
   183  		// Unpause a valid container
   184  		_, err = pods.Unpause(bt.conn, newpod)
   185  		Expect(err).To(BeNil())
   186  		response, err = pods.Inspect(bt.conn, newpod)
   187  		Expect(err).To(BeNil())
   188  		Expect(response.State.Status).To(Equal(define.PodStateRunning))
   189  		for _, i := range response.Containers {
   190  			Expect(define.StringToContainerStatus(i.State)).
   191  				To(Equal(define.ContainerStateRunning))
   192  		}
   193  	})
   194  
   195  	It("start stop restart pod", func() {
   196  		// Start an invalid pod
   197  		_, err = pods.Start(bt.conn, "dummyName")
   198  		Expect(err).ToNot(BeNil())
   199  		code, _ := bindings.CheckResponseCode(err)
   200  		Expect(code).To(BeNumerically("==", http.StatusNotFound))
   201  
   202  		// Stop an invalid pod
   203  		_, err = pods.Stop(bt.conn, "dummyName", nil)
   204  		Expect(err).ToNot(BeNil())
   205  		code, _ = bindings.CheckResponseCode(err)
   206  		Expect(code).To(BeNumerically("==", http.StatusNotFound))
   207  
   208  		// Restart an invalid pod
   209  		_, err = pods.Restart(bt.conn, "dummyName")
   210  		Expect(err).ToNot(BeNil())
   211  		code, _ = bindings.CheckResponseCode(err)
   212  		Expect(code).To(BeNumerically("==", http.StatusNotFound))
   213  
   214  		// Start a valid pod and inspect status of each container
   215  		_, err = pods.Start(bt.conn, newpod)
   216  		Expect(err).To(BeNil())
   217  
   218  		response, err := pods.Inspect(bt.conn, newpod)
   219  		Expect(err).To(BeNil())
   220  		Expect(response.State.Status).To(Equal(define.PodStateRunning))
   221  		for _, i := range response.Containers {
   222  			Expect(define.StringToContainerStatus(i.State)).
   223  				To(Equal(define.ContainerStateRunning))
   224  		}
   225  
   226  		// Start an already running  pod
   227  		_, err = pods.Start(bt.conn, newpod)
   228  		Expect(err).To(BeNil())
   229  
   230  		// Stop the running pods
   231  		_, err = pods.Stop(bt.conn, newpod, nil)
   232  		Expect(err).To(BeNil())
   233  		response, _ = pods.Inspect(bt.conn, newpod)
   234  		Expect(response.State.Status).To(Equal(define.PodStateExited))
   235  		for _, i := range response.Containers {
   236  			Expect(define.StringToContainerStatus(i.State)).
   237  				To(Equal(define.ContainerStateStopped))
   238  		}
   239  
   240  		// Stop an already stopped pod
   241  		_, err = pods.Stop(bt.conn, newpod, nil)
   242  		Expect(err).To(BeNil())
   243  
   244  		_, err = pods.Restart(bt.conn, newpod)
   245  		Expect(err).To(BeNil())
   246  		response, _ = pods.Inspect(bt.conn, newpod)
   247  		Expect(response.State.Status).To(Equal(define.PodStateRunning))
   248  		for _, i := range response.Containers {
   249  			Expect(define.StringToContainerStatus(i.State)).
   250  				To(Equal(define.ContainerStateRunning))
   251  		}
   252  	})
   253  
   254  	// Test to validate all the pods in the stopped/exited state are pruned successfully.
   255  	It("prune pod", func() {
   256  		// Add a new pod
   257  		var newpod2 string = "newpod2"
   258  		bt.Podcreate(&newpod2)
   259  		// No pods pruned since no pod in exited state
   260  		err = pods.Prune(bt.conn)
   261  		Expect(err).To(BeNil())
   262  		podSummary, err := pods.List(bt.conn, nil)
   263  		Expect(err).To(BeNil())
   264  		Expect(len(podSummary)).To(Equal(2))
   265  
   266  		// Prune only one pod which is in exited state.
   267  		// Start then stop a pod.
   268  		// pod moves to exited state one pod should be pruned now.
   269  		_, err = pods.Start(bt.conn, newpod)
   270  		Expect(err).To(BeNil())
   271  		_, err = pods.Stop(bt.conn, newpod, nil)
   272  		Expect(err).To(BeNil())
   273  		response, err := pods.Inspect(bt.conn, newpod)
   274  		Expect(err).To(BeNil())
   275  		Expect(response.State.Status).To(Equal(define.PodStateExited))
   276  		err = pods.Prune(bt.conn)
   277  		Expect(err).To(BeNil())
   278  		podSummary, err = pods.List(bt.conn, nil)
   279  		Expect(err).To(BeNil())
   280  		Expect(len(podSummary)).To(Equal(1))
   281  
   282  		// Test prune all pods in exited state.
   283  		bt.Podcreate(&newpod)
   284  		_, err = pods.Start(bt.conn, newpod)
   285  		Expect(err).To(BeNil())
   286  		_, err = pods.Start(bt.conn, newpod2)
   287  		Expect(err).To(BeNil())
   288  		_, err = pods.Stop(bt.conn, newpod, nil)
   289  		Expect(err).To(BeNil())
   290  		response, err = pods.Inspect(bt.conn, newpod)
   291  		Expect(err).To(BeNil())
   292  		Expect(response.State.Status).To(Equal(define.PodStateExited))
   293  		for _, i := range response.Containers {
   294  			Expect(define.StringToContainerStatus(i.State)).
   295  				To(Equal(define.ContainerStateStopped))
   296  		}
   297  		_, err = pods.Stop(bt.conn, newpod2, nil)
   298  		Expect(err).To(BeNil())
   299  		response, err = pods.Inspect(bt.conn, newpod2)
   300  		Expect(err).To(BeNil())
   301  		Expect(response.State.Status).To(Equal(define.PodStateExited))
   302  		for _, i := range response.Containers {
   303  			Expect(define.StringToContainerStatus(i.State)).
   304  				To(Equal(define.ContainerStateStopped))
   305  		}
   306  		err = pods.Prune(bt.conn)
   307  		Expect(err).To(BeNil())
   308  		podSummary, err = pods.List(bt.conn, nil)
   309  		Expect(err).To(BeNil())
   310  		Expect(len(podSummary)).To(Equal(0))
   311  	})
   312  
   313  	It("simple create pod", func() {
   314  		ps := specgen.PodSpecGenerator{}
   315  		ps.Name = "foobar"
   316  		_, err := pods.CreatePodFromSpec(bt.conn, &ps)
   317  		Expect(err).To(BeNil())
   318  
   319  		exists, err := pods.Exists(bt.conn, "foobar")
   320  		Expect(err).To(BeNil())
   321  		Expect(exists).To(BeTrue())
   322  	})
   323  
   324  	// Test validates the pod top bindings
   325  	It("pod top", func() {
   326  		var name string = "podA"
   327  
   328  		bt.Podcreate(&name)
   329  		_, err := pods.Start(bt.conn, name)
   330  		Expect(err).To(BeNil())
   331  
   332  		// By name
   333  		_, err = pods.Top(bt.conn, name, nil)
   334  		Expect(err).To(BeNil())
   335  
   336  		// With descriptors
   337  		output, err := pods.Top(bt.conn, name, []string{"user,pid,hpid"})
   338  		Expect(err).To(BeNil())
   339  		header := strings.Split(output[0], "\t")
   340  		for _, d := range []string{"USER", "PID", "HPID"} {
   341  			Expect(d).To(BeElementOf(header))
   342  		}
   343  
   344  		// With bogus ID
   345  		_, err = pods.Top(bt.conn, "IdoNotExist", nil)
   346  		Expect(err).ToNot(BeNil())
   347  
   348  		// With bogus descriptors
   349  		_, err = pods.Top(bt.conn, name, []string{"Me,Neither"})
   350  		Expect(err).ToNot(BeNil())
   351  	})
   352  })