diff --git a/pkg/gce-pd-csi-driver/node.go b/pkg/gce-pd-csi-driver/node.go index 080261aaf..25a29d396 100644 --- a/pkg/gce-pd-csi-driver/node.go +++ b/pkg/gce-pd-csi-driver/node.go @@ -296,10 +296,7 @@ func (ns *GCENodeServer) NodeGetInfo(ctx context.Context, req *csi.NodeGetInfoRe volumeLimits, err := ns.GetVolumeLimits() resp := &csi.NodeGetInfoResponse{ - NodeId: nodeID, - // TODO(#19): Set MaxVolumesPerNode based on Node Type - // Default of 0 means that CO Decides how many nodes can be published - // Can get from metadata server "machine-type" + NodeId: nodeID, MaxVolumesPerNode: volumeLimits, AccessibleTopology: top, } diff --git a/pkg/gce-pd-csi-driver/node_test.go b/pkg/gce-pd-csi-driver/node_test.go index 96c79d4ff..939e44004 100644 --- a/pkg/gce-pd-csi-driver/node_test.go +++ b/pkg/gce-pd-csi-driver/node_test.go @@ -19,10 +19,16 @@ import ( csi "github.com/container-storage-interface/spec/lib/go/csi" "golang.org/x/net/context" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" metadataservice "sigs.k8s.io/gcp-compute-persistent-disk-csi-driver/pkg/gce-cloud-provider/metadata" mountmanager "sigs.k8s.io/gcp-compute-persistent-disk-csi-driver/pkg/mount-manager" ) +const defaultVolumeID = "project/test001/zones/c1/disks/testDisk" +const defaultTargetPath = "/mnt/test" +const defaultStagingPath = "/staging" + func getTestGCEDriver(t *testing.T) *GCEDriver { gceDriver := GetGCEDriver() err := gceDriver.SetupGCEDriver(nil, mountmanager.NewFakeSafeMounter(), mountmanager.NewFakeDeviceUtils(), metadataservice.NewFakeService(), driver, "test-vendor") @@ -86,3 +92,270 @@ func TestNodeGetVolumeLimits(t *testing.T) { } } } + +func TestNodePublishVolume(t *testing.T) { + gceDriver := getTestGCEDriver(t) + ns := gceDriver.ns + testCases := []struct { + name string + req *csi.NodePublishVolumeRequest + expErrCode codes.Code + }{ + { + name: "Valid request", + req: &csi.NodePublishVolumeRequest{ + VolumeId: defaultVolumeID, + TargetPath: defaultTargetPath, + StagingTargetPath: defaultStagingPath, + Readonly: false, + VolumeCapability: &csi.VolumeCapability{}, + }, + }, + { + name: "Invalid request (No VolumeId)", + req: &csi.NodePublishVolumeRequest{ + TargetPath: defaultTargetPath, + StagingTargetPath: defaultStagingPath, + Readonly: false, + VolumeCapability: &csi.VolumeCapability{}, + }, + expErrCode: codes.InvalidArgument, + }, + { + name: "Invalid request (No TargetPath)", + req: &csi.NodePublishVolumeRequest{ + VolumeId: defaultVolumeID, + StagingTargetPath: defaultStagingPath, + Readonly: false, + VolumeCapability: &csi.VolumeCapability{}, + }, + expErrCode: codes.InvalidArgument, + }, + { + name: "Invalid request (No StagingTargetPath)", + req: &csi.NodePublishVolumeRequest{ + VolumeId: defaultVolumeID, + TargetPath: defaultTargetPath, + Readonly: false, + VolumeCapability: &csi.VolumeCapability{}, + }, + expErrCode: codes.InvalidArgument, + }, + { + name: "Invalid request (Nil VolumeCapability)", + req: &csi.NodePublishVolumeRequest{ + VolumeId: defaultVolumeID, + TargetPath: defaultTargetPath, + StagingTargetPath: defaultStagingPath, + Readonly: false, + VolumeCapability: nil, + }, + expErrCode: codes.InvalidArgument, + }, + } + for _, tc := range testCases { + t.Logf("Test case: %s", tc.name) + _, err := ns.NodePublishVolume(context.Background(), tc.req) + if err != nil { + serverError, ok := status.FromError(err) + if !ok { + t.Fatalf("Could not get error status code from err: %v", err) + } + if serverError.Code() != tc.expErrCode { + t.Fatalf("Expected error code: %v, got: %v. err : %v", tc.expErrCode, serverError.Code(), err) + } + continue + } + if tc.expErrCode != codes.OK { + t.Fatalf("Expected error: %v, got no error", tc.expErrCode) + } + } +} + +func TestNodeUnpublishVolume(t *testing.T) { + gceDriver := getTestGCEDriver(t) + ns := gceDriver.ns + testCases := []struct { + name string + req *csi.NodeUnpublishVolumeRequest + expErrCode codes.Code + }{ + { + name: "Valid request", + req: &csi.NodeUnpublishVolumeRequest{ + VolumeId: defaultVolumeID, + TargetPath: defaultTargetPath, + }, + }, + { + name: "Invalid request (No VolumeId)", + req: &csi.NodeUnpublishVolumeRequest{ + TargetPath: defaultTargetPath, + }, + expErrCode: codes.InvalidArgument, + }, + { + name: "Invalid request (No TargetPath)", + req: &csi.NodeUnpublishVolumeRequest{ + VolumeId: defaultVolumeID, + }, + expErrCode: codes.InvalidArgument, + }, + } + for _, tc := range testCases { + t.Logf("Test case: %s", tc.name) + _, err := ns.NodeUnpublishVolume(context.Background(), tc.req) + if err != nil { + serverError, ok := status.FromError(err) + if !ok { + t.Fatalf("Could not get error status code from err: %v", err) + } + if serverError.Code() != tc.expErrCode { + t.Fatalf("Expected error code: %v, got: %v. err : %v", tc.expErrCode, serverError.Code(), err) + } + continue + } + if tc.expErrCode != codes.OK { + t.Fatalf("Expected error: %v, got no error", tc.expErrCode) + } + } +} + +func TestNodeStageVolume(t *testing.T) { + gceDriver := getTestGCEDriver(t) + ns := gceDriver.ns + volumeID := "project/test001/zones/c1/disks/testDisk" + blockCap := &csi.VolumeCapability_Block{ + Block: &csi.VolumeCapability_BlockVolume{}, + } + cap := &csi.VolumeCapability{ + AccessType: blockCap, + } + + testCases := []struct { + name string + req *csi.NodeStageVolumeRequest + expErrCode codes.Code + }{ + { + name: "Valid request", + req: &csi.NodeStageVolumeRequest{ + VolumeId: volumeID, + StagingTargetPath: defaultStagingPath, + VolumeCapability: &csi.VolumeCapability{}, + }, + }, + { + name: "Invalid request (No VolumeId)", + req: &csi.NodeStageVolumeRequest{ + StagingTargetPath: defaultStagingPath, + VolumeCapability: &csi.VolumeCapability{}, + }, + expErrCode: codes.InvalidArgument, + }, + { + name: "Invalid request (No StagingTargetPath)", + req: &csi.NodeStageVolumeRequest{ + VolumeId: volumeID, + VolumeCapability: &csi.VolumeCapability{}, + }, + expErrCode: codes.InvalidArgument, + }, + { + name: "Invalid request (Nil VolumeCapability)", + req: &csi.NodeStageVolumeRequest{ + VolumeId: volumeID, + StagingTargetPath: defaultStagingPath, + VolumeCapability: nil, + }, + expErrCode: codes.InvalidArgument, + }, + { + name: "Invalid request (No Mount in capability)", + req: &csi.NodeStageVolumeRequest{ + VolumeId: volumeID, + StagingTargetPath: defaultStagingPath, + VolumeCapability: cap, + }, + expErrCode: codes.Unimplemented, + }, + // Capability Mount. codes.Unimplemented + } + for _, tc := range testCases { + t.Logf("Test case: %s", tc.name) + _, err := ns.NodeStageVolume(context.Background(), tc.req) + if err != nil { + serverError, ok := status.FromError(err) + if !ok { + t.Fatalf("Could not get error status code from err: %v", err) + } + if serverError.Code() != tc.expErrCode { + t.Fatalf("Expected error code: %v, got: %v. err : %v", tc.expErrCode, serverError.Code(), err) + } + continue + } + if tc.expErrCode != codes.OK { + t.Fatalf("Expected error: %v, got no error", tc.expErrCode) + } + } +} + +func TestNodeUnstageVolume(t *testing.T) { + gceDriver := getTestGCEDriver(t) + ns := gceDriver.ns + testCases := []struct { + name string + req *csi.NodeUnstageVolumeRequest + expErrCode codes.Code + }{ + { + name: "Valid request", + req: &csi.NodeUnstageVolumeRequest{ + VolumeId: defaultVolumeID, + StagingTargetPath: defaultStagingPath, + }, + }, + { + name: "Invalid request (No VolumeId)", + req: &csi.NodeUnstageVolumeRequest{ + StagingTargetPath: defaultStagingPath, + }, + expErrCode: codes.InvalidArgument, + }, + { + name: "Invalid request (No StagingTargetPath)", + req: &csi.NodeUnstageVolumeRequest{ + VolumeId: defaultVolumeID, + }, + expErrCode: codes.InvalidArgument, + }, + } + for _, tc := range testCases { + t.Logf("Test case: %s", tc.name) + _, err := ns.NodeUnstageVolume(context.Background(), tc.req) + if err != nil { + serverError, ok := status.FromError(err) + if !ok { + t.Fatalf("Could not get error status code from err: %v", err) + } + if serverError.Code() != tc.expErrCode { + t.Fatalf("Expected error code: %v, got: %v. err : %v", tc.expErrCode, serverError.Code(), err) + } + continue + } + if tc.expErrCode != codes.OK { + t.Fatalf("Expected error: %v, got no error", tc.expErrCode) + } + } +} + +func TestNodeGetCapabilities(t *testing.T) { + gceDriver := getTestGCEDriver(t) + ns := gceDriver.ns + req := &csi.NodeGetCapabilitiesRequest{} + + _, err := ns.NodeGetCapabilities(context.Background(), req) + if err != nil { + t.Fatalf("Unexpedted error: %v", err) + } +}