csi-driver-smb/pkg/smb/controllerserver_test.go

909 lines
25 KiB
Go

/*
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 smb
import (
"context"
"fmt"
"os"
"path/filepath"
"reflect"
"runtime"
"testing"
"github.com/container-storage-interface/spec/lib/go/csi"
"github.com/kubernetes-csi/csi-driver-smb/test/utils/testutil"
"github.com/stretchr/testify/assert"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
const (
testServer = "test-server/baseDir"
testCSIVolume = "test-csi"
testVolumeID = "test-server/baseDir#test-csi##"
)
func TestControllerGetCapabilities(t *testing.T) {
d := NewFakeDriver()
controlCap := []*csi.ControllerServiceCapability{
{
Type: &csi.ControllerServiceCapability_Rpc{},
},
}
d.Cap = controlCap
req := csi.ControllerGetCapabilitiesRequest{}
resp, err := d.ControllerGetCapabilities(context.Background(), &req)
assert.NoError(t, err)
assert.NotNil(t, resp)
assert.Equal(t, resp.Capabilities, controlCap)
}
func TestCreateVolume(t *testing.T) {
d := NewFakeDriver()
blockVolCap := []*csi.VolumeCapability{
{
AccessType: &csi.VolumeCapability_Block{
Block: &csi.VolumeCapability_BlockVolume{},
},
},
}
// Setup workingMountDir
workingMountDir, err := os.Getwd()
if err != nil {
t.Errorf("failed to get current working directory")
}
d.workingMountDir = workingMountDir
// Setup mounter
mounter, err := NewFakeMounter()
if err != nil {
t.Fatalf("failed to get fake mounter: %v", err)
}
d.mounter = mounter
sourceTest := testutil.GetWorkDirPath("test-csi", t)
cases := []struct {
name string
req *csi.CreateVolumeRequest
resp *csi.CreateVolumeResponse
skipOnWindows bool
flakyWindowsErrorMessage string
expectErr bool
}{
{
name: "valid defaults",
req: &csi.CreateVolumeRequest{
Name: testCSIVolume,
VolumeCapabilities: []*csi.VolumeCapability{
{
AccessType: &csi.VolumeCapability_Mount{
Mount: &csi.VolumeCapability_MountVolume{},
},
AccessMode: &csi.VolumeCapability_AccessMode{
Mode: csi.VolumeCapability_AccessMode_MULTI_NODE_MULTI_WRITER,
},
},
},
Parameters: map[string]string{
sourceField: testServer,
},
Secrets: map[string]string{
usernameField: "test",
passwordField: "test",
domainField: "test_doamin",
},
},
resp: &csi.CreateVolumeResponse{
Volume: &csi.Volume{
VolumeId: testVolumeID,
VolumeContext: map[string]string{
sourceField: testServer,
subDirField: testCSIVolume,
},
},
},
skipOnWindows: true,
flakyWindowsErrorMessage: fmt.Sprintf("volume(vol_1##) mount \"test-server\" on %#v failed with "+
"smb mapping failed with error: rpc error: code = Unknown desc = NewSmbGlobalMapping failed.",
sourceTest),
},
{
name: "name empty",
req: &csi.CreateVolumeRequest{
VolumeCapabilities: []*csi.VolumeCapability{
{
AccessType: &csi.VolumeCapability_Mount{
Mount: &csi.VolumeCapability_MountVolume{},
},
AccessMode: &csi.VolumeCapability_AccessMode{
Mode: csi.VolumeCapability_AccessMode_MULTI_NODE_MULTI_WRITER,
},
},
},
Parameters: map[string]string{
sourceField: testServer,
},
},
expectErr: true,
},
{
name: "Volume capabilities missing",
req: &csi.CreateVolumeRequest{
VolumeCapabilities: []*csi.VolumeCapability{},
},
expectErr: true,
},
{
name: "block volume capability not supported",
req: &csi.CreateVolumeRequest{
VolumeCapabilities: blockVolCap,
},
expectErr: true,
},
{
name: "invalid create context",
req: &csi.CreateVolumeRequest{
Name: testCSIVolume,
VolumeCapabilities: []*csi.VolumeCapability{
{
AccessType: &csi.VolumeCapability_Mount{
Mount: &csi.VolumeCapability_MountVolume{},
},
AccessMode: &csi.VolumeCapability_AccessMode{
Mode: csi.VolumeCapability_AccessMode_MULTI_NODE_MULTI_WRITER,
},
},
},
Parameters: map[string]string{
"unknown-parameter": "foo",
},
},
expectErr: true,
},
}
for _, test := range cases {
t.Run(test.name, func(t *testing.T) {
if test.skipOnWindows && runtime.GOOS == "windows" {
return
}
// Setup
_ = os.MkdirAll(filepath.Join(d.workingMountDir, testCSIVolume), os.ModePerm)
// Run
resp, err := d.CreateVolume(context.TODO(), test.req)
// Verify
if test.expectErr && err == nil {
t.Errorf("test %q failed; got success", test.name)
}
// separate assertion for flaky error messages
if test.flakyWindowsErrorMessage != "" && runtime.GOOS == "windows" {
fmt.Println("Skipping checks on Windows ENV") // nolint
} else {
if !test.expectErr && err != nil {
t.Errorf("test %q failed: %v", test.name, err)
}
if !reflect.DeepEqual(resp, test.resp) {
t.Errorf("test %q failed: got resp %+v, expected %+v", test.name, resp, test.resp)
}
if !test.expectErr {
info, err := os.Stat(filepath.Join(d.workingMountDir, test.req.Name, test.req.Name))
if err != nil {
t.Errorf("test %q failed: couldn't find volume subdirectory: %v", test.name, err)
}
if !info.IsDir() {
t.Errorf("test %q failed: subfile not a directory", test.name)
}
}
}
})
}
}
func TestDeleteVolume(t *testing.T) {
d := NewFakeDriver()
// Setup workingMountDir
workingMountDir, err := os.Getwd()
if err != nil {
t.Errorf("failed to get current working directory")
}
d.workingMountDir = workingMountDir
// Setup mounter
mounter, err := NewFakeMounter()
if err != nil {
t.Fatalf("failed to get fake mounter: %v", err)
}
d.mounter = mounter
cases := []struct {
desc string
req *csi.DeleteVolumeRequest
resp *csi.DeleteVolumeResponse
expectedErr error
}{
{
desc: "Volume ID missing",
req: &csi.DeleteVolumeRequest{},
resp: nil,
expectedErr: status.Error(codes.InvalidArgument, "Volume ID missing in request"),
},
{
desc: "Valid request",
req: &csi.DeleteVolumeRequest{
VolumeId: testVolumeID,
Secrets: map[string]string{
usernameField: "test",
passwordField: "test",
domainField: "test_doamin",
},
},
resp: &csi.DeleteVolumeResponse{},
expectedErr: nil,
},
}
for _, test := range cases {
t.Run(test.desc, func(t *testing.T) {
// Setup
_ = os.MkdirAll(filepath.Join(d.workingMountDir, testCSIVolume), os.ModePerm)
_, _ = os.Create(filepath.Join(d.workingMountDir, testCSIVolume, testCSIVolume))
// Run
resp, err := d.DeleteVolume(context.TODO(), test.req)
// Verify
if runtime.GOOS == "windows" {
// skip checks
fmt.Println("Skipping checks on Windows ENV") // nolint
} else {
if test.expectedErr == nil && err != nil {
t.Errorf("test %q failed: %v", test.desc, err)
}
if test.expectedErr != nil && err == nil {
t.Errorf("test %q failed; expected error %v, got success", test.desc, test.expectedErr)
}
if !reflect.DeepEqual(resp, test.resp) {
t.Errorf("test %q failed: got resp %+v, expected %+v", test.desc, resp, test.resp)
}
if _, err := os.Stat(filepath.Join(d.workingMountDir, testCSIVolume, testCSIVolume)); test.expectedErr == nil && !os.IsNotExist(err) {
t.Errorf("test %q failed: expected volume subdirectory deleted, it still exists", test.desc)
}
}
})
}
}
func TestValidateVolumeCapabilities(t *testing.T) {
d := NewFakeDriver()
mountVolCap := []*csi.VolumeCapability{
{
AccessType: &csi.VolumeCapability_Mount{
Mount: &csi.VolumeCapability_MountVolume{},
},
AccessMode: &csi.VolumeCapability_AccessMode{
Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER,
},
},
}
blockVolCap := []*csi.VolumeCapability{
{
AccessType: &csi.VolumeCapability_Block{
Block: &csi.VolumeCapability_BlockVolume{},
},
},
}
tests := []struct {
desc string
req *csi.ValidateVolumeCapabilitiesRequest
expectedErr error
}{
{
desc: "Volume ID missing",
req: &csi.ValidateVolumeCapabilitiesRequest{},
expectedErr: status.Error(codes.InvalidArgument, "Volume ID missing in request"),
},
{
desc: "Volume capabilities missing",
req: &csi.ValidateVolumeCapabilitiesRequest{VolumeId: "vol_1"},
expectedErr: status.Error(codes.InvalidArgument, "volume capabilities missing in request"),
},
{
desc: "block volume capability not supported",
req: &csi.ValidateVolumeCapabilitiesRequest{
VolumeId: "vol_1",
VolumeCapabilities: blockVolCap,
},
expectedErr: status.Error(codes.InvalidArgument, "block volume capability not supported"),
},
{
desc: "Valid request",
req: &csi.ValidateVolumeCapabilitiesRequest{
VolumeId: "vol_1#f5713de20cde511e8ba4900#fileshare#diskname#",
VolumeCapabilities: mountVolCap,
},
expectedErr: nil,
},
}
for _, test := range tests {
_, err := d.ValidateVolumeCapabilities(context.Background(), test.req)
if !reflect.DeepEqual(err, test.expectedErr) {
t.Errorf("[test: %s] Unexpected error: %v, expected error: %v", test.desc, err, test.expectedErr)
}
}
}
func TestControllerPublishVolume(t *testing.T) {
d := NewFakeDriver()
req := csi.ControllerPublishVolumeRequest{}
resp, err := d.ControllerPublishVolume(context.Background(), &req)
assert.Nil(t, resp)
if !reflect.DeepEqual(err, status.Error(codes.Unimplemented, "")) {
t.Errorf("Unexpected error: %v", err)
}
}
func TestControllerUnpublishVolume(t *testing.T) {
d := NewFakeDriver()
req := csi.ControllerUnpublishVolumeRequest{}
resp, err := d.ControllerUnpublishVolume(context.Background(), &req)
assert.Nil(t, resp)
if !reflect.DeepEqual(err, status.Error(codes.Unimplemented, "")) {
t.Errorf("Unexpected error: %v", err)
}
}
func TestGetCapacity(t *testing.T) {
d := NewFakeDriver()
req := csi.GetCapacityRequest{}
resp, err := d.GetCapacity(context.Background(), &req)
assert.Nil(t, resp)
if !reflect.DeepEqual(err, status.Error(codes.Unimplemented, "")) {
t.Errorf("Unexpected error: %v", err)
}
}
func TestListVolumes(t *testing.T) {
d := NewFakeDriver()
req := csi.ListVolumesRequest{}
resp, err := d.ListVolumes(context.Background(), &req)
assert.Nil(t, resp)
if !reflect.DeepEqual(err, status.Error(codes.Unimplemented, "")) {
t.Errorf("Unexpected error: %v", err)
}
}
func TestControllerExpandVolume(t *testing.T) {
d := NewFakeDriver()
testCases := []struct {
name string
testFunc func(t *testing.T)
}{
{
name: "volume ID missing",
testFunc: func(t *testing.T) {
req := &csi.ControllerExpandVolumeRequest{}
_, err := d.ControllerExpandVolume(context.Background(), req)
expectedErr := status.Error(codes.InvalidArgument, "Volume ID missing in request")
if !reflect.DeepEqual(err, expectedErr) {
t.Errorf("actualErr: (%v), expectedErr: (%v)", err, expectedErr)
}
},
},
{
name: "Capacity Range missing",
testFunc: func(t *testing.T) {
req := &csi.ControllerExpandVolumeRequest{
VolumeId: "unit-test",
}
_, err := d.ControllerExpandVolume(context.Background(), req)
expectedErr := status.Error(codes.InvalidArgument, "Capacity Range missing in request")
if !reflect.DeepEqual(err, expectedErr) {
t.Errorf("actualErr: (%v), expectedErr: (%v)", err, expectedErr)
}
},
},
{
name: "Error = nil",
testFunc: func(t *testing.T) {
req := &csi.ControllerExpandVolumeRequest{
VolumeId: "unit-test",
CapacityRange: &csi.CapacityRange{
RequiredBytes: 10000,
},
}
_, err := d.ControllerExpandVolume(context.Background(), req)
if !reflect.DeepEqual(err, nil) {
t.Errorf("actualErr: (%v), expectedErr: (%v)", err, nil)
}
},
},
}
for _, tc := range testCases {
t.Run(tc.name, tc.testFunc)
}
}
func TestControllerGetVolume(t *testing.T) {
d := NewFakeDriver()
req := csi.ControllerGetVolumeRequest{}
resp, err := d.ControllerGetVolume(context.Background(), &req)
assert.Nil(t, resp)
if !reflect.DeepEqual(err, status.Error(codes.Unimplemented, "")) {
t.Errorf("Unexpected error: %v", err)
}
}
func TestCreateSnapshot(t *testing.T) {
d := NewFakeDriver()
req := csi.CreateSnapshotRequest{}
resp, err := d.CreateSnapshot(context.Background(), &req)
assert.Nil(t, resp)
if !reflect.DeepEqual(err, status.Error(codes.Unimplemented, "")) {
t.Errorf("Unexpected error: %v", err)
}
}
func TestDeleteSnapshot(t *testing.T) {
d := NewFakeDriver()
req := csi.DeleteSnapshotRequest{}
resp, err := d.DeleteSnapshot(context.Background(), &req)
assert.Nil(t, resp)
if !reflect.DeepEqual(err, status.Error(codes.Unimplemented, "")) {
t.Errorf("Unexpected error: %v", err)
}
}
func TestListSnapshots(t *testing.T) {
d := NewFakeDriver()
req := csi.ListSnapshotsRequest{}
resp, err := d.ListSnapshots(context.Background(), &req)
assert.Nil(t, resp)
if !reflect.DeepEqual(err, status.Error(codes.Unimplemented, "")) {
t.Errorf("Unexpected error: %v", err)
}
}
func TestGetSmbVolFromID(t *testing.T) {
cases := []struct {
desc string
volumeID string
source string
subDir string
uuid string
onDelete string
expectErr bool
}{
{
desc: "correct volume id",
volumeID: "smb-server.default.svc.cluster.local/share#pvc-4729891a-f57e-4982-9c60-e9884af1be2f",
source: "//smb-server.default.svc.cluster.local/share",
subDir: "pvc-4729891a-f57e-4982-9c60-e9884af1be2f",
expectErr: false,
},
{
desc: "correct volume id with //",
volumeID: "//smb-server.default.svc.cluster.local/share#pvc-4729891a-f57e-4982-9c60-e9884af1be2f",
source: "//smb-server.default.svc.cluster.local/share",
subDir: "pvc-4729891a-f57e-4982-9c60-e9884af1be2f",
expectErr: false,
},
{
desc: "correct volume id with empty uuid",
volumeID: "smb-server.default.svc.cluster.local/share#pvc-4729891a-f57e-4982-9c60-e9884af1be2f#",
source: "//smb-server.default.svc.cluster.local/share",
subDir: "pvc-4729891a-f57e-4982-9c60-e9884af1be2f",
expectErr: false,
},
{
desc: "correct volume id with multiple base directories",
volumeID: "smb-server.default.svc.cluster.local/share/dir1/dir2#pvc-4729891a-f57e-4982-9c60-e9884af1be2f",
source: "//smb-server.default.svc.cluster.local/share/dir1/dir2",
subDir: "pvc-4729891a-f57e-4982-9c60-e9884af1be2f",
expectErr: false,
},
{
desc: "existing sub dir",
volumeID: "smb-server.default.svc.cluster.local/share#subdir#pvc-4729891a-f57e-4982-9c60-e9884af1be2f",
source: "//smb-server.default.svc.cluster.local/share",
subDir: "subdir",
uuid: "pvc-4729891a-f57e-4982-9c60-e9884af1be2f",
expectErr: false,
},
{
desc: "valid request nested ondelete retain",
volumeID: "smb-server.default.svc.cluster.local/share#subdir#pvc-4729891a-f57e-4982-9c60-e9884af1be2f#retain",
source: "//smb-server.default.svc.cluster.local/share",
subDir: "subdir",
uuid: "pvc-4729891a-f57e-4982-9c60-e9884af1be2f",
onDelete: "retain",
expectErr: false,
},
{
desc: "valid request nested ondelete archive",
volumeID: "smb-server.default.svc.cluster.local/share#subdir#pvc-4729891a-f57e-4982-9c60-e9884af1be2f#archive",
source: "//smb-server.default.svc.cluster.local/share",
subDir: "subdir",
uuid: "pvc-4729891a-f57e-4982-9c60-e9884af1be2f",
onDelete: "archive",
expectErr: false,
},
{
desc: "incorrect volume id",
volumeID: "smb-server.default.svc.cluster.local/share",
source: "//smb-server.default.svc.cluster.local/share",
subDir: "pvc-4729891a-f57e-4982-9c60-e9884af1be2f",
expectErr: true,
},
}
for _, test := range cases {
t.Run(test.desc, func(t *testing.T) {
smbVolume, err := getSmbVolFromID(test.volumeID)
if !test.expectErr {
assert.Equal(t, smbVolume.source, test.source)
assert.Equal(t, smbVolume.subDir, test.subDir)
assert.Equal(t, smbVolume.uuid, test.uuid)
assert.Equal(t, smbVolume.onDelete, test.onDelete)
assert.Nil(t, err)
} else {
assert.NotNil(t, err)
}
})
}
}
func TestGetVolumeIDFromSmbVol(t *testing.T) {
cases := []struct {
desc string
vol *smbVolume
result string
}{
{
desc: "volume without uuid",
vol: &smbVolume{
source: "//smb-server.default.svc.cluster.local/share",
subDir: "subdir",
},
result: "smb-server.default.svc.cluster.local/share#subdir##",
},
{
desc: "volume with uuid",
vol: &smbVolume{
source: "//smb-server.default.svc.cluster.local/share",
subDir: "subdir",
uuid: "uuid",
},
result: "smb-server.default.svc.cluster.local/share#subdir#uuid#",
},
{
desc: "volume without subdir",
vol: &smbVolume{
source: "//smb-server.default.svc.cluster.local/share",
},
result: "smb-server.default.svc.cluster.local/share###",
},
{
desc: "volume with nested onDelete retain",
vol: &smbVolume{
source: "//smb-server.default.svc.cluster.local/share",
subDir: "subdir",
uuid: "uuid",
onDelete: "retain",
},
result: "smb-server.default.svc.cluster.local/share#subdir#uuid#retain",
},
}
for _, test := range cases {
volumeID := getVolumeIDFromSmbVol(test.vol)
assert.Equal(t, volumeID, test.result)
}
}
func TestGetInternalMountPath(t *testing.T) {
cases := []struct {
desc string
workingMountDir string
vol *smbVolume
result string
}{
{
desc: "nil volume",
workingMountDir: "/tmp",
result: "",
},
{
desc: "uuid not empty",
workingMountDir: "/tmp",
vol: &smbVolume{
subDir: "subdir",
uuid: "uuid",
},
result: filepath.Join("/tmp", "uuid"),
},
{
desc: "uuid empty",
workingMountDir: "/tmp",
vol: &smbVolume{
subDir: "subdir",
uuid: "",
},
result: filepath.Join("/tmp", "subdir"),
},
}
for _, test := range cases {
path := getInternalMountPath(test.workingMountDir, test.vol)
assert.Equal(t, path, test.result)
}
}
func TestNewSMBVolume(t *testing.T) {
cases := []struct {
desc string
name string
size int64
params map[string]string
expectVol *smbVolume
expectErr error
}{
{
desc: "subDir is specified",
name: "pv-name",
size: 100,
params: map[string]string{
"source": "//smb-server.default.svc.cluster.local/share",
"subDir": "subdir",
},
expectVol: &smbVolume{
id: "smb-server.default.svc.cluster.local/share#subdir#pv-name#",
source: "//smb-server.default.svc.cluster.local/share",
subDir: "subdir",
size: 100,
uuid: "pv-name",
},
},
{
desc: "subDir with pv/pvc metadata is specified",
name: "pv-name",
size: 100,
params: map[string]string{
"source": "//smb-server.default.svc.cluster.local/share",
"subDir": fmt.Sprintf("subdir-%s-%s-%s", pvcNameMetadata, pvcNamespaceMetadata, pvNameMetadata),
pvcNameKey: "pvcname",
pvcNamespaceKey: "pvcnamespace",
pvNameKey: "pvname",
},
expectVol: &smbVolume{
id: "smb-server.default.svc.cluster.local/share#subdir-pvcname-pvcnamespace-pvname#pv-name#",
source: "//smb-server.default.svc.cluster.local/share",
subDir: "subdir-pvcname-pvcnamespace-pvname",
size: 100,
uuid: "pv-name",
},
},
{
desc: "subDir not specified",
name: "pv-name",
size: 200,
params: map[string]string{
"source": "//smb-server.default.svc.cluster.local/share",
},
expectVol: &smbVolume{
id: "smb-server.default.svc.cluster.local/share#pv-name##",
source: "//smb-server.default.svc.cluster.local/share",
subDir: "pv-name",
size: 200,
uuid: "",
},
},
{
desc: "invalid parameter",
params: map[string]string{"invalid-parameter": "value"},
expectVol: nil,
expectErr: fmt.Errorf("invalid parameter %s in storage class", "invalid-parameter"),
},
{
desc: "source value is empty",
params: map[string]string{},
expectVol: nil,
expectErr: fmt.Errorf("%s is a required parameter", sourceField),
},
}
for _, test := range cases {
vol, err := newSMBVolume(test.name, test.size, test.params, "")
if !reflect.DeepEqual(err, test.expectErr) {
t.Errorf("[test: %s] Unexpected error: %v, expected error: %v", test.desc, err, test.expectErr)
}
if !reflect.DeepEqual(vol, test.expectVol) {
t.Errorf("[test: %s] Unexpected vol: %v, expected vol: %v", test.desc, vol, test.expectVol)
}
}
}
func TestIsValidVolumeCapabilities(t *testing.T) {
mountVolumeCapabilities := []*csi.VolumeCapability{
{
AccessType: &csi.VolumeCapability_Mount{
Mount: &csi.VolumeCapability_MountVolume{},
},
},
}
blockVolumeCapabilities := []*csi.VolumeCapability{
{
AccessType: &csi.VolumeCapability_Block{
Block: &csi.VolumeCapability_BlockVolume{},
},
},
}
cases := []struct {
desc string
volCaps []*csi.VolumeCapability
expectErr error
}{
{
volCaps: mountVolumeCapabilities,
expectErr: nil,
},
{
volCaps: blockVolumeCapabilities,
expectErr: fmt.Errorf("block volume capability not supported"),
},
{
volCaps: []*csi.VolumeCapability{},
expectErr: fmt.Errorf("volume capabilities missing in request"),
},
}
for _, test := range cases {
err := isValidVolumeCapabilities(test.volCaps)
if !reflect.DeepEqual(err, test.expectErr) {
t.Errorf("[test: %s] Unexpected error: %v, expected error: %v", test.desc, err, test.expectErr)
}
}
}
func TestCopyFromVolume(t *testing.T) {
d := NewFakeDriver()
// Setup workingMountDir
workingMountDir, err := os.Getwd()
if err != nil {
t.Errorf("failed to get current working directory")
}
d.workingMountDir = workingMountDir
// Setup mounter
mounter, err := NewFakeMounter()
if err != nil {
t.Fatalf("failed to get fake mounter: %v", err)
}
d.mounter = mounter
cases := []struct {
desc string
req *csi.CreateVolumeRequest
dstVol *smbVolume
expectErr error
}{
{
desc: "getInternalVolumePath failed",
req: &csi.CreateVolumeRequest{
Name: testCSIVolume,
VolumeCapabilities: []*csi.VolumeCapability{
{
AccessType: &csi.VolumeCapability_Mount{
Mount: &csi.VolumeCapability_MountVolume{},
},
AccessMode: &csi.VolumeCapability_AccessMode{
Mode: csi.VolumeCapability_AccessMode_MULTI_NODE_MULTI_WRITER,
},
},
},
Parameters: map[string]string{
sourceField: testServer,
},
Secrets: map[string]string{
usernameField: "test",
passwordField: "test",
domainField: "test_doamin",
},
VolumeContentSource: &csi.VolumeContentSource{
Type: &csi.VolumeContentSource_Volume{
Volume: &csi.VolumeContentSource_VolumeSource{
VolumeId: "unit-test",
},
},
},
},
dstVol: &smbVolume{
id: "smb-server.default.svc.cluster.local/share#pvc-4729891a-f57e-4982-9c60-e9884af1be2f",
source: "//smb-server.default.svc.cluster.local/share",
subDir: "pvc-4729891a-f57e-4982-9c60-e9884af1be2f",
},
expectErr: status.Error(codes.NotFound, "could not split \"unit-test\" into server and subDir"),
},
{
desc: "valid copy",
req: &csi.CreateVolumeRequest{
Name: testCSIVolume,
VolumeCapabilities: []*csi.VolumeCapability{
{
AccessType: &csi.VolumeCapability_Mount{
Mount: &csi.VolumeCapability_MountVolume{},
},
AccessMode: &csi.VolumeCapability_AccessMode{
Mode: csi.VolumeCapability_AccessMode_MULTI_NODE_MULTI_WRITER,
},
},
},
Parameters: map[string]string{
sourceField: testServer,
},
Secrets: map[string]string{
usernameField: "test",
passwordField: "test",
domainField: "test_doamin",
},
VolumeContentSource: &csi.VolumeContentSource{
Type: &csi.VolumeContentSource_Volume{
Volume: &csi.VolumeContentSource_VolumeSource{
VolumeId: testVolumeID,
},
},
},
},
dstVol: &smbVolume{
id: "smb-server.default.svc.cluster.local/share#pvc-4729891a-f57e-4982-9c60-e9884af1be2f",
source: "//smb-server.default.svc.cluster.local/share",
subDir: "pvc-4729891a-f57e-4982-9c60-e9884af1be2f",
},
expectErr: nil,
},
}
for _, test := range cases {
if test.desc == "valid copy" && runtime.GOOS == "windows" {
t.Skip("Skipping test on Windows")
}
// Setup
_ = os.MkdirAll(filepath.Join(d.workingMountDir, testCSIVolume, testCSIVolume), os.ModePerm)
err := d.copyFromVolume(context.TODO(), test.req, test.dstVol)
if runtime.GOOS == "windows" {
fmt.Println("Skipping checks on Windows ENV") // nolint
} else {
if !reflect.DeepEqual(err, test.expectErr) {
t.Errorf("[test: %s] Unexpected error: %v, expected error: %v", test.desc, err, test.expectErr)
}
}
}
}