Add unit tests for skipping attach

This commit is contained in:
Jan Safranek
2018-08-29 13:23:15 +02:00
committed by Hemant Kumar
parent c6c74d6846
commit f474b54447
6 changed files with 285 additions and 75 deletions

View File

@@ -60,10 +60,14 @@ go_test(
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library", "//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
"//staging/src/k8s.io/client-go/testing:go_default_library", "//staging/src/k8s.io/client-go/testing:go_default_library",
"//staging/src/k8s.io/client-go/util/testing:go_default_library", "//staging/src/k8s.io/client-go/util/testing:go_default_library",
"//staging/src/k8s.io/csi-api/pkg/apis/csi/v1alpha1:go_default_library",
"//staging/src/k8s.io/csi-api/pkg/client/clientset/versioned/fake:go_default_library",
"//vendor/github.com/container-storage-interface/spec/lib/go/csi/v0:go_default_library", "//vendor/github.com/container-storage-interface/spec/lib/go/csi/v0:go_default_library",
"//vendor/github.com/golang/glog:go_default_library",
], ],
) )

View File

@@ -24,19 +24,28 @@ import (
"testing" "testing"
"time" "time"
"github.com/golang/glog"
storage "k8s.io/api/storage/v1beta1" storage "k8s.io/api/storage/v1beta1"
apierrs "k8s.io/apimachinery/pkg/api/errors" apierrs "k8s.io/apimachinery/pkg/api/errors"
meta "k8s.io/apimachinery/pkg/apis/meta/v1" meta "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/watch" "k8s.io/apimachinery/pkg/watch"
utilfeature "k8s.io/apiserver/pkg/util/feature"
clientset "k8s.io/client-go/kubernetes"
fakeclient "k8s.io/client-go/kubernetes/fake" fakeclient "k8s.io/client-go/kubernetes/fake"
core "k8s.io/client-go/testing" core "k8s.io/client-go/testing"
utiltesting "k8s.io/client-go/util/testing" utiltesting "k8s.io/client-go/util/testing"
fakecsi "k8s.io/csi-api/pkg/client/clientset/versioned/fake"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
volumetest "k8s.io/kubernetes/pkg/volume/testing" volumetest "k8s.io/kubernetes/pkg/volume/testing"
) )
var (
bFalse bool = false
bTrue bool = true
)
func makeTestAttachment(attachID, nodeName, pvName string) *storage.VolumeAttachment { func makeTestAttachment(attachID, nodeName, pvName string) *storage.VolumeAttachment {
return &storage.VolumeAttachment{ return &storage.VolumeAttachment{
ObjectMeta: meta.ObjectMeta{ ObjectMeta: meta.ObjectMeta{
@@ -57,6 +66,40 @@ func makeTestAttachment(attachID, nodeName, pvName string) *storage.VolumeAttach
} }
} }
func markVolumeAttached(t *testing.T, client clientset.Interface, watch *watch.RaceFreeFakeWatcher, attachID string, status storage.VolumeAttachmentStatus) {
ticker := time.NewTicker(10 * time.Millisecond)
var attach *storage.VolumeAttachment
var err error
defer ticker.Stop()
// wait for attachment to be saved
for i := 0; i < 100; i++ {
attach, err = client.StorageV1beta1().VolumeAttachments().Get(attachID, meta.GetOptions{})
if err != nil {
if apierrs.IsNotFound(err) {
<-ticker.C
continue
}
t.Error(err)
}
if attach != nil {
glog.Infof("stopping wait")
break
}
}
glog.Infof("stopped wait")
if attach == nil {
t.Logf("attachment not found for id:%v", attachID)
} else {
attach.Status = status
_, err := client.StorageV1beta1().VolumeAttachments().Update(attach)
if err != nil {
t.Error(err)
}
watch.Modify(attach)
}
}
func TestAttacherAttach(t *testing.T) { func TestAttacherAttach(t *testing.T) {
testCases := []struct { testCases := []struct {
@@ -120,8 +163,7 @@ func TestAttacherAttach(t *testing.T) {
// attacher loop // attacher loop
for i, tc := range testCases { for i, tc := range testCases {
t.Logf("test case: %s", tc.name) t.Logf("test case: %s", tc.name)
plug, fakeWatcher, tmpDir, _ := newTestWatchPlugin(t, nil)
plug, fakeWatcher, tmpDir, _ := newTestWatchPlugin(t)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
attacher, err := plug.NewAttacher() attacher, err := plug.NewAttacher()
@@ -146,42 +188,158 @@ func TestAttacherAttach(t *testing.T) {
} }
}(tc.attachID, tc.nodeName, tc.shouldFail) }(tc.attachID, tc.nodeName, tc.shouldFail)
// update attachment to avoid long waitForAttachment var status storage.VolumeAttachmentStatus
ticker := time.NewTicker(10 * time.Millisecond) if tc.injectAttacherError {
defer ticker.Stop() status.Attached = false
// wait for attachment to be saved status.AttachError = &storage.VolumeError{
var attach *storage.VolumeAttachment Message: "attacher error",
for i := 0; i < 100; i++ {
attach, err = csiAttacher.k8s.StorageV1beta1().VolumeAttachments().Get(tc.attachID, meta.GetOptions{})
if err != nil {
if apierrs.IsNotFound(err) {
<-ticker.C
continue
}
t.Error(err)
} }
if attach != nil {
break
}
}
if attach == nil {
t.Logf("attachment not found for id:%v", tc.attachID)
} else { } else {
if tc.injectAttacherError { status.Attached = true
attach.Status.Attached = false
attach.Status.AttachError = &storage.VolumeError{
Message: "attacher error",
}
} else {
attach.Status.Attached = true
}
_, err = csiAttacher.k8s.StorageV1beta1().VolumeAttachments().Update(attach)
if err != nil {
t.Error(err)
}
fakeWatcher.Modify(attach)
} }
markVolumeAttached(t, csiAttacher.k8s, fakeWatcher, tc.attachID, status)
}
}
func TestAttacherWithCSIDriver(t *testing.T) {
originalFeatures := utilfeature.DefaultFeatureGate.DeepCopy()
defer func() {
utilfeature.DefaultFeatureGate = originalFeatures
}()
err := utilfeature.DefaultFeatureGate.Set("CSISkipAttach=true")
if err != nil {
t.Fatalf("Failed to set CSISkipAttach=true: %s", err)
}
tests := []struct {
name string
driver string
expectVolumeAttachment bool
}{
{
name: "CSIDriver not attachable",
driver: "not-attachable",
expectVolumeAttachment: false,
},
{
name: "CSIDriver is attachable",
driver: "attachable",
expectVolumeAttachment: true,
},
{
name: "CSIDriver.AttachRequired not set -> failure",
driver: "nil",
expectVolumeAttachment: true,
},
{
name: "CSIDriver does not exist not set -> failure",
driver: "unknown",
expectVolumeAttachment: true,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
fakeCSIClient := fakecsi.NewSimpleClientset(
getCSIDriver("not-attachable", nil, &bFalse),
getCSIDriver("attachable", nil, &bTrue),
getCSIDriver("nil", nil, nil),
)
plug, fakeWatcher, tmpDir, _ := newTestWatchPlugin(t, fakeCSIClient)
defer os.RemoveAll(tmpDir)
attacher, err := plug.NewAttacher()
if err != nil {
t.Fatalf("failed to create new attacher: %v", err)
}
csiAttacher := attacher.(*csiAttacher)
spec := volume.NewSpecFromPersistentVolume(makeTestPV("test-pv", 10, test.driver, "test-vol"), false)
expectedAttachID := getAttachmentName("test-vol", test.driver, "node")
status := storage.VolumeAttachmentStatus{
Attached: true,
}
if test.expectVolumeAttachment {
go markVolumeAttached(t, csiAttacher.k8s, fakeWatcher, expectedAttachID, status)
}
attachID, err := csiAttacher.Attach(spec, types.NodeName("node"))
if err != nil {
t.Errorf("Attach() failed: %s", err)
}
if test.expectVolumeAttachment && attachID == "" {
t.Errorf("Epected attachID, got nothing")
}
if !test.expectVolumeAttachment && attachID != "" {
t.Errorf("Epected empty attachID, got %q", attachID)
}
})
}
}
func TestAttacherWaitForVolumeAttachmentWithCSIDriver(t *testing.T) {
originalFeatures := utilfeature.DefaultFeatureGate.DeepCopy()
defer func() {
utilfeature.DefaultFeatureGate = originalFeatures
}()
err := utilfeature.DefaultFeatureGate.Set("CSISkipAttach=true")
if err != nil {
t.Fatalf("Failed to set CSISkipAttach=true: %s", err)
}
// In order to detect if the volume plugin would skip WaitForAttach for non-attachable drivers,
// we do not instantiate any VolumeAttachment. So if the plugin does not skip attach, WaitForVolumeAttachment
// will return an error that volume attachment was not found.
tests := []struct {
name string
driver string
expectError bool
}{
{
name: "CSIDriver not attachable -> success",
driver: "not-attachable",
expectError: false,
},
{
name: "CSIDriver is attachable -> failure",
driver: "attachable",
expectError: true,
},
{
name: "CSIDriver.AttachRequired not set -> failure",
driver: "nil",
expectError: true,
},
{
name: "CSIDriver does not exist not set -> failure",
driver: "unknown",
expectError: true,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
fakeCSIClient := fakecsi.NewSimpleClientset(
getCSIDriver("not-attachable", nil, &bFalse),
getCSIDriver("attachable", nil, &bTrue),
getCSIDriver("nil", nil, nil),
)
plug, tmpDir := newTestPlugin(t, nil, fakeCSIClient)
defer os.RemoveAll(tmpDir)
attacher, err := plug.NewAttacher()
if err != nil {
t.Fatalf("failed to create new attacher: %v", err)
}
csiAttacher := attacher.(*csiAttacher)
spec := volume.NewSpecFromPersistentVolume(makeTestPV("test-pv", 10, test.driver, "test-vol"), false)
_, err = csiAttacher.WaitForAttach(spec, "", nil, time.Second)
if err != nil && !test.expectError {
t.Errorf("Unexpected error: %s", err)
}
if err == nil && test.expectError {
t.Errorf("Expected error, got none")
}
})
} }
} }
@@ -237,7 +395,7 @@ func TestAttacherWaitForVolumeAttachment(t *testing.T) {
} }
for i, tc := range testCases { for i, tc := range testCases {
plug, fakeWatcher, tmpDir, _ := newTestWatchPlugin(t) plug, fakeWatcher, tmpDir, _ := newTestWatchPlugin(t, nil)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
attacher, err := plug.NewAttacher() attacher, err := plug.NewAttacher()
@@ -287,7 +445,7 @@ func TestAttacherWaitForVolumeAttachment(t *testing.T) {
} }
func TestAttacherVolumesAreAttached(t *testing.T) { func TestAttacherVolumesAreAttached(t *testing.T) {
plug, tmpDir := newTestPlugin(t) plug, tmpDir := newTestPlugin(t, nil, nil)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
attacher, err := plug.NewAttacher() attacher, err := plug.NewAttacher()
@@ -374,7 +532,7 @@ func TestAttacherDetach(t *testing.T) {
for _, tc := range testCases { for _, tc := range testCases {
t.Logf("running test: %v", tc.name) t.Logf("running test: %v", tc.name)
plug, fakeWatcher, tmpDir, client := newTestWatchPlugin(t) plug, fakeWatcher, tmpDir, client := newTestWatchPlugin(t, nil)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
if tc.reactor != nil { if tc.reactor != nil {
client.PrependReactor("*", "*", tc.reactor) client.PrependReactor("*", "*", tc.reactor)
@@ -423,7 +581,7 @@ func TestAttacherDetach(t *testing.T) {
func TestAttacherGetDeviceMountPath(t *testing.T) { func TestAttacherGetDeviceMountPath(t *testing.T) {
// Setup // Setup
// Create a new attacher // Create a new attacher
plug, _, tmpDir, _ := newTestWatchPlugin(t) plug, _, tmpDir, _ := newTestWatchPlugin(t, nil)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
attacher, err0 := plug.NewAttacher() attacher, err0 := plug.NewAttacher()
if err0 != nil { if err0 != nil {
@@ -532,7 +690,7 @@ func TestAttacherMountDevice(t *testing.T) {
// Setup // Setup
// Create a new attacher // Create a new attacher
plug, fakeWatcher, tmpDir, _ := newTestWatchPlugin(t) plug, fakeWatcher, tmpDir, _ := newTestWatchPlugin(t, nil)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
attacher, err0 := plug.NewAttacher() attacher, err0 := plug.NewAttacher()
if err0 != nil { if err0 != nil {
@@ -663,7 +821,7 @@ func TestAttacherUnmountDevice(t *testing.T) {
t.Logf("Running test case: %s", tc.testName) t.Logf("Running test case: %s", tc.testName)
// Setup // Setup
// Create a new attacher // Create a new attacher
plug, _, tmpDir, _ := newTestWatchPlugin(t) plug, _, tmpDir, _ := newTestWatchPlugin(t, nil)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
attacher, err0 := plug.NewAttacher() attacher, err0 := plug.NewAttacher()
if err0 != nil { if err0 != nil {
@@ -749,7 +907,7 @@ func TestAttacherUnmountDevice(t *testing.T) {
} }
// create a plugin mgr to load plugins and setup a fake client // create a plugin mgr to load plugins and setup a fake client
func newTestWatchPlugin(t *testing.T) (*csiPlugin, *watch.RaceFreeFakeWatcher, string, *fakeclient.Clientset) { func newTestWatchPlugin(t *testing.T, csiClient *fakecsi.Clientset) (*csiPlugin, *watch.RaceFreeFakeWatcher, string, *fakeclient.Clientset) {
tmpDir, err := utiltesting.MkTmpdir("csi-test") tmpDir, err := utiltesting.MkTmpdir("csi-test")
if err != nil { if err != nil {
t.Fatalf("can't create temp dir: %v", err) t.Fatalf("can't create temp dir: %v", err)
@@ -759,10 +917,15 @@ func newTestWatchPlugin(t *testing.T) (*csiPlugin, *watch.RaceFreeFakeWatcher, s
fakeWatcher := watch.NewRaceFreeFake() fakeWatcher := watch.NewRaceFreeFake()
fakeClient.Fake.PrependWatchReactor("*", core.DefaultWatchReactor(fakeWatcher, nil)) fakeClient.Fake.PrependWatchReactor("*", core.DefaultWatchReactor(fakeWatcher, nil))
fakeClient.Fake.WatchReactionChain = fakeClient.Fake.WatchReactionChain[:1] fakeClient.Fake.WatchReactionChain = fakeClient.Fake.WatchReactionChain[:1]
host := volumetest.NewFakeVolumeHost( if csiClient == nil {
csiClient = fakecsi.NewSimpleClientset()
}
host := volumetest.NewFakeVolumeHostWithCSINodeName(
tmpDir, tmpDir,
fakeClient, fakeClient,
csiClient,
nil, nil,
"node",
) )
plugMgr := &volume.VolumePluginMgr{} plugMgr := &volume.VolumePluginMgr{}
plugMgr.InitPlugins(ProbeVolumePlugins(), nil /* prober */, host) plugMgr.InitPlugins(ProbeVolumePlugins(), nil /* prober */, host)
@@ -777,5 +940,12 @@ func newTestWatchPlugin(t *testing.T) (*csiPlugin, *watch.RaceFreeFakeWatcher, s
t.Fatalf("cannot assert plugin to be type csiPlugin") t.Fatalf("cannot assert plugin to be type csiPlugin")
} }
for {
// Wait until the informer in CSI volume plugin has all CSIDrivers.
if csiPlug.csiDriverInformer.Informer().HasSynced() {
break
}
}
return csiPlug, fakeWatcher, tmpDir, fakeClient return csiPlug, fakeWatcher, tmpDir, fakeClient
} }

View File

@@ -31,7 +31,7 @@ import (
) )
func TestBlockMapperGetGlobalMapPath(t *testing.T) { func TestBlockMapperGetGlobalMapPath(t *testing.T) {
plug, tmpDir := newTestPlugin(t) plug, tmpDir := newTestPlugin(t, nil, nil)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
// TODO (vladimirvivien) specName with slashes will not work // TODO (vladimirvivien) specName with slashes will not work
@@ -77,13 +77,14 @@ func TestBlockMapperGetGlobalMapPath(t *testing.T) {
} }
func TestBlockMapperSetupDevice(t *testing.T) { func TestBlockMapperSetupDevice(t *testing.T) {
plug, tmpDir := newTestPlugin(t) plug, tmpDir := newTestPlugin(t, nil, nil)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
fakeClient := fakeclient.NewSimpleClientset() fakeClient := fakeclient.NewSimpleClientset()
host := volumetest.NewFakeVolumeHostWithNodeName( host := volumetest.NewFakeVolumeHostWithCSINodeName(
tmpDir, tmpDir,
fakeClient, fakeClient,
nil, nil,
nil,
"fakeNode", "fakeNode",
) )
plug.host = host plug.host = host
@@ -134,13 +135,14 @@ func TestBlockMapperSetupDevice(t *testing.T) {
} }
func TestBlockMapperMapDevice(t *testing.T) { func TestBlockMapperMapDevice(t *testing.T) {
plug, tmpDir := newTestPlugin(t) plug, tmpDir := newTestPlugin(t, nil, nil)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
fakeClient := fakeclient.NewSimpleClientset() fakeClient := fakeclient.NewSimpleClientset()
host := volumetest.NewFakeVolumeHostWithNodeName( host := volumetest.NewFakeVolumeHostWithCSINodeName(
tmpDir, tmpDir,
fakeClient, fakeClient,
nil, nil,
nil,
"fakeNode", "fakeNode",
) )
plug.host = host plug.host = host
@@ -202,13 +204,14 @@ func TestBlockMapperMapDevice(t *testing.T) {
} }
func TestBlockMapperTearDownDevice(t *testing.T) { func TestBlockMapperTearDownDevice(t *testing.T) {
plug, tmpDir := newTestPlugin(t) plug, tmpDir := newTestPlugin(t, nil, nil)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
fakeClient := fakeclient.NewSimpleClientset() fakeClient := fakeclient.NewSimpleClientset()
host := volumetest.NewFakeVolumeHostWithNodeName( host := volumetest.NewFakeVolumeHostWithCSINodeName(
tmpDir, tmpDir,
fakeClient, fakeClient,
nil, nil,
nil,
"fakeNode", "fakeNode",
) )
plug.host = host plug.host = host

View File

@@ -30,20 +30,23 @@ import (
meta "k8s.io/apimachinery/pkg/apis/meta/v1" meta "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
fakeclient "k8s.io/client-go/kubernetes/fake" fakeclient "k8s.io/client-go/kubernetes/fake"
csiapi "k8s.io/csi-api/pkg/apis/csi/v1alpha1"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
volumetest "k8s.io/kubernetes/pkg/volume/testing" volumetest "k8s.io/kubernetes/pkg/volume/testing"
"k8s.io/kubernetes/pkg/volume/util" "k8s.io/kubernetes/pkg/volume/util"
) )
var ( var (
testDriver = "test-driver" testDriver = "test-driver"
testVol = "vol-123" testVol = "vol-123"
testns = "test-ns" testns = "test-ns"
testPodUID = types.UID("test-pod") testPod = "test-pod"
testPodUID = types.UID("test-pod")
testAccount = "test-service-account"
) )
func TestMounterGetPath(t *testing.T) { func TestMounterGetPath(t *testing.T) {
plug, tmpDir := newTestPlugin(t) plug, tmpDir := newTestPlugin(t, nil, nil)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
// TODO (vladimirvivien) specName with slashes will not work // TODO (vladimirvivien) specName with slashes will not work
@@ -86,13 +89,14 @@ func TestMounterGetPath(t *testing.T) {
} }
func TestMounterSetUp(t *testing.T) { func TestMounterSetUp(t *testing.T) {
plug, tmpDir := newTestPlugin(t) plug, tmpDir := newTestPlugin(t, nil, nil)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
fakeClient := fakeclient.NewSimpleClientset() fakeClient := fakeclient.NewSimpleClientset()
host := volumetest.NewFakeVolumeHostWithNodeName( host := volumetest.NewFakeVolumeHostWithCSINodeName(
tmpDir, tmpDir,
fakeClient, fakeClient,
nil, nil,
nil,
"fakeNode", "fakeNode",
) )
plug.host = host plug.host = host
@@ -167,7 +171,7 @@ func TestMounterSetUp(t *testing.T) {
} }
func TestUnmounterTeardown(t *testing.T) { func TestUnmounterTeardown(t *testing.T) {
plug, tmpDir := newTestPlugin(t) plug, tmpDir := newTestPlugin(t, nil, nil)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
pv := makeTestPV("test-pv", 10, testDriver, testVol) pv := makeTestPV("test-pv", 10, testDriver, testVol)
@@ -216,7 +220,7 @@ func TestUnmounterTeardown(t *testing.T) {
} }
func TestSaveVolumeData(t *testing.T) { func TestSaveVolumeData(t *testing.T) {
plug, tmpDir := newTestPlugin(t) plug, tmpDir := newTestPlugin(t, nil, nil)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
testCases := []struct { testCases := []struct {
name string name string
@@ -262,3 +266,16 @@ func TestSaveVolumeData(t *testing.T) {
} }
} }
} }
func getCSIDriver(name string, requiresPodInfo *bool, attachable *bool) *csiapi.CSIDriver {
return &csiapi.CSIDriver{
ObjectMeta: meta.ObjectMeta{
Name: name,
},
Spec: csiapi.CSIDriverSpec{
Driver: name,
PodInfoRequiredOnMount: requiresPodInfo,
AttachRequired: attachable,
},
}
}

View File

@@ -30,12 +30,13 @@ import (
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
fakeclient "k8s.io/client-go/kubernetes/fake" fakeclient "k8s.io/client-go/kubernetes/fake"
utiltesting "k8s.io/client-go/util/testing" utiltesting "k8s.io/client-go/util/testing"
fakecsi "k8s.io/csi-api/pkg/client/clientset/versioned/fake"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
volumetest "k8s.io/kubernetes/pkg/volume/testing" volumetest "k8s.io/kubernetes/pkg/volume/testing"
) )
// create a plugin mgr to load plugins and setup a fake client // create a plugin mgr to load plugins and setup a fake client
func newTestPlugin(t *testing.T) (*csiPlugin, string) { func newTestPlugin(t *testing.T, client *fakeclient.Clientset, csiClient *fakecsi.Clientset) (*csiPlugin, string) {
err := utilfeature.DefaultFeatureGate.Set("CSIBlockVolume=true") err := utilfeature.DefaultFeatureGate.Set("CSIBlockVolume=true")
if err != nil { if err != nil {
t.Fatalf("Failed to enable feature gate for CSIBlockVolume: %v", err) t.Fatalf("Failed to enable feature gate for CSIBlockVolume: %v", err)
@@ -46,11 +47,18 @@ func newTestPlugin(t *testing.T) (*csiPlugin, string) {
t.Fatalf("can't create temp dir: %v", err) t.Fatalf("can't create temp dir: %v", err)
} }
fakeClient := fakeclient.NewSimpleClientset() if client == nil {
host := volumetest.NewFakeVolumeHost( client = fakeclient.NewSimpleClientset()
}
if csiClient == nil {
csiClient = fakecsi.NewSimpleClientset()
}
host := volumetest.NewFakeVolumeHostWithCSINodeName(
tmpDir, tmpDir,
fakeClient, client,
csiClient,
nil, nil,
"fakeNode",
) )
plugMgr := &volume.VolumePluginMgr{} plugMgr := &volume.VolumePluginMgr{}
plugMgr.InitPlugins(ProbeVolumePlugins(), nil /* prober */, host) plugMgr.InitPlugins(ProbeVolumePlugins(), nil /* prober */, host)
@@ -65,6 +73,13 @@ func newTestPlugin(t *testing.T) (*csiPlugin, string) {
t.Fatalf("cannot assert plugin to be type csiPlugin") t.Fatalf("cannot assert plugin to be type csiPlugin")
} }
for {
// Wait until the informer in CSI volume plugin has all CSIDrivers.
if csiPlug.csiDriverInformer.Informer().HasSynced() {
break
}
}
return csiPlug, tmpDir return csiPlug, tmpDir
} }
@@ -92,7 +107,7 @@ func makeTestPV(name string, sizeGig int, driverName, volID string) *api.Persist
} }
func TestPluginGetPluginName(t *testing.T) { func TestPluginGetPluginName(t *testing.T) {
plug, tmpDir := newTestPlugin(t) plug, tmpDir := newTestPlugin(t, nil, nil)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
if plug.GetPluginName() != "kubernetes.io/csi" { if plug.GetPluginName() != "kubernetes.io/csi" {
t.Errorf("unexpected plugin name %v", plug.GetPluginName()) t.Errorf("unexpected plugin name %v", plug.GetPluginName())
@@ -100,7 +115,7 @@ func TestPluginGetPluginName(t *testing.T) {
} }
func TestPluginGetVolumeName(t *testing.T) { func TestPluginGetVolumeName(t *testing.T) {
plug, tmpDir := newTestPlugin(t) plug, tmpDir := newTestPlugin(t, nil, nil)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
testCases := []struct { testCases := []struct {
name string name string
@@ -129,7 +144,7 @@ func TestPluginGetVolumeName(t *testing.T) {
} }
func TestPluginCanSupport(t *testing.T) { func TestPluginCanSupport(t *testing.T) {
plug, tmpDir := newTestPlugin(t) plug, tmpDir := newTestPlugin(t, nil, nil)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
pv := makeTestPV("test-pv", 10, testDriver, testVol) pv := makeTestPV("test-pv", 10, testDriver, testVol)
@@ -141,7 +156,7 @@ func TestPluginCanSupport(t *testing.T) {
} }
func TestPluginConstructVolumeSpec(t *testing.T) { func TestPluginConstructVolumeSpec(t *testing.T) {
plug, tmpDir := newTestPlugin(t) plug, tmpDir := newTestPlugin(t, nil, nil)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
testCases := []struct { testCases := []struct {
@@ -201,7 +216,7 @@ func TestPluginConstructVolumeSpec(t *testing.T) {
} }
func TestPluginNewMounter(t *testing.T) { func TestPluginNewMounter(t *testing.T) {
plug, tmpDir := newTestPlugin(t) plug, tmpDir := newTestPlugin(t, nil, nil)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
pv := makeTestPV("test-pv", 10, testDriver, testVol) pv := makeTestPV("test-pv", 10, testDriver, testVol)
@@ -249,7 +264,7 @@ func TestPluginNewMounter(t *testing.T) {
} }
func TestPluginNewUnmounter(t *testing.T) { func TestPluginNewUnmounter(t *testing.T) {
plug, tmpDir := newTestPlugin(t) plug, tmpDir := newTestPlugin(t, nil, nil)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
pv := makeTestPV("test-pv", 10, testDriver, testVol) pv := makeTestPV("test-pv", 10, testDriver, testVol)
@@ -294,7 +309,7 @@ func TestPluginNewUnmounter(t *testing.T) {
} }
func TestPluginNewAttacher(t *testing.T) { func TestPluginNewAttacher(t *testing.T) {
plug, tmpDir := newTestPlugin(t) plug, tmpDir := newTestPlugin(t, nil, nil)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
attacher, err := plug.NewAttacher() attacher, err := plug.NewAttacher()
@@ -312,7 +327,7 @@ func TestPluginNewAttacher(t *testing.T) {
} }
func TestPluginNewDetacher(t *testing.T) { func TestPluginNewDetacher(t *testing.T) {
plug, tmpDir := newTestPlugin(t) plug, tmpDir := newTestPlugin(t, nil, nil)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
detacher, err := plug.NewDetacher() detacher, err := plug.NewDetacher()
@@ -330,7 +345,7 @@ func TestPluginNewDetacher(t *testing.T) {
} }
func TestPluginNewBlockMapper(t *testing.T) { func TestPluginNewBlockMapper(t *testing.T) {
plug, tmpDir := newTestPlugin(t) plug, tmpDir := newTestPlugin(t, nil, nil)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
pv := makeTestPV("test-block-pv", 10, testDriver, testVol) pv := makeTestPV("test-block-pv", 10, testDriver, testVol)
@@ -375,7 +390,7 @@ func TestPluginNewBlockMapper(t *testing.T) {
} }
func TestPluginNewUnmapper(t *testing.T) { func TestPluginNewUnmapper(t *testing.T) {
plug, tmpDir := newTestPlugin(t) plug, tmpDir := newTestPlugin(t, nil, nil)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
pv := makeTestPV("test-pv", 10, testDriver, testVol) pv := makeTestPV("test-pv", 10, testDriver, testVol)
@@ -432,7 +447,7 @@ func TestPluginNewUnmapper(t *testing.T) {
} }
func TestPluginConstructBlockVolumeSpec(t *testing.T) { func TestPluginConstructBlockVolumeSpec(t *testing.T) {
plug, tmpDir := newTestPlugin(t) plug, tmpDir := newTestPlugin(t, nil, nil)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
testCases := []struct { testCases := []struct {

View File

@@ -73,9 +73,10 @@ func NewFakeVolumeHostWithNodeLabels(rootDir string, kubeClient clientset.Interf
return volHost return volHost
} }
func NewFakeVolumeHostWithNodeName(rootDir string, kubeClient clientset.Interface, plugins []VolumePlugin, nodeName string) *fakeVolumeHost { func NewFakeVolumeHostWithCSINodeName(rootDir string, kubeClient clientset.Interface, csiClient csiclientset.Interface, plugins []VolumePlugin, nodeName string) *fakeVolumeHost {
volHost := newFakeVolumeHost(rootDir, kubeClient, plugins, nil, nil) volHost := newFakeVolumeHost(rootDir, kubeClient, plugins, nil, nil)
volHost.nodeName = nodeName volHost.nodeName = nodeName
volHost.csiClient = csiClient
return volHost return volHost
} }