1
16
17 package portworx
18
19 import (
20 "fmt"
21 "os"
22 "path/filepath"
23 "testing"
24
25 "k8s.io/mount-utils"
26
27 v1 "k8s.io/api/core/v1"
28 "k8s.io/apimachinery/pkg/api/resource"
29 "k8s.io/apimachinery/pkg/types"
30 utiltesting "k8s.io/client-go/util/testing"
31 "k8s.io/kubernetes/pkg/volume"
32 volumetest "k8s.io/kubernetes/pkg/volume/testing"
33 )
34
35 const (
36 PortworxTestVolume = "portworx-test-vol"
37 )
38
39 func TestCanSupport(t *testing.T) {
40 tmpDir, err := utiltesting.MkTmpdir("portworxVolumeTest")
41 if err != nil {
42 t.Fatalf("can't make a temp dir: %v", err)
43 }
44 defer os.RemoveAll(tmpDir)
45 plugMgr := volume.VolumePluginMgr{}
46 plugMgr.InitPlugins(ProbeVolumePlugins(), nil , volumetest.NewFakeVolumeHost(t, tmpDir, nil, nil))
47
48 plug, err := plugMgr.FindPluginByName("kubernetes.io/portworx-volume")
49 if err != nil {
50 t.Fatal("Can't find the plugin by name")
51 }
52 if plug.GetPluginName() != "kubernetes.io/portworx-volume" {
53 t.Errorf("Wrong name: %s", plug.GetPluginName())
54 }
55 if !plug.CanSupport(&volume.Spec{Volume: &v1.Volume{VolumeSource: v1.VolumeSource{PortworxVolume: &v1.PortworxVolumeSource{}}}}) {
56 t.Errorf("Expected true")
57 }
58 if !plug.CanSupport(&volume.Spec{PersistentVolume: &v1.PersistentVolume{Spec: v1.PersistentVolumeSpec{PersistentVolumeSource: v1.PersistentVolumeSource{PortworxVolume: &v1.PortworxVolumeSource{}}}}}) {
59 t.Errorf("Expected true")
60 }
61 }
62
63 func TestGetAccessModes(t *testing.T) {
64 tmpDir, err := utiltesting.MkTmpdir("portworxVolumeTest")
65 if err != nil {
66 t.Fatalf("can't make a temp dir: %v", err)
67 }
68 defer os.RemoveAll(tmpDir)
69 plugMgr := volume.VolumePluginMgr{}
70 plugMgr.InitPlugins(ProbeVolumePlugins(), nil , volumetest.NewFakeVolumeHost(t, tmpDir, nil, nil))
71
72 plug, err := plugMgr.FindPersistentPluginByName("kubernetes.io/portworx-volume")
73 if err != nil {
74 t.Errorf("Can't find the plugin by name")
75 }
76
77 if !volumetest.ContainsAccessMode(plug.GetAccessModes(), v1.ReadWriteOnce) {
78 t.Errorf("Expected to support AccessModeTypes: %s", v1.ReadWriteOnce)
79 }
80 if !volumetest.ContainsAccessMode(plug.GetAccessModes(), v1.ReadWriteMany) {
81 t.Errorf("Expected to support AccessModeTypes: %s", v1.ReadWriteMany)
82 }
83 if volumetest.ContainsAccessMode(plug.GetAccessModes(), v1.ReadOnlyMany) {
84 t.Errorf("Expected not to support AccessModeTypes: %s", v1.ReadOnlyMany)
85 }
86 }
87
88 type fakePortworxManager struct {
89 attachCalled bool
90 mountCalled bool
91 }
92
93 func (fake *fakePortworxManager) AttachVolume(b *portworxVolumeMounter, attachOptions map[string]string) (string, error) {
94 fake.attachCalled = true
95 return "", nil
96 }
97
98 func (fake *fakePortworxManager) DetachVolume(c *portworxVolumeUnmounter) error {
99 return nil
100 }
101
102 func (fake *fakePortworxManager) MountVolume(b *portworxVolumeMounter, mountPath string) error {
103 fake.mountCalled = true
104 return nil
105 }
106
107 func (fake *fakePortworxManager) UnmountVolume(c *portworxVolumeUnmounter, mountPath string) error {
108 return nil
109 }
110
111 func (fake *fakePortworxManager) CreateVolume(c *portworxVolumeProvisioner) (volumeID string, volumeSizeGB int64, labels map[string]string, err error) {
112 labels = make(map[string]string)
113 labels["fakeportworxmanager"] = "yes"
114 return PortworxTestVolume, 100, labels, nil
115 }
116
117 func (fake *fakePortworxManager) DeleteVolume(cd *portworxVolumeDeleter) error {
118 if cd.volumeID != PortworxTestVolume {
119 return fmt.Errorf("Deleter got unexpected volume name: %s", cd.volumeID)
120 }
121 return nil
122 }
123
124 func (fake *fakePortworxManager) ResizeVolume(spec *volume.Spec, newSize resource.Quantity, volumeHost volume.VolumeHost) error {
125 return nil
126 }
127
128 func TestPlugin(t *testing.T) {
129 tmpDir, err := utiltesting.MkTmpdir("portworxVolumeTest")
130 if err != nil {
131 t.Fatalf("can't make a temp dir: %v", err)
132 }
133 defer os.RemoveAll(tmpDir)
134 plugMgr := volume.VolumePluginMgr{}
135 plugMgr.InitPlugins(ProbeVolumePlugins(), nil , volumetest.NewFakeVolumeHost(t, tmpDir, nil, nil))
136
137 plug, err := plugMgr.FindPluginByName("kubernetes.io/portworx-volume")
138 if err != nil {
139 t.Errorf("Can't find the plugin by name")
140 }
141 spec := &v1.Volume{
142 Name: "vol1",
143 VolumeSource: v1.VolumeSource{
144 PortworxVolume: &v1.PortworxVolumeSource{
145 VolumeID: PortworxTestVolume,
146 FSType: "ext4",
147 },
148 },
149 }
150 fakeManager := &fakePortworxManager{}
151
152 fakeMounter := mount.NewFakeMounter(nil)
153 mounter, err := plug.(*portworxVolumePlugin).newMounterInternal(volume.NewSpecFromVolume(spec), types.UID("poduid"), fakeManager, fakeMounter)
154 if err != nil {
155 t.Errorf("Failed to make a new Mounter: %v", err)
156 }
157 if mounter == nil {
158 t.Errorf("Got a nil Mounter")
159 }
160
161 volPath := filepath.Join(tmpDir, "pods/poduid/volumes/kubernetes.io~portworx-volume/vol1")
162 path := mounter.GetPath()
163 if path != volPath {
164 t.Errorf("Got unexpected path: %s", path)
165 }
166
167 if err := mounter.SetUp(volume.MounterArgs{}); err != nil {
168 t.Errorf("Expected success, got: %v", err)
169 }
170 if _, err := os.Stat(path); err != nil {
171 if os.IsNotExist(err) {
172 t.Errorf("SetUp() failed, volume path not created: %s", path)
173 } else {
174 t.Errorf("SetUp() failed: %v", err)
175 }
176 }
177 if !fakeManager.attachCalled {
178 t.Errorf("Attach watch not called")
179 }
180 if !fakeManager.mountCalled {
181 t.Errorf("Mount watch not called")
182 }
183
184
185 fakeManager = &fakePortworxManager{}
186 unmounter, err := plug.(*portworxVolumePlugin).newUnmounterInternal("vol1", types.UID("poduid"), fakeManager, fakeMounter)
187 if err != nil {
188 t.Errorf("Failed to make a new Unmounter: %v", err)
189 }
190 if unmounter == nil {
191 t.Errorf("Got a nil Unmounter")
192 }
193
194 if err := unmounter.TearDown(); err != nil {
195 t.Errorf("Expected success, got: %v", err)
196 }
197
198
199 options := volume.VolumeOptions{
200 PVC: volumetest.CreateTestPVC("100Gi", []v1.PersistentVolumeAccessMode{v1.ReadWriteOnce}),
201 PersistentVolumeReclaimPolicy: v1.PersistentVolumeReclaimDelete,
202 }
203
204 provisioner, err := plug.(*portworxVolumePlugin).newProvisionerInternal(options, &fakePortworxManager{})
205 if err != nil {
206 t.Errorf("Error creating a new provisioner:%v", err)
207 }
208 persistentSpec, err := provisioner.Provision(nil, nil)
209 if err != nil {
210 t.Errorf("Provision() failed: %v", err)
211 }
212
213 if persistentSpec.Spec.PersistentVolumeSource.PortworxVolume.VolumeID != PortworxTestVolume {
214 t.Errorf("Provision() returned unexpected volume ID: %s", persistentSpec.Spec.PersistentVolumeSource.PortworxVolume.VolumeID)
215 }
216 cap := persistentSpec.Spec.Capacity[v1.ResourceStorage]
217 size := cap.Value()
218 if size != 100*1024*1024*1024 {
219 t.Errorf("Provision() returned unexpected volume size: %v", size)
220 }
221
222 if persistentSpec.Labels["fakeportworxmanager"] != "yes" {
223 t.Errorf("Provision() returned unexpected labels: %v", persistentSpec.Labels)
224 }
225
226
227 volSpec := &volume.Spec{
228 PersistentVolume: persistentSpec,
229 }
230 deleter, err := plug.(*portworxVolumePlugin).newDeleterInternal(volSpec, &fakePortworxManager{})
231 if err != nil {
232 t.Errorf("Error creating a new Deleter:%v", err)
233 }
234 err = deleter.Delete()
235 if err != nil {
236 t.Errorf("Deleter() failed: %v", err)
237 }
238 }
239
View as plain text