Skip to content
This repository was archived by the owner on Mar 22, 2018. It is now read-only.

Commit 3f26167

Browse files
committed
add unit test for csi cinder driver
1 parent 781a89a commit 3f26167

10 files changed

Lines changed: 680 additions & 90 deletions

File tree

pkg/cinder/controllerserver.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ func (cs *controllerServer) CreateVolume(ctx context.Context, req *csi.CreateVol
5353

5454
// Volume Availability - Default is nova
5555
volAvailability := req.GetParameters()["availability"]
56-
if len(volType) == 0 {
56+
if len(volAvailability) == 0 {
5757
volAvailability = "nova"
5858
}
5959

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
package cinder
2+
3+
import (
4+
"testing"
5+
6+
"github.com/container-storage-interface/spec/lib/go/csi"
7+
"github.com/kubernetes-csi/drivers/pkg/cinder/openstack"
8+
"github.com/stretchr/testify/assert"
9+
"github.com/stretchr/testify/mock"
10+
)
11+
12+
var fakeCs *controllerServer
13+
14+
// Init Controller Server
15+
func init() {
16+
if fakeCs == nil {
17+
d := NewDriver(fakeNodeID, fakeEndpoint)
18+
fakeCs = NewControllerServer(d)
19+
}
20+
}
21+
22+
// Test CreateVolume
23+
func TestCreateVolume(t *testing.T) {
24+
25+
// mock OpenStack
26+
osmock := new(openstack.OpenStackMock)
27+
// CreateVolume(name string, size int, vtype, availability string, tags *map[string]string) (string, string, error)
28+
osmock.On("CreateVolume", fakeVolName, mock.AnythingOfType("int"), fakeVolType, fakeAvailability, (*map[string]string)(nil)).Return(fakeVolID, fakeAvailability, nil)
29+
openstack.OsInstance = osmock
30+
31+
// Init assert
32+
assert := assert.New(t)
33+
34+
// Fake request
35+
fakeReq := &csi.CreateVolumeRequest{
36+
Version: &version,
37+
Name: fakeVolName,
38+
VolumeCapabilities: nil,
39+
}
40+
41+
// Invoke CreateVolume
42+
actualRes, err := fakeCs.CreateVolume(fakeCtx, fakeReq)
43+
if err != nil {
44+
t.Errorf("failed to CreateVolume: %v", err)
45+
}
46+
47+
// Assert
48+
assert.NotNil(actualRes.VolumeInfo)
49+
50+
assert.NotEqual(0, len(actualRes.VolumeInfo.Id), "Volume Id is nil")
51+
52+
assert.Equal(fakeAvailability, actualRes.VolumeInfo.Attributes["availability"])
53+
}
54+
55+
// Test DeleteVolume
56+
func TestDeleteVolume(t *testing.T) {
57+
58+
// mock OpenStack
59+
osmock := new(openstack.OpenStackMock)
60+
// DeleteVolume(volumeID string) error
61+
osmock.On("DeleteVolume", fakeVolID).Return(nil)
62+
openstack.OsInstance = osmock
63+
64+
// Init assert
65+
assert := assert.New(t)
66+
67+
// Fake request
68+
fakeReq := &csi.DeleteVolumeRequest{
69+
Version: &version,
70+
VolumeId: fakeVolID,
71+
}
72+
73+
// Expected Result
74+
expectedRes := &csi.DeleteVolumeResponse{}
75+
76+
// Invoke DeleteVolume
77+
actualRes, err := fakeCs.DeleteVolume(fakeCtx, fakeReq)
78+
if err != nil {
79+
t.Errorf("failed to DeleteVolume: %v", err)
80+
}
81+
82+
// Assert
83+
assert.Equal(expectedRes, actualRes)
84+
}
85+
86+
// Test ControllerPublishVolume
87+
func TestControllerPublishVolume(t *testing.T) {
88+
89+
// mock OpenStack
90+
osmock := new(openstack.OpenStackMock)
91+
// AttachVolume(instanceID, volumeID string) (string, error)
92+
osmock.On("AttachVolume", fakeNodeID, fakeVolID).Return(fakeVolID, nil)
93+
// WaitDiskAttached(instanceID string, volumeID string) error
94+
osmock.On("WaitDiskAttached", fakeNodeID, fakeVolID).Return(nil)
95+
// GetAttachmentDiskPath(instanceID, volumeID string) (string, error)
96+
osmock.On("GetAttachmentDiskPath", fakeNodeID, fakeVolID).Return(fakeDevicePath, nil)
97+
openstack.OsInstance = osmock
98+
99+
// Init assert
100+
assert := assert.New(t)
101+
102+
// Fake request
103+
fakeReq := &csi.ControllerPublishVolumeRequest{
104+
Version: &version,
105+
VolumeId: fakeVolID,
106+
NodeId: fakeNodeID,
107+
VolumeCapability: nil,
108+
Readonly: false,
109+
}
110+
111+
// Expected Result
112+
expectedRes := &csi.ControllerPublishVolumeResponse{
113+
PublishVolumeInfo: map[string]string{
114+
"DevicePath": fakeDevicePath,
115+
},
116+
}
117+
118+
// Invoke ControllerPublishVolume
119+
actualRes, err := fakeCs.ControllerPublishVolume(fakeCtx, fakeReq)
120+
if err != nil {
121+
t.Errorf("failed to ControllerPublishVolume: %v", err)
122+
}
123+
124+
// Assert
125+
assert.Equal(expectedRes, actualRes)
126+
}
127+
128+
// Test ControllerUnpublishVolume
129+
func TestControllerUnpublishVolume(t *testing.T) {
130+
131+
// mock OpenStack
132+
osmock := new(openstack.OpenStackMock)
133+
// DetachVolume(instanceID, volumeID string) error
134+
osmock.On("DetachVolume", fakeNodeID, fakeVolID).Return(nil)
135+
// WaitDiskDetached(instanceID string, volumeID string) error
136+
osmock.On("WaitDiskDetached", fakeNodeID, fakeVolID).Return(nil)
137+
openstack.OsInstance = osmock
138+
139+
// Init assert
140+
assert := assert.New(t)
141+
142+
// Fake request
143+
fakeReq := &csi.ControllerUnpublishVolumeRequest{
144+
Version: &version,
145+
VolumeId: fakeVolID,
146+
NodeId: fakeNodeID,
147+
}
148+
149+
// Expected Result
150+
expectedRes := &csi.ControllerUnpublishVolumeResponse{}
151+
152+
// Invoke ControllerUnpublishVolume
153+
actualRes, err := fakeCs.ControllerUnpublishVolume(fakeCtx, fakeReq)
154+
if err != nil {
155+
t.Errorf("failed to ControllerUnpublishVolume: %v", err)
156+
}
157+
158+
// Assert
159+
assert.Equal(expectedRes, actualRes)
160+
}

pkg/cinder/fake.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package cinder
2+
3+
import (
4+
"golang.org/x/net/context"
5+
)
6+
7+
var fakeNodeID = "CSINodeID"
8+
var fakeEndpoint = "tcp://127.0.0.1:10000"
9+
var fakeCtx = context.Background()
10+
var fakeVolName = "CSIVolumeName"
11+
var fakeVolID = "CSIVolumeID"
12+
var fakeVolType = "lvmdriver-1"
13+
var fakeAvailability = "nova"
14+
var fakeDevicePath = "/dev/xxx"
15+
var fakeTargetPath = "/mnt/cinder"

pkg/cinder/mount/mount.go

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
/*
2+
Copyright 2017 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package mount
18+
19+
import (
20+
"fmt"
21+
"io/ioutil"
22+
"os"
23+
"time"
24+
25+
"k8s.io/kubernetes/pkg/util/mount"
26+
"k8s.io/kubernetes/pkg/volume/util"
27+
utilexec "k8s.io/utils/exec"
28+
29+
"github.com/golang/glog"
30+
)
31+
32+
const (
33+
probeVolumeDuration = 1 * time.Second
34+
probeVolumeTimeout = 60 * time.Second
35+
)
36+
37+
type IMount interface {
38+
ScanForAttach(devicePath string) error
39+
IsLikelyNotMountPointAttach(targetpath string) (bool, error)
40+
FormatAndMount(source string, target string, fstype string, options []string) error
41+
IsLikelyNotMountPointDetach(targetpath string) (bool, error)
42+
UnmountPath(mountPath string) error
43+
}
44+
45+
type Mount struct {
46+
}
47+
48+
var MInstance IMount = nil
49+
50+
func GetMountProvider() (IMount, error) {
51+
52+
if MInstance == nil {
53+
MInstance = &Mount{}
54+
}
55+
return MInstance, nil
56+
}
57+
58+
// probeVolume probes volume in compute
59+
func probeVolume() error {
60+
// rescan scsi bus
61+
scsi_path := "/sys/class/scsi_host/"
62+
if dirs, err := ioutil.ReadDir(scsi_path); err == nil {
63+
for _, f := range dirs {
64+
name := scsi_path + f.Name() + "/scan"
65+
data := []byte("- - -")
66+
ioutil.WriteFile(name, data, 0666)
67+
}
68+
}
69+
70+
executor := utilexec.New()
71+
args := []string{"trigger"}
72+
cmd := executor.Command("udevadm", args...)
73+
_, err := cmd.CombinedOutput()
74+
if err != nil {
75+
glog.V(3).Infof("error running udevadm trigger %v\n", err)
76+
return err
77+
}
78+
glog.V(4).Infof("Successfully probed all attachments")
79+
return nil
80+
}
81+
82+
// ScanForAttach
83+
func (m *Mount) ScanForAttach(devicePath string) error {
84+
ticker := time.NewTicker(probeVolumeDuration)
85+
defer ticker.Stop()
86+
timer := time.NewTimer(probeVolumeTimeout)
87+
defer timer.Stop()
88+
89+
for {
90+
select {
91+
case <-ticker.C:
92+
glog.V(5).Infof("Checking Cinder disk %q is attached.", devicePath)
93+
probeVolume()
94+
95+
exists, err := util.PathExists(devicePath)
96+
if exists && err == nil {
97+
return nil
98+
} else {
99+
glog.V(3).Infof("Could not find attached Cinder disk %s", devicePath)
100+
}
101+
case <-timer.C:
102+
return fmt.Errorf("Could not find attached Cinder disk %s. Timeout waiting for mount paths to be created.", devicePath)
103+
}
104+
}
105+
}
106+
107+
// FormatAndMount
108+
func (m *Mount) FormatAndMount(source string, target string, fstype string, options []string) error {
109+
diskMounter := &mount.SafeFormatAndMount{Interface: mount.New(""), Exec: mount.NewOsExec()}
110+
return diskMounter.FormatAndMount(source, target, fstype, options)
111+
}
112+
113+
// IsLikelyNotMountPointAttach
114+
func (m *Mount) IsLikelyNotMountPointAttach(targetpath string) (bool, error) {
115+
notMnt, err := mount.New("").IsLikelyNotMountPoint(targetpath)
116+
if err != nil {
117+
if os.IsNotExist(err) {
118+
err = os.MkdirAll(targetpath, 0750)
119+
if err == nil {
120+
notMnt = true
121+
}
122+
}
123+
}
124+
return notMnt, err
125+
}
126+
127+
// IsLikelyNotMountPointDetach
128+
func (m *Mount) IsLikelyNotMountPointDetach(targetpath string) (bool, error) {
129+
notMnt, err := mount.New("").IsLikelyNotMountPoint(targetpath)
130+
if err != nil {
131+
if os.IsNotExist(err) {
132+
return notMnt,fmt.Errorf("targetpath not found")
133+
} else {
134+
return notMnt, err
135+
}
136+
}
137+
return notMnt, nil
138+
}
139+
140+
// UnmountPath
141+
func (m *Mount) UnmountPath(mountPath string) error {
142+
return util.UnmountPath(mountPath, mount.New(""))
143+
}

0 commit comments

Comments
 (0)