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
0d81e4c8
Commit
0d81e4c8
authored
Mar 31, 2017
by
Jeff Vance
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
improve error handling in e2e helpers by always returning error
parent
55042b0b
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
117 additions
and
107 deletions
+117
-107
pv_util.go
test/e2e/framework/pv_util.go
+0
-0
kubelet.go
test/e2e/kubelet.go
+3
-3
BUILD
test/e2e/storage/BUILD
+1
-0
pd.go
test/e2e/storage/pd.go
+2
-2
persistent_volumes-disruptive.go
test/e2e/storage/persistent_volumes-disruptive.go
+10
-7
persistent_volumes-gce.go
test/e2e/storage/persistent_volumes-gce.go
+20
-18
persistent_volumes-vsphere.go
test/e2e/storage/persistent_volumes-vsphere.go
+14
-26
persistent_volumes.go
test/e2e/storage/persistent_volumes.go
+0
-0
pv_reclaimpolicy.go
test/e2e/storage/pv_reclaimpolicy.go
+7
-7
pvc_label_selector.go
test/e2e/storage/pvc_label_selector.go
+6
-6
volume_provisioning.go
test/e2e/storage/volume_provisioning.go
+25
-21
volumes.go
test/e2e/storage/volumes.go
+1
-2
vsphere_volume_ops_storm.go
test/e2e/storage/vsphere_volume_ops_storm.go
+7
-4
vsphere_volume_placement.go
test/e2e/storage/vsphere_volume_placement.go
+5
-5
BUILD
test/e2e/upgrades/BUILD
+1
-0
persistent_volumes.go
test/e2e/upgrades/persistent_volumes.go
+15
-6
No files found.
test/e2e/framework/pv_util.go
View file @
0d81e4c8
This diff is collapsed.
Click to expand it.
test/e2e/kubelet.go
View file @
0d81e4c8
...
...
@@ -457,8 +457,8 @@ var _ = framework.KubeDescribe("kubelet", func() {
})
AfterEach
(
func
()
{
framework
.
DeletePodWithWait
(
f
,
c
,
pod
)
framework
.
DeletePodWithWait
(
f
,
c
,
nfsServerPod
)
framework
.
ExpectNoError
(
framework
.
DeletePodWithWait
(
f
,
c
,
pod
),
"AfterEach: Failed to delete pod "
,
pod
.
Name
)
framework
.
ExpectNoError
(
framework
.
DeletePodWithWait
(
f
,
c
,
nfsServerPod
),
"AfterEach: Failed to delete pod "
,
nfsServerPod
.
Name
)
})
// execute It blocks from above table of tests
...
...
@@ -470,7 +470,7 @@ var _ = framework.KubeDescribe("kubelet", func() {
stopNfsServer
(
nfsServerPod
)
By
(
"Delete the pod mounted to the NFS volume"
)
framework
.
DeletePodWithWait
(
f
,
c
,
pod
)
framework
.
ExpectNoError
(
framework
.
DeletePodWithWait
(
f
,
c
,
pod
),
"Failed to delete pod "
,
pod
.
Name
)
// pod object is now stale, but is intentionally not nil
By
(
"Check if pod's host has been cleaned up -- expect not"
)
...
...
test/e2e/storage/BUILD
View file @
0d81e4c8
...
...
@@ -52,6 +52,7 @@ go_library(
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/uuid:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
...
...
test/e2e/storage/pd.go
View file @
0d81e4c8
...
...
@@ -521,7 +521,7 @@ var _ = framework.KubeDescribe("Pod Disks", func() {
framework
.
SkipUnlessProviderIs
(
"gce"
)
By
(
"delete a PD"
)
framework
.
DeletePDWithRetry
(
"non-exist"
)
framework
.
ExpectNoError
(
framework
.
DeletePDWithRetry
(
"non-exist"
)
)
})
})
...
...
@@ -697,7 +697,7 @@ func detachAndDeletePDs(diskName string, hosts []types.NodeName) {
waitForPDDetach
(
diskName
,
host
)
}
By
(
fmt
.
Sprintf
(
"Deleting PD %q"
,
diskName
))
framework
.
DeletePDWithRetry
(
diskName
)
framework
.
ExpectNoError
(
framework
.
DeletePDWithRetry
(
diskName
)
)
}
func
waitForPDInVolumesInUse
(
...
...
test/e2e/storage/persistent_volumes-disruptive.go
View file @
0d81e4c8
...
...
@@ -184,7 +184,7 @@ func testVolumeUnmountsFromDeletedPod(c clientset.Interface, f *framework.Framew
By
(
"Restarting the kubelet."
)
kubeletCommand
(
kStop
,
c
,
clientPod
)
framework
.
DeletePodWithWait
(
f
,
c
,
clientPod
)
framework
.
ExpectNoError
(
framework
.
DeletePodWithWait
(
f
,
c
,
clientPod
),
"Failed to delete pod "
,
clientPod
.
Name
)
kubeletCommand
(
kStart
,
c
,
clientPod
)
By
(
"Expecting the volume mount not to be found."
)
...
...
@@ -195,13 +195,16 @@ func testVolumeUnmountsFromDeletedPod(c clientset.Interface, f *framework.Framew
framework
.
Logf
(
"Volume mount detected on pod and written file is readable post-restart."
)
}
// initTestCase initializes spec resources (pv, pvc, and pod) and returns pointers to be consumed by the test
// initTestCase initializes spec resources (pv, pvc, and pod) and returns pointers to be consumed
// by the test.
func
initTestCase
(
f
*
framework
.
Framework
,
c
clientset
.
Interface
,
pvConfig
framework
.
PersistentVolumeConfig
,
pvcConfig
framework
.
PersistentVolumeClaimConfig
,
ns
,
nodeName
string
)
(
*
v1
.
Pod
,
*
v1
.
PersistentVolume
,
*
v1
.
PersistentVolumeClaim
)
{
pv
,
pvc
:=
framework
.
CreatePVPVC
(
c
,
pvConfig
,
pvcConfig
,
ns
,
false
)
pv
,
pvc
,
err
:=
framework
.
CreatePVPVC
(
c
,
pvConfig
,
pvcConfig
,
ns
,
false
)
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
pod
:=
framework
.
MakePod
(
ns
,
[]
*
v1
.
PersistentVolumeClaim
{
pvc
},
true
,
""
)
pod
.
Spec
.
NodeName
=
nodeName
framework
.
Logf
(
"Creating nfs client Pod %s on node %s"
,
pod
.
Name
,
nodeName
)
pod
,
err
:
=
c
.
CoreV1
()
.
Pods
(
ns
)
.
Create
(
pod
)
pod
,
err
=
c
.
CoreV1
()
.
Pods
(
ns
)
.
Create
(
pod
)
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
err
=
framework
.
WaitForPodRunningInNamespace
(
c
,
pod
)
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
...
...
@@ -217,9 +220,9 @@ func initTestCase(f *framework.Framework, c clientset.Interface, pvConfig framew
// tearDownTestCase destroy resources created by initTestCase.
func
tearDownTestCase
(
c
clientset
.
Interface
,
f
*
framework
.
Framework
,
ns
string
,
pod
*
v1
.
Pod
,
pvc
*
v1
.
PersistentVolumeClaim
,
pv
*
v1
.
PersistentVolume
)
{
framework
.
DeletePodWithWait
(
f
,
c
,
pod
)
framework
.
DeletePersistentVolumeClaim
(
c
,
pvc
.
Name
,
ns
)
framework
.
DeletePersistentVolume
(
c
,
pv
.
Name
)
framework
.
ExpectNoError
(
framework
.
DeletePodWithWait
(
f
,
c
,
pod
),
"tearDown: Failed to delete pod "
,
pod
.
Name
)
framework
.
ExpectNoError
(
framework
.
DeletePersistentVolumeClaim
(
c
,
pvc
.
Name
,
ns
),
"tearDown: Failed to delete PVC "
,
pvc
.
Name
)
framework
.
ExpectNoError
(
framework
.
DeletePersistentVolume
(
c
,
pv
.
Name
),
"tearDown: Failed to delete PV "
,
pv
.
Name
)
}
// kubeletCommand performs `start`, `restart`, or `stop` on the kubelet running on the node of the target pod.
...
...
test/e2e/storage/persistent_volumes-gce.go
View file @
0d81e4c8
...
...
@@ -24,6 +24,7 @@ import (
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/types"
utilerrors
"k8s.io/apimachinery/pkg/util/errors"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
"k8s.io/kubernetes/test/e2e/framework"
...
...
@@ -41,11 +42,13 @@ func verifyGCEDiskAttached(diskName string, nodeName types.NodeName) bool {
// initializeGCETestSpec creates a PV, PVC, and ClientPod that will run until killed by test or clean up.
func
initializeGCETestSpec
(
c
clientset
.
Interface
,
ns
string
,
pvConfig
framework
.
PersistentVolumeConfig
,
pvcConfig
framework
.
PersistentVolumeClaimConfig
,
isPrebound
bool
)
(
*
v1
.
Pod
,
*
v1
.
PersistentVolume
,
*
v1
.
PersistentVolumeClaim
)
{
By
(
"Creating the PV and PVC"
)
pv
,
pvc
:=
framework
.
CreatePVPVC
(
c
,
pvConfig
,
pvcConfig
,
ns
,
isPrebound
)
framework
.
WaitOnPVandPVC
(
c
,
ns
,
pv
,
pvc
)
pv
,
pvc
,
err
:=
framework
.
CreatePVPVC
(
c
,
pvConfig
,
pvcConfig
,
ns
,
isPrebound
)
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
framework
.
ExpectNoError
(
framework
.
WaitOnPVandPVC
(
c
,
ns
,
pv
,
pvc
))
By
(
"Creating the Client Pod"
)
clientPod
:=
framework
.
CreateClientPod
(
c
,
ns
,
pvc
)
clientPod
,
err
:=
framework
.
CreateClientPod
(
c
,
ns
,
pvc
)
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
return
clientPod
,
pv
,
pvc
}
...
...
@@ -104,11 +107,13 @@ var _ = framework.KubeDescribe("PersistentVolumes:GCEPD [Volume]", func() {
AfterEach
(
func
()
{
framework
.
Logf
(
"AfterEach: Cleaning up test resources"
)
if
c
!=
nil
{
framework
.
DeletePodWithWait
(
f
,
c
,
clientPod
)
framework
.
PVPVCCleanup
(
c
,
ns
,
pv
,
pvc
)
framework
.
ExpectNoError
(
framework
.
DeletePodWithWait
(
f
,
c
,
clientPod
))
if
errs
:=
framework
.
PVPVCCleanup
(
c
,
ns
,
pv
,
pvc
);
len
(
errs
)
>
0
{
framework
.
Failf
(
"AfterEach: Failed to delete PVC and/or PV. Errors: %v"
,
utilerrors
.
NewAggregate
(
errs
))
}
clientPod
,
pv
,
pvc
,
node
=
nil
,
nil
,
nil
,
""
if
diskName
!=
""
{
framework
.
DeletePDWithRetry
(
diskName
)
framework
.
ExpectNoError
(
framework
.
DeletePDWithRetry
(
diskName
)
)
}
}
})
...
...
@@ -118,15 +123,14 @@ var _ = framework.KubeDescribe("PersistentVolumes:GCEPD [Volume]", func() {
It
(
"should test that deleting a PVC before the pod does not cause pod deletion to fail on PD detach"
,
func
()
{
By
(
"Deleting the Claim"
)
framework
.
DeletePersistentVolumeClaim
(
c
,
pvc
.
Name
,
ns
)
verifyGCEDiskAttached
(
diskName
,
node
)
framework
.
ExpectNoError
(
framework
.
DeletePersistentVolumeClaim
(
c
,
pvc
.
Name
,
ns
),
"Unable to delete PVC "
,
pvc
.
Name
)
Expect
(
verifyGCEDiskAttached
(
diskName
,
node
))
.
To
(
BeTrue
()
)
By
(
"Deleting the Pod"
)
framework
.
DeletePodWithWait
(
f
,
c
,
clientPod
)
framework
.
ExpectNoError
(
framework
.
DeletePodWithWait
(
f
,
c
,
clientPod
),
"Failed to delete pod "
,
clientPod
.
Name
)
By
(
"Verifying Persistent Disk detach"
)
err
=
waitForPDDetach
(
diskName
,
node
)
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
framework
.
ExpectNoError
(
waitForPDDetach
(
diskName
,
node
),
"PD "
,
diskName
,
" did not detach"
)
})
// Attach a persistent disk to a pod using a PVC.
...
...
@@ -134,15 +138,14 @@ var _ = framework.KubeDescribe("PersistentVolumes:GCEPD [Volume]", func() {
It
(
"should test that deleting the PV before the pod does not cause pod deletion to fail on PD detach"
,
func
()
{
By
(
"Deleting the Persistent Volume"
)
framework
.
DeletePersistentVolume
(
c
,
pv
.
Name
)
verifyGCEDiskAttached
(
diskName
,
node
)
framework
.
ExpectNoError
(
framework
.
DeletePersistentVolume
(
c
,
pv
.
Name
),
"Failed to delete PV "
,
pv
.
Name
)
Expect
(
verifyGCEDiskAttached
(
diskName
,
node
))
.
To
(
BeTrue
()
)
By
(
"Deleting the client pod"
)
framework
.
DeletePodWithWait
(
f
,
c
,
clientPod
)
framework
.
ExpectNoError
(
framework
.
DeletePodWithWait
(
f
,
c
,
clientPod
),
"Failed to delete pod "
,
clientPod
.
Name
)
By
(
"Verifying Persistent Disk detaches"
)
err
=
waitForPDDetach
(
diskName
,
node
)
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
framework
.
ExpectNoError
(
waitForPDDetach
(
diskName
,
node
),
"PD "
,
diskName
,
" did not detach"
)
})
// Test that a Pod and PVC attached to a GCEPD successfully unmounts and detaches when the encompassing Namespace is deleted.
...
...
@@ -156,7 +159,6 @@ var _ = framework.KubeDescribe("PersistentVolumes:GCEPD [Volume]", func() {
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
By
(
"Verifying Persistent Disk detaches"
)
err
=
waitForPDDetach
(
diskName
,
node
)
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
framework
.
ExpectNoError
(
waitForPDDetach
(
diskName
,
node
),
"PD "
,
diskName
,
" did not detach"
)
})
})
test/e2e/storage/persistent_volumes-vsphere.go
View file @
0d81e4c8
...
...
@@ -17,7 +17,6 @@ limitations under the License.
package
storage
import
(
apierrs
"k8s.io/apimachinery/pkg/api/errors"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/kubernetes/pkg/api/v1"
...
...
@@ -95,11 +94,13 @@ var _ = framework.KubeDescribe("PersistentVolumes:vsphere", func() {
}
}
By
(
"Creating the PV and PVC"
)
pv
,
pvc
=
framework
.
CreatePVPVC
(
c
,
pvConfig
,
pvcConfig
,
ns
,
false
)
framework
.
WaitOnPVandPVC
(
c
,
ns
,
pv
,
pvc
)
pv
,
pvc
,
err
=
framework
.
CreatePVPVC
(
c
,
pvConfig
,
pvcConfig
,
ns
,
false
)
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
framework
.
ExpectNoError
(
framework
.
WaitOnPVandPVC
(
c
,
ns
,
pv
,
pvc
))
By
(
"Creating the Client Pod"
)
clientPod
=
framework
.
CreateClientPod
(
c
,
ns
,
pvc
)
clientPod
,
err
=
framework
.
CreateClientPod
(
c
,
ns
,
pvc
)
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
node
:=
types
.
NodeName
(
clientPod
.
Spec
.
NodeName
)
By
(
"Verify disk should be attached to the node"
)
...
...
@@ -111,18 +112,13 @@ var _ = framework.KubeDescribe("PersistentVolumes:vsphere", func() {
AfterEach
(
func
()
{
framework
.
Logf
(
"AfterEach: Cleaning up test resources"
)
if
c
!=
nil
{
if
clientPod
!=
nil
{
clientPod
,
err
=
c
.
CoreV1
()
.
Pods
(
ns
)
.
Get
(
clientPod
.
Name
,
metav1
.
GetOptions
{})
if
!
apierrs
.
IsNotFound
(
err
)
{
framework
.
DeletePodWithWait
(
f
,
c
,
clientPod
)
}
}
framework
.
ExpectNoError
(
framework
.
DeletePodWithWait
(
f
,
c
,
clientPod
),
"AfterEach: failed to delete pod "
,
clientPod
.
Name
)
if
pv
!=
nil
{
framework
.
DeletePersistentVolume
(
c
,
pv
.
Name
)
framework
.
ExpectNoError
(
framework
.
DeletePersistentVolume
(
c
,
pv
.
Name
),
"AfterEach: failed to delete PV "
,
pv
.
Name
)
}
if
pvc
!=
nil
{
framework
.
DeletePersistentVolumeClaim
(
c
,
pvc
.
Name
,
ns
)
framework
.
ExpectNoError
(
framework
.
DeletePersistentVolumeClaim
(
c
,
pvc
.
Name
,
ns
),
"AfterEach: failed to delete PVC "
,
pvc
.
Name
)
}
}
})
...
...
@@ -150,16 +146,11 @@ var _ = framework.KubeDescribe("PersistentVolumes:vsphere", func() {
It
(
"should test that deleting a PVC before the pod does not cause pod deletion to fail on PD detach"
,
func
()
{
By
(
"Deleting the Claim"
)
framework
.
DeletePersistentVolumeClaim
(
c
,
pvc
.
Name
,
ns
)
pvc
,
err
=
c
.
CoreV1
()
.
PersistentVolumeClaims
(
ns
)
.
Get
(
pvc
.
Name
,
metav1
.
GetOptions
{})
if
!
apierrs
.
IsNotFound
(
err
)
{
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
}
framework
.
ExpectNoError
(
framework
.
DeletePersistentVolumeClaim
(
c
,
pvc
.
Name
,
ns
),
"Failed to delete PVC "
,
pvc
.
Name
)
pvc
=
nil
By
(
"Deleting the Pod"
)
framework
.
DeletePodWithWait
(
f
,
c
,
clientPod
)
By
(
"Deleting the Pod"
)
framework
.
ExpectNoError
(
framework
.
DeletePodWithWait
(
f
,
c
,
clientPod
),
"Failed to delete pod "
,
clientPod
.
Name
)
})
/*
...
...
@@ -171,13 +162,10 @@ var _ = framework.KubeDescribe("PersistentVolumes:vsphere", func() {
*/
It
(
"should test that deleting the PV before the pod does not cause pod deletion to fail on PD detach"
,
func
()
{
By
(
"Deleting the Persistent Volume"
)
framework
.
DeletePersistentVolume
(
c
,
pv
.
Name
)
pv
,
err
=
c
.
CoreV1
()
.
PersistentVolumes
()
.
Get
(
pv
.
Name
,
metav1
.
GetOptions
{})
if
!
apierrs
.
IsNotFound
(
err
)
{
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
}
framework
.
ExpectNoError
(
framework
.
DeletePersistentVolume
(
c
,
pv
.
Name
),
"Failed to delete PV "
,
pv
.
Name
)
pv
=
nil
By
(
"Deleting the pod"
)
framework
.
DeletePodWithWait
(
f
,
c
,
clientPod
)
framework
.
ExpectNoError
(
framework
.
DeletePodWithWait
(
f
,
c
,
clientPod
),
"Failed to delete pod "
,
clientPod
.
Name
)
})
})
test/e2e/storage/persistent_volumes.go
View file @
0d81e4c8
This diff is collapsed.
Click to expand it.
test/e2e/storage/pv_reclaimpolicy.go
View file @
0d81e4c8
...
...
@@ -119,14 +119,14 @@ var _ = framework.KubeDescribe("PersistentVolumes [Feature:ReclaimPolicy]", func
writeContentToVSpherePV
(
c
,
pvc
,
volumeFileContent
)
By
(
"Delete PVC"
)
framework
.
DeletePersistentVolumeClaim
(
c
,
pvc
.
Name
,
ns
)
framework
.
ExpectNoError
(
framework
.
DeletePersistentVolumeClaim
(
c
,
pvc
.
Name
,
ns
),
"Failed to delete PVC "
,
pvc
.
Name
)
pvc
=
nil
By
(
"Verify PV is retained"
)
framework
.
Logf
(
"Waiting for PV %v to become Released"
,
pv
.
Name
)
err
=
framework
.
WaitForPersistentVolumePhase
(
v1
.
VolumeReleased
,
c
,
pv
.
Name
,
3
*
time
.
Second
,
300
*
time
.
Second
)
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
framework
.
DeletePersistentVolume
(
c
,
pv
.
Name
)
framework
.
ExpectNoError
(
framework
.
DeletePersistentVolume
(
c
,
pv
.
Name
),
"Failed to delete PV "
,
pv
.
Name
)
By
(
"Creating the PV for same volume path"
)
pv
=
getVSpherePersistentVolumeSpec
(
volumePath
,
v1
.
PersistentVolumeReclaimRetain
,
nil
)
...
...
@@ -139,7 +139,7 @@ var _ = framework.KubeDescribe("PersistentVolumes [Feature:ReclaimPolicy]", func
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
By
(
"wait for the pv and pvc to bind"
)
framework
.
WaitOnPVandPVC
(
c
,
ns
,
pv
,
pvc
)
framework
.
ExpectNoError
(
framework
.
WaitOnPVandPVC
(
c
,
ns
,
pv
,
pvc
)
)
verifyContentOfVSpherePV
(
c
,
pvc
,
volumeFileContent
)
})
...
...
@@ -173,10 +173,10 @@ func testCleanupVSpherePersistentVolumeReclaim(vsp *vsphere.VSphere, c clientset
vsp
.
DeleteVolume
(
volumePath
)
}
if
pv
!=
nil
{
framework
.
DeletePersistentVolume
(
c
,
pv
.
Name
)
framework
.
ExpectNoError
(
framework
.
DeletePersistentVolume
(
c
,
pv
.
Name
),
"Failed to delete PV "
,
pv
.
Name
)
}
if
pvc
!=
nil
{
framework
.
DeletePersistentVolumeClaim
(
c
,
pvc
.
Name
,
ns
)
framework
.
ExpectNoError
(
framework
.
DeletePersistentVolumeClaim
(
c
,
pvc
.
Name
,
ns
),
"Failed to delete PVC "
,
pvc
.
Name
)
}
}
...
...
@@ -185,10 +185,10 @@ func deletePVCAfterBind(c clientset.Interface, ns string, pvc *v1.PersistentVolu
var
err
error
By
(
"wait for the pv and pvc to bind"
)
framework
.
WaitOnPVandPVC
(
c
,
ns
,
pv
,
pvc
)
framework
.
ExpectNoError
(
framework
.
WaitOnPVandPVC
(
c
,
ns
,
pv
,
pvc
)
)
By
(
"delete pvc"
)
framework
.
DeletePersistentVolumeClaim
(
c
,
pvc
.
Name
,
ns
)
framework
.
ExpectNoError
(
framework
.
DeletePersistentVolumeClaim
(
c
,
pvc
.
Name
,
ns
),
"Failed to delete PVC "
,
pvc
.
Name
)
pvc
,
err
=
c
.
CoreV1
()
.
PersistentVolumeClaims
(
ns
)
.
Get
(
pvc
.
Name
,
metav1
.
GetOptions
{})
if
!
apierrs
.
IsNotFound
(
err
)
{
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
...
...
test/e2e/storage/pvc_label_selector.go
View file @
0d81e4c8
...
...
@@ -81,14 +81,14 @@ var _ = framework.KubeDescribe("PersistentVolumes [Feature:LabelSelector]", func
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
By
(
"wait for the pvc_ssd to bind with pv_ssd"
)
framework
.
WaitOnPVandPVC
(
c
,
ns
,
pv_ssd
,
pvc_ssd
)
framework
.
ExpectNoError
(
framework
.
WaitOnPVandPVC
(
c
,
ns
,
pv_ssd
,
pvc_ssd
)
)
By
(
"Verify status of pvc_vvol is pending"
)
err
=
framework
.
WaitForPersistentVolumeClaimPhase
(
v1
.
ClaimPending
,
c
,
ns
,
pvc_vvol
.
Name
,
3
*
time
.
Second
,
300
*
time
.
Second
)
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
By
(
"delete pvc_ssd"
)
framework
.
DeletePersistentVolumeClaim
(
c
,
pvc_ssd
.
Name
,
ns
)
framework
.
ExpectNoError
(
framework
.
DeletePersistentVolumeClaim
(
c
,
pvc_ssd
.
Name
,
ns
),
"Failed to delete PVC "
,
pvc_ssd
.
Name
)
By
(
"verify pv_ssd is deleted"
)
err
=
framework
.
WaitForPersistentVolumeDeleted
(
c
,
pv_ssd
.
Name
,
3
*
time
.
Second
,
300
*
time
.
Second
)
...
...
@@ -96,7 +96,7 @@ var _ = framework.KubeDescribe("PersistentVolumes [Feature:LabelSelector]", func
volumePath
=
""
By
(
"delete pvc_vvol"
)
framework
.
DeletePersistentVolumeClaim
(
c
,
pvc_vvol
.
Name
,
ns
)
framework
.
ExpectNoError
(
framework
.
DeletePersistentVolumeClaim
(
c
,
pvc_vvol
.
Name
,
ns
),
"Failed to delete PVC "
,
pvc_vvol
.
Name
)
})
})
})
...
...
@@ -139,12 +139,12 @@ func testCleanupVSpherePVClabelselector(c clientset.Interface, ns string, volume
vsp
.
DeleteVolume
(
volumePath
)
}
if
pvc_ssd
!=
nil
{
framework
.
DeletePersistentVolumeClaim
(
c
,
pvc_ssd
.
Name
,
ns
)
framework
.
ExpectNoError
(
framework
.
DeletePersistentVolumeClaim
(
c
,
pvc_ssd
.
Name
,
ns
),
"Failed to delete PVC "
,
pvc_ssd
.
Name
)
}
if
pvc_vvol
!=
nil
{
framework
.
DeletePersistentVolumeClaim
(
c
,
pvc_vvol
.
Name
,
ns
)
framework
.
ExpectNoError
(
framework
.
DeletePersistentVolumeClaim
(
c
,
pvc_vvol
.
Name
,
ns
),
"Failed to delete PVC "
,
pvc_vvol
.
Name
)
}
if
pv_ssd
!=
nil
{
framework
.
DeletePersistentVolume
(
c
,
pv_ssd
.
Name
)
framework
.
ExpectNoError
(
framework
.
DeletePersistentVolume
(
c
,
pv_ssd
.
Name
),
"Faled to delete PV "
,
pv_ssd
.
Name
)
}
}
test/e2e/storage/volume_provisioning.go
View file @
0d81e4c8
...
...
@@ -68,7 +68,7 @@ func testDynamicProvisioning(t storageClassTest, client clientset.Interface, cla
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
defer
func
()
{
framework
.
Logf
(
"deleting storage class %s"
,
class
.
Name
)
client
.
StorageV1
()
.
StorageClasses
()
.
Delete
(
class
.
Name
,
nil
)
framework
.
ExpectNoError
(
client
.
StorageV1
()
.
StorageClasses
()
.
Delete
(
class
.
Name
,
nil
)
)
}()
}
...
...
@@ -76,8 +76,12 @@ func testDynamicProvisioning(t storageClassTest, client clientset.Interface, cla
claim
,
err
=
client
.
CoreV1
()
.
PersistentVolumeClaims
(
claim
.
Namespace
)
.
Create
(
claim
)
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
defer
func
()
{
framework
.
Logf
(
"deleting claim %s/%s"
,
claim
.
Namespace
,
claim
.
Name
)
client
.
CoreV1
()
.
PersistentVolumeClaims
(
claim
.
Namespace
)
.
Delete
(
claim
.
Name
,
nil
)
framework
.
Logf
(
"deleting claim %q/%q"
,
claim
.
Namespace
,
claim
.
Name
)
// typically this claim has already been deleted
err
=
client
.
CoreV1
()
.
PersistentVolumeClaims
(
claim
.
Namespace
)
.
Delete
(
claim
.
Name
,
nil
)
if
err
!=
nil
&&
!
apierrs
.
IsNotFound
(
err
)
{
framework
.
Failf
(
"Error deleting claim %q. Error: %v"
,
claim
.
Name
,
err
)
}
}()
err
=
framework
.
WaitForPersistentVolumeClaimPhase
(
v1
.
ClaimBound
,
client
,
claim
.
Namespace
,
claim
.
Name
,
framework
.
Poll
,
framework
.
ClaimProvisionTimeout
)
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
...
...
@@ -125,7 +129,7 @@ func testDynamicProvisioning(t storageClassTest, client clientset.Interface, cla
By
(
"checking the created volume is readable and retains data"
)
runInPodWithVolume
(
client
,
claim
.
Namespace
,
claim
.
Name
,
"grep 'hello world' /mnt/test/data"
)
By
(
"deleting the claim"
)
By
(
fmt
.
Sprintf
(
"deleting claim %q/%q"
,
claim
.
Namespace
,
claim
.
Name
)
)
framework
.
ExpectNoError
(
client
.
CoreV1
()
.
PersistentVolumeClaims
(
claim
.
Namespace
)
.
Delete
(
claim
.
Name
,
nil
))
// Wait for the PV to get deleted. Technically, the first few delete
...
...
@@ -133,6 +137,7 @@ func testDynamicProvisioning(t storageClassTest, client clientset.Interface, cla
// kubelet is slowly cleaning up the previous pod, however it should succeed
// in a couple of minutes. Wait 20 minutes to recover from random cloud
// hiccups.
By
(
fmt
.
Sprintf
(
"deleting the claim's PV %q"
,
pv
.
Name
))
framework
.
ExpectNoError
(
framework
.
WaitForPersistentVolumeDeleted
(
client
,
pv
.
Name
,
5
*
time
.
Second
,
20
*
time
.
Minute
))
}
...
...
@@ -391,8 +396,8 @@ var _ = framework.KubeDescribe("Dynamic Provisioning", func() {
}
})
// NOTE: Slow! The test will wait up to 5 minutes (framework.ClaimProvisionTimeout)
when there is
// no regression.
// NOTE: Slow! The test will wait up to 5 minutes (framework.ClaimProvisionTimeout)
//
when there is
no regression.
It
(
"should not provision a volume in an unmanaged GCE zone. [Slow] [Volume]"
,
func
()
{
framework
.
SkipUnlessProviderIs
(
"gce"
,
"gke"
)
var
suffix
string
=
"unmananged"
...
...
@@ -410,6 +415,7 @@ var _ = framework.KubeDescribe("Dynamic Provisioning", func() {
// Get a list of all zones in the project
zones
,
err
:=
gceCloud
.
GetComputeService
()
.
Zones
.
List
(
framework
.
TestContext
.
CloudConfig
.
ProjectID
)
.
Do
()
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
for
_
,
z
:=
range
zones
.
Items
{
allZones
.
Insert
(
z
.
Name
)
}
...
...
@@ -440,7 +446,9 @@ var _ = framework.KubeDescribe("Dynamic Provisioning", func() {
pvc
.
Spec
.
StorageClassName
=
&
sc
.
Name
pvc
,
err
=
c
.
CoreV1
()
.
PersistentVolumeClaims
(
ns
)
.
Create
(
pvc
)
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
defer
framework
.
DeletePersistentVolumeClaim
(
c
,
pvc
.
Name
,
ns
)
defer
func
()
{
framework
.
ExpectNoError
(
framework
.
DeletePersistentVolumeClaim
(
c
,
pvc
.
Name
,
ns
),
"Failed to delete PVC "
,
pvc
.
Name
)
}()
// The claim should timeout phase:Pending
err
=
framework
.
WaitForPersistentVolumeClaimPhase
(
v1
.
ClaimBound
,
c
,
ns
,
pvc
.
Name
,
2
*
time
.
Second
,
framework
.
ClaimProvisionTimeout
)
...
...
@@ -475,17 +483,16 @@ var _ = framework.KubeDescribe("Dynamic Provisioning", func() {
suffix
:=
fmt
.
Sprintf
(
"race-%d"
,
i
)
claim
:=
newClaim
(
test
,
ns
,
suffix
)
claim
.
Spec
.
StorageClassName
=
&
class
.
Name
tmpClaim
:=
framework
.
CreatePVC
(
c
,
ns
,
claim
)
framework
.
DeletePersistentVolumeClaim
(
c
,
tmpClaim
.
Name
,
ns
)
tmpClaim
,
err
:=
framework
.
CreatePVC
(
c
,
ns
,
claim
)
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
framework
.
ExpectNoError
(
framework
.
DeletePersistentVolumeClaim
(
c
,
tmpClaim
.
Name
,
ns
))
}
By
(
fmt
.
Sprintf
(
"Checking for residual PersistentVolumes associated with StorageClass %s"
,
class
.
Name
))
residualPVs
,
err
=
waitForProvisionedVolumesDeleted
(
c
,
class
.
Name
)
if
err
!=
nil
{
// Cleanup the test resources before breaking
deleteProvisionedVolumesAndDisks
(
c
,
residualPVs
)
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
}
// Cleanup the test resources before breaking
defer
deleteProvisionedVolumesAndDisks
(
c
,
residualPVs
)
// Report indicators of regression
if
len
(
residualPVs
)
>
0
{
...
...
@@ -548,9 +555,6 @@ var _ = framework.KubeDescribe("Dynamic Provisioning", func() {
expectedSize
:
"2Gi"
,
}
claim
:=
newClaim
(
test
,
ns
,
"default"
)
defer
func
()
{
framework
.
DeletePersistentVolumeClaim
(
c
,
claim
.
Name
,
ns
)
}()
testDynamicProvisioning
(
test
,
c
,
claim
,
nil
)
})
...
...
@@ -573,7 +577,7 @@ var _ = framework.KubeDescribe("Dynamic Provisioning", func() {
claim
,
err
:=
c
.
CoreV1
()
.
PersistentVolumeClaims
(
ns
)
.
Create
(
claim
)
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
defer
func
()
{
framework
.
DeletePersistentVolumeClaim
(
c
,
claim
.
Name
,
ns
)
framework
.
ExpectNoError
(
framework
.
DeletePersistentVolumeClaim
(
c
,
claim
.
Name
,
ns
)
)
}()
// The claim should timeout phase:Pending
...
...
@@ -604,7 +608,7 @@ var _ = framework.KubeDescribe("Dynamic Provisioning", func() {
claim
,
err
:=
c
.
CoreV1
()
.
PersistentVolumeClaims
(
ns
)
.
Create
(
claim
)
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
defer
func
()
{
framework
.
DeletePersistentVolumeClaim
(
c
,
claim
.
Name
,
ns
)
framework
.
ExpectNoError
(
framework
.
DeletePersistentVolumeClaim
(
c
,
claim
.
Name
,
ns
)
)
}()
// The claim should timeout phase:Pending
...
...
@@ -731,10 +735,10 @@ func runInPodWithVolume(c clientset.Interface, ns, claimName, command string) {
},
}
pod
,
err
:=
c
.
CoreV1
()
.
Pods
(
ns
)
.
Create
(
pod
)
framework
.
ExpectNoError
(
err
,
"Failed to create pod: %v"
,
err
)
defer
func
()
{
framework
.
DeletePodOrFail
(
c
,
ns
,
pod
.
Name
)
}()
framework
.
ExpectNoError
(
err
,
"Failed to create pod: %v"
,
err
)
framework
.
ExpectNoError
(
framework
.
WaitForPodSuccessInNamespaceSlow
(
c
,
pod
.
Name
,
pod
.
Namespace
))
}
...
...
@@ -907,8 +911,8 @@ func deleteStorageClass(c clientset.Interface, className string) {
// deleteProvisionedVolumes [gce||gke only] iteratively deletes persistent volumes and attached GCE PDs.
func
deleteProvisionedVolumesAndDisks
(
c
clientset
.
Interface
,
pvs
[]
*
v1
.
PersistentVolume
)
{
for
_
,
pv
:=
range
pvs
{
framework
.
DeletePDWithRetry
(
pv
.
Spec
.
PersistentVolumeSource
.
GCEPersistentDisk
.
PDName
)
framework
.
DeletePersistentVolume
(
c
,
pv
.
Name
)
framework
.
ExpectNoError
(
framework
.
DeletePDWithRetry
(
pv
.
Spec
.
PersistentVolumeSource
.
GCEPersistentDisk
.
PDName
)
)
framework
.
ExpectNoError
(
framework
.
DeletePersistentVolume
(
c
,
pv
.
Name
)
)
}
}
...
...
test/e2e/storage/volumes.go
View file @
0d81e4c8
...
...
@@ -517,9 +517,8 @@ var _ = framework.KubeDescribe("Volumes [Volume]", func() {
By
(
"creating a test gce pd volume"
)
volumeName
,
err
:=
framework
.
CreatePDWithRetry
()
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
defer
func
()
{
framework
.
DeletePDWithRetry
(
volumeName
)
framework
.
ExpectNoError
(
framework
.
DeletePDWithRetry
(
volumeName
)
)
}()
defer
func
()
{
...
...
test/e2e/storage/vsphere_volume_ops_storm.go
View file @
0d81e4c8
...
...
@@ -99,21 +99,24 @@ var _ = framework.KubeDescribe("vsphere volume operations storm [Volume]", func(
By
(
"Creating PVCs using the Storage Class"
)
count
:=
0
for
count
<
volume_ops_scale
{
pvclaims
[
count
]
=
framework
.
CreatePVC
(
client
,
namespace
,
getVSphereClaimSpecWithStorageClassAnnotation
(
namespace
,
storageclass
))
pvclaims
[
count
],
err
=
framework
.
CreatePVC
(
client
,
namespace
,
getVSphereClaimSpecWithStorageClassAnnotation
(
namespace
,
storageclass
))
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
count
++
}
By
(
"Waiting for all claims to be in bound phase"
)
persistentvolumes
=
framework
.
WaitForPVClaimBoundPhase
(
client
,
pvclaims
)
persistentvolumes
,
err
=
framework
.
WaitForPVClaimBoundPhase
(
client
,
pvclaims
)
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
By
(
"Creating pod to attach PVs to the node"
)
pod
:=
framework
.
CreatePod
(
client
,
namespace
,
pvclaims
,
false
,
""
)
pod
,
err
:=
framework
.
CreatePod
(
client
,
namespace
,
pvclaims
,
false
,
""
)
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
By
(
"Verify all volumes are accessible and available in the pod"
)
verifyVSphereVolumesAccessible
(
pod
,
persistentvolumes
,
vsp
)
By
(
"Deleting pod"
)
framework
.
DeletePodWithWait
(
f
,
client
,
pod
)
framework
.
ExpectNoError
(
framework
.
DeletePodWithWait
(
f
,
client
,
pod
)
)
By
(
"Waiting for volumes to be detached from the node"
)
for
_
,
pv
:=
range
persistentvolumes
{
...
...
test/e2e/storage/vsphere_volume_placement.go
View file @
0d81e4c8
...
...
@@ -277,8 +277,8 @@ var _ = framework.KubeDescribe("Volume Placement [Volume]", func() {
defer
func
()
{
By
(
"clean up undeleted pods"
)
framework
.
DeletePodWithWait
(
f
,
c
,
podA
)
framework
.
DeletePodWithWait
(
f
,
c
,
podB
)
framework
.
ExpectNoError
(
framework
.
DeletePodWithWait
(
f
,
c
,
podA
),
"defer: Failed to delete pod "
,
podA
.
Name
)
framework
.
ExpectNoError
(
framework
.
DeletePodWithWait
(
f
,
c
,
podB
),
"defer: Failed to delete pod "
,
podB
.
Name
)
By
(
fmt
.
Sprintf
(
"wait for volumes to be detached from the node: %v"
,
node1Name
))
for
_
,
volumePath
:=
range
volumePaths
{
waitForVSphereDiskToDetach
(
vsp
,
volumePath
,
types
.
NodeName
(
node1Name
))
...
...
@@ -319,9 +319,9 @@ var _ = framework.KubeDescribe("Volume Placement [Volume]", func() {
verifyFilesExistOnVSphereVolume
(
ns
,
podB
.
Name
,
podBFiles
)
By
(
"Deleting pod-A"
)
framework
.
DeletePodWithWait
(
f
,
c
,
podA
)
framework
.
ExpectNoError
(
framework
.
DeletePodWithWait
(
f
,
c
,
podA
),
"Failed to delete pod "
,
podA
.
Name
)
By
(
"Deleting pod-B"
)
framework
.
DeletePodWithWait
(
f
,
c
,
podB
)
framework
.
ExpectNoError
(
framework
.
DeletePodWithWait
(
f
,
c
,
podB
),
"Failed to delete pod "
,
podB
.
Name
)
}
})
})
...
...
@@ -377,7 +377,7 @@ func createAndVerifyFilesOnVolume(namespace string, podname string, newEmptyfile
func
deletePodAndWaitForVolumeToDetach
(
f
*
framework
.
Framework
,
c
clientset
.
Interface
,
pod
*
v1
.
Pod
,
vsp
*
vsphere
.
VSphere
,
nodeName
string
,
volumePaths
[]
string
)
{
By
(
"Deleting pod"
)
framework
.
DeletePodWithWait
(
f
,
c
,
pod
)
framework
.
ExpectNoError
(
framework
.
DeletePodWithWait
(
f
,
c
,
pod
),
"Failed to delete pod "
,
pod
.
Name
)
By
(
"Waiting for volume to be detached from the node"
)
for
_
,
volumePath
:=
range
volumePaths
{
...
...
test/e2e/upgrades/BUILD
View file @
0d81e4c8
...
...
@@ -42,6 +42,7 @@ go_library(
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/uuid:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
],
...
...
test/e2e/upgrades/persistent_volumes.go
View file @
0d81e4c8
...
...
@@ -17,10 +17,12 @@ limitations under the License.
package
upgrades
import
(
utilerrors
"k8s.io/apimachinery/pkg/util/errors"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/test/e2e/framework"
.
"github.com/onsi/ginkgo"
.
"github.com/onsi/gomega"
)
// PersistentVolumeUpgradeTest test that a pv is available before and after a cluster upgrade.
...
...
@@ -50,13 +52,14 @@ func (t *PersistentVolumeUpgradeTest) createGCEVolume() *v1.PersistentVolumeSour
},
}
}
func
(
t
*
PersistentVolumeUpgradeTest
)
deleteGCEVolume
(
pvSource
*
v1
.
PersistentVolumeSource
)
{
framework
.
DeletePDWithRetry
(
pvSource
.
GCEPersistentDisk
.
PDName
)
func
(
t
*
PersistentVolumeUpgradeTest
)
deleteGCEVolume
(
pvSource
*
v1
.
PersistentVolumeSource
)
error
{
return
framework
.
DeletePDWithRetry
(
pvSource
.
GCEPersistentDisk
.
PDName
)
}
// Setup creates a pv and then verifies that a pod can consume it. The pod writes data to the volume.
func
(
t
*
PersistentVolumeUpgradeTest
)
Setup
(
f
*
framework
.
Framework
)
{
var
err
error
// TODO: generalize this to other providers
framework
.
SkipUnlessProviderIs
(
"gce"
,
"gke"
)
...
...
@@ -76,8 +79,9 @@ func (t *PersistentVolumeUpgradeTest) Setup(f *framework.Framework) {
}
By
(
"Creating the PV and PVC"
)
t
.
pv
,
t
.
pvc
=
framework
.
CreatePVPVC
(
f
.
ClientSet
,
pvConfig
,
pvcConfig
,
ns
,
true
)
framework
.
WaitOnPVandPVC
(
f
.
ClientSet
,
ns
,
t
.
pv
,
t
.
pvc
)
t
.
pv
,
t
.
pvc
,
err
=
framework
.
CreatePVPVC
(
f
.
ClientSet
,
pvConfig
,
pvcConfig
,
ns
,
true
)
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
framework
.
ExpectNoError
(
framework
.
WaitOnPVandPVC
(
f
.
ClientSet
,
ns
,
t
.
pv
,
t
.
pvc
))
By
(
"Consuming the PV before upgrade"
)
t
.
testPod
(
f
,
pvWriteCmd
+
";"
+
pvReadCmd
)
...
...
@@ -93,8 +97,13 @@ func (t *PersistentVolumeUpgradeTest) Test(f *framework.Framework, done <-chan s
// Teardown cleans up any remaining resources.
func
(
t
*
PersistentVolumeUpgradeTest
)
Teardown
(
f
*
framework
.
Framework
)
{
framework
.
PVPVCCleanup
(
f
.
ClientSet
,
f
.
Namespace
.
Name
,
t
.
pv
,
t
.
pvc
)
t
.
deleteGCEVolume
(
t
.
pvSource
)
errs
:=
framework
.
PVPVCCleanup
(
f
.
ClientSet
,
f
.
Namespace
.
Name
,
t
.
pv
,
t
.
pvc
)
if
err
:=
t
.
deleteGCEVolume
(
t
.
pvSource
);
err
!=
nil
{
errs
=
append
(
errs
,
err
)
}
if
len
(
errs
)
>
0
{
framework
.
Failf
(
"Failed to delete 1 or more PVs/PVCs and/or the GCE volume. Errors: %v"
,
utilerrors
.
NewAggregate
(
errs
))
}
}
// testPod creates a pod that consumes a pv and prints it out. The output is then verified.
...
...
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