@@ -85,7 +85,7 @@ const (
85
85
var (
86
86
// default provisioner image used for e2e tests
87
87
provisionerImageName = "quay.io/external_storage/local-volume-provisioner:latest"
88
- provisionerImagePullPolicy v1.PullPolicy = "Never "
88
+ provisionerImagePullPolicy v1.PullPolicy = "Always "
89
89
// storage class volume binding modes
90
90
waitMode = storagev1 .VolumeBindingWaitForFirstConsumer
91
91
immediateMode = storagev1 .VolumeBindingImmediate
@@ -232,9 +232,9 @@ var _ = utils.SIGDescribe("PersistentVolumes-local ", func() {
232
232
})
233
233
234
234
AfterEach (func () {
235
+ deleteProvisionerDaemonset (config )
235
236
cleanupLocalVolumeProvisioner (config )
236
237
cleanupStorageClass (config )
237
- deleteProvisionerDaemonset (config )
238
238
})
239
239
240
240
It ("should create and recreate local persistent volume" , func () {
@@ -290,15 +290,18 @@ var _ = utils.SIGDescribe("PersistentVolumes-local ", func() {
290
290
})
291
291
292
292
AfterEach (func () {
293
+ deleteProvisionerDaemonset (config )
293
294
cleanupLocalVolumeProvisioner (config )
294
295
cleanupStorageClass (config )
295
- deleteProvisionerDaemonset (config )
296
296
})
297
297
298
298
It ("should not create local persistent volume for filesystem volume that was not bind mounted" , func () {
299
299
directoryPath := filepath .Join (config .discoveryDir , "notbindmount" )
300
300
By ("Creating a directory, not bind mounted, in discovery directory" )
301
301
mkdirCmd := fmt .Sprintf ("mkdir -p %v -m 777" , directoryPath )
302
+ if nodeOSDistroIs ("windows" ) {
303
+ mkdirCmd = fmt .Sprintf ("mkdir -Force %v" , directoryPath )
304
+ }
302
305
execResult , err := config .hostExec .Execute (mkdirCmd , config .node0 )
303
306
utils .LogResult (execResult )
304
307
Expect (err ).NotTo (HaveOccurred ())
@@ -313,6 +316,11 @@ var _ = utils.SIGDescribe("PersistentVolumes-local ", func() {
313
316
"Error getting logs from pod %s in namespace %s" , provisionerPodName , config .ns )
314
317
315
318
expectedLogMessage := "path \" /mnt/local-storage/notbindmount\" is not an actual mountpoint"
319
+ // the expected log message above is thrown in Linux if the mount path doesn't exist in /proc/mounts
320
+ // in Windows we instead look for the error `path "%q" fs stats error`
321
+ if nodeOSDistroIs ("windows" ) {
322
+ expectedLogMessage = `path "c:\\mnt\\local-storage\\notbindmount" fs stats error`
323
+ }
316
324
Expect (strings .Contains (logs , expectedLogMessage )).To (BeTrue ())
317
325
})
318
326
})
@@ -321,11 +329,19 @@ var _ = utils.SIGDescribe("PersistentVolumes-local ", func() {
321
329
Context ("Stress with local volume provisioner [Serial]" , func () {
322
330
var testVols [][]* localVolume
323
331
324
- const (
332
+ var (
325
333
volsPerNode = 10 // Make this non-divisable by volsPerPod to increase changes of partial binding failure
326
334
volsPerPod = 3
327
335
podsFactor = 4
328
336
)
337
+ if nodeOSDistroIs ("windows" ) {
338
+ // the Windows image is big and having `volsPerNode/volsPerPod + 1` pods pulling it
339
+ // at the same time consumes all the bandwidth, in Windows these parameters are
340
+ // changed so that the stress test is with fewer parallel pods
341
+ volsPerNode = 7
342
+ volsPerPod = 3
343
+ podsFactor = 3
344
+ }
329
345
330
346
BeforeEach (func () {
331
347
setupStorageClass (config , & waitMode )
@@ -343,14 +359,11 @@ var _ = utils.SIGDescribe("PersistentVolumes-local ", func() {
343
359
testVols = append (testVols , vols )
344
360
}
345
361
346
- By ("Starting the local volume provisioner" )
347
362
createProvisionerDaemonset (config )
348
363
})
349
364
350
365
AfterEach (func () {
351
- By ("Deleting provisioner daemonset" )
352
366
deleteProvisionerDaemonset (config )
353
-
354
367
for i , vols := range testVols {
355
368
for _ , vol := range vols {
356
369
cleanupLocalVolumeProvisionerMountPoint (config , vol , & config .nodes [i ])
@@ -393,7 +406,8 @@ var _ = utils.SIGDescribe("PersistentVolumes-local ", func() {
393
406
for i := 0 ; i < numConcurrentPods ; i ++ {
394
407
pvcs := []* v1.PersistentVolumeClaim {}
395
408
for j := 0 ; j < volsPerPod ; j ++ {
396
- pvc := e2epv .MakePersistentVolumeClaim (makeLocalPVCConfig (config , DirectoryLocalVolumeType ), config .ns )
409
+ pvcConfig := makeLocalPVCConfig (config , DirectoryLocalVolumeType )
410
+ pvc := e2epv .MakePersistentVolumeClaim (pvcConfig , config .ns )
397
411
pvc , err := e2epv .CreatePVC (config .client , config .ns , pvc )
398
412
framework .ExpectNoError (err )
399
413
pvcs = append (pvcs , pvc )
@@ -429,7 +443,8 @@ var _ = utils.SIGDescribe("PersistentVolumes-local ", func() {
429
443
}()
430
444
431
445
By ("Waiting for all pods to complete successfully" )
432
- err := wait .PollImmediate (time .Second , 5 * time .Minute , func () (done bool , err error ) {
446
+ timeout := 10 * time .Minute
447
+ err := wait .PollImmediate (time .Second , timeout , func () (done bool , err error ) {
433
448
podsList , err := config .client .CoreV1 ().Pods (config .ns ).List (context .TODO (), metav1.ListOptions {})
434
449
if err != nil {
435
450
return false , err
@@ -475,6 +490,7 @@ func setupStorageClass(config *localTestConfig, mode *storagev1.VolumeBindingMod
475
490
}
476
491
477
492
func cleanupStorageClass (config * localTestConfig ) {
493
+ By ("Cleanup StorageClass" )
478
494
framework .ExpectNoError (config .client .StorageV1 ().StorageClasses ().Delete (context .TODO (), config .scName , metav1.DeleteOptions {}))
479
495
}
480
496
@@ -505,6 +521,9 @@ func cleanupLocalVolumeProvisioner(config *localTestConfig) {
505
521
for _ , node := range config .nodes {
506
522
By (fmt .Sprintf ("Removing the test discovery directory on node %v" , node .Name ))
507
523
removeCmd := fmt .Sprintf ("[ ! -e %v ] || rm -r %v" , config .discoveryDir , config .discoveryDir )
524
+ if nodeOSDistroIs ("windows" ) {
525
+ removeCmd = fmt .Sprintf ("rmdir -Recurse -Force %v" , config .discoveryDir )
526
+ }
508
527
execResult , err := config .hostExec .Execute (removeCmd , & node )
509
528
utils .LogResult (execResult )
510
529
Expect (err ).NotTo (HaveOccurred ())
@@ -629,8 +648,22 @@ func findLoopDevice(config *localTestConfig, file string, node *v1.Node) string
629
648
return strings .TrimSpace (loopDevResult )
630
649
}
631
650
651
+ // normalizePath makes sure the given path is a valid path on Windows too
652
+ // by making sure all instances of `/` are replaced with `\\`, and the
653
+ // path beings with `c:`
654
+ func normalizePath (path string ) string {
655
+ if ! nodeOSDistroIs ("windows" ) {
656
+ return path
657
+ }
658
+ normalizedPath := strings .Replace (path , "/" , "\\ " , - 1 )
659
+ if strings .HasPrefix (normalizedPath , "\\ " ) {
660
+ normalizedPath = "c:" + normalizedPath
661
+ }
662
+ return normalizedPath
663
+ }
664
+
632
665
func setupLocalVolumeProvisionerMountPoint (config * localTestConfig , node * v1.Node , volumeType localVolumeType ) * localVolume {
633
- volumePath := path .Join (config .discoveryDir , fmt .Sprintf ("vol-%v" , string (uuid .NewUUID ())))
666
+ volumePath := normalizePath ( path .Join (config .discoveryDir , fmt .Sprintf ("vol-%v" , string (uuid .NewUUID () ))))
634
667
if volumeType == DirectoryLocalVolumeType {
635
668
lv := & localVolume {
636
669
volumePath : volumePath ,
@@ -648,6 +681,7 @@ func setupLocalVolumeProvisionerMountPoint(config *localTestConfig, node *v1.Nod
648
681
649
682
By (fmt .Sprintf ("Mounting local directory at path %q" , volumePath ))
650
683
if nodeOSDistroIs ("windows" ) {
684
+ // NOTE: the value must be greater than the PVC config ClaimSize
651
685
vhd := setupVHD (config , node , volumePath , 1024 * 1024 * 1024 /* 1GB */ )
652
686
lv .vhd = vhd
653
687
} else {
@@ -807,10 +841,7 @@ func createProvisionerDaemonset(config *localTestConfig) {
807
841
// mounted as volumes in the pod
808
842
// see helm/provisioner/templates/daemonset_windows.yaml for more details
809
843
if nodeOSDistroIs ("windows" ) {
810
- apiGroups := []string {
811
- "disk-v1" , "volume-v1" , "filesystem-v1" ,
812
- "disk-v1beta2" , "volume-v1beta2" , "filesystem-v1beta1" ,
813
- }
844
+ apiGroups := []string {"volume-v1" , "volume-v1beta2" }
814
845
815
846
for _ , apiGroup := range apiGroups {
816
847
additionalVolumes = append (
@@ -1017,7 +1048,7 @@ func createWriteCmd(testDir string, testFile string, writeTestFileContent string
1017
1048
func createFileDoesntExistCmd (testFileDir string , testFile string ) string {
1018
1049
testFilePath := filepath .Join (testFileDir , testFile )
1019
1050
if nodeOSDistroIs ("windows" ) {
1020
- return fmt .Sprintf ("if(-not( Test-Path -Path %s) ) { throw 'File exists' }" , testFilePath )
1051
+ return fmt .Sprintf ("if ( Test-Path -Path %s) { throw 'File exists' }" , testFilePath )
1021
1052
}
1022
1053
return fmt .Sprintf ("[ ! -e %s ]" , testFilePath )
1023
1054
}
@@ -1054,6 +1085,7 @@ func (c *localTestConfig) isNodeInList(name string) bool {
1054
1085
}
1055
1086
1056
1087
func deleteProvisionerDaemonset (config * localTestConfig ) {
1088
+ By ("Cleanup Provisioner daemonset" )
1057
1089
ds , err := config .client .AppsV1 ().DaemonSets (config .ns ).Get (context .TODO (), daemonSetName , metav1.GetOptions {})
1058
1090
if ds == nil {
1059
1091
return
@@ -1125,6 +1157,7 @@ func makeLocalPVCConfig(config *localTestConfig, volumeType localVolumeType) e2e
1125
1157
pvcConfig := e2epv.PersistentVolumeClaimConfig {
1126
1158
AccessModes : []v1.PersistentVolumeAccessMode {v1 .ReadWriteOnce },
1127
1159
StorageClassName : & config .scName ,
1160
+ ClaimSize : "100M" ,
1128
1161
}
1129
1162
if volumeType == BlockLocalVolumeType {
1130
1163
pvcVolumeMode := v1 .PersistentVolumeBlock
0 commit comments