diff --git a/fs.go b/fs.go index 43421bb..fba250f 100644 --- a/fs.go +++ b/fs.go @@ -145,6 +145,22 @@ func (s *System) RestoreFileSystemFromSnapshot(restoreSnapParam *types.RestoreFs return nil, nil } +// GetFsSnapshotsByVolumeID gets list of snapshots associated with a filesystem +func (s *System) GetFsSnapshotsByVolumeID(fsID string) ([]types.FileSystem, error) { + defer TimeSpent("GetFsSnapshotsByVolumeID", time.Now()) + var snapshotList []types.FileSystem + fsList, err := s.GetAllFileSystems() + if err != nil { + return nil, err + } + for _, fs := range fsList { + if fs.ParentID == fsID { + snapshotList = append(snapshotList, fs) + } + } + return snapshotList, err +} + // DeleteFileSystem deletes a file system func (s *System) DeleteFileSystem(name string) error { defer TimeSpent("DeleteFileSystem", time.Now()) diff --git a/fs_test.go b/fs_test.go index 8876dad..c6bbc55 100644 --- a/fs_test.go +++ b/fs_test.go @@ -412,6 +412,108 @@ func TestCreateFileSystemSnapshot(t *testing.T) { } } +func TestGetFsSnapshotsByVolumeID(t *testing.T) { + type checkFn func(*testing.T, []types.FileSystem, error) + check := func(fns ...checkFn) []checkFn { return fns } + + hasNoError := func(t *testing.T, resp []types.FileSystem, err error) { + if err != nil { + t.Fatalf("expected no error") + } + } + + hasError := func(t *testing.T, resp []types.FileSystem, err error) { + if err == nil { + t.Fatalf("expected error") + } + } + + checkResp := func(snapLength int) func(t *testing.T, resp []types.FileSystem, err error) { + return func(t *testing.T, resp []types.FileSystem, err error) { + assert.Equal(t, snapLength, len(resp)) + } + } + + tests := map[string]func(t *testing.T) (*httptest.Server, []checkFn){ + "success": func(t *testing.T) (*httptest.Server, []checkFn) { + + href := "/rest/v1/file-systems" + var resp []types.FileSystem + + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodGet { + t.Fatal(fmt.Errorf("wrong method. Expected %s; but got %s", http.MethodGet, r.Method)) + } + + if r.URL.Path != href { + t.Fatal(fmt.Errorf("wrong path. Expected %s; but got %s", href, r.URL.Path)) + } + + resp = []types.FileSystem{ + { + ID: "64366a19-54e8-1544-f3d7-2a50fb1ccff3", + Name: "fs-test-1", + }, + { + ID: "6436aa58-e6a1-a4e2-de7b-2a50fb1ccff3", + Name: "fs-test-2", + }, + } + + respData, err := json.Marshal(resp) + if err != nil { + t.Fatal(err) + } + fmt.Fprintln(w, string(respData)) + + })) + return ts, check(hasNoError, checkResp(len(resp))) + }, + + "operation-failed": func(t *testing.T) (*httptest.Server, []checkFn) { + href := "/rest/v1/file-systems" + + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodGet { + t.Fatal(fmt.Errorf("wrong method. Expected %s; but got %s", http.MethodGet, r.Method)) + } + + if r.URL.Path != href { + t.Fatal(fmt.Errorf("wrong path. Expected %s; but got %s", href, r.URL.Path)) + } + + http.Error(w, "operation failed", http.StatusUnprocessableEntity) + })) + return ts, check(hasError) + }, + } + + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + ts, checkFns := tc(t) + defer ts.Close() + + client, err := NewClientWithArgs(ts.URL, "", math.MaxInt64, true, false) + client.configConnect.Version = "4.0" + if err != nil { + t.Fatal(err) + } + + s := System{ + client: client, + } + + fsID := "64366a19-54e8-1544-f3d7-2a50fb1ccff3" + + resp, err := s.GetFsSnapshotsByVolumeID(fsID) + for _, checkFn := range checkFns { + checkFn(t, resp, err) + } + + }) + } +} + func TestRestoreFileSystemFromSnapshot(t *testing.T) { type checkFn func(*testing.T, *types.RestoreFsSnapResponse, error) check := func(fns ...checkFn) []checkFn { return fns } diff --git a/inttests/fs_test.go b/inttests/fs_test.go index 70f7b73..009f0b3 100644 --- a/inttests/fs_test.go +++ b/inttests/fs_test.go @@ -210,6 +210,69 @@ func TestRestoreFileSystemSnapshot(t *testing.T) { } +func TestGetFsSnapshotsByVolumeID(t *testing.T) { + system := getSystem() + assert.NotNil(t, system) + + fsName := fmt.Sprintf("%s-%s", "FS", testPrefix) + + // get protection domain + pd := getProtectionDomain(t) + assert.NotNil(t, pd) + + // get storage pool + pool := getStoragePool(t) + assert.NotNil(t, pool) + var spID string + if pd != nil && pool != nil { + sp, _ := pd.FindStoragePool(pool.StoragePool.ID, "", "") + assert.NotNil(t, sp) + spID = sp.ID + } + + // get NAS server ID + var nasServerName string + if os.Getenv("GOSCALEIO_NASSERVER") != "" { + nasServerName = os.Getenv("GOSCALEIO_NASSERVER") + } + nasServer, err := system.GetNASByIDName("", nasServerName) + assert.NotNil(t, nasServer) + assert.Nil(t, err) + + fs := &types.FsCreate{ + Name: fsName, + SizeTotal: 16106127360, + StoragePoolID: spID, + NasServerID: nasServer.ID, + } + + // create the file system + filesystem, err := system.CreateFileSystem(fs) + fsID := filesystem.ID + assert.Nil(t, err) + assert.NotNil(t, fsID) + + snapResp, err := system.CreateFileSystemSnapshot(&types.CreateFileSystemSnapshotParam{ + Name: "test-snapshot", + }, fsID) + + assert.NotNil(t, snapResp) + assert.Nil(t, err) + + snap, err := system.GetFileSystemByIDName(snapResp.ID, "") + assert.NotNil(t, snap) + assert.Nil(t, err) + + snapList, err := system.GetFsSnapshotsByVolumeID(fsID) + assert.NotNil(t, snapList) + assert.Nil(t, err) + + err = system.DeleteFileSystem(snap.Name) + assert.Nil(t, err) + err = system.DeleteFileSystem(fs.Name) + assert.Nil(t, err) +} + // TestGetFileSystemByIDName will return specific filesystem by name or ID func TestGetFileSystemByIDName(t *testing.T) {