...

Source file src/k8s.io/kubernetes/pkg/volume/flexvolume/flexvolume_test.go

Documentation: k8s.io/kubernetes/pkg/volume/flexvolume

     1  /*
     2  Copyright 2015 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 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  // NOTE: Typically, Windows requires file extensions for executable files. If a file does not
    80  // have a file extension, Windows will check if there is a file with the given name + one of the
    81  // extensions from $env:PATHEXT (in order) and run that file with that extension.
    82  // For example, if we have the file C:\\foo.bat, we can run C:\\foo.
    83  // For these tests, .bat was chosen since it's one of the default values in $env.PATHEXT. .ps1 is
    84  // not in that list, but it might be useful for flexvolumes to be able to handle powershell scripts.
    85  // There's no argument count variable in batch. Instead, we can check that the n-th argument
    86  // is an empty string.
    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