diff --git a/pkg/api/controllers/attachment.go b/pkg/api/controllers/attachment.go index aa1c15be6..cf0f2902a 100644 --- a/pkg/api/controllers/attachment.go +++ b/pkg/api/controllers/attachment.go @@ -87,22 +87,35 @@ func (v *VolumeAttachmentPortal) CreateVolumeAttachment() { return } - if vol.Status == model.VolumeAvailable { - db.UpdateVolumeStatus(ctx, db.C, vol.Id, model.VolumeAttaching) - } else if vol.Status == model.VolumeInUse { - if vol.MultiAttach { - db.UpdateVolumeStatus(ctx, db.C, vol.Id, model.VolumeAttaching) - } else { - errMsg := "volume is already attached to one of the host. If you want to attach to multiple host, volume multiattach must be true" - v.ErrorHandle(model.ErrorBadRequest, errMsg) - return - } - } else { - errMsg := "status of volume is available. It can be attached to host" + if vol.Status != model.VolumeAvailable { + errMsg := fmt.Sprintf("volume:%s status:%s should be available when mapping volume.", vol.Name, vol.Status) + v.ErrorHandle(model.ErrorBadRequest, errMsg) + return + } + + if (vol.Attached != nil && *vol.Attached) && !vol.MultiAttach { + errMsg := fmt.Sprintf("volume:%s is already attached to host:%s. If you want to attach to multiple host, volume multiattach must be true", vol.Name, host.HostName) + v.ErrorHandle(model.ErrorBadRequest, errMsg) + return + } + + // Check volume attachment with host id and volume id + attachments, err := db.C.ListVolumeAttachmentsWithFilter(ctx, + map[string][]string{"hostId": []string{attachment.HostId}, + "volumeId": []string{attachment.VolumeId}}) + if err != nil { + errMsg := fmt.Sprintf("check volume attachment failed, host:%s, volume:%s, err:%v", host.HostName, vol.Name, err) + v.ErrorHandle(model.ErrorBadRequest, errMsg) + return + } + if len(attachments) > 0 { + errMsg := fmt.Sprintf("cannot attach volume:%s to same host:%s twice", vol.Name, host.HostName) v.ErrorHandle(model.ErrorBadRequest, errMsg) return } + // TODO: should we set volume status with VolumeAttaching?? + // Set AccessProtocol pol, err := db.C.GetPool(ctx, vol.PoolId) if err != nil { @@ -146,14 +159,6 @@ func (v *VolumeAttachmentPortal) CreateVolumeAttachment() { } defer v.CtrClient.Close() - // // Note: In some protocols, there is no related initiator - // var initiatorPort = "" - // for _, e := range host.Initiators { - // if e.Protocol == protocol { - // initiatorPort = e.PortName - // break - // } - // } var initiators []*pb.Initiator for _, e := range host.Initiators { initiator := pb.Initiator{ @@ -291,16 +296,10 @@ func (v *VolumeAttachmentPortal) DeleteVolumeAttachment() { return } - // If volume id is invalid, it would mean that volume attachment creation failed before the create method - // in storage driver was called, and delete its db entry directly. vol, err := db.C.GetVolume(ctx, attachment.VolumeId) if err != nil { - if err := db.C.DeleteVolumeAttachment(ctx, attachment.Id); err != nil { - errMsg := fmt.Sprintf("failed to delete volume attachment: %s", err.Error()) - v.ErrorHandle(model.ErrorBadRequest, errMsg) - return - } - v.SuccessHandle(StatusAccepted, nil) + errMsg := fmt.Sprintf("get volume failed in delete volume attachment method: %v", err) + v.ErrorHandle(model.ErrorBadRequest, errMsg) return } diff --git a/pkg/api/controllers/volume.go b/pkg/api/controllers/volume.go index de39c1857..3e044086a 100755 --- a/pkg/api/controllers/volume.go +++ b/pkg/api/controllers/volume.go @@ -239,6 +239,36 @@ func (v *VolumePortal) ExtendVolume() { return } + if volume.Status != model.VolumeAvailable && volume.Status != model.VolumeErrorExtending { + errMsg := "the status of the volume to be extended must be available or error extending!" + v.ErrorHandle(model.ErrorBadRequest, errMsg) + return + } + + if extendRequestBody.NewSize <= volume.Size { + errMsg := fmt.Sprintf("new size for extend must be greater than current size."+ + "(current: %d GB, extended: %d GB).", volume.Size, extendRequestBody.NewSize) + v.ErrorHandle(model.ErrorBadRequest, errMsg) + return + } + + pool, err := db.C.GetPool(ctx, volume.PoolId) + if err != nil { + errMsg := fmt.Sprintf("pool %s not found: %s", id, err.Error()) + v.ErrorHandle(model.ErrorNotFound, errMsg) + return + } + if pool.FreeCapacity < extendRequestBody.NewSize-volume.Size { + errMsg := fmt.Sprintf("pool:%s capacity:%v is not enough", pool.Name, pool.FreeCapacity) + v.ErrorHandle(model.ErrorBadRequest, errMsg) + return + } + if pool.Status != model.PoolAvailable { + errMsg := fmt.Sprintf("pool:%s with status:%s can not support extending volume", pool.Name, pool.Status) + v.ErrorHandle(model.ErrorBadRequest, errMsg) + return + } + prf, err := db.C.GetProfile(ctx, volume.ProfileId) if err != nil { errMsg := fmt.Sprintf("extend volume failed: %v", err.Error()) @@ -248,7 +278,8 @@ func (v *VolumePortal) ExtendVolume() { // NOTE:It will update the the status of the volume waiting for expansion in // the database to "extending" and return the result immediately. - result, err := util.ExtendVolumeDBEntry(ctx, id, &extendRequestBody) + volume.Status = model.VolumeExtending + result, err := db.C.ExtendVolume(ctx, volume) if err != nil { errMsg := fmt.Sprintf("extend volume failed: %s", err.Error()) v.ErrorHandle(model.ErrorBadRequest, errMsg) @@ -271,6 +302,8 @@ func (v *VolumePortal) ExtendVolume() { opt := &pb.ExtendVolumeOpts{ Id: id, Size: extendRequestBody.NewSize, + PoolId: pool.Id, + PoolName: pool.Name, Metadata: result.Metadata, Context: ctx.ToJson(), Profile: prf.ToJson(), diff --git a/pkg/api/controllers/volume_test.go b/pkg/api/controllers/volume_test.go index 5481a1ded..bd71862dd 100755 --- a/pkg/api/controllers/volume_test.go +++ b/pkg/api/controllers/volume_test.go @@ -256,6 +256,7 @@ func TestExtendVolume(t *testing.T) { mockClient.On("GetVolume", c.NewAdminContext(), "bd5b12a8-a101-11e7-941e-d77981b584d8").Return(&SampleVolumes[0], nil) mockClient.On("ExtendVolume", c.NewAdminContext(), &expected).Return(&expected, nil) mockClient.On("GetProfile", c.NewAdminContext(), SampleReplications[0].ProfileId).Return(&SampleProfiles[0], nil) + mockClient.On("GetPool", c.NewAdminContext(), SampleVolumes[0].PoolId).Return(&SamplePools[0], nil) db.C = mockClient r, _ := http.NewRequest("POST", "/v1beta/block/volumes/bd5b12a8-a101-11e7-941e-d77981b584d8/resize", bytes.NewBuffer(jsonStr)) diff --git a/pkg/api/util/db.go b/pkg/api/util/db.go index ead9cb66c..91b33f5c2 100644 --- a/pkg/api/util/db.go +++ b/pkg/api/util/db.go @@ -446,8 +446,8 @@ func CreateVolumeSnapshotDBEntry(ctx *c.Context, in *model.VolumeSnapshotSpec) ( log.Error("get volume failed in create volume snapshot method: ", err) return nil, err } - if vol.Status != model.VolumeAvailable && vol.Status != model.VolumeInUse { - errMsg := "only the status of volume is available or in-use, the snapshot can be created" + if vol.Status != model.VolumeAvailable { + errMsg := "only the status of volume is available, the snapshot can be created" log.Error(errMsg) return nil, errors.New(errMsg) } @@ -504,8 +504,8 @@ func CreateReplicationDBEntry(ctx *c.Context, in *model.ReplicationSpec) (*model log.Error("get primary volume failed in create volume replication method: ", err) return nil, err } - if pVol.Status != model.VolumeAvailable && pVol.Status != model.VolumeInUse { - var errMsg = fmt.Errorf("only the status of primary volume is available or in-use, the replicaiton can be created") + if pVol.Status != model.VolumeAvailable { + var errMsg = fmt.Errorf("only the status of primary volume is available, the replicaiton can be created") log.Error(errMsg) return nil, errMsg } @@ -514,8 +514,8 @@ func CreateReplicationDBEntry(ctx *c.Context, in *model.ReplicationSpec) (*model log.Error("get secondary volume failed in create volume replication method: ", err) return nil, err } - if sVol.Status != model.VolumeAvailable && sVol.Status != model.VolumeInUse { - var errMsg = fmt.Errorf("only the status of secondary volume is available or in-use, the replicaiton can be created") + if sVol.Status != model.VolumeAvailable { + var errMsg = fmt.Errorf("only the status of secondary volume is available, the replicaiton can be created") log.Error(errMsg) return nil, errMsg } @@ -800,7 +800,7 @@ func ValidateAddVolumes(ctx *c.Context, volumes []*model.VolumeSpec, addVolumes if !utils.Contained(addVolRef.ProfileId, vg.Profiles) { return nil, fmt.Errorf("cannot add volume %s to group %s , volume profile is not supported by the group.", addVolRef.Id, vg.Id) } - if addVolRef.Status != model.VolumeAvailable && addVolRef.Status != model.VolumeInUse { + if addVolRef.Status != model.VolumeAvailable { return nil, fmt.Errorf("cannot add volume %s to group %s because volume is in invalid status %s", addVolRef.Id, vg.Id, addVolRef.Status) } if addVolRef.PoolId != vg.PoolId { @@ -818,7 +818,7 @@ func ValidateRemoveVolumes(ctx *c.Context, volumes []*model.VolumeSpec, removeVo for _, v := range removeVolumes { for _, volume := range volumes { if v == volume.Id { - if volume.Status != model.VolumeAvailable && volume.Status != model.VolumeInUse && volume.Status != model.VolumeError && volume.Status != model.VolumeErrorDeleting { + if volume.Status != model.VolumeAvailable && volume.Status != model.VolumeError && volume.Status != model.VolumeErrorDeleting { return nil, fmt.Errorf("cannot remove volume %s from group %s, volume is in invalid status %s", volume.Id, vg.Id, volume.Status) } break @@ -890,7 +890,7 @@ func DeleteVolumeGroupDBEntry(ctx *c.Context, volumeGroupId string) error { var volumesUpdate []*model.VolumeSpec for _, value := range volumes { - if value.AttachStatus == model.VolumeAttached { + if *value.Attached { msg := fmt.Sprintf("volume %s in group %s is attached. Need to deach first.", value.Id, vg.Id) log.Error(msg) return errors.New(msg) diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go index 0754781ab..1bfeacc48 100755 --- a/pkg/controller/controller.go +++ b/pkg/controller/controller.go @@ -21,7 +21,6 @@ package controller import ( "context" "encoding/json" - "errors" "fmt" log "github.com/golang/glog" @@ -216,7 +215,7 @@ func (c *Controller) ExtendVolume(contx context.Context, opt *pb.ExtendVolumeOpt log.Info("Controller server receive extend volume request, vr =", opt) ctx := osdsCtx.NewContextFromJson(opt.GetContext()) - vol, err := db.C.GetVolume(ctx, opt.Id) + vol, err := db.C.GetVolume(ctx, opt.GetId()) if err != nil { log.Error("get volume failed in extend volume method: ", err.Error()) return pb.GenericResponseError(err), err @@ -226,33 +225,17 @@ func (c *Controller) ExtendVolume(contx context.Context, opt *pb.ExtendVolumeOpt var rollBack = false defer func() { if rollBack { - db.UpdateVolumeStatus(ctx, db.C, opt.Id, model.VolumeAvailable) + vol.Status = model.VolumeErrorExtending + db.C.UpdateVolume(ctx, vol) } }() - pool, err := db.C.GetPool(ctx, vol.PoolId) - if nil != err { - log.Error("get pool failed in extend volume method: ", err.Error()) - rollBack = true - return pb.GenericResponseError(err), err - } - - var newSize = opt.GetSize() - if pool.FreeCapacity <= (newSize - vol.Size) { - reason := fmt.Sprintf("pool free capacity(%d) < new size(%d) - old size(%d)", - pool.FreeCapacity, newSize, vol.Size) - rollBack = true - return pb.GenericResponseError(reason), errors.New(reason) - } - opt.PoolId = pool.Id - opt.PoolName = pool.Name - prf := model.NewProfileFromJson(opt.Profile) - // Select the storage tag according to the lifecycle flag. + prf := model.NewProfileFromJson(opt.Profile) c.policyController = policy.NewController(prf) c.policyController.Setup(EXTEND_LIFECIRCLE_FLAG) - dockInfo, err := db.C.GetDockByPoolId(ctx, vol.PoolId) + dockInfo, err := db.C.GetDockByPoolId(ctx, opt.PoolId) if err != nil { log.Error("when search dock in db by pool id: ", err.Error()) rollBack = true @@ -263,19 +246,21 @@ func (c *Controller) ExtendVolume(contx context.Context, opt *pb.ExtendVolumeOpt c.volumeController.SetDock(dockInfo) opt.DriverName = dockInfo.DriverName - result, err := c.volumeController.ExtendVolume(opt) - if err != nil { + if _, err := c.volumeController.ExtendVolume(opt); err != nil { log.Error("extend volume failed: ", err.Error()) rollBack = true return pb.GenericResponseError(err), err } // Update the volume data in database. - result.Size = newSize - result.PoolId, result.ProfileId = opt.GetPoolId(), opt.GetProfileId() - db.C.UpdateStatus(ctx, result, model.VolumeAvailable) + vol.Size = opt.GetSize() + vol.Status = model.VolumeAvailable + if _, err := db.C.UpdateVolume(ctx, vol); err != nil { + log.Errorf("failed to update volume size and status: %v", err.Error()) + return pb.GenericResponseError(err), err + } - volBody, _ := json.Marshal(result) + volBody, _ := json.Marshal(vol) var errChan = make(chan error, 1) defer close(errChan) go c.policyController.ExecuteAsyncPolicy(opt, string(volBody), errChan) @@ -285,7 +270,7 @@ func (c *Controller) ExtendVolume(contx context.Context, opt *pb.ExtendVolumeOpt return pb.GenericResponseError(err), err } - return pb.GenericResponseResult(result), nil + return pb.GenericResponseResult(vol), nil } // CreateVolumeAttachment implements pb.ControllerServer.CreateVolumeAttachment @@ -306,7 +291,6 @@ func (c *Controller) CreateVolumeAttachment(contx context.Context, opt *pb.Creat result, err := c.volumeController.CreateVolumeAttachment(opt) if err != nil { db.UpdateVolumeAttachmentStatus(ctx, db.C, opt.Id, model.VolumeAttachError) - db.UpdateVolumeStatus(ctx, db.C, opt.VolumeId, model.VolumeAvailable) msg := fmt.Sprintf("create volume attachment failed: %v", err) log.Error(msg) return pb.GenericResponseError(msg), err @@ -317,14 +301,14 @@ func (c *Controller) CreateVolumeAttachment(contx context.Context, opt *pb.Creat log.Error("get volume failed in CreateVolumeAttachment method: ", err.Error()) return pb.GenericResponseError(err), err } - - if vol.Status == model.VolumeAttaching { - db.UpdateVolumeStatus(ctx, db.C, vol.Id, model.VolumeInUse) - } else { - msg := fmt.Sprintf("wrong volume status when volume attachment creation completed") + vol.Attached = new(bool) + *vol.Attached = true + if _, err := db.C.UpdateVolume(ctx, vol); err != nil { + msg := fmt.Sprintf("failed to set volume:%s attached to true", vol.Name) log.Error(msg) return pb.GenericResponseError(msg), err } + result.AccessProtocol = opt.AccessProtocol result.Status = model.VolumeAttachAvailable @@ -354,7 +338,7 @@ func (c *Controller) DeleteVolumeAttachment(contx context.Context, opt *pb.Delet if err = c.volumeController.DeleteVolumeAttachment(opt); err != nil { msg := fmt.Sprintf("delete volume attachment failed: %v", err) log.Error(msg) - db.C.DeleteVolumeAttachment(ctx, opt.Id) + db.UpdateVolumeAttachmentStatus(ctx, db.C, opt.Id, model.VolumeAttachErrorDeleting) return pb.GenericResponseError(msg), err } @@ -364,8 +348,28 @@ func (c *Controller) DeleteVolumeAttachment(contx context.Context, opt *pb.Delet return pb.GenericResponseError(msg), err } - db.UpdateVolumeStatus(ctx, db.C, opt.VolumeId, model.VolumeAvailable) + // Check and update volume attached status + attachments, err := db.C.ListVolumeAttachmentsWithFilter(ctx, map[string][]string{"volumeId": []string{opt.VolumeId}}) + if err != nil { + msg := fmt.Sprintf("list volume attachment failed in controller.DeleteAttachment: %v", err) + log.Error(msg) + return pb.GenericResponseError(msg), err + } + if len(attachments) == 0 { + vol, err := db.C.GetVolume(ctx, opt.VolumeId) + if err != nil { + msg := fmt.Sprintf("get volume failed in controller.DeleteAttachment: %v", err) + log.Error(msg) + return pb.GenericResponseError(msg), err + } + vol.Attached = new(bool) + if _, err := db.C.UpdateVolume(ctx, vol); err != nil { + msg := fmt.Sprintf("set volume attached to false failed in controller.DeleteAttachment: %v", err) + log.Error(msg) + return pb.GenericResponseError(msg), err + } + } return pb.GenericResponseResult(nil), nil } diff --git a/pkg/controller/controller_test.go b/pkg/controller/controller_test.go index 9be5013d4..24c03f12f 100755 --- a/pkg/controller/controller_test.go +++ b/pkg/controller/controller_test.go @@ -271,54 +271,6 @@ func TestDeleteVolume(t *testing.T) { } } -func TestExtendVolume(t *testing.T) { - var req = &pb.ExtendVolumeOpts{ - Id: "bd5b12a8-a101-11e7-941e-d77981b584d8", - PoolId: "084bf71e-a102-11e7-88a8-e31fe6d52248", - ProfileId: "1106b972-66ef-11e7-b172-db03f3689c9c", - Size: int64(1), - Context: c.NewAdminContext().ToJson(), - } - var vol2 = &SampleVolumes[0] - mockClient := new(dbtest.Client) - mockClient.On("GetVolume", c.NewAdminContext(), req.Id).Return(vol2, nil) - mockClient.On("GetPool", c.NewAdminContext(), req.PoolId).Return(&SamplePools[0], nil) - mockClient.On("GetDefaultProfile", c.NewAdminContext()).Return(&SampleProfiles[0], nil) - mockClient.On("GetProfile", c.NewAdminContext(), req.ProfileId).Return(&SampleProfiles[0], nil) - mockClient.On("GetDockByPoolId", c.NewAdminContext(), req.PoolId).Return(&SampleDocks[0], nil) - mockClient.On("UpdateStatus", c.NewAdminContext(), vol2, vol2.Status).Return(nil) - db.C = mockClient - - var ctrl = &Controller{ - selector: &fakeSelector{ - res: &model.StoragePoolSpec{ - BaseModel: &model.BaseModel{ - Id: "084bf71e-a102-11e7-88a8-e31fe6d52248", - }, - DockId: "b7602e18-771e-11e7-8f38-dbd6d291f4e0", - }, - err: nil, - }, - volumeController: NewFakeVolumeController(), - } - - req.Size = int64(92) - _, err := ctrl.ExtendVolume(context.Background(), req) - expectedError := "pool free capacity(90) < new size(92) - old size(1)" - if err == nil { - t.Errorf("Expected Non-%v, got %v\n", nil, err) - } else { - if expectedError != err.Error() { - t.Errorf("Expected Non-%v, got %v\n", expectedError, err.Error()) - } - } - - req.Size = int64(2) - if _, err = ctrl.ExtendVolume(context.Background(), req); err != nil { - t.Errorf("Failed to extend volume: %v\n", err) - } -} - func TestCreateVolumeAttachment(t *testing.T) { var req = &pb.CreateVolumeAttachmentOpts{ Id: "f2dda3d2-bf79-11e7-8665-f750b088f63e", @@ -333,7 +285,8 @@ func TestCreateVolumeAttachment(t *testing.T) { mockClient.On("GetPool", c.NewAdminContext(), vol.PoolId).Return(&SamplePools[0], nil) mockClient.On("GetDockByPoolId", c.NewAdminContext(), "084bf71e-a102-11e7-88a8-e31fe6d52248").Return(&SampleDocks[0], nil) mockClient.On("UpdateStatus", c.NewAdminContext(), volatm, volatm.Status).Return(nil) - mockClient.On("UpdateStatus", c.NewAdminContext(), vol, model.VolumeInUse).Return(nil) + mockClient.On("UpdateVolumeAttachment", c.NewAdminContext(), volatm.Id, volatm).Return(volatm, nil) + mockClient.On("UpdateVolume", c.NewAdminContext(), vol).Return(vol, nil) db.C = mockClient @@ -357,6 +310,7 @@ func TestDeleteVolumeAttachment(t *testing.T) { var vol = &SampleVolumes[0] mockClient := new(dbtest.Client) mockClient.On("GetVolume", c.NewAdminContext(), req.VolumeId).Return(vol, nil) + mockClient.On("ListVolumeAttachmentsWithFilter", c.NewAdminContext(), map[string][]string{"volumeId": []string{req.VolumeId}}).Return([]*model.VolumeAttachmentSpec{&model.VolumeAttachmentSpec{}}, nil) mockClient.On("GetDockByPoolId", c.NewAdminContext(), vol.PoolId).Return(&SampleDocks[0], nil) mockClient.On("DeleteVolumeAttachment", c.NewAdminContext(), req.Id).Return(nil) mockClient.On("UpdateStatus", c.NewAdminContext(), vol, model.VolumeAvailable).Return(nil) diff --git a/pkg/db/drivers/etcd/etcd.go b/pkg/db/drivers/etcd/etcd.go index bb4ab52cc..17053d03f 100644 --- a/pkg/db/drivers/etcd/etcd.go +++ b/pkg/db/drivers/etcd/etcd.go @@ -1426,6 +1426,8 @@ func (c *Client) CreateVolume(ctx *c.Context, vol *model.VolumeSpec) (*model.Vol } vol.TenantId = ctx.TenantId + // Set attached as false when creating volume + vol.Attached = new(bool) volBody, err := json.Marshal(vol) if err != nil { return nil, err @@ -1684,6 +1686,10 @@ func (c *Client) UpdateVolume(ctx *c.Context, vol *model.VolumeSpec) (*model.Vol result.GroupId = vol.GroupId } + if vol.Attached != nil { + result.Attached = vol.Attached + } + // Set update time result.UpdatedAt = time.Now().Format(constants.TimeFormat) diff --git a/pkg/model/status.go b/pkg/model/status.go index b71a72718..6f6390949 100644 --- a/pkg/model/status.go +++ b/pkg/model/status.go @@ -14,6 +14,12 @@ package model +// Storage pool status +const ( + PoolAvailable = "available" + PoolUnAvailable = "unavailable" +) + // fileshare status const ( FileShareCreating = "creating" @@ -46,7 +52,6 @@ const ( const ( VolumeCreating = "creating" VolumeAvailable = "available" - VolumeInUse = "inUse" VolumeDeleting = "deleting" VolumeError = "error" VolumeErrorDeleting = "errorDeleting" @@ -54,16 +59,6 @@ const ( VolumeExtending = "extending" ) -// volume attach status -const ( - VolumeAttaching = "attaching" - VolumeAttached = "attached" - VolumeDetached = "detached" - VolumeReserved = "reserved" - VolumeErrorAttaching = "errorAttaching" - VolumeErrorDetaching = "errorDetaching" -) - // volume snapshot status const ( VolumeSnapCreating = "creating" diff --git a/pkg/model/volume.go b/pkg/model/volume.go index e2488ecd4..7b22f156b 100755 --- a/pkg/model/volume.go +++ b/pkg/model/volume.go @@ -76,7 +76,7 @@ type VolumeSpec struct { // The uuid of the replication which the volume belongs to. ReplicationDriverData map[string]string `json:"replicationDriverData,omitempty"` // Attach status of the volume. - AttachStatus string + Attached *bool `json:"attached,omitempty"` // Whether the volume can be attached more than once, default value is false. MultiAttach bool `json:"multiAttach,omitempty"` diff --git a/test/integration/client_test.go b/test/integration/client_test.go index e7a840f92..5da64a7c9 100755 --- a/test/integration/client_test.go +++ b/test/integration/client_test.go @@ -293,7 +293,7 @@ func TestClientExtendVolume(t *testing.T) { func TestClientCreateVolumeAttachment(t *testing.T) { var body = &model.VolumeAttachmentSpec{ VolumeId: "bd5b12a8-a101-11e7-941e-d77981b584d8", - HostId: "202964b5-8e73-46fd-b41b-a8e403f3c30b", + HostId: "eb73e59a-8b0f-4517-8b95-023ec134aec9", } if _, err := c.CreateVolumeAttachment(body); err != nil { diff --git a/testutils/collection/data.go b/testutils/collection/data.go index 147377827..bd51369db 100644 --- a/testutils/collection/data.go +++ b/testutils/collection/data.go @@ -163,6 +163,7 @@ var ( }, Name: "sample-pool-01", Description: "This is the first sample storage pool for testing", + Status: "available", StorageType: "block", TotalCapacity: int64(100), FreeCapacity: int64(90), @@ -195,6 +196,7 @@ var ( }, Name: "sample-pool-02", Description: "This is the second sample storage pool for testing", + Status: "available", StorageType: "block", TotalCapacity: int64(200), FreeCapacity: int64(170), @@ -1172,6 +1174,7 @@ var ( "name": "sample-pool-01", "description": "This is the first sample storage pool for testing", "storageType": "block", + "status": "available", "totalCapacity": 100, "freeCapacity": 90, "dockId": "b7602e18-771e-11e7-8f38-dbd6d291f4e0", diff --git a/testutils/db/fake.go b/testutils/db/fake.go index 2ec7e1bf7..6bfb104c7 100755 --- a/testutils/db/fake.go +++ b/testutils/db/fake.go @@ -431,7 +431,19 @@ func (fc *FakeDbClient) GetVolumeAttachment(ctx *c.Context, attachmentId string) func (fc *FakeDbClient) ListVolumeAttachmentsWithFilter(ctx *c.Context, m map[string][]string) ([]*model.VolumeAttachmentSpec, error) { var atcs []*model.VolumeAttachmentSpec + hostIds := m["hostId"] + volumeIds := m["volumeId"] for i := range SampleAttachments { + if len(hostIds) > 0 { + if hostIds[0] != SampleAttachments[i].HostId { + break + } + } + if len(volumeIds) > 0 { + if volumeIds[0] != SampleAttachments[i].VolumeId { + break + } + } atcs = append(atcs, &SampleAttachments[i]) } return atcs, nil