test: Add unit tests for identityserver and nodeserver
Signed-off-by: Mayank Shah <mayankshah1614@gmail.com>
This commit is contained in:
parent
bef4ee7dbb
commit
35e3b0a065
3
go.mod
3
go.mod
@ -5,6 +5,7 @@ go 1.13
|
|||||||
require (
|
require (
|
||||||
github.com/container-storage-interface/spec v1.3.0
|
github.com/container-storage-interface/spec v1.3.0
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
|
||||||
|
github.com/golang/protobuf v1.4.1
|
||||||
github.com/kubernetes-csi/csi-lib-utils v0.7.0
|
github.com/kubernetes-csi/csi-lib-utils v0.7.0
|
||||||
github.com/kubernetes-csi/external-snapshotter/v2 v2.0.0-20200617021606-4800ca72d403
|
github.com/kubernetes-csi/external-snapshotter/v2 v2.0.0-20200617021606-4800ca72d403
|
||||||
github.com/onsi/ginkgo v1.11.0
|
github.com/onsi/ginkgo v1.11.0
|
||||||
@ -12,7 +13,7 @@ require (
|
|||||||
github.com/pborman/uuid v1.2.0
|
github.com/pborman/uuid v1.2.0
|
||||||
github.com/prometheus/client_golang v1.5.1 // indirect
|
github.com/prometheus/client_golang v1.5.1 // indirect
|
||||||
github.com/spf13/cobra v0.0.5
|
github.com/spf13/cobra v0.0.5
|
||||||
github.com/stretchr/testify v1.5.1 // indirect
|
github.com/stretchr/testify v1.5.1
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 // indirect
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 // indirect
|
||||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e
|
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e
|
||||||
golang.org/x/text v0.3.3 // indirect
|
golang.org/x/text v0.3.3 // indirect
|
||||||
|
|||||||
28
pkg/mounter/safe_mounter_unix.go
Normal file
28
pkg/mounter/safe_mounter_unix.go
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// +build linux darwin
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright 2020 The Kubernetes Authors.
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package mounter
|
||||||
|
|
||||||
|
import (
|
||||||
|
utilexec "k8s.io/utils/exec"
|
||||||
|
"k8s.io/utils/mount"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewSafeMounter() (*mount.SafeFormatAndMount, error) {
|
||||||
|
return &mount.SafeFormatAndMount{
|
||||||
|
Interface: mount.New(""),
|
||||||
|
Exec: utilexec.New(),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
73
pkg/nfs/fake_mounter.go
Normal file
73
pkg/nfs/fake_mounter.go
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2020 The Kubernetes Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package nfs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/kubernetes-csi/csi-driver-nfs/pkg/mounter"
|
||||||
|
|
||||||
|
"k8s.io/utils/mount"
|
||||||
|
)
|
||||||
|
|
||||||
|
type fakeMounter struct {
|
||||||
|
mount.FakeMounter
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mount overrides mount.FakeMounter.Mount.
|
||||||
|
func (f *fakeMounter) Mount(source string, target string, fstype string, options []string) error {
|
||||||
|
if strings.Contains(source, "error_mount") {
|
||||||
|
return fmt.Errorf("fake Mount: source error")
|
||||||
|
} else if strings.Contains(target, "error_mount") {
|
||||||
|
return fmt.Errorf("fake Mount: target error")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MountSensitive overrides mount.FakeMounter.MountSensitive.
|
||||||
|
func (f *fakeMounter) MountSensitive(source string, target string, fstype string, options []string, sensitiveOptions []string) error {
|
||||||
|
if strings.Contains(source, "error_mount_sens") {
|
||||||
|
return fmt.Errorf("fake MountSensitive: source error")
|
||||||
|
} else if strings.Contains(target, "error_mount_sens") {
|
||||||
|
return fmt.Errorf("fake MountSensitive: target error")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//IsLikelyNotMountPoint overrides mount.FakeMounter.IsLikelyNotMountPoint.
|
||||||
|
func (f *fakeMounter) IsLikelyNotMountPoint(file string) (bool, error) {
|
||||||
|
if strings.Contains(file, "error_is_likely") {
|
||||||
|
return false, fmt.Errorf("fake IsLikelyNotMountPoint: fake error")
|
||||||
|
}
|
||||||
|
if strings.Contains(file, "false_is_likely") {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFakeMounter() (*mount.SafeFormatAndMount, error) {
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
return mounter.NewSafeMounter()
|
||||||
|
}
|
||||||
|
return &mount.SafeFormatAndMount{
|
||||||
|
Interface: &fakeMounter{},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
102
pkg/nfs/identityserver_test.go
Normal file
102
pkg/nfs/identityserver_test.go
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2020 The Kubernetes Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package nfs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/container-storage-interface/spec/lib/go/csi"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"google.golang.org/grpc/codes"
|
||||||
|
"google.golang.org/grpc/status"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGetPluginInfo(t *testing.T) {
|
||||||
|
req := csi.GetPluginInfoRequest{}
|
||||||
|
emptyNameDriver := NewEmptyDriver("name")
|
||||||
|
emptyVersionDriver := NewEmptyDriver("version")
|
||||||
|
tests := []struct {
|
||||||
|
desc string
|
||||||
|
driver *Driver
|
||||||
|
expectedErr error
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
desc: "Successful Request",
|
||||||
|
driver: NewEmptyDriver(""),
|
||||||
|
expectedErr: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "Driver name missing",
|
||||||
|
driver: emptyNameDriver,
|
||||||
|
expectedErr: status.Error(codes.Unavailable, "Driver name not configured"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "Driver version missing",
|
||||||
|
driver: emptyVersionDriver,
|
||||||
|
expectedErr: status.Error(codes.Unavailable, "Driver is missing version"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
fakeIdentityServer := IdentityServer{
|
||||||
|
Driver: test.driver,
|
||||||
|
}
|
||||||
|
_, err := fakeIdentityServer.GetPluginInfo(context.Background(), &req)
|
||||||
|
if !reflect.DeepEqual(err, test.expectedErr) {
|
||||||
|
t.Errorf("Unexpected error: %v\nExpected: %v", err, test.expectedErr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestProbe(t *testing.T) {
|
||||||
|
d := NewEmptyDriver("")
|
||||||
|
req := csi.ProbeRequest{}
|
||||||
|
fakeIdentityServer := IdentityServer{
|
||||||
|
Driver: d,
|
||||||
|
}
|
||||||
|
resp, err := fakeIdentityServer.Probe(context.Background(), &req)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, resp)
|
||||||
|
assert.Equal(t, resp.XXX_sizecache, int32(0))
|
||||||
|
assert.Equal(t, resp.Ready.Value, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetPluginCapabilities(t *testing.T) {
|
||||||
|
expectedCap := []*csi.PluginCapability{
|
||||||
|
{
|
||||||
|
Type: &csi.PluginCapability_Service_{
|
||||||
|
Service: &csi.PluginCapability_Service{
|
||||||
|
Type: csi.PluginCapability_Service_CONTROLLER_SERVICE,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
d := NewEmptyDriver("")
|
||||||
|
fakeIdentityServer := IdentityServer{
|
||||||
|
Driver: d,
|
||||||
|
}
|
||||||
|
req := csi.GetPluginCapabilitiesRequest{}
|
||||||
|
resp, err := fakeIdentityServer.GetPluginCapabilities(context.Background(), &req)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, resp)
|
||||||
|
assert.Equal(t, resp.XXX_sizecache, int32(0))
|
||||||
|
assert.Equal(t, resp.Capabilities, expectedCap)
|
||||||
|
|
||||||
|
}
|
||||||
@ -19,6 +19,7 @@ package nfs
|
|||||||
import (
|
import (
|
||||||
"github.com/container-storage-interface/spec/lib/go/csi"
|
"github.com/container-storage-interface/spec/lib/go/csi"
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
|
"github.com/golang/protobuf/ptypes/wrappers"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
@ -45,8 +46,12 @@ func (ids *IdentityServer) GetPluginInfo(ctx context.Context, req *csi.GetPlugin
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Probe check whether the plugin is running or not.
|
||||||
|
// This method does not need to return anything.
|
||||||
|
// Currently the spec does not dictate what you should return either.
|
||||||
|
// Hence, return an empty response
|
||||||
func (ids *IdentityServer) Probe(ctx context.Context, req *csi.ProbeRequest) (*csi.ProbeResponse, error) {
|
func (ids *IdentityServer) Probe(ctx context.Context, req *csi.ProbeRequest) (*csi.ProbeResponse, error) {
|
||||||
return &csi.ProbeResponse{}, nil
|
return &csi.ProbeResponse{Ready: &wrappers.BoolValue{Value: true}}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ids *IdentityServer) GetPluginCapabilities(ctx context.Context, req *csi.GetPluginCapabilitiesRequest) (*csi.GetPluginCapabilitiesResponse, error) {
|
func (ids *IdentityServer) GetPluginCapabilities(ctx context.Context, req *csi.GetPluginCapabilitiesRequest) (*csi.GetPluginCapabilitiesResponse, error) {
|
||||||
|
|||||||
56
pkg/nfs/nfs_test.go
Normal file
56
pkg/nfs/nfs_test.go
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2019 The Kubernetes Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package nfs
|
||||||
|
|
||||||
|
import "github.com/container-storage-interface/spec/lib/go/csi"
|
||||||
|
|
||||||
|
const (
|
||||||
|
fakeNodeID = "fakeNodeID"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewEmptyDriver(emptyField string) *Driver {
|
||||||
|
var d *Driver
|
||||||
|
var perm *uint32
|
||||||
|
switch emptyField {
|
||||||
|
case "version":
|
||||||
|
d = &Driver{
|
||||||
|
name: DriverName,
|
||||||
|
version: "",
|
||||||
|
nodeID: fakeNodeID,
|
||||||
|
cap: map[csi.VolumeCapability_AccessMode_Mode]bool{},
|
||||||
|
perm: perm,
|
||||||
|
}
|
||||||
|
case "name":
|
||||||
|
d = &Driver{
|
||||||
|
name: "",
|
||||||
|
version: version,
|
||||||
|
nodeID: fakeNodeID,
|
||||||
|
cap: map[csi.VolumeCapability_AccessMode_Mode]bool{},
|
||||||
|
perm: perm,
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
d = &Driver{
|
||||||
|
name: DriverName,
|
||||||
|
version: version,
|
||||||
|
nodeID: fakeNodeID,
|
||||||
|
cap: map[csi.VolumeCapability_AccessMode_Mode]bool{},
|
||||||
|
perm: perm,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return d
|
||||||
|
}
|
||||||
@ -160,3 +160,13 @@ func (ns *NodeServer) NodeStageVolume(ctx context.Context, req *csi.NodeStageVol
|
|||||||
func (ns *NodeServer) NodeExpandVolume(ctx context.Context, req *csi.NodeExpandVolumeRequest) (*csi.NodeExpandVolumeResponse, error) {
|
func (ns *NodeServer) NodeExpandVolume(ctx context.Context, req *csi.NodeExpandVolumeRequest) (*csi.NodeExpandVolumeResponse, error) {
|
||||||
return nil, status.Error(codes.Unimplemented, "")
|
return nil, status.Error(codes.Unimplemented, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func makeDir(pathname string) error {
|
||||||
|
err := os.MkdirAll(pathname, os.FileMode(0755))
|
||||||
|
if err != nil {
|
||||||
|
if !os.IsExist(err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
213
pkg/nfs/nodeserver_test.go
Normal file
213
pkg/nfs/nodeserver_test.go
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2020 The Kubernetes Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package nfs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"os"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/container-storage-interface/spec/lib/go/csi"
|
||||||
|
"github.com/kubernetes-csi/csi-driver-nfs/test/utils/testutil"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"google.golang.org/grpc/codes"
|
||||||
|
"google.golang.org/grpc/status"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNodePublishVolume(t *testing.T) {
|
||||||
|
volumeCap := csi.VolumeCapability_AccessMode{Mode: csi.VolumeCapability_AccessMode_MULTI_NODE_MULTI_WRITER}
|
||||||
|
alreadyMountedTarget := testutil.GetWorkDirPath("false_is_likely_exist_target", t)
|
||||||
|
targetTest := testutil.GetWorkDirPath("target_test", t)
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
desc string
|
||||||
|
req csi.NodePublishVolumeRequest
|
||||||
|
skipOnWindows bool
|
||||||
|
expectedErr error
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
desc: "[Error] Volume capabilities missing",
|
||||||
|
req: csi.NodePublishVolumeRequest{},
|
||||||
|
expectedErr: status.Error(codes.InvalidArgument, "Volume capability missing in request"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "[Error] Volume ID missing",
|
||||||
|
req: csi.NodePublishVolumeRequest{VolumeCapability: &csi.VolumeCapability{AccessMode: &volumeCap}},
|
||||||
|
expectedErr: status.Error(codes.InvalidArgument, "Volume ID missing in request"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "[Error] Target path missing",
|
||||||
|
req: csi.NodePublishVolumeRequest{VolumeCapability: &csi.VolumeCapability{AccessMode: &volumeCap},
|
||||||
|
VolumeId: "vol_1"},
|
||||||
|
expectedErr: status.Error(codes.InvalidArgument, "Target path not provided"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "[Success] Stage target path missing",
|
||||||
|
req: csi.NodePublishVolumeRequest{VolumeCapability: &csi.VolumeCapability{AccessMode: &volumeCap},
|
||||||
|
VolumeId: "vol_1",
|
||||||
|
TargetPath: targetTest},
|
||||||
|
expectedErr: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "[Success] Valid request read only",
|
||||||
|
req: csi.NodePublishVolumeRequest{VolumeCapability: &csi.VolumeCapability{AccessMode: &volumeCap},
|
||||||
|
VolumeId: "vol_1",
|
||||||
|
TargetPath: targetTest,
|
||||||
|
Readonly: true},
|
||||||
|
expectedErr: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "[Success] Valid request already mounted",
|
||||||
|
req: csi.NodePublishVolumeRequest{VolumeCapability: &csi.VolumeCapability{AccessMode: &volumeCap},
|
||||||
|
VolumeId: "vol_1",
|
||||||
|
TargetPath: alreadyMountedTarget,
|
||||||
|
Readonly: true},
|
||||||
|
expectedErr: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "[Success] Valid request",
|
||||||
|
req: csi.NodePublishVolumeRequest{VolumeCapability: &csi.VolumeCapability{AccessMode: &volumeCap},
|
||||||
|
VolumeId: "vol_1",
|
||||||
|
TargetPath: targetTest,
|
||||||
|
Readonly: true},
|
||||||
|
expectedErr: nil,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup
|
||||||
|
_ = makeDir(alreadyMountedTarget)
|
||||||
|
|
||||||
|
ns, err := getTestNodeServer()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range tests {
|
||||||
|
_, err := ns.NodePublishVolume(context.Background(), &tc.req)
|
||||||
|
if !reflect.DeepEqual(err, tc.expectedErr) {
|
||||||
|
t.Errorf("Desc:%v\nUnexpected error: %v\nExpected: %v", tc.desc, err, tc.expectedErr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
err = os.RemoveAll(targetTest)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
err = os.RemoveAll(alreadyMountedTarget)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNodeUnpublishVolume(t *testing.T) {
|
||||||
|
errorTarget := testutil.GetWorkDirPath("error_is_likely_target", t)
|
||||||
|
targetTest := testutil.GetWorkDirPath("target_test", t)
|
||||||
|
targetFile := testutil.GetWorkDirPath("abc.go", t)
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
desc string
|
||||||
|
req csi.NodeUnpublishVolumeRequest
|
||||||
|
expectedErr error
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
desc: "[Error] Volume ID missing",
|
||||||
|
req: csi.NodeUnpublishVolumeRequest{TargetPath: targetTest},
|
||||||
|
expectedErr: status.Error(codes.InvalidArgument, "Volume ID missing in request"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "[Error] Target missing",
|
||||||
|
req: csi.NodeUnpublishVolumeRequest{VolumeId: "vol_1"},
|
||||||
|
expectedErr: status.Error(codes.InvalidArgument, "Target path missing in request"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "[Error] Unmount error mocked by IsLikelyNotMountPoint",
|
||||||
|
req: csi.NodeUnpublishVolumeRequest{TargetPath: errorTarget, VolumeId: "vol_1"},
|
||||||
|
expectedErr: status.Error(codes.Internal, "fake IsLikelyNotMountPoint: fake error"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "[Error] Volume not mounted",
|
||||||
|
req: csi.NodeUnpublishVolumeRequest{TargetPath: targetFile, VolumeId: "vol_1"},
|
||||||
|
expectedErr: status.Error(codes.NotFound, "Volume not mounted"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup
|
||||||
|
_ = makeDir(errorTarget)
|
||||||
|
|
||||||
|
ns, err := getTestNodeServer()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range tests {
|
||||||
|
_, err := ns.NodeUnpublishVolume(context.Background(), &tc.req)
|
||||||
|
if !reflect.DeepEqual(err, tc.expectedErr) {
|
||||||
|
t.Errorf("Desc:%v\nUnexpected error: %v\nExpected: %v", tc.desc, err, tc.expectedErr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
err = os.RemoveAll(errorTarget)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNodeGetInfo(t *testing.T) {
|
||||||
|
|
||||||
|
ns, err := getTestNodeServer()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test valid request
|
||||||
|
req := csi.NodeGetInfoRequest{}
|
||||||
|
resp, err := ns.NodeGetInfo(context.Background(), &req)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, resp.GetNodeId(), fakeNodeID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNodeGetCapabilities(t *testing.T) {
|
||||||
|
|
||||||
|
ns, err := getTestNodeServer()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
capType := &csi.NodeServiceCapability_Rpc{
|
||||||
|
Rpc: &csi.NodeServiceCapability_RPC{
|
||||||
|
Type: csi.NodeServiceCapability_RPC_UNKNOWN,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test valid request
|
||||||
|
req := csi.NodeGetCapabilitiesRequest{}
|
||||||
|
resp, err := ns.NodeGetCapabilities(context.Background(), &req)
|
||||||
|
assert.NotNil(t, resp)
|
||||||
|
assert.Equal(t, resp.Capabilities[0].GetType(), capType)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getTestNodeServer() (NodeServer, error) {
|
||||||
|
d := NewEmptyDriver("")
|
||||||
|
mounter, err := NewFakeMounter()
|
||||||
|
if err != nil {
|
||||||
|
return NodeServer{}, errors.New("failed to get fake mounter")
|
||||||
|
}
|
||||||
|
return NodeServer{
|
||||||
|
Driver: d,
|
||||||
|
mounter: mounter,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
32
test/utils/testutil/testutil.go
Normal file
32
test/utils/testutil/testutil.go
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2020 The Kubernetes Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package testutil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetWorkDirPath returns the path to the current working directory
|
||||||
|
func GetWorkDirPath(dir string, t *testing.T) string {
|
||||||
|
path, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to get working directory: %s", err)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s%c%s", path, os.PathSeparator, dir)
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user