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/mock: Add NodeGetVolumeStats sanity check #147

Merged
merged 1 commit into from
Dec 4, 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
36 changes: 35 additions & 1 deletion mock/service/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,13 @@ func (s *service) NodeGetCapabilities(
},
},
},
{
Type: &csi.NodeServiceCapability_Rpc{
Rpc: &csi.NodeServiceCapability_RPC{
Type: csi.NodeServiceCapability_RPC_GET_VOLUME_STATS,
},
},
},
},
}, nil
}
Expand All @@ -239,6 +246,33 @@ func (s *service) NodeGetInfo(ctx context.Context,

func (s *service) NodeGetVolumeStats(ctx context.Context,
req *csi.NodeGetVolumeStatsRequest) (*csi.NodeGetVolumeStatsResponse, error) {
return &csi.NodeGetVolumeStatsResponse{}, nil

if len(req.GetVolumeId()) == 0 {
return nil, status.Error(codes.InvalidArgument, "Volume ID cannot be empty")
}

if len(req.GetVolumePath()) == 0 {
return nil, status.Error(codes.InvalidArgument, "Volume Path cannot be empty")
}

i, v := s.findVolNoLock("id", req.VolumeId)
if i < 0 {
return nil, status.Error(codes.NotFound, req.VolumeId)
}

nodeMntPathKey := path.Join(s.nodeID, req.VolumePath)

_, exists := v.VolumeContext[nodeMntPathKey]
if !exists {
return nil, status.Errorf(codes.NotFound, "volume %q doest not exist on the specified path %q", req.VolumeId, req.VolumeId)
}

return &csi.NodeGetVolumeStatsResponse{
Usage: []*csi.VolumeUsage{
{
Total: v.GetCapacityBytes(),
Unit: csi.VolumeUsage_BYTES,
},
},
}, nil
}
248 changes: 248 additions & 0 deletions pkg/sanity/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ var _ = DescribeSanity("Node Service", func(sc *SanityContext) {

controllerPublishSupported bool
nodeStageSupported bool
nodeVolumeStatsSupported bool
)

BeforeEach(func() {
Expand All @@ -90,6 +91,7 @@ var _ = DescribeSanity("Node Service", func(sc *SanityContext) {
err := createMountTargetLocation(sc.Config.StagingPath)
Expect(err).NotTo(HaveOccurred())
}
nodeVolumeStatsSupported = isNodeCapabilitySupported(c, csi.NodeServiceCapability_RPC_GET_VOLUME_STATS)
cl = &Cleanup{
Context: sc,
NodeClient: c,
Expand Down Expand Up @@ -350,6 +352,238 @@ var _ = DescribeSanity("Node Service", func(sc *SanityContext) {
})
})

Describe("NodeGetVolumeStats", func() {
BeforeEach(func() {
if !nodeVolumeStatsSupported {
Skip("NodeGetVolume not supported")
}
})

It("should fail when no volume id is provided", func() {
_, err := c.NodeGetVolumeStats(
context.Background(),
&csi.NodeGetVolumeStatsRequest{
VolumePath: "some/path",
},
)
Expect(err).To(HaveOccurred())

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

It("should fail when no volume path is provided", func() {
_, err := c.NodeGetVolumeStats(
context.Background(),
&csi.NodeGetVolumeStatsRequest{
VolumeId: "id",
},
)
Expect(err).To(HaveOccurred())

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

It("should fail when volume is not found", func() {
_, err := c.NodeGetVolumeStats(
context.Background(),
&csi.NodeGetVolumeStatsRequest{
VolumeId: "id",
VolumePath: "some/path",
},
)
Expect(err).To(HaveOccurred())

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

It("should fail when volume does not exist on the specified path", func() {
name := uniqueString("sanity-node-get-volume-stats")

By("creating a single node writer volume")
vol, err := s.CreateVolume(
context.Background(),
&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,
},
},
},
Secrets: sc.Secrets.CreateVolumeSecret,
},
)
Expect(err).NotTo(HaveOccurred())
Expect(vol).NotTo(BeNil())
Expect(vol.GetVolume()).NotTo(BeNil())
Expect(vol.GetVolume().GetVolumeId()).NotTo(BeEmpty())
cl.RegisterVolume(name, VolumeInfo{VolumeID: vol.GetVolume().GetVolumeId()})

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

var conpubvol *csi.ControllerPublishVolumeResponse
if controllerPublishSupported {
By("controller publishing volume")

conpubvol, err = s.ControllerPublishVolume(
context.Background(),
&csi.ControllerPublishVolumeRequest{
VolumeId: vol.GetVolume().GetVolumeId(),
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,
},
},
VolumeContext: vol.GetVolume().GetVolumeContext(),
Readonly: false,
Secrets: sc.Secrets.ControllerPublishVolumeSecret,
},
)
Expect(err).NotTo(HaveOccurred())
cl.RegisterVolume(name, VolumeInfo{VolumeID: vol.GetVolume().GetVolumeId(), NodeID: nid.GetNodeId()})
Expect(conpubvol).NotTo(BeNil())
}
// NodeStageVolume
if nodeStageSupported {
By("node staging volume")
nodestagevol, err := c.NodeStageVolume(
context.Background(),
&csi.NodeStageVolumeRequest{
VolumeId: vol.GetVolume().GetVolumeId(),
VolumeCapability: &csi.VolumeCapability{
AccessType: &csi.VolumeCapability_Mount{
Mount: &csi.VolumeCapability_MountVolume{},
},
AccessMode: &csi.VolumeCapability_AccessMode{
Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER,
},
},
StagingTargetPath: sc.Config.StagingPath,
VolumeContext: vol.GetVolume().GetVolumeContext(),
PublishContext: conpubvol.GetPublishContext(),
Secrets: sc.Secrets.NodeStageVolumeSecret,
},
)
Expect(err).NotTo(HaveOccurred())
Expect(nodestagevol).NotTo(BeNil())
}
// NodePublishVolume
By("publishing the volume on a node")
var stagingPath string
if nodeStageSupported {
stagingPath = sc.Config.StagingPath
}
nodepubvol, err := c.NodePublishVolume(
context.Background(),
&csi.NodePublishVolumeRequest{
VolumeId: vol.GetVolume().GetVolumeId(),
TargetPath: sc.Config.TargetPath,
StagingTargetPath: stagingPath,
VolumeCapability: &csi.VolumeCapability{
AccessType: &csi.VolumeCapability_Mount{
Mount: &csi.VolumeCapability_MountVolume{},
},
AccessMode: &csi.VolumeCapability_AccessMode{
Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER,
},
},
VolumeContext: vol.GetVolume().GetVolumeContext(),
PublishContext: conpubvol.GetPublishContext(),
Secrets: sc.Secrets.NodePublishVolumeSecret,
},
)
Expect(err).NotTo(HaveOccurred())
Expect(nodepubvol).NotTo(BeNil())

// NodeGetVolumeStats
By("Get node volume stats")
_, err = c.NodeGetVolumeStats(
context.Background(),
&csi.NodeGetVolumeStatsRequest{
VolumeId: vol.GetVolume().GetVolumeId(),
VolumePath: "some/path",
},
)
Expect(err).To(HaveOccurred())

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

// NodeUnpublishVolume
By("cleaning up calling nodeunpublish")
nodeunpubvol, err := c.NodeUnpublishVolume(
context.Background(),
&csi.NodeUnpublishVolumeRequest{
VolumeId: vol.GetVolume().GetVolumeId(),
TargetPath: sc.Config.TargetPath,
})
Expect(err).NotTo(HaveOccurred())
Expect(nodeunpubvol).NotTo(BeNil())

if nodeStageSupported {
By("cleaning up calling nodeunstage")
nodeunstagevol, err := c.NodeUnstageVolume(
context.Background(),
&csi.NodeUnstageVolumeRequest{
VolumeId: vol.GetVolume().GetVolumeId(),
StagingTargetPath: sc.Config.StagingPath,
},
)
Expect(err).NotTo(HaveOccurred())
Expect(nodeunstagevol).NotTo(BeNil())
}

if controllerPublishSupported {
By("cleaning up calling controllerunpublishing")

controllerunpubvol, err := s.ControllerUnpublishVolume(
context.Background(),
&csi.ControllerUnpublishVolumeRequest{
VolumeId: vol.GetVolume().GetVolumeId(),
NodeId: nid.GetNodeId(),
Secrets: sc.Secrets.ControllerUnpublishVolumeSecret,
},
)
Expect(err).NotTo(HaveOccurred())
Expect(controllerunpubvol).NotTo(BeNil())
}

By("cleaning up deleting the volume")

_, err = s.DeleteVolume(
context.Background(),
&csi.DeleteVolumeRequest{
VolumeId: vol.GetVolume().GetVolumeId(),
Secrets: sc.Secrets.DeleteVolumeSecret,
},
)
Expect(err).NotTo(HaveOccurred())

})

})

It("should work", func() {
name := uniqueString("sanity-node-full")

Expand Down Expand Up @@ -464,6 +698,20 @@ var _ = DescribeSanity("Node Service", func(sc *SanityContext) {
Expect(err).NotTo(HaveOccurred())
Expect(nodepubvol).NotTo(BeNil())

// NodeGetVolumeStats
if nodeVolumeStatsSupported {
By("Get node volume stats")
statsResp, err := c.NodeGetVolumeStats(
context.Background(),
&csi.NodeGetVolumeStatsRequest{
VolumeId: vol.GetVolume().GetVolumeId(),
VolumePath: sc.Config.TargetPath,
},
)
Expect(err).ToNot(HaveOccurred())
Expect(statsResp.GetUsage()).ToNot(BeNil())
}

// NodeUnpublishVolume
By("cleaning up calling nodeunpublish")
nodeunpubvol, err := c.NodeUnpublishVolume(
Expand Down