1
16
17 package flexvolume
18
19 import (
20 "bytes"
21 "fmt"
22 "os"
23 "path/filepath"
24 goruntime "runtime"
25 "testing"
26 "text/template"
27
28 "k8s.io/api/core/v1"
29 utiltesting "k8s.io/client-go/util/testing"
30 utilfs "k8s.io/kubernetes/pkg/util/filesystem"
31 "k8s.io/kubernetes/pkg/volume"
32 volumetest "k8s.io/kubernetes/pkg/volume/testing"
33 "k8s.io/utils/exec"
34 )
35
36 const execScriptTempl1 = `#!/usr/bin/env bash
37 if [ "$1" == "init" -a $# -eq 1 ]; then
38 echo -n '{
39 "status": "Success"
40 }'
41 exit 0
42 fi
43
44 PATH=$2
45 if [ "$1" == "attach" -a $# -eq 2 ]; then
46 echo -n '{
47 "device": "{{.DevicePath}}",
48 "status": "Success"
49 }'
50 exit 0
51 elif [ "$1" == "detach" -a $# -eq 2 ]; then
52 echo -n '{
53 "status": "Success"
54 }'
55 exit 0
56 elif [ "$1" == "getvolumename" -a $# -eq 4 ]; then
57 echo -n '{
58 "status": "Success",
59 "volume": "fakevolume"
60 }'
61 exit 0
62 elif [ "$1" == "isattached" -a $# -eq 2 ]; then
63 echo -n '{
64 "status": "Success",
65 "attached": true
66 }'
67 exit 0
68 fi
69
70 echo -n '{
71 "status": "Not supported"
72 }'
73 exit 1
74
75 # Direct the arguments to a file to be tested against later
76 echo -n $@ &> {{.OutputFile}}
77 `
78
79
80
81
82
83
84
85
86
87 const execScriptTemplBat = `
88 @echo off
89
90 if "%1"=="init" if "%2"=="" (
91 echo {"status": "Success"}
92 exit 0
93 )
94 if "%1"=="attach" if "%3"=="" (
95 echo {"device": "{{.DevicePath}}", "status": "Success"}
96 exit 0
97 )
98
99 if "%1"=="detach" if "%3"=="" (
100 echo {"status": "Success"}
101 exit 0
102 )
103
104 if "%1"=="getvolumename" if "%5"=="" (
105 echo {"status": "Success", "volume": "fakevolume"}
106 exit 0
107 )
108
109 if "%1"=="isattached" if "%3"=="" (
110 echo {"status": "Success", "attached": true}
111 exit 0
112 )
113
114 echo {"status": "Not supported"}
115 exit 1
116 `
117
118 func installPluginUnderTest(t *testing.T, vendorName, plugName, tmpDir string, execScriptTempl string, execTemplateData *map[string]interface{}) {
119 vendoredName := plugName
120 if vendorName != "" {
121 vendoredName = fmt.Sprintf("%s~%s", vendorName, plugName)
122 }
123 pluginDir := filepath.Join(tmpDir, vendoredName)
124 err := os.MkdirAll(pluginDir, 0777)
125 if err != nil {
126 t.Errorf("Failed to create plugin: %v", err)
127 }
128 pluginExec := filepath.Join(pluginDir, plugName)
129 if goruntime.GOOS == "windows" {
130 pluginExec = pluginExec + ".bat"
131 }
132 f, err := os.Create(pluginExec)
133 if err != nil {
134 t.Errorf("Failed to install plugin")
135 }
136 err = f.Chmod(0777)
137 if err != nil {
138 t.Errorf("Failed to set exec perms on plugin")
139 }
140 if execTemplateData == nil {
141 execTemplateData = &map[string]interface{}{
142 "DevicePath": "/dev/sdx",
143 "OutputFile": filepath.Join(pluginDir, plugName+".out"),
144 }
145 }
146
147 tObj := template.Must(template.New("test").Parse(execScriptTempl))
148 buf := &bytes.Buffer{}
149 if err := tObj.Execute(buf, *execTemplateData); err != nil {
150 t.Errorf("Error in executing script template - %v", err)
151 }
152 execScript := buf.String()
153 _, err = f.WriteString(execScript)
154 if err != nil {
155 t.Errorf("Failed to write plugin exec")
156 }
157 f.Close()
158 }
159
160 func TestCanSupport(t *testing.T) {
161 tmpDir, err := utiltesting.MkTmpdir("flexvolume_test")
162 if err != nil {
163 t.Fatalf("error creating temp dir: %v", err)
164 }
165 defer os.RemoveAll(tmpDir)
166
167 plugMgr := volume.VolumePluginMgr{}
168 runner := exec.New()
169 execScriptTempl := execScriptTempl1
170 if goruntime.GOOS == "windows" {
171 execScriptTempl = execScriptTemplBat
172 }
173 installPluginUnderTest(t, "kubernetes.io", "fakeAttacher", tmpDir, execScriptTempl, nil)
174 if err := plugMgr.InitPlugins(nil, GetDynamicPluginProberWithoutWatcher(tmpDir, runner), volumetest.NewFakeVolumeHost(t, "fake", nil, nil)); err != nil {
175 t.Fatalf("Could not initialize plugins: %v", err)
176 }
177 plugin, err := plugMgr.FindPluginByName("kubernetes.io/fakeAttacher")
178 if err != nil {
179 t.Fatalf("Can't find the plugin by name")
180 }
181 if plugin.GetPluginName() != "kubernetes.io/fakeAttacher" {
182 t.Errorf("Wrong name: %s", plugin.GetPluginName())
183 }
184 if !plugin.CanSupport(&volume.Spec{Volume: &v1.Volume{VolumeSource: v1.VolumeSource{FlexVolume: &v1.FlexVolumeSource{Driver: "kubernetes.io/fakeAttacher"}}}}) {
185 t.Errorf("Expected true")
186 }
187 if !plugin.CanSupport(&volume.Spec{PersistentVolume: &v1.PersistentVolume{Spec: v1.PersistentVolumeSpec{PersistentVolumeSource: v1.PersistentVolumeSource{FlexVolume: &v1.FlexPersistentVolumeSource{Driver: "kubernetes.io/fakeAttacher"}}}}}) {
188 t.Errorf("Expected true")
189 }
190 if plugin.CanSupport(&volume.Spec{Volume: &v1.Volume{VolumeSource: v1.VolumeSource{}}}) {
191 t.Errorf("Expected false")
192 }
193 }
194
195 func TestGetAccessModes(t *testing.T) {
196 tmpDir, err := utiltesting.MkTmpdir("flexvolume_test")
197 if err != nil {
198 t.Fatalf("error creating temp dir: %v", err)
199 }
200 defer os.RemoveAll(tmpDir)
201
202 plugMgr := volume.VolumePluginMgr{}
203 runner := exec.New()
204 execScriptTempl := execScriptTempl1
205 if goruntime.GOOS == "windows" {
206 execScriptTempl = execScriptTemplBat
207 }
208 installPluginUnderTest(t, "kubernetes.io", "fakeAttacher", tmpDir, execScriptTempl, nil)
209 if err := plugMgr.InitPlugins(nil, GetDynamicPluginProberWithoutWatcher(tmpDir, runner), volumetest.NewFakeVolumeHost(t, tmpDir, nil, nil)); err != nil {
210 t.Fatalf("Could not initialize plugins: %v", err)
211 }
212 plugin, err := plugMgr.FindPersistentPluginByName("kubernetes.io/fakeAttacher")
213 if err != nil {
214 t.Fatalf("Can't find the plugin by name")
215 }
216 if !volumetest.ContainsAccessMode(plugin.GetAccessModes(), v1.ReadWriteOnce) || !volumetest.ContainsAccessMode(plugin.GetAccessModes(), v1.ReadOnlyMany) {
217 t.Errorf("Expected two AccessModeTypes: %s and %s", v1.ReadWriteOnce, v1.ReadOnlyMany)
218 }
219 }
220
221 func GetDynamicPluginProberWithoutWatcher(pluginDir string, runner exec.Interface) volume.DynamicPluginProber {
222 return &flexVolumeProber{
223 pluginDir: pluginDir,
224 watcher: newFakeWatcher(),
225 factory: pluginFactory{},
226 runner: runner,
227 fs: &utilfs.DefaultFs{},
228 }
229 }
230
View as plain text