Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
b89b3672
Commit
b89b3672
authored
Nov 07, 2018
by
Masaki Kimura
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Make csi drivers and in-tree drivers share e2e tests
parent
465d578d
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
387 additions
and
233 deletions
+387
-233
BUILD
test/e2e/storage/BUILD
+1
-1
csi_volumes.go
test/e2e/storage/csi_volumes.go
+71
-222
BUILD
test/e2e/storage/drivers/BUILD
+4
-0
csi.go
test/e2e/storage/drivers/csi.go
+281
-0
csi_objects.go
test/e2e/storage/drivers/csi_objects.go
+1
-1
in_tree_volumes.go
test/e2e/storage/in_tree_volumes.go
+6
-1
base.go
test/e2e/storage/testsuites/base.go
+4
-4
provisioning.go
test/e2e/storage/testsuites/provisioning.go
+1
-1
subpath.go
test/e2e/storage/testsuites/subpath.go
+17
-2
volumemode.go
test/e2e/storage/testsuites/volumemode.go
+1
-1
No files found.
test/e2e/storage/BUILD
View file @
b89b3672
...
...
@@ -3,7 +3,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"csi_objects.go",
"csi_volumes.go",
"empty_dir_wrapper.go",
"ephemeral_volume.go",
...
...
@@ -72,6 +71,7 @@ go_library(
"//test/e2e/framework/providers/gce:go_default_library",
"//test/e2e/framework/testfiles:go_default_library",
"//test/e2e/storage/drivers:go_default_library",
"//test/e2e/storage/testpatterns:go_default_library",
"//test/e2e/storage/testsuites:go_default_library",
"//test/e2e/storage/utils:go_default_library",
"//test/utils/image:go_default_library",
...
...
test/e2e/storage/csi_volumes.go
View file @
b89b3672
...
...
@@ -19,9 +19,7 @@ package storage
import
(
"context"
"fmt"
"math/rand"
"regexp"
"time"
"k8s.io/api/core/v1"
storagev1
"k8s.io/api/storage/v1"
...
...
@@ -32,6 +30,8 @@ import (
csiclient
"k8s.io/csi-api/pkg/client/clientset/versioned"
"k8s.io/kubernetes/test/e2e/framework"
"k8s.io/kubernetes/test/e2e/framework/podlogs"
"k8s.io/kubernetes/test/e2e/storage/drivers"
"k8s.io/kubernetes/test/e2e/storage/testpatterns"
"k8s.io/kubernetes/test/e2e/storage/testsuites"
"k8s.io/kubernetes/test/e2e/storage/utils"
imageutils
"k8s.io/kubernetes/test/utils/image"
...
...
@@ -42,39 +42,56 @@ import (
.
"github.com/onsi/gomega"
)
type
csiTestDriver
interface
{
createCSIDriver
()
cleanupCSIDriver
()
createStorageClassTest
()
testsuites
.
StorageClassTest
// List of testDrivers to be executed in below loop
var
csiTestDrivers
=
[]
func
()
drivers
.
TestDriver
{
drivers
.
InitHostPathCSIDriver
,
drivers
.
InitGcePDCSIDriver
,
drivers
.
InitGcePDExternalCSIDriver
,
}
var
csiTestDrivers
=
map
[
string
]
func
(
f
*
framework
.
Framework
,
config
framework
.
VolumeTestConfig
)
csiTestDriver
{
"hostPath"
:
initCSIHostpath
,
"gcePD"
:
initCSIgcePD
,
// TODO(#70258): this is temporary until we can figure out how to make e2e tests a library
"[Feature: gcePD-external]"
:
initCSIgcePDExternal
,
// List of testSuites to be executed in below loop
var
csiTestSuites
=
[]
func
()
testsuites
.
TestSuite
{
testsuites
.
InitVolumesTestSuite
,
testsuites
.
InitVolumeIOTestSuite
,
testsuites
.
InitVolumeModeTestSuite
,
testsuites
.
InitSubPathTestSuite
,
testsuites
.
InitProvisioningTestSuite
,
}
func
csiTunePattern
(
patterns
[]
testpatterns
.
TestPattern
)
[]
testpatterns
.
TestPattern
{
tunedPatterns
:=
[]
testpatterns
.
TestPattern
{}
for
_
,
pattern
:=
range
patterns
{
// Skip inline volume and pre-provsioned PV tests for csi drivers
if
pattern
.
VolType
==
testpatterns
.
InlineVolume
||
pattern
.
VolType
==
testpatterns
.
PreprovisionedPV
{
continue
}
tunedPatterns
=
append
(
tunedPatterns
,
pattern
)
}
return
tunedPatterns
}
// This executes testSuites for csi volumes.
var
_
=
utils
.
SIGDescribe
(
"CSI Volumes"
,
func
()
{
f
:=
framework
.
NewDefaultFramework
(
"csi-volumes"
)
var
(
cancel
context
.
CancelFunc
cs
clientset
.
Interface
csics
csiclient
.
Interface
ns
*
v1
.
Namespace
node
v1
.
Node
config
framework
.
VolumeTestConfig
)
BeforeEach
(
func
()
{
ctx
,
c
:=
context
.
WithCancel
(
context
.
Background
())
cancel
=
c
cs
=
f
.
ClientSet
csics
=
f
.
CSIClientSet
ns
=
f
.
Namespace
config
=
framework
.
VolumeTestConfig
{
Namespace
:
ns
.
Name
,
Prefix
:
"csi"
,
}
// Debugging of the following tests heavily depends on the log output
// of the different containers. Therefore include all of that in log
// files (when using --report-dir, as in the CI) or the output stream
...
...
@@ -100,69 +117,50 @@ var _ = utils.SIGDescribe("CSI Volumes", func() {
if
framework
.
TestContext
.
ReportDir
==
""
{
podlogs
.
WatchPods
(
ctx
,
cs
,
ns
.
Name
,
GinkgoWriter
)
}
nodes
:=
framework
.
GetReadySchedulableNodesOrDie
(
f
.
ClientSet
)
node
=
nodes
.
Items
[
rand
.
Intn
(
len
(
nodes
.
Items
))]
config
=
framework
.
VolumeTestConfig
{
Namespace
:
ns
.
Name
,
Prefix
:
"csi"
,
// TODO(#70259): this needs to be parameterized so only hostpath sets node name
ClientNodeName
:
node
.
Name
,
ServerNodeName
:
node
.
Name
,
WaitForCompletion
:
true
,
}
})
AfterEach
(
func
()
{
cancel
()
})
for
driverName
,
initCSIDriver
:=
range
csiTestDrivers
{
curDriverName
:=
driverName
curInitCSIDriver
:=
initCSIDriver
Context
(
fmt
.
Sprintf
(
"CSI plugin test using CSI driver: %s"
,
curDriverName
),
func
()
{
var
(
driver
csiTestDriver
)
for
_
,
initDriver
:=
range
csiTestDrivers
{
curDriver
:=
initDriver
()
Context
(
fmt
.
Sprintf
(
drivers
.
GetDriverNameWithFeatureTags
(
curDriver
)),
func
()
{
driver
:=
curDriver
BeforeEach
(
func
()
{
driver
=
curInitCSIDriver
(
f
,
config
)
driver
.
createCSIDriver
()
// setupDriver
drivers
.
SetCommonDriverParameters
(
driver
,
f
,
config
)
driver
.
CreateDriver
()
})
AfterEach
(
func
()
{
driver
.
cleanupCSIDriver
()
// Cleanup driver
driver
.
CleanupDriver
()
})
It
(
"should provision storage"
,
func
()
{
t
:=
driver
.
createStorageClassTest
()
claim
:=
newClaim
(
t
,
ns
.
GetName
(),
""
)
var
class
*
storagev1
.
StorageClass
if
t
.
StorageClassName
==
""
{
class
=
newStorageClass
(
t
,
ns
.
GetName
(),
""
)
claim
.
Spec
.
StorageClassName
=
&
class
.
ObjectMeta
.
Name
}
else
{
scName
:=
t
.
StorageClassName
claim
.
Spec
.
StorageClassName
=
&
scName
}
testsuites
.
TestDynamicProvisioning
(
t
,
cs
,
claim
,
class
)
})
testsuites
.
RunTestSuite
(
f
,
config
,
driver
,
csiTestSuites
,
csiTunePattern
)
})
}
// The CSIDriverRegistry feature gate is needed for this test in Kubernetes 1.12.
Context
(
"CSI attach test using HostPath driver [Feature:CSISkipAttach]"
,
func
()
{
var
(
driver
csiTestDriver
cs
clientset
.
Interface
csics
csiclient
.
Interface
driver
drivers
.
TestDriver
)
BeforeEach
(
func
()
{
driver
=
initCSIHostpath
(
f
,
config
)
driver
.
createCSIDriver
()
cs
=
f
.
ClientSet
csics
=
f
.
CSIClientSet
driver
=
drivers
.
InitHostPathCSIDriver
()
drivers
.
SetCommonDriverParameters
(
driver
,
f
,
config
)
driver
.
CreateDriver
()
})
AfterEach
(
func
()
{
driver
.
cleanupCSI
Driver
()
driver
.
Cleanup
Driver
()
})
tests
:=
[]
struct
{
...
...
@@ -194,15 +192,27 @@ var _ = utils.SIGDescribe("CSI Volumes", func() {
test
:=
t
It
(
test
.
name
,
func
()
{
if
test
.
driverExists
{
d
river
:=
createCSIDriver
(
csics
,
"csi-hostpath-"
+
f
.
UniqueName
,
test
.
driverAttachable
)
if
d
river
!=
nil
{
defer
csics
.
CsiV1alpha1
()
.
CSIDrivers
()
.
Delete
(
d
river
.
Name
,
nil
)
csiD
river
:=
createCSIDriver
(
csics
,
"csi-hostpath-"
+
f
.
UniqueName
,
test
.
driverAttachable
)
if
csiD
river
!=
nil
{
defer
csics
.
CsiV1alpha1
()
.
CSIDrivers
()
.
Delete
(
csiD
river
.
Name
,
nil
)
}
}
By
(
"Creating pod"
)
t
:=
driver
.
createStorageClassTest
()
class
,
claim
,
pod
:=
startPausePod
(
cs
,
t
,
ns
.
Name
)
var
sc
*
storagev1
.
StorageClass
if
dDriver
,
ok
:=
driver
.
(
drivers
.
DynamicPVTestDriver
);
ok
{
sc
=
dDriver
.
GetDynamicProvisionStorageClass
(
""
)
}
nodeName
:=
driver
.
GetDriverInfo
()
.
Config
.
ClientNodeName
scTest
:=
testsuites
.
StorageClassTest
{
Name
:
driver
.
GetDriverInfo
()
.
Name
,
Provisioner
:
sc
.
Provisioner
,
Parameters
:
sc
.
Parameters
,
ClaimSize
:
"1Gi"
,
ExpectedSize
:
"1Gi"
,
NodeName
:
nodeName
,
}
class
,
claim
,
pod
:=
startPausePod
(
cs
,
scTest
,
ns
.
Name
)
if
class
!=
nil
{
defer
cs
.
StorageV1
()
.
StorageClasses
()
.
Delete
(
class
.
Name
,
nil
)
}
...
...
@@ -223,7 +233,7 @@ var _ = utils.SIGDescribe("CSI Volumes", func() {
By
(
"Checking if VolumeAttachment was created for the pod"
)
// Check that VolumeAttachment does not exist
handle
:=
getVolumeHandle
(
cs
,
claim
)
attachmentHash
:=
sha256
.
Sum256
([]
byte
(
fmt
.
Sprintf
(
"%s%s%s"
,
handle
,
t
.
Provisioner
,
node
.
Name
)))
attachmentHash
:=
sha256
.
Sum256
([]
byte
(
fmt
.
Sprintf
(
"%s%s%s"
,
handle
,
scTest
.
Provisioner
,
node
Name
)))
attachmentName
:=
fmt
.
Sprintf
(
"csi-%x"
,
attachmentHash
)
_
,
err
=
cs
.
StorageV1beta1
()
.
VolumeAttachments
()
.
Get
(
attachmentName
,
metav1
.
GetOptions
{})
if
err
!=
nil
{
...
...
@@ -326,164 +336,3 @@ func startPausePod(cs clientset.Interface, t testsuites.StorageClassTest, ns str
framework
.
ExpectNoError
(
err
,
"Failed to create pod: %v"
,
err
)
return
class
,
claim
,
pod
}
type
hostpathCSIDriver
struct
{
f
*
framework
.
Framework
config
framework
.
VolumeTestConfig
cleanup
func
()
}
func
initCSIHostpath
(
f
*
framework
.
Framework
,
config
framework
.
VolumeTestConfig
)
csiTestDriver
{
return
&
hostpathCSIDriver
{
f
:
f
,
config
:
config
,
}
}
func
(
h
*
hostpathCSIDriver
)
createStorageClassTest
()
testsuites
.
StorageClassTest
{
return
testsuites
.
StorageClassTest
{
Name
:
"csi-hostpath"
,
Parameters
:
map
[
string
]
string
{},
ClaimSize
:
"1Gi"
,
ExpectedSize
:
"1Gi"
,
// The hostpath driver only works when everything runs on a single node.
NodeName
:
h
.
config
.
ServerNodeName
,
// Provisioner and storage class name must match what's used in
// csi-storageclass.yaml, plus the test-specific suffix.
Provisioner
:
"csi-hostpath-"
+
h
.
f
.
UniqueName
,
StorageClassName
:
"csi-hostpath-sc-"
+
h
.
f
.
UniqueName
,
}
}
func
(
h
*
hostpathCSIDriver
)
createCSIDriver
()
{
By
(
"deploying csi hostpath driver"
)
// TODO (?): the storage.csi.image.version and storage.csi.image.registry
// settings are ignored for this test. We could patch the image definitions.
o
:=
utils
.
PatchCSIOptions
{
OldDriverName
:
"csi-hostpath"
,
NewDriverName
:
"csi-hostpath-"
+
h
.
f
.
UniqueName
,
DriverContainerName
:
"hostpath"
,
ProvisionerContainerName
:
"csi-provisioner"
,
NodeName
:
h
.
config
.
ServerNodeName
,
}
cleanup
,
err
:=
h
.
f
.
CreateFromManifests
(
func
(
item
interface
{})
error
{
return
utils
.
PatchCSIDeployment
(
h
.
f
,
o
,
item
)
},
"test/e2e/testing-manifests/storage-csi/driver-registrar/rbac.yaml"
,
"test/e2e/testing-manifests/storage-csi/external-attacher/rbac.yaml"
,
"test/e2e/testing-manifests/storage-csi/external-provisioner/rbac.yaml"
,
"test/e2e/testing-manifests/storage-csi/hostpath/hostpath/csi-hostpath-attacher.yaml"
,
"test/e2e/testing-manifests/storage-csi/hostpath/hostpath/csi-hostpath-provisioner.yaml"
,
"test/e2e/testing-manifests/storage-csi/hostpath/hostpath/csi-hostpathplugin.yaml"
,
"test/e2e/testing-manifests/storage-csi/hostpath/hostpath/e2e-test-rbac.yaml"
,
"test/e2e/testing-manifests/storage-csi/hostpath/usage/csi-storageclass.yaml"
,
)
h
.
cleanup
=
cleanup
if
err
!=
nil
{
framework
.
Failf
(
"deploying csi hostpath driver: %v"
,
err
)
}
}
func
(
h
*
hostpathCSIDriver
)
cleanupCSIDriver
()
{
if
h
.
cleanup
!=
nil
{
By
(
"uninstalling csi hostpath driver"
)
h
.
cleanup
()
}
}
type
gcePDCSIDriver
struct
{
f
*
framework
.
Framework
config
framework
.
VolumeTestConfig
cleanup
func
()
}
func
initCSIgcePD
(
f
*
framework
.
Framework
,
config
framework
.
VolumeTestConfig
)
csiTestDriver
{
cs
:=
f
.
ClientSet
framework
.
SkipUnlessProviderIs
(
"gce"
,
"gke"
)
framework
.
SkipIfMultizone
(
cs
)
// TODO(#62561): Use credentials through external pod identity when that goes GA instead of downloading keys.
createGCESecrets
(
cs
,
config
)
framework
.
SkipUnlessSecretExistsAfterWait
(
cs
,
"cloud-sa"
,
config
.
Namespace
,
3
*
time
.
Minute
)
return
&
gcePDCSIDriver
{
f
:
f
,
config
:
config
,
}
}
func
(
g
*
gcePDCSIDriver
)
createStorageClassTest
()
testsuites
.
StorageClassTest
{
return
testsuites
.
StorageClassTest
{
Name
:
"com.google.csi.gcepd"
,
// *Not* renaming the driver, see below.
Provisioner
:
"com.google.csi.gcepd"
,
Parameters
:
map
[
string
]
string
{
"type"
:
"pd-standard"
},
ClaimSize
:
"5Gi"
,
ExpectedSize
:
"5Gi"
,
}
}
func
(
g
*
gcePDCSIDriver
)
createCSIDriver
()
{
By
(
"deploying gce-pd driver"
)
// It would be safer to rename the gcePD driver, but that
// hasn't been done before either and attempts to do so now led to
// errors during driver registration, therefore it is disabled
// by passing a nil function below.
//
// These are the options which would have to be used:
// o := utils.PatchCSIOptions{
// OldDriverName: "com.google.csi.gcepd",
// NewDriverName: "com.google.csi.gcepd-" + g.f.UniqueName,
// DriverContainerName: "gce-driver",
// ProvisionerContainerName: "csi-external-provisioner",
// }
cleanup
,
err
:=
g
.
f
.
CreateFromManifests
(
nil
,
"test/e2e/testing-manifests/storage-csi/driver-registrar/rbac.yaml"
,
"test/e2e/testing-manifests/storage-csi/external-attacher/rbac.yaml"
,
"test/e2e/testing-manifests/storage-csi/external-provisioner/rbac.yaml"
,
"test/e2e/testing-manifests/storage-csi/gce-pd/csi-controller-rbac.yaml"
,
"test/e2e/testing-manifests/storage-csi/gce-pd/node_ds.yaml"
,
"test/e2e/testing-manifests/storage-csi/gce-pd/controller_ss.yaml"
,
)
g
.
cleanup
=
cleanup
if
err
!=
nil
{
framework
.
Failf
(
"deploying csi hostpath driver: %v"
,
err
)
}
}
func
(
g
*
gcePDCSIDriver
)
cleanupCSIDriver
()
{
By
(
"uninstalling gce-pd driver"
)
if
g
.
cleanup
!=
nil
{
g
.
cleanup
()
}
}
type
gcePDCSIDriverExternal
struct
{
}
func
initCSIgcePDExternal
(
f
*
framework
.
Framework
,
config
framework
.
VolumeTestConfig
)
csiTestDriver
{
cs
:=
f
.
ClientSet
framework
.
SkipUnlessProviderIs
(
"gce"
,
"gke"
)
framework
.
SkipIfMultizone
(
cs
)
return
&
gcePDCSIDriverExternal
{}
}
func
(
g
*
gcePDCSIDriverExternal
)
createStorageClassTest
()
testsuites
.
StorageClassTest
{
return
testsuites
.
StorageClassTest
{
Name
:
"com.google.csi.gcepd"
,
Provisioner
:
"com.google.csi.gcepd"
,
Parameters
:
map
[
string
]
string
{
"type"
:
"pd-standard"
},
ClaimSize
:
"5Gi"
,
ExpectedSize
:
"5Gi"
,
}
}
func
(
g
*
gcePDCSIDriverExternal
)
createCSIDriver
()
{
}
func
(
g
*
gcePDCSIDriverExternal
)
cleanupCSIDriver
()
{
}
test/e2e/storage/drivers/BUILD
View file @
b89b3672
...
...
@@ -4,6 +4,8 @@ go_library(
name = "go_default_library",
srcs = [
"base.go",
"csi.go",
"csi_objects.go",
"in_tree.go",
],
importpath = "k8s.io/kubernetes/test/e2e/storage/drivers",
...
...
@@ -17,7 +19,9 @@ go_library(
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/uuid:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/authentication/serviceaccount:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
"//test/e2e/framework:go_default_library",
"//test/e2e/storage/testpatterns:go_default_library",
"//test/e2e/storage/utils:go_default_library",
...
...
test/e2e/storage/drivers/csi.go
0 → 100644
View file @
b89b3672
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* This file defines various csi volume test drivers for TestSuites.
*
* There are two ways, how to prepare test drivers:
* 1) With containerized server (NFS, Ceph, Gluster, iSCSI, ...)
* It creates a server pod which defines one volume for the tests.
* These tests work only when privileged containers are allowed, exporting
* various filesystems (NFS, GlusterFS, ...) usually needs some mounting or
* other privileged magic in the server pod.
*
* Note that the server containers are for testing purposes only and should not
* be used in production.
*
* 2) With server or cloud provider outside of Kubernetes (Cinder, GCE, AWS, Azure, ...)
* Appropriate server or cloud provider must exist somewhere outside
* the tested Kubernetes cluster. CreateVolume will create a new volume to be
* used in the TestSuites for inlineVolume or DynamicPV tests.
*/
package
drivers
import
(
"fmt"
"math/rand"
"time"
.
"github.com/onsi/ginkgo"
storagev1
"k8s.io/api/storage/v1"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/kubernetes/test/e2e/framework"
"k8s.io/kubernetes/test/e2e/storage/testpatterns"
"k8s.io/kubernetes/test/e2e/storage/utils"
)
// hostpathCSI
type
hostpathCSIDriver
struct
{
cleanup
func
()
driverInfo
DriverInfo
}
var
_
TestDriver
=
&
hostpathCSIDriver
{}
var
_
DynamicPVTestDriver
=
&
hostpathCSIDriver
{}
// InitHostPathCSIDriver returns hostpathCSIDriver that implements TestDriver interface
func
InitHostPathCSIDriver
()
TestDriver
{
return
&
hostpathCSIDriver
{
driverInfo
:
DriverInfo
{
Name
:
"csi-hostpath"
,
FeatureTag
:
""
,
MaxFileSize
:
testpatterns
.
FileSizeMedium
,
SupportedFsType
:
sets
.
NewString
(
""
,
// Default fsType
),
IsPersistent
:
true
,
IsFsGroupSupported
:
false
,
IsBlockSupported
:
false
,
},
}
}
func
(
h
*
hostpathCSIDriver
)
GetDriverInfo
()
*
DriverInfo
{
return
&
h
.
driverInfo
}
func
(
h
*
hostpathCSIDriver
)
SkipUnsupportedTest
(
pattern
testpatterns
.
TestPattern
)
{
}
func
(
h
*
hostpathCSIDriver
)
GetDynamicProvisionStorageClass
(
fsType
string
)
*
storagev1
.
StorageClass
{
provisioner
:=
h
.
driverInfo
.
Name
+
h
.
driverInfo
.
Framework
.
UniqueName
parameters
:=
map
[
string
]
string
{}
ns
:=
h
.
driverInfo
.
Framework
.
Namespace
.
Name
suffix
:=
fmt
.
Sprintf
(
"%s-sc"
,
provisioner
)
return
getStorageClass
(
provisioner
,
parameters
,
nil
,
ns
,
suffix
)
}
func
(
h
*
hostpathCSIDriver
)
CreateDriver
()
{
By
(
"deploying csi hostpath driver"
)
f
:=
h
.
driverInfo
.
Framework
cs
:=
f
.
ClientSet
// pods should be scheduled on the node
nodes
:=
framework
.
GetReadySchedulableNodesOrDie
(
cs
)
node
:=
nodes
.
Items
[
rand
.
Intn
(
len
(
nodes
.
Items
))]
h
.
driverInfo
.
Config
.
ClientNodeName
=
node
.
Name
h
.
driverInfo
.
Config
.
ServerNodeName
=
node
.
Name
// TODO (?): the storage.csi.image.version and storage.csi.image.registry
// settings are ignored for this test. We could patch the image definitions.
o
:=
utils
.
PatchCSIOptions
{
OldDriverName
:
h
.
driverInfo
.
Name
,
NewDriverName
:
h
.
driverInfo
.
Name
+
h
.
driverInfo
.
Framework
.
UniqueName
,
DriverContainerName
:
"hostpath"
,
ProvisionerContainerName
:
"csi-provisioner"
,
NodeName
:
h
.
driverInfo
.
Config
.
ServerNodeName
,
}
cleanup
,
err
:=
h
.
driverInfo
.
Framework
.
CreateFromManifests
(
func
(
item
interface
{})
error
{
return
utils
.
PatchCSIDeployment
(
h
.
driverInfo
.
Framework
,
o
,
item
)
},
"test/e2e/testing-manifests/storage-csi/driver-registrar/rbac.yaml"
,
"test/e2e/testing-manifests/storage-csi/external-attacher/rbac.yaml"
,
"test/e2e/testing-manifests/storage-csi/external-provisioner/rbac.yaml"
,
"test/e2e/testing-manifests/storage-csi/hostpath/hostpath/csi-hostpath-attacher.yaml"
,
"test/e2e/testing-manifests/storage-csi/hostpath/hostpath/csi-hostpath-provisioner.yaml"
,
"test/e2e/testing-manifests/storage-csi/hostpath/hostpath/csi-hostpathplugin.yaml"
,
"test/e2e/testing-manifests/storage-csi/hostpath/hostpath/e2e-test-rbac.yaml"
,
)
h
.
cleanup
=
cleanup
if
err
!=
nil
{
framework
.
Failf
(
"deploying csi hostpath driver: %v"
,
err
)
}
}
func
(
h
*
hostpathCSIDriver
)
CleanupDriver
()
{
if
h
.
cleanup
!=
nil
{
By
(
"uninstalling csi hostpath driver"
)
h
.
cleanup
()
}
}
// gce-pd
type
gcePDCSIDriver
struct
{
cleanup
func
()
driverInfo
DriverInfo
}
var
_
TestDriver
=
&
gcePDCSIDriver
{}
var
_
DynamicPVTestDriver
=
&
gcePDCSIDriver
{}
// InitGcePDCSIDriver returns gcePDCSIDriver that implements TestDriver interface
func
InitGcePDCSIDriver
()
TestDriver
{
return
&
gcePDCSIDriver
{
driverInfo
:
DriverInfo
{
Name
:
"com.google.csi.gcepd"
,
FeatureTag
:
"[Serial]"
,
MaxFileSize
:
testpatterns
.
FileSizeMedium
,
SupportedFsType
:
sets
.
NewString
(
""
,
// Default fsType
"ext2"
,
"ext3"
,
"ext4"
,
"xfs"
,
),
IsPersistent
:
true
,
IsFsGroupSupported
:
true
,
IsBlockSupported
:
false
,
},
}
}
func
(
g
*
gcePDCSIDriver
)
GetDriverInfo
()
*
DriverInfo
{
return
&
g
.
driverInfo
}
func
(
g
*
gcePDCSIDriver
)
SkipUnsupportedTest
(
pattern
testpatterns
.
TestPattern
)
{
f
:=
g
.
driverInfo
.
Framework
cs
:=
f
.
ClientSet
config
:=
g
.
driverInfo
.
Config
framework
.
SkipUnlessProviderIs
(
"gce"
,
"gke"
)
framework
.
SkipIfMultizone
(
cs
)
// TODO(#62561): Use credentials through external pod identity when that goes GA instead of downloading keys.
createGCESecrets
(
cs
,
config
)
framework
.
SkipUnlessSecretExistsAfterWait
(
cs
,
"cloud-sa"
,
config
.
Namespace
,
3
*
time
.
Minute
)
}
func
(
g
*
gcePDCSIDriver
)
GetDynamicProvisionStorageClass
(
fsType
string
)
*
storagev1
.
StorageClass
{
ns
:=
g
.
driverInfo
.
Framework
.
Namespace
.
Name
provisioner
:=
g
.
driverInfo
.
Name
suffix
:=
fmt
.
Sprintf
(
"%s-sc"
,
g
.
driverInfo
.
Name
)
parameters
:=
map
[
string
]
string
{
"type"
:
"pd-standard"
}
return
getStorageClass
(
provisioner
,
parameters
,
nil
,
ns
,
suffix
)
}
func
(
g
*
gcePDCSIDriver
)
CreateDriver
()
{
By
(
"deploying csi gce-pd driver"
)
// It would be safer to rename the gcePD driver, but that
// hasn't been done before either and attempts to do so now led to
// errors during driver registration, therefore it is disabled
// by passing a nil function below.
//
// These are the options which would have to be used:
// o := utils.PatchCSIOptions{
// OldDriverName: "com.google.csi.gcepd",
// NewDriverName: "com.google.csi.gcepd-" + g.f.UniqueName,
// DriverContainerName: "gce-driver",
// ProvisionerContainerName: "csi-external-provisioner",
// }
cleanup
,
err
:=
g
.
driverInfo
.
Framework
.
CreateFromManifests
(
nil
,
"test/e2e/testing-manifests/storage-csi/driver-registrar/rbac.yaml"
,
"test/e2e/testing-manifests/storage-csi/external-attacher/rbac.yaml"
,
"test/e2e/testing-manifests/storage-csi/external-provisioner/rbac.yaml"
,
"test/e2e/testing-manifests/storage-csi/gce-pd/csi-controller-rbac.yaml"
,
"test/e2e/testing-manifests/storage-csi/gce-pd/node_ds.yaml"
,
"test/e2e/testing-manifests/storage-csi/gce-pd/controller_ss.yaml"
,
)
g
.
cleanup
=
cleanup
if
err
!=
nil
{
framework
.
Failf
(
"deploying csi gce-pd driver: %v"
,
err
)
}
}
func
(
g
*
gcePDCSIDriver
)
CleanupDriver
()
{
By
(
"uninstalling gce-pd driver"
)
if
g
.
cleanup
!=
nil
{
g
.
cleanup
()
}
}
// gcePd-external
type
gcePDExternalCSIDriver
struct
{
driverInfo
DriverInfo
}
var
_
TestDriver
=
&
gcePDExternalCSIDriver
{}
var
_
DynamicPVTestDriver
=
&
gcePDExternalCSIDriver
{}
// InitGcePDExternalCSIDriver returns gcePDExternalCSIDriver that implements TestDriver interface
func
InitGcePDExternalCSIDriver
()
TestDriver
{
return
&
gcePDExternalCSIDriver
{
driverInfo
:
DriverInfo
{
Name
:
"com.google.csi.gcepd"
,
// TODO(#70258): this is temporary until we can figure out how to make e2e tests a library
FeatureTag
:
"[Serial][Feature: gcePD-external]"
,
MaxFileSize
:
testpatterns
.
FileSizeMedium
,
SupportedFsType
:
sets
.
NewString
(
""
,
// Default fsType
"ext2"
,
"ext3"
,
"ext4"
,
"xfs"
,
),
IsPersistent
:
true
,
IsFsGroupSupported
:
true
,
IsBlockSupported
:
false
,
},
}
}
func
(
g
*
gcePDExternalCSIDriver
)
GetDriverInfo
()
*
DriverInfo
{
return
&
g
.
driverInfo
}
func
(
g
*
gcePDExternalCSIDriver
)
SkipUnsupportedTest
(
pattern
testpatterns
.
TestPattern
)
{
framework
.
SkipUnlessProviderIs
(
"gce"
,
"gke"
)
framework
.
SkipIfMultizone
(
g
.
driverInfo
.
Framework
.
ClientSet
)
}
func
(
g
*
gcePDExternalCSIDriver
)
GetDynamicProvisionStorageClass
(
fsType
string
)
*
storagev1
.
StorageClass
{
ns
:=
g
.
driverInfo
.
Framework
.
Namespace
.
Name
provisioner
:=
g
.
driverInfo
.
Name
suffix
:=
fmt
.
Sprintf
(
"%s-sc"
,
g
.
driverInfo
.
Name
)
parameters
:=
map
[
string
]
string
{
"type"
:
"pd-standard"
}
return
getStorageClass
(
provisioner
,
parameters
,
nil
,
ns
,
suffix
)
}
func
(
g
*
gcePDExternalCSIDriver
)
CreateDriver
()
{
}
func
(
g
*
gcePDExternalCSIDriver
)
CleanupDriver
()
{
}
test/e2e/storage/csi_objects.go
→
test/e2e/storage/
drivers/
csi_objects.go
View file @
b89b3672
...
...
@@ -17,7 +17,7 @@ limitations under the License.
// This file is used to deploy the CSI hostPath plugin
// More Information: https://github.com/kubernetes-csi/drivers/tree/master/pkg/hostpath
package
storage
package
drivers
import
(
"flag"
...
...
test/e2e/storage/in_tree_volumes.go
View file @
b89b3672
...
...
@@ -23,6 +23,7 @@ import (
"k8s.io/api/core/v1"
"k8s.io/kubernetes/test/e2e/framework"
"k8s.io/kubernetes/test/e2e/storage/drivers"
"k8s.io/kubernetes/test/e2e/storage/testpatterns"
"k8s.io/kubernetes/test/e2e/storage/testsuites"
"k8s.io/kubernetes/test/e2e/storage/utils"
)
...
...
@@ -53,6 +54,10 @@ var testSuites = []func() testsuites.TestSuite{
testsuites
.
InitProvisioningTestSuite
,
}
func
intreeTunePattern
(
patterns
[]
testpatterns
.
TestPattern
)
[]
testpatterns
.
TestPattern
{
return
patterns
}
// This executes testSuites for in-tree volumes.
var
_
=
utils
.
SIGDescribe
(
"In-tree Volumes"
,
func
()
{
f
:=
framework
.
NewDefaultFramework
(
"volumes"
)
...
...
@@ -86,7 +91,7 @@ var _ = utils.SIGDescribe("In-tree Volumes", func() {
driver
.
CleanupDriver
()
})
testsuites
.
RunTestSuite
(
f
,
config
,
driver
,
testSuites
)
testsuites
.
RunTestSuite
(
f
,
config
,
driver
,
testSuites
,
intreeTunePattern
)
})
}
})
test/e2e/storage/testsuites/base.go
View file @
b89b3672
...
...
@@ -66,12 +66,12 @@ func getTestNameStr(suite TestSuite, pattern testpatterns.TestPattern) string {
}
// RunTestSuite runs all testpatterns of all testSuites for a driver
func
RunTestSuite
(
f
*
framework
.
Framework
,
config
framework
.
VolumeTestConfig
,
driver
drivers
.
TestDriver
,
tsInits
[]
func
()
TestSuite
)
{
func
RunTestSuite
(
f
*
framework
.
Framework
,
config
framework
.
VolumeTestConfig
,
driver
drivers
.
TestDriver
,
tsInits
[]
func
()
TestSuite
,
tunePatternFunc
func
([]
testpatterns
.
TestPattern
)
[]
testpatterns
.
TestPattern
)
{
for
_
,
testSuiteInit
:=
range
tsInits
{
suite
:=
testSuiteInit
()
tsInfo
:=
suite
.
getTestSuiteInfo
(
)
patterns
:=
tunePatternFunc
(
suite
.
getTestSuiteInfo
()
.
testPatterns
)
for
_
,
pattern
:=
range
tsInfo
.
testP
atterns
{
for
_
,
pattern
:=
range
p
atterns
{
suite
.
execTest
(
driver
,
pattern
)
}
}
...
...
@@ -164,7 +164,7 @@ func (r *genericVolumeTestResource) setupResource(driver drivers.TestDriver, pat
case
testpatterns
.
DynamicPV
:
framework
.
Logf
(
"Creating resource for dynamic PV"
)
if
dDriver
,
ok
:=
driver
.
(
drivers
.
DynamicPVTestDriver
);
ok
{
claimSize
:=
"
2
Gi"
claimSize
:=
"
5
Gi"
r
.
sc
=
dDriver
.
GetDynamicProvisionStorageClass
(
fsType
)
By
(
"creating a StorageClass "
+
r
.
sc
.
Name
)
...
...
test/e2e/storage/testsuites/provisioning.go
View file @
b89b3672
...
...
@@ -151,7 +151,7 @@ func (p *provisioningTestResource) setupResource(driver drivers.TestDriver, patt
framework
.
Skipf
(
"Driver %q does not define Dynamic Provision StorageClass - skipping"
,
driver
.
GetDriverInfo
()
.
Name
)
}
p
.
driver
=
driver
p
.
claimSize
=
"
2
Gi"
p
.
claimSize
=
"
5
Gi"
p
.
pvc
=
getClaim
(
p
.
claimSize
,
driver
.
GetDriverInfo
()
.
Framework
.
Namespace
.
Name
)
p
.
pvc
.
Spec
.
StorageClassName
=
&
p
.
sc
.
Name
framework
.
Logf
(
"In creating storage class object and pvc object for driver - sc: %v, pvc: %v"
,
p
.
sc
,
p
.
pvc
)
...
...
test/e2e/storage/testsuites/subpath.go
View file @
b89b3672
...
...
@@ -19,6 +19,7 @@ package testsuites
import
(
"fmt"
"path/filepath"
"regexp"
"strings"
"k8s.io/api/core/v1"
...
...
@@ -315,7 +316,8 @@ func testSubPath(input *subPathTestInput) {
})
It
(
"should unmount if pod is force deleted while kubelet is down [Disruptive][Slow]"
,
func
()
{
if
input
.
volType
==
"hostPath"
||
input
.
volType
==
"hostPathSymlink"
{
if
strings
.
HasPrefix
(
input
.
volType
,
"hostPath"
)
||
strings
.
HasPrefix
(
input
.
volType
,
"csi-hostpath"
)
{
// TODO: This skip should be removed once #61446 is fixed
framework
.
Skipf
(
"%s volume type does not support reconstruction, skipping"
,
input
.
volType
)
}
testSubpathReconstruction
(
input
.
f
,
input
.
pod
,
true
)
...
...
@@ -380,10 +382,23 @@ func TestBasicSubpathFile(f *framework.Framework, contents string, pod *v1.Pod,
Expect
(
err
)
.
NotTo
(
HaveOccurred
(),
"while deleting pod"
)
}
func
generateSuffixForPodName
(
s
string
)
string
{
// Pod name must:
// 1. consist of lower case alphanumeric characters or '-',
// 2. start and end with an alphanumeric character.
// (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?')
// Therefore, suffix is generated by following steps:
// 1. all strings other than [A-Za-z0-9] is replaced with "-",
// 2. add lower case alphanumeric characters at the end ('-[a-z0-9]{4}' is added),
// 3. convert the entire strings to lower case.
re
:=
regexp
.
MustCompile
(
"[^A-Za-z0-9]"
)
return
strings
.
ToLower
(
fmt
.
Sprintf
(
"%s-%s"
,
re
.
ReplaceAllString
(
s
,
"-"
),
rand
.
String
(
4
)))
}
// SubpathTestPod returns a pod spec for subpath tests
func
SubpathTestPod
(
f
*
framework
.
Framework
,
subpath
,
volumeType
string
,
source
*
v1
.
VolumeSource
,
privilegedSecurityContext
bool
)
*
v1
.
Pod
{
var
(
suffix
=
strings
.
ToLower
(
fmt
.
Sprintf
(
"%s-%s"
,
volumeType
,
rand
.
String
(
4
))
)
suffix
=
generateSuffixForPodName
(
volumeType
)
gracePeriod
=
int64
(
1
)
probeVolumeName
=
"liveness-probe-volume"
)
...
...
test/e2e/storage/testsuites/volumemode.go
View file @
b89b3672
...
...
@@ -197,7 +197,7 @@ func (s *volumeModeTestResource) setupResource(driver drivers.TestDriver, patter
}
s
.
sc
.
VolumeBindingMode
=
&
volBindMode
claimSize
:=
"
2
Gi"
claimSize
:=
"
5
Gi"
s
.
pvc
=
getClaim
(
claimSize
,
ns
.
Name
)
s
.
pvc
.
Spec
.
StorageClassName
=
&
s
.
sc
.
Name
s
.
pvc
.
Spec
.
VolumeMode
=
&
volMode
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment