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

sanity: Add more ControllerPublishVolume tests #77

Merged
merged 1 commit into from
Jun 29, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 31 additions & 2 deletions mock/service/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (

const (
MaxStorageCapacity = tib
ReadOnlyKey = "readonly"
)

func (s *service) CreateVolume(
Expand Down Expand Up @@ -135,21 +136,48 @@ func (s *service) ControllerPublishVolume(

// Check to see if the volume is already published.
if device := v.Attributes[devPathKey]; device != "" {
var volRo bool
var roVal string
if ro, ok := v.Attributes[ReadOnlyKey]; ok {
roVal = ro
}

if roVal == "true" {
volRo = true
} else {
volRo = false
}

// Check if readonly flag is compatible with the publish request.
if req.GetReadonly() != volRo {
return nil, status.Error(codes.AlreadyExists, "Volume published but has incompatible readonly flag")
}

return &csi.ControllerPublishVolumeResponse{
PublishInfo: map[string]string{
"device": device,
"device": device,
"readonly": roVal,
},
}, nil
}

var roVal string
if req.GetReadonly() {
roVal = "true"
} else {
roVal = "false"
}

// Publish the volume.
device := "/dev/mock"
v.Attributes[devPathKey] = device
v.Attributes[ReadOnlyKey] = roVal
s.vols[i] = v

return &csi.ControllerPublishVolumeResponse{
PublishInfo: map[string]string{
"device": device,
"device": device,
"readonly": roVal,
},
}, nil
}
Expand Down Expand Up @@ -192,6 +220,7 @@ func (s *service) ControllerUnpublishVolume(

// Unpublish the volume.
delete(v.Attributes, devPathKey)
delete(v.Attributes, ReadOnlyKey)
s.vols[i] = v

return &csi.ControllerUnpublishVolumeResponse{}, nil
Expand Down
206 changes: 206 additions & 0 deletions pkg/sanity/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -806,6 +806,212 @@ var _ = Describe("ControllerPublishVolume [Controller Server]", func() {
_, err = c.DeleteVolume(context.Background(), delReq)
Expect(err).NotTo(HaveOccurred())
})

It("should fail when the volume does not exist", func() {

By("calling controller publish on a non-existent volume")

pubReq := &csi.ControllerPublishVolumeRequest{
VolumeId: "some-vol-id",
NodeId: "some-node-id",
VolumeCapability: &csi.VolumeCapability{
AccessType: &csi.VolumeCapability_Mount{
Mount: &csi.VolumeCapability_MountVolume{},
},
AccessMode: &csi.VolumeCapability_AccessMode{
Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER,
},
},
Readonly: false,
}

if secrets != nil {
pubReq.ControllerPublishSecrets = secrets.ControllerPublishVolumeSecret
}

conpubvol, err := c.ControllerPublishVolume(context.Background(), pubReq)
Expect(err).To(HaveOccurred())
Expect(conpubvol).To(BeNil())

serverError, ok := status.FromError(err)
Expect(ok).To(BeTrue())
Expect(serverError.Code()).To(Equal(codes.NotFound))
})

It("should fail when the node does not exist", func() {

// Create Volume First
By("creating a single node writer volume")
name := "sanity"
req := &csi.CreateVolumeRequest{
Name: name,
VolumeCapabilities: []*csi.VolumeCapability{
{
AccessType: &csi.VolumeCapability_Mount{
Mount: &csi.VolumeCapability_MountVolume{},
},
AccessMode: &csi.VolumeCapability_AccessMode{
Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER,
},
},
},
}

if secrets != nil {
req.ControllerCreateSecrets = secrets.CreateVolumeSecret
}

vol, err := c.CreateVolume(context.Background(), req)
Expect(err).NotTo(HaveOccurred())
Expect(vol).NotTo(BeNil())
Expect(vol.GetVolume()).NotTo(BeNil())
Expect(vol.GetVolume().GetId()).NotTo(BeEmpty())

// ControllerPublishVolume
By("calling controllerpublish on that volume")

pubReq := &csi.ControllerPublishVolumeRequest{
VolumeId: vol.GetVolume().GetId(),
NodeId: "some-fake-node-id",
VolumeCapability: &csi.VolumeCapability{
AccessType: &csi.VolumeCapability_Mount{
Mount: &csi.VolumeCapability_MountVolume{},
},
AccessMode: &csi.VolumeCapability_AccessMode{
Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER,
},
},
Readonly: false,
}

if secrets != nil {
pubReq.ControllerPublishSecrets = secrets.ControllerPublishVolumeSecret
}

conpubvol, err := c.ControllerPublishVolume(context.Background(), pubReq)
Expect(err).To(HaveOccurred())
Expect(conpubvol).To(BeNil())

serverError, ok := status.FromError(err)
Expect(ok).To(BeTrue())
Expect(serverError.Code()).To(Equal(codes.NotFound))

By("cleaning up deleting the volume")

delReq := &csi.DeleteVolumeRequest{
VolumeId: vol.GetVolume().GetId(),
}

if secrets != nil {
delReq.ControllerDeleteSecrets = secrets.DeleteVolumeSecret
}

_, err = c.DeleteVolume(context.Background(), delReq)
Expect(err).NotTo(HaveOccurred())
})

It("should fail when the volume is already published but is incompatible", func() {

// Create Volume First
By("creating a single node writer volume")
name := "sanity"
req := &csi.CreateVolumeRequest{
Name: name,
VolumeCapabilities: []*csi.VolumeCapability{
{
AccessType: &csi.VolumeCapability_Mount{
Mount: &csi.VolumeCapability_MountVolume{},
},
AccessMode: &csi.VolumeCapability_AccessMode{
Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER,
},
},
},
}

if secrets != nil {
req.ControllerCreateSecrets = secrets.CreateVolumeSecret
}

vol, err := c.CreateVolume(context.Background(), req)
Expect(err).NotTo(HaveOccurred())
Expect(vol).NotTo(BeNil())
Expect(vol.GetVolume()).NotTo(BeNil())
Expect(vol.GetVolume().GetId()).NotTo(BeEmpty())

By("getting a node id")
nid, err := n.NodeGetId(
context.Background(),
&csi.NodeGetIdRequest{})
Expect(err).NotTo(HaveOccurred())
Expect(nid).NotTo(BeNil())
Expect(nid.GetNodeId()).NotTo(BeEmpty())

// ControllerPublishVolume
By("calling controllerpublish on that volume")

pubReq := &csi.ControllerPublishVolumeRequest{
VolumeId: vol.GetVolume().GetId(),
NodeId: nid.GetNodeId(),
VolumeCapability: &csi.VolumeCapability{
AccessType: &csi.VolumeCapability_Mount{
Mount: &csi.VolumeCapability_MountVolume{},
},
AccessMode: &csi.VolumeCapability_AccessMode{
Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER,
},
},
Readonly: false,
}

if secrets != nil {
pubReq.ControllerPublishSecrets = secrets.ControllerPublishVolumeSecret
}

conpubvol, err := c.ControllerPublishVolume(context.Background(), pubReq)
Expect(err).NotTo(HaveOccurred())
Expect(conpubvol).NotTo(BeNil())

// Publish again with different attributes.
pubReq.Readonly = true

conpubvol, err = c.ControllerPublishVolume(context.Background(), pubReq)
Expect(err).To(HaveOccurred())
Expect(conpubvol).To(BeNil())

serverError, ok := status.FromError(err)
Expect(ok).To(BeTrue())
Expect(serverError.Code()).To(Equal(codes.AlreadyExists))

By("cleaning up unpublishing the volume")

unpubReq := &csi.ControllerUnpublishVolumeRequest{
VolumeId: vol.GetVolume().GetId(),
// NodeID is optional in ControllerUnpublishVolume
NodeId: nid.GetNodeId(),
}

if secrets != nil {
unpubReq.ControllerUnpublishSecrets = secrets.ControllerUnpublishVolumeSecret
}

conunpubvol, err := c.ControllerUnpublishVolume(context.Background(), unpubReq)
Expect(err).NotTo(HaveOccurred())
Expect(conunpubvol).NotTo(BeNil())

By("cleaning up deleting the volume")

delReq := &csi.DeleteVolumeRequest{
VolumeId: vol.GetVolume().GetId(),
}

if secrets != nil {
delReq.ControllerDeleteSecrets = secrets.DeleteVolumeSecret
}

_, err = c.DeleteVolume(context.Background(), delReq)
Expect(err).NotTo(HaveOccurred())
})
})

var _ = Describe("ControllerUnpublishVolume [Controller Server]", func() {
Expand Down