Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add test for volume snapshot #83

Merged
merged 1 commit into from
Jul 18, 2018
Merged

Conversation

wackxu
Copy link
Contributor

@wackxu wackxu commented Jun 20, 2018

/assign @lpabon

Copy link
Contributor

@darkowlzz darkowlzz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes look good.
Could you also implement snapshots in the mock driver so that we could test the changes and fix any bugs that are not obvious?


It("should fail when no name is provided", func() {

req := &csi.CreateSnapshotRequest{}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be better to add the other attributes here and just exclude name.

BeforeEach(func() {
c = csi.NewControllerClient(conn)

if !isControllerCapabilitySupported(c, csi.ControllerServiceCapability_RPC_LIST_VOLUMES) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be ControllerServiceCapability_RPC_LIST_SNAPSHOTS. Looks like this is causing the test to fail.

@wackxu
Copy link
Contributor Author

wackxu commented Jun 28, 2018

@darkowlzz Thanks for your review, will update it.

@wackxu wackxu force-pushed the addtest branch 3 times, most recently from ff727c2 to a709649 Compare June 28, 2018 14:09
@davidz627
Copy link
Contributor

/cc @jingxu97 @xing-yang

Copy link
Contributor

@darkowlzz darkowlzz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding the mock driver implementation.
I've suggested some improvements.

return nil, status.Error(codes.InvalidArgument, "Not Implemented")
// Check arguments
if len(req.GetName()) == 0 {
return nil, status.Error(codes.InvalidArgument, "Name missing in request")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Snapshot Name cannot be empty"? Maybe it's better to be consistent with CreateVolume error messages.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

return nil, status.Error(codes.InvalidArgument, "Name missing in request")
}
if len(req.GetSourceVolumeId()) == 0 {
return nil, status.Error(codes.InvalidArgument, "SourceVolumeId missing in request")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Snapshot SourceVolumeId cannot be empty"? Maybe it's better to be consistent with CreateVolume error messages.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

// Requested snapshot name already exists
if v.GetSourceVolumeId() == req.SourceVolumeId {
return nil, status.Error(codes.AlreadyExists,
fmt.Sprintf("Snapshot with name %s already exists", req.GetName()))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the snapshot exists with the same source volume ID, I think it should return OK.
And there should be a check for parameters as well.
If the source volume ID and parameters are equal, return OK, else return ALREADY_EXISTS error.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1. If source_volume_id, create_snapshot_secrets, and parameters are the same for the same snapshot name, it should return OK for idempotency.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated for check parameters also, I do not think we should check create_snapshot_secrets that may change every request.

ctx context.Context, name string) (int, csi.Snapshot) {

return s.findSnapshot("name", name)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add a newline at the end.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@@ -48,6 +48,11 @@ func verifyVolumeInfo(v *csi.Volume) {
Expect(v.GetId()).NotTo(BeEmpty())
}

func verifySnapshotInfo(snapshot *csi.Snapshot) {
Expect(snapshot).NotTo(BeNil())
Expect(snapshot.GetId()).NotTo(BeEmpty())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can add some more verification here.

SourceVolumeID is REQUIRED.

Snapshot definition talks about SizeBytes.

The size of the volume MUST NOT be less than the size of the source snapshot.

Let's add those.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated for check attributes that is REQUIRED. As for SizeBytes,

The purpose of this field is to give CO guidance on how much space is needed to
// create a volume from this snapshot. The size of the volume MUST NOT
// be less than the size of the source snapshot.

I think it is used to CO when restore volume from a snapshot to verify there is enough space. So we do not need verify here.

}

// case 2: SourceVolumeId is not empty, return snapshots that match the source volume id.
if len(req.SourceVolumeId) != 0 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would recommend using req.GetSourceVolumeId().

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

},
},
}, nil
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need to consider both req.GetSnapshotId() and req.GetSourceVolumeID when they aren't empty. If the volume received from ID has a different source volume ID, do not include them in the snapshot list.


// case 2: SourceVolumeId is not empty, return snapshots that match the source volume id.
if len(req.SourceVolumeId) != 0 {
i, snapshot := s.findSnapshotNoLock("id", req.SourceVolumeId)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"id" -> "sourceVolumeId"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, done

</provider>
</entry>
</component>
</project>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need this file :)

Copy link
Member

@lpabon lpabon Jul 2, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct, please remove this file.

@@ -271,7 +271,7 @@ func (s *service) ListVolumes(
i int
j = startingToken
entries = make(
[]*csi.ListVolumesResponse_Entry,
[]*csi.ListVolumesResponse_Entry,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looked better before :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@lpabon
Copy link
Member

lpabon commented Jul 2, 2018

Seems that there are two CI errors: Go fmt errors and some failed csi-sanity errors

@wackxu wackxu force-pushed the addtest branch 7 times, most recently from 0888172 to 8ab5016 Compare July 6, 2018 06:53
@wackxu
Copy link
Contributor Author

wackxu commented Jul 6, 2018

@lpabon @darkowlzz updated all comments, PTAL

// themselves have fields that are.
copy(s.snapshots[i:], s.snapshots[i+1:])
s.snapshots[len(s.snapshots)-1] = Snapshot{}
s.snapshots = s.snapshots[:len(s.snapshots)-1]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line 440 removes the last element which was just initialized in line 439. It looks to me that line 439 is not needed, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just imitate the code about volume deletion, make sense, will delete it.

// locking the service's snapshot slice for the duration of the
// ListSnapshots RPC.
var snapshots []csi.Snapshot
func() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've never seen an anonymous function without a go statement or assigned to a variable. Just curious, but why use this style?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI, when I review, I'm not only looking for bugs, but I am looking at maintenance. If it is hard to maintain, even if it works, it should be redone.

// ListSnapshots RPC.
var snapshots []csi.Snapshot
func() {
s.snapshotsRWL.RLock()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have to be very careful creating a deadlock situation sometime in the future. I would instead place these locks as close to the object as possible. I would suggest creating a new data structure object that handles the the work with the list. It supports Insert, Delete, List, Find, etc. and it is the one managing the lock

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just imitate the code about volume deletion, make sense, I will update the code and commit a separate pr to change the volume part.

}

func (s *service) ListSnapshots(ctx context.Context,
req *csi.ListSnapshotsRequest) (*csi.ListSnapshotsResponse, error) {
return nil, status.Error(codes.InvalidArgument, "Not Implemented")

// case 1: SnapshotId is not empty, return snapshots that match the snapshot id.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is too large, do you mind breaking it up by the cases you have?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sense, will update.

@pohly pohly mentioned this pull request Jul 11, 2018
@wackxu wackxu force-pushed the addtest branch 2 times, most recently from 0a5929c to 626cfbb Compare July 13, 2018 09:34
@lpabon lpabon merged commit 718c954 into kubernetes-csi:master Jul 18, 2018
@wackxu wackxu deleted the addtest branch July 19, 2018 02:51
suneeth51 pushed a commit to suneeth51/csi-test that referenced this pull request Sep 11, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants