diff options
author | Brent Baude <bbaude@redhat.com> | 2020-02-23 11:00:09 -0600 |
---|---|---|
committer | Brent Baude <bbaude@redhat.com> | 2020-02-27 13:11:42 -0600 |
commit | 306b44380fec7a6653baf8fa8e2929a8f0115659 (patch) | |
tree | 8affebec363f9a6a25cfbbfd6d6f58b133bd92f7 /pkg/bindings | |
parent | 3d1af087e6beba5ac31e2c6758fd5696d6d7883f (diff) | |
download | podman-306b44380fec7a6653baf8fa8e2929a8f0115659.tar.gz podman-306b44380fec7a6653baf8fa8e2929a8f0115659.tar.bz2 podman-306b44380fec7a6653baf8fa8e2929a8f0115659.zip |
binding tests for volumes
add binding tests for volumes: inspect(get), create, remove, prune, and list
implement filters ability for volumes
Signed-off-by: Brent Baude <bbaude@redhat.com>
Diffstat (limited to 'pkg/bindings')
-rw-r--r-- | pkg/bindings/containers/create.go | 2 | ||||
-rw-r--r-- | pkg/bindings/test/volumes_test.go | 174 | ||||
-rw-r--r-- | pkg/bindings/volumes/volumes.go | 52 |
3 files changed, 213 insertions, 15 deletions
diff --git a/pkg/bindings/containers/create.go b/pkg/bindings/containers/create.go index 2943cb522..43a3ef02d 100644 --- a/pkg/bindings/containers/create.go +++ b/pkg/bindings/containers/create.go @@ -19,7 +19,7 @@ func CreateWithSpec(ctx context.Context, s specgen.SpecGenerator) (utils.Contain } specgenString, err := jsoniter.MarshalToString(s) if err != nil { - return ccr, nil + return ccr, err } stringReader := strings.NewReader(specgenString) response, err := conn.DoRequest(stringReader, http.MethodPost, "/containers/create", nil) diff --git a/pkg/bindings/test/volumes_test.go b/pkg/bindings/test/volumes_test.go new file mode 100644 index 000000000..c8940d46e --- /dev/null +++ b/pkg/bindings/test/volumes_test.go @@ -0,0 +1,174 @@ +package test_bindings + +import ( + "context" + "fmt" + "github.com/containers/libpod/pkg/api/handlers" + "github.com/containers/libpod/pkg/bindings/containers" + "github.com/containers/libpod/pkg/bindings/volumes" + "net/http" + "time" + + "github.com/containers/libpod/pkg/bindings" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + "github.com/onsi/gomega/gexec" +) + +var _ = Describe("Podman volumes", func() { + var ( + //tempdir string + //err error + //podmanTest *PodmanTestIntegration + bt *bindingTest + s *gexec.Session + connText context.Context + err error + trueFlag = true + ) + + BeforeEach(func() { + //tempdir, err = CreateTempDirInTempDir() + //if err != nil { + // os.Exit(1) + //} + //podmanTest = PodmanTestCreate(tempdir) + //podmanTest.Setup() + //podmanTest.SeedImages() + bt = newBindingTest() + bt.RestoreImagesFromCache() + s = bt.startAPIService() + time.Sleep(1 * time.Second) + connText, err = bindings.NewConnection(context.Background(), bt.sock) + Expect(err).To(BeNil()) + }) + + AfterEach(func() { + //podmanTest.Cleanup() + //f := CurrentGinkgoTestDescription() + //processTestResult(f) + s.Kill() + bt.cleanup() + }) + + It("create volume", func() { + // create a volume with blank config should work + _, err := volumes.Create(connText, handlers.VolumeCreateConfig{}) + Expect(err).To(BeNil()) + + vcc := handlers.VolumeCreateConfig{ + Name: "foobar", + Label: nil, + Opts: nil, + } + vol, err := volumes.Create(connText, vcc) + Expect(err).To(BeNil()) + Expect(vol.Name).To(Equal("foobar")) + + // create volume with same name should 500 + _, err = volumes.Create(connText, vcc) + Expect(err).ToNot(BeNil()) + code, _ := bindings.CheckResponseCode(err) + Expect(code).To(BeNumerically("==", http.StatusInternalServerError)) + }) + + It("inspect volume", func() { + vol, err := volumes.Create(connText, handlers.VolumeCreateConfig{}) + Expect(err).To(BeNil()) + data, err := volumes.Inspect(connText, vol.Name) + Expect(err).To(BeNil()) + Expect(data.Name).To(Equal(vol.Name)) + }) + + It("remove volume", func() { + // removing a bogus volume should result in 404 + err := volumes.Remove(connText, "foobar", nil) + code, _ := bindings.CheckResponseCode(err) + Expect(code).To(BeNumerically("==", http.StatusNotFound)) + + // Removing an unused volume should work + vol, err := volumes.Create(connText, handlers.VolumeCreateConfig{}) + Expect(err).To(BeNil()) + err = volumes.Remove(connText, vol.Name, nil) + Expect(err).To(BeNil()) + + // Removing a volume that is being used without force should be 409 + vol, err = volumes.Create(connText, handlers.VolumeCreateConfig{}) + Expect(err).To(BeNil()) + session := bt.runPodman([]string{"run", "-dt", "-v", fmt.Sprintf("%s:/foobar", vol.Name), "--name", "vtest", alpine.name, "top"}) + session.Wait(45) + err = volumes.Remove(connText, vol.Name, nil) + Expect(err).ToNot(BeNil()) + code, _ = bindings.CheckResponseCode(err) + Expect(code).To(BeNumerically("==", http.StatusConflict)) + + // Removing with a volume in use with force should work with a stopped container + zero := 0 + err = containers.Stop(connText, "vtest", &zero) + Expect(err).To(BeNil()) + err = volumes.Remove(connText, vol.Name, &trueFlag) + Expect(err).To(BeNil()) + }) + + It("list volumes", func() { + // no volumes should be ok + vols, err := volumes.List(connText, nil) + Expect(err).To(BeNil()) + Expect(len(vols)).To(BeZero()) + + // create a bunch of named volumes and make verify with list + volNames := []string{"homer", "bart", "lisa", "maggie", "marge"} + for i := 0; i < 5; i++ { + _, err = volumes.Create(connText, handlers.VolumeCreateConfig{Name: volNames[i]}) + Expect(err).To(BeNil()) + } + vols, err = volumes.List(connText, nil) + Expect(err).To(BeNil()) + Expect(len(vols)).To(BeNumerically("==", 5)) + for _, v := range vols { + Expect(StringInSlice(v.Name, volNames)).To(BeTrue()) + } + + // list with bad filter should be 500 + filters := make(map[string][]string) + filters["foobar"] = []string{"1234"} + _, err = volumes.List(connText, filters) + Expect(err).ToNot(BeNil()) + code, _ := bindings.CheckResponseCode(err) + Expect(code).To(BeNumerically("==", http.StatusInternalServerError)) + + filters = make(map[string][]string) + filters["name"] = []string{"homer"} + vols, err = volumes.List(connText, filters) + Expect(err).To(BeNil()) + Expect(len(vols)).To(BeNumerically("==", 1)) + Expect(vols[0].Name).To(Equal("homer")) + }) + + // TODO we need to add filtering to tests + It("prune unused volume", func() { + // Pruning when no volumes present should be ok + _, err := volumes.Prune(connText) + Expect(err).To(BeNil()) + + // Removing an unused volume should work + _, err = volumes.Create(connText, handlers.VolumeCreateConfig{}) + Expect(err).To(BeNil()) + vols, err := volumes.Prune(connText) + Expect(err).To(BeNil()) + Expect(len(vols)).To(BeNumerically("==", 1)) + + _, err = volumes.Create(connText, handlers.VolumeCreateConfig{Name: "homer"}) + Expect(err).To(BeNil()) + _, err = volumes.Create(connText, handlers.VolumeCreateConfig{}) + Expect(err).To(BeNil()) + session := bt.runPodman([]string{"run", "-dt", "-v", fmt.Sprintf("%s:/homer", "homer"), "--name", "vtest", alpine.name, "top"}) + session.Wait(45) + vols, err = volumes.Prune(connText) + Expect(err).To(BeNil()) + Expect(len(vols)).To(BeNumerically("==", 1)) + _, err = volumes.Inspect(connText, "homer") + Expect(err).To(BeNil()) + }) + +}) diff --git a/pkg/bindings/volumes/volumes.go b/pkg/bindings/volumes/volumes.go index 7f6a9cc9b..0bc818605 100644 --- a/pkg/bindings/volumes/volumes.go +++ b/pkg/bindings/volumes/volumes.go @@ -5,27 +5,33 @@ import ( "net/http" "net/url" "strconv" + "strings" "github.com/containers/libpod/libpod" "github.com/containers/libpod/pkg/api/handlers" "github.com/containers/libpod/pkg/bindings" + jsoniter "github.com/json-iterator/go" ) // Create creates a volume given its configuration. -func Create(ctx context.Context, config handlers.VolumeCreateConfig) (string, error) { - // TODO This is incomplete. The config needs to be sent via the body +func Create(ctx context.Context, config handlers.VolumeCreateConfig) (*libpod.VolumeConfig, error) { var ( - volumeID string + v libpod.VolumeConfig ) conn, err := bindings.GetClient(ctx) if err != nil { - return "", err + return nil, err + } + createString, err := jsoniter.MarshalToString(config) + if err != nil { + return nil, err } - response, err := conn.DoRequest(nil, http.MethodPost, "/volumes/create", nil) + stringReader := strings.NewReader(createString) + response, err := conn.DoRequest(stringReader, http.MethodPost, "/volumes/create", nil) if err != nil { - return volumeID, err + return nil, err } - return volumeID, response.Process(&volumeID) + return &v, response.Process(&v) } // Inspect returns low-level information about a volume. @@ -37,18 +43,36 @@ func Inspect(ctx context.Context, nameOrID string) (*libpod.InspectVolumeData, e if err != nil { return nil, err } - response, err := conn.DoRequest(nil, http.MethodPost, "/volumes/%s/json", nil, nameOrID) + response, err := conn.DoRequest(nil, http.MethodGet, "/volumes/%s/json", nil, nameOrID) if err != nil { return &inspect, err } return &inspect, response.Process(&inspect) } -func List() error { - // TODO - // The API side of things for this one does a lot in main and therefore - // is not implemented yet. - return bindings.ErrNotImplemented // nolint:typecheck +// List returns the configurations for existing volumes in the form of a slice. Optionally, filters +// can be used to refine the list of volumes. +func List(ctx context.Context, filters map[string][]string) ([]*libpod.VolumeConfig, error) { + var ( + vols []*libpod.VolumeConfig + ) + conn, err := bindings.GetClient(ctx) + if err != nil { + return nil, err + } + params := url.Values{} + if len(filters) > 0 { + strFilters, err := bindings.FiltersToString(filters) + if err != nil { + return nil, err + } + params.Set("filters", strFilters) + } + response, err := conn.DoRequest(nil, http.MethodGet, "/volumes/json", params) + if err != nil { + return vols, err + } + return vols, response.Process(&vols) } // Prune removes unused volumes from the local filesystem. @@ -78,7 +102,7 @@ func Remove(ctx context.Context, nameOrID string, force *bool) error { if force != nil { params.Set("force", strconv.FormatBool(*force)) } - response, err := conn.DoRequest(nil, http.MethodPost, "/volumes/%s/prune", params, nameOrID) + response, err := conn.DoRequest(nil, http.MethodDelete, "/volumes/%s", params, nameOrID) if err != nil { return err } |