e2e/storage: introduce TestVolume interface

This increases type safety and makes the code easier to read because
it becomes obvious that the "test resource" passed to some functions
must be the result of a previous CreateVolume.

This makes it possible to remove:
- functions that never did anything (the DeleteVolume methods in
  drivers that never create a volume)
- type casts (in the DeleteVolume implementation)
- the unused DeleteVolume parameters
- the stand-alone DeleteVolume function (which would be just a non-nil
  check)

GetPersistentVolumeSource and GetVolumeSource could also become
methods on more specific interfaces - they don't actually use anything
from TestDriver instance which provides them.

The main motivation however is to reduce the number of methods which
might need an explicit test config parameter.
This commit is contained in:
Patrick Ohly 2018-12-28 23:22:06 +01:00
parent bf20886f4e
commit 1cb121d2a9
6 changed files with 203 additions and 253 deletions

View File

@ -69,9 +69,10 @@ type nfsDriver struct {
driverInfo testsuites.DriverInfo driverInfo testsuites.DriverInfo
} }
type nfsTestResource struct { type nfsVolume struct {
serverIP string serverIP string
serverPod *v1.Pod serverPod *v1.Pod
f *framework.Framework
} }
var _ testsuites.TestDriver = &nfsDriver{} var _ testsuites.TestDriver = &nfsDriver{}
@ -108,24 +109,24 @@ func (n *nfsDriver) GetDriverInfo() *testsuites.DriverInfo {
func (n *nfsDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern) { func (n *nfsDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern) {
} }
func (n *nfsDriver) GetVolumeSource(readOnly bool, fsType string, testResource interface{}) *v1.VolumeSource { func (n *nfsDriver) GetVolumeSource(readOnly bool, fsType string, volume testsuites.TestVolume) *v1.VolumeSource {
ntr, ok := testResource.(*nfsTestResource) nv, ok := volume.(*nfsVolume)
Expect(ok).To(BeTrue(), "Failed to cast test resource to NFS Test Resource") Expect(ok).To(BeTrue(), "Failed to cast test volume to NFS test volume")
return &v1.VolumeSource{ return &v1.VolumeSource{
NFS: &v1.NFSVolumeSource{ NFS: &v1.NFSVolumeSource{
Server: ntr.serverIP, Server: nv.serverIP,
Path: "/", Path: "/",
ReadOnly: readOnly, ReadOnly: readOnly,
}, },
} }
} }
func (n *nfsDriver) GetPersistentVolumeSource(readOnly bool, fsType string, testResource interface{}) (*v1.PersistentVolumeSource, *v1.VolumeNodeAffinity) { func (n *nfsDriver) GetPersistentVolumeSource(readOnly bool, fsType string, volume testsuites.TestVolume) (*v1.PersistentVolumeSource, *v1.VolumeNodeAffinity) {
ntr, ok := testResource.(*nfsTestResource) nv, ok := volume.(*nfsVolume)
Expect(ok).To(BeTrue(), "Failed to cast test resource to NFS Test Resource") Expect(ok).To(BeTrue(), "Failed to cast test volume to NFS test volume")
return &v1.PersistentVolumeSource{ return &v1.PersistentVolumeSource{
NFS: &v1.NFSVolumeSource{ NFS: &v1.NFSVolumeSource{
Server: ntr.serverIP, Server: nv.serverIP,
Path: "/", Path: "/",
ReadOnly: readOnly, ReadOnly: readOnly,
}, },
@ -175,7 +176,7 @@ func (n *nfsDriver) CleanupDriver() {
cs.RbacV1beta1().ClusterRoleBindings().Delete(clusterRoleBindingName, metav1.NewDeleteOptions(0)) cs.RbacV1beta1().ClusterRoleBindings().Delete(clusterRoleBindingName, metav1.NewDeleteOptions(0))
} }
func (n *nfsDriver) CreateVolume(volType testpatterns.TestVolType) interface{} { func (n *nfsDriver) CreateVolume(volType testpatterns.TestVolType) testsuites.TestVolume {
f := n.driverInfo.Config.Framework f := n.driverInfo.Config.Framework
cs := f.ClientSet cs := f.ClientSet
ns := f.Namespace ns := f.Namespace
@ -189,9 +190,10 @@ func (n *nfsDriver) CreateVolume(volType testpatterns.TestVolType) interface{} {
case testpatterns.PreprovisionedPV: case testpatterns.PreprovisionedPV:
config, serverPod, serverIP := framework.NewNFSServer(cs, ns.Name, []string{}) config, serverPod, serverIP := framework.NewNFSServer(cs, ns.Name, []string{})
n.driverInfo.Config.ServerConfig = &config n.driverInfo.Config.ServerConfig = &config
return &nfsTestResource{ return &nfsVolume{
serverIP: serverIP, serverIP: serverIP,
serverPod: serverPod, serverPod: serverPod,
f: f,
} }
case testpatterns.DynamicPV: case testpatterns.DynamicPV:
// Do nothing // Do nothing
@ -201,22 +203,8 @@ func (n *nfsDriver) CreateVolume(volType testpatterns.TestVolType) interface{} {
return nil return nil
} }
func (n *nfsDriver) DeleteVolume(volType testpatterns.TestVolType, testResource interface{}) { func (v *nfsVolume) DeleteVolume() {
f := n.driverInfo.Config.Framework framework.CleanUpVolumeServer(v.f, v.serverPod)
ntr, ok := testResource.(*nfsTestResource)
Expect(ok).To(BeTrue(), "Failed to cast test resource to NFS Test Resource")
switch volType {
case testpatterns.InlineVolume:
fallthrough
case testpatterns.PreprovisionedPV:
framework.CleanUpVolumeServer(f, ntr.serverPod)
case testpatterns.DynamicPV:
// Do nothing
default:
framework.Failf("Unsupported volType:%v is specified", volType)
}
} }
// Gluster // Gluster
@ -224,9 +212,10 @@ type glusterFSDriver struct {
driverInfo testsuites.DriverInfo driverInfo testsuites.DriverInfo
} }
type glusterTestResource struct { type glusterVolume struct {
prefix string prefix string
serverPod *v1.Pod serverPod *v1.Pod
f *framework.Framework
} }
var _ testsuites.TestDriver = &glusterFSDriver{} var _ testsuites.TestDriver = &glusterFSDriver{}
@ -261,11 +250,11 @@ func (g *glusterFSDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern)
framework.SkipUnlessNodeOSDistroIs("gci", "ubuntu", "custom") framework.SkipUnlessNodeOSDistroIs("gci", "ubuntu", "custom")
} }
func (g *glusterFSDriver) GetVolumeSource(readOnly bool, fsType string, testResource interface{}) *v1.VolumeSource { func (g *glusterFSDriver) GetVolumeSource(readOnly bool, fsType string, volume testsuites.TestVolume) *v1.VolumeSource {
gtr, ok := testResource.(*glusterTestResource) gv, ok := volume.(*glusterVolume)
Expect(ok).To(BeTrue(), "Failed to cast test resource to Gluster Test Resource") Expect(ok).To(BeTrue(), "Failed to cast test volume to Gluster test volume")
name := gtr.prefix + "-server" name := gv.prefix + "-server"
return &v1.VolumeSource{ return &v1.VolumeSource{
Glusterfs: &v1.GlusterfsVolumeSource{ Glusterfs: &v1.GlusterfsVolumeSource{
EndpointsName: name, EndpointsName: name,
@ -276,11 +265,11 @@ func (g *glusterFSDriver) GetVolumeSource(readOnly bool, fsType string, testReso
} }
} }
func (g *glusterFSDriver) GetPersistentVolumeSource(readOnly bool, fsType string, testResource interface{}) (*v1.PersistentVolumeSource, *v1.VolumeNodeAffinity) { func (g *glusterFSDriver) GetPersistentVolumeSource(readOnly bool, fsType string, volume testsuites.TestVolume) (*v1.PersistentVolumeSource, *v1.VolumeNodeAffinity) {
gtr, ok := testResource.(*glusterTestResource) gv, ok := volume.(*glusterVolume)
Expect(ok).To(BeTrue(), "Failed to cast test resource to Gluster Test Resource") Expect(ok).To(BeTrue(), "Failed to cast test volume to Gluster test volume")
name := gtr.prefix + "-server" name := gv.prefix + "-server"
return &v1.PersistentVolumeSource{ return &v1.PersistentVolumeSource{
Glusterfs: &v1.GlusterfsPersistentVolumeSource{ Glusterfs: &v1.GlusterfsPersistentVolumeSource{
EndpointsName: name, EndpointsName: name,
@ -297,28 +286,26 @@ func (g *glusterFSDriver) CreateDriver() {
func (g *glusterFSDriver) CleanupDriver() { func (g *glusterFSDriver) CleanupDriver() {
} }
func (g *glusterFSDriver) CreateVolume(volType testpatterns.TestVolType) interface{} { func (g *glusterFSDriver) CreateVolume(volType testpatterns.TestVolType) testsuites.TestVolume {
f := g.driverInfo.Config.Framework f := g.driverInfo.Config.Framework
cs := f.ClientSet cs := f.ClientSet
ns := f.Namespace ns := f.Namespace
config, serverPod, _ := framework.NewGlusterfsServer(cs, ns.Name) config, serverPod, _ := framework.NewGlusterfsServer(cs, ns.Name)
g.driverInfo.Config.ServerConfig = &config g.driverInfo.Config.ServerConfig = &config
return &glusterTestResource{ return &glusterVolume{
prefix: config.Prefix, prefix: config.Prefix,
serverPod: serverPod, serverPod: serverPod,
f: f,
} }
} }
func (g *glusterFSDriver) DeleteVolume(volType testpatterns.TestVolType, testResource interface{}) { func (v *glusterVolume) DeleteVolume() {
f := g.driverInfo.Config.Framework f := v.f
cs := f.ClientSet cs := f.ClientSet
ns := f.Namespace ns := f.Namespace
gtr, ok := testResource.(*glusterTestResource) name := v.prefix + "-server"
Expect(ok).To(BeTrue(), "Failed to cast test resource to Gluster Test Resource")
name := gtr.prefix + "-server"
framework.Logf("Deleting Gluster endpoints %q...", name) framework.Logf("Deleting Gluster endpoints %q...", name)
err := cs.CoreV1().Endpoints(ns.Name).Delete(name, nil) err := cs.CoreV1().Endpoints(ns.Name).Delete(name, nil)
@ -328,8 +315,8 @@ func (g *glusterFSDriver) DeleteVolume(volType testpatterns.TestVolType, testRes
} }
framework.Logf("Gluster endpoints %q not found, assuming deleted", name) framework.Logf("Gluster endpoints %q not found, assuming deleted", name)
} }
framework.Logf("Deleting Gluster server pod %q...", gtr.serverPod.Name) framework.Logf("Deleting Gluster server pod %q...", v.serverPod.Name)
err = framework.DeletePodWithWait(f, cs, gtr.serverPod) err = framework.DeletePodWithWait(f, cs, v.serverPod)
if err != nil { if err != nil {
framework.Failf("Gluster server pod delete failed: %v", err) framework.Failf("Gluster server pod delete failed: %v", err)
} }
@ -340,9 +327,10 @@ func (g *glusterFSDriver) DeleteVolume(volType testpatterns.TestVolType, testRes
type iSCSIDriver struct { type iSCSIDriver struct {
driverInfo testsuites.DriverInfo driverInfo testsuites.DriverInfo
} }
type iSCSITestResource struct { type iSCSIVolume struct {
serverPod *v1.Pod serverPod *v1.Pod
serverIP string serverIP string
f *framework.Framework
} }
var _ testsuites.TestDriver = &iSCSIDriver{} var _ testsuites.TestDriver = &iSCSIDriver{}
@ -383,13 +371,13 @@ func (i *iSCSIDriver) GetDriverInfo() *testsuites.DriverInfo {
func (i *iSCSIDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern) { func (i *iSCSIDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern) {
} }
func (i *iSCSIDriver) GetVolumeSource(readOnly bool, fsType string, testResource interface{}) *v1.VolumeSource { func (i *iSCSIDriver) GetVolumeSource(readOnly bool, fsType string, volume testsuites.TestVolume) *v1.VolumeSource {
itr, ok := testResource.(*iSCSITestResource) iv, ok := volume.(*iSCSIVolume)
Expect(ok).To(BeTrue(), "Failed to cast test resource to iSCSI Test Resource") Expect(ok).To(BeTrue(), "Failed to cast test volume to iSCSI test volume")
volSource := v1.VolumeSource{ volSource := v1.VolumeSource{
ISCSI: &v1.ISCSIVolumeSource{ ISCSI: &v1.ISCSIVolumeSource{
TargetPortal: itr.serverIP + ":3260", TargetPortal: iv.serverIP + ":3260",
// from test/images/volume/iscsi/initiatorname.iscsi // from test/images/volume/iscsi/initiatorname.iscsi
IQN: "iqn.2003-01.org.linux-iscsi.f21.x8664:sn.4b0aae584f7c", IQN: "iqn.2003-01.org.linux-iscsi.f21.x8664:sn.4b0aae584f7c",
Lun: 0, Lun: 0,
@ -402,13 +390,13 @@ func (i *iSCSIDriver) GetVolumeSource(readOnly bool, fsType string, testResource
return &volSource return &volSource
} }
func (i *iSCSIDriver) GetPersistentVolumeSource(readOnly bool, fsType string, testResource interface{}) (*v1.PersistentVolumeSource, *v1.VolumeNodeAffinity) { func (i *iSCSIDriver) GetPersistentVolumeSource(readOnly bool, fsType string, volume testsuites.TestVolume) (*v1.PersistentVolumeSource, *v1.VolumeNodeAffinity) {
itr, ok := testResource.(*iSCSITestResource) iv, ok := volume.(*iSCSIVolume)
Expect(ok).To(BeTrue(), "Failed to cast test resource to iSCSI Test Resource") Expect(ok).To(BeTrue(), "Failed to cast test volume to iSCSI test volume")
pvSource := v1.PersistentVolumeSource{ pvSource := v1.PersistentVolumeSource{
ISCSI: &v1.ISCSIPersistentVolumeSource{ ISCSI: &v1.ISCSIPersistentVolumeSource{
TargetPortal: itr.serverIP + ":3260", TargetPortal: iv.serverIP + ":3260",
IQN: "iqn.2003-01.org.linux-iscsi.f21.x8664:sn.4b0aae584f7c", IQN: "iqn.2003-01.org.linux-iscsi.f21.x8664:sn.4b0aae584f7c",
Lun: 0, Lun: 0,
ReadOnly: readOnly, ReadOnly: readOnly,
@ -426,26 +414,22 @@ func (i *iSCSIDriver) CreateDriver() {
func (i *iSCSIDriver) CleanupDriver() { func (i *iSCSIDriver) CleanupDriver() {
} }
func (i *iSCSIDriver) CreateVolume(volType testpatterns.TestVolType) interface{} { func (i *iSCSIDriver) CreateVolume(volType testpatterns.TestVolType) testsuites.TestVolume {
f := i.driverInfo.Config.Framework f := i.driverInfo.Config.Framework
cs := f.ClientSet cs := f.ClientSet
ns := f.Namespace ns := f.Namespace
config, serverPod, serverIP := framework.NewISCSIServer(cs, ns.Name) config, serverPod, serverIP := framework.NewISCSIServer(cs, ns.Name)
i.driverInfo.Config.ServerConfig = &config i.driverInfo.Config.ServerConfig = &config
return &iSCSITestResource{ return &iSCSIVolume{
serverPod: serverPod, serverPod: serverPod,
serverIP: serverIP, serverIP: serverIP,
f: f,
} }
} }
func (i *iSCSIDriver) DeleteVolume(volType testpatterns.TestVolType, testResource interface{}) { func (v *iSCSIVolume) DeleteVolume() {
f := i.driverInfo.Config.Framework framework.CleanUpVolumeServer(v.f, v.serverPod)
itr, ok := testResource.(*iSCSITestResource)
Expect(ok).To(BeTrue(), "Failed to cast test resource to iSCSI Test Resource")
framework.CleanUpVolumeServer(f, itr.serverPod)
} }
// Ceph RBD // Ceph RBD
@ -453,10 +437,11 @@ type rbdDriver struct {
driverInfo testsuites.DriverInfo driverInfo testsuites.DriverInfo
} }
type rbdTestResource struct { type rbdVolume struct {
serverPod *v1.Pod serverPod *v1.Pod
serverIP string serverIP string
secret *v1.Secret secret *v1.Secret
f *framework.Framework
} }
var _ testsuites.TestDriver = &rbdDriver{} var _ testsuites.TestDriver = &rbdDriver{}
@ -497,18 +482,18 @@ func (r *rbdDriver) GetDriverInfo() *testsuites.DriverInfo {
func (r *rbdDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern) { func (r *rbdDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern) {
} }
func (r *rbdDriver) GetVolumeSource(readOnly bool, fsType string, testResource interface{}) *v1.VolumeSource { func (r *rbdDriver) GetVolumeSource(readOnly bool, fsType string, volume testsuites.TestVolume) *v1.VolumeSource {
rtr, ok := testResource.(*rbdTestResource) rv, ok := volume.(*rbdVolume)
Expect(ok).To(BeTrue(), "Failed to cast test resource to RBD Test Resource") Expect(ok).To(BeTrue(), "Failed to cast test volume to RBD test volume")
volSource := v1.VolumeSource{ volSource := v1.VolumeSource{
RBD: &v1.RBDVolumeSource{ RBD: &v1.RBDVolumeSource{
CephMonitors: []string{rtr.serverIP}, CephMonitors: []string{rv.serverIP},
RBDPool: "rbd", RBDPool: "rbd",
RBDImage: "foo", RBDImage: "foo",
RadosUser: "admin", RadosUser: "admin",
SecretRef: &v1.LocalObjectReference{ SecretRef: &v1.LocalObjectReference{
Name: rtr.secret.Name, Name: rv.secret.Name,
}, },
ReadOnly: readOnly, ReadOnly: readOnly,
}, },
@ -519,21 +504,21 @@ func (r *rbdDriver) GetVolumeSource(readOnly bool, fsType string, testResource i
return &volSource return &volSource
} }
func (r *rbdDriver) GetPersistentVolumeSource(readOnly bool, fsType string, testResource interface{}) (*v1.PersistentVolumeSource, *v1.VolumeNodeAffinity) { func (r *rbdDriver) GetPersistentVolumeSource(readOnly bool, fsType string, volume testsuites.TestVolume) (*v1.PersistentVolumeSource, *v1.VolumeNodeAffinity) {
f := r.driverInfo.Config.Framework f := r.driverInfo.Config.Framework
ns := f.Namespace ns := f.Namespace
rtr, ok := testResource.(*rbdTestResource) rv, ok := volume.(*rbdVolume)
Expect(ok).To(BeTrue(), "Failed to cast test resource to RBD Test Resource") Expect(ok).To(BeTrue(), "Failed to cast test volume to RBD test volume")
pvSource := v1.PersistentVolumeSource{ pvSource := v1.PersistentVolumeSource{
RBD: &v1.RBDPersistentVolumeSource{ RBD: &v1.RBDPersistentVolumeSource{
CephMonitors: []string{rtr.serverIP}, CephMonitors: []string{rv.serverIP},
RBDPool: "rbd", RBDPool: "rbd",
RBDImage: "foo", RBDImage: "foo",
RadosUser: "admin", RadosUser: "admin",
SecretRef: &v1.SecretReference{ SecretRef: &v1.SecretReference{
Name: rtr.secret.Name, Name: rv.secret.Name,
Namespace: ns.Name, Namespace: ns.Name,
}, },
ReadOnly: readOnly, ReadOnly: readOnly,
@ -551,27 +536,23 @@ func (r *rbdDriver) CreateDriver() {
func (r *rbdDriver) CleanupDriver() { func (r *rbdDriver) CleanupDriver() {
} }
func (r *rbdDriver) CreateVolume(volType testpatterns.TestVolType) interface{} { func (r *rbdDriver) CreateVolume(volType testpatterns.TestVolType) testsuites.TestVolume {
f := r.driverInfo.Config.Framework f := r.driverInfo.Config.Framework
cs := f.ClientSet cs := f.ClientSet
ns := f.Namespace ns := f.Namespace
config, serverPod, secret, serverIP := framework.NewRBDServer(cs, ns.Name) config, serverPod, secret, serverIP := framework.NewRBDServer(cs, ns.Name)
r.driverInfo.Config.ServerConfig = &config r.driverInfo.Config.ServerConfig = &config
return &rbdTestResource{ return &rbdVolume{
serverPod: serverPod, serverPod: serverPod,
serverIP: serverIP, serverIP: serverIP,
secret: secret, secret: secret,
f: f,
} }
} }
func (r *rbdDriver) DeleteVolume(volType testpatterns.TestVolType, testResource interface{}) { func (v *rbdVolume) DeleteVolume() {
f := r.driverInfo.Config.Framework framework.CleanUpVolumeServerWithSecret(v.f, v.serverPod, v.secret)
rtr, ok := testResource.(*rbdTestResource)
Expect(ok).To(BeTrue(), "Failed to cast test resource to RBD Test Resource")
framework.CleanUpVolumeServerWithSecret(f, rtr.serverPod, rtr.secret)
} }
// Ceph // Ceph
@ -583,10 +564,11 @@ type cephFSDriver struct {
driverInfo testsuites.DriverInfo driverInfo testsuites.DriverInfo
} }
type cephTestResource struct { type cephVolume struct {
serverPod *v1.Pod serverPod *v1.Pod
serverIP string serverIP string
secret *v1.Secret secret *v1.Secret
f *framework.Framework
} }
var _ testsuites.TestDriver = &cephFSDriver{} var _ testsuites.TestDriver = &cephFSDriver{}
@ -621,35 +603,35 @@ func (c *cephFSDriver) GetDriverInfo() *testsuites.DriverInfo {
func (c *cephFSDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern) { func (c *cephFSDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern) {
} }
func (c *cephFSDriver) GetVolumeSource(readOnly bool, fsType string, testResource interface{}) *v1.VolumeSource { func (c *cephFSDriver) GetVolumeSource(readOnly bool, fsType string, volume testsuites.TestVolume) *v1.VolumeSource {
ctr, ok := testResource.(*cephTestResource) cv, ok := volume.(*cephVolume)
Expect(ok).To(BeTrue(), "Failed to cast test resource to Ceph Test Resource") Expect(ok).To(BeTrue(), "Failed to cast test volume to Ceph test volume")
return &v1.VolumeSource{ return &v1.VolumeSource{
CephFS: &v1.CephFSVolumeSource{ CephFS: &v1.CephFSVolumeSource{
Monitors: []string{ctr.serverIP + ":6789"}, Monitors: []string{cv.serverIP + ":6789"},
User: "kube", User: "kube",
SecretRef: &v1.LocalObjectReference{ SecretRef: &v1.LocalObjectReference{
Name: ctr.secret.Name, Name: cv.secret.Name,
}, },
ReadOnly: readOnly, ReadOnly: readOnly,
}, },
} }
} }
func (c *cephFSDriver) GetPersistentVolumeSource(readOnly bool, fsType string, testResource interface{}) (*v1.PersistentVolumeSource, *v1.VolumeNodeAffinity) { func (c *cephFSDriver) GetPersistentVolumeSource(readOnly bool, fsType string, volume testsuites.TestVolume) (*v1.PersistentVolumeSource, *v1.VolumeNodeAffinity) {
f := c.driverInfo.Config.Framework f := c.driverInfo.Config.Framework
ns := f.Namespace ns := f.Namespace
ctr, ok := testResource.(*cephTestResource) cv, ok := volume.(*cephVolume)
Expect(ok).To(BeTrue(), "Failed to cast test resource to Ceph Test Resource") Expect(ok).To(BeTrue(), "Failed to cast test volume to Ceph test volume")
return &v1.PersistentVolumeSource{ return &v1.PersistentVolumeSource{
CephFS: &v1.CephFSPersistentVolumeSource{ CephFS: &v1.CephFSPersistentVolumeSource{
Monitors: []string{ctr.serverIP + ":6789"}, Monitors: []string{cv.serverIP + ":6789"},
User: "kube", User: "kube",
SecretRef: &v1.SecretReference{ SecretRef: &v1.SecretReference{
Name: ctr.secret.Name, Name: cv.secret.Name,
Namespace: ns.Name, Namespace: ns.Name,
}, },
ReadOnly: readOnly, ReadOnly: readOnly,
@ -663,27 +645,23 @@ func (c *cephFSDriver) CreateDriver() {
func (c *cephFSDriver) CleanupDriver() { func (c *cephFSDriver) CleanupDriver() {
} }
func (c *cephFSDriver) CreateVolume(volType testpatterns.TestVolType) interface{} { func (c *cephFSDriver) CreateVolume(volType testpatterns.TestVolType) testsuites.TestVolume {
f := c.driverInfo.Config.Framework f := c.driverInfo.Config.Framework
cs := f.ClientSet cs := f.ClientSet
ns := f.Namespace ns := f.Namespace
config, serverPod, secret, serverIP := framework.NewRBDServer(cs, ns.Name) config, serverPod, secret, serverIP := framework.NewRBDServer(cs, ns.Name)
c.driverInfo.Config.ServerConfig = &config c.driverInfo.Config.ServerConfig = &config
return &cephTestResource{ return &cephVolume{
serverPod: serverPod, serverPod: serverPod,
serverIP: serverIP, serverIP: serverIP,
secret: secret, secret: secret,
f: f,
} }
} }
func (c *cephFSDriver) DeleteVolume(volType testpatterns.TestVolType, testResource interface{}) { func (v *cephVolume) DeleteVolume() {
f := c.driverInfo.Config.Framework framework.CleanUpVolumeServerWithSecret(v.f, v.serverPod, v.secret)
ctr, ok := testResource.(*cephTestResource)
Expect(ok).To(BeTrue(), "Failed to cast test resource to Ceph Test Resource")
framework.CleanUpVolumeServerWithSecret(f, ctr.serverPod, ctr.secret)
} }
// Hostpath // Hostpath
@ -722,7 +700,7 @@ func (h *hostPathDriver) GetDriverInfo() *testsuites.DriverInfo {
func (h *hostPathDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern) { func (h *hostPathDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern) {
} }
func (h *hostPathDriver) GetVolumeSource(readOnly bool, fsType string, testResource interface{}) *v1.VolumeSource { func (h *hostPathDriver) GetVolumeSource(readOnly bool, fsType string, volume testsuites.TestVolume) *v1.VolumeSource {
// hostPath doesn't support readOnly volume // hostPath doesn't support readOnly volume
if readOnly { if readOnly {
return nil return nil
@ -740,7 +718,7 @@ func (h *hostPathDriver) CreateDriver() {
func (h *hostPathDriver) CleanupDriver() { func (h *hostPathDriver) CleanupDriver() {
} }
func (h *hostPathDriver) CreateVolume(volType testpatterns.TestVolType) interface{} { func (h *hostPathDriver) CreateVolume(volType testpatterns.TestVolType) testsuites.TestVolume {
f := h.driverInfo.Config.Framework f := h.driverInfo.Config.Framework
cs := f.ClientSet cs := f.ClientSet
@ -751,9 +729,6 @@ func (h *hostPathDriver) CreateVolume(volType testpatterns.TestVolType) interfac
return nil return nil
} }
func (h *hostPathDriver) DeleteVolume(volType testpatterns.TestVolType, testResource interface{}) {
}
// HostPathSymlink // HostPathSymlink
type hostPathSymlinkDriver struct { type hostPathSymlinkDriver struct {
node v1.Node node v1.Node
@ -761,10 +736,11 @@ type hostPathSymlinkDriver struct {
driverInfo testsuites.DriverInfo driverInfo testsuites.DriverInfo
} }
type hostPathSymlinkTestResource struct { type hostPathSymlinkVolume struct {
targetPath string targetPath string
sourcePath string sourcePath string
prepPod *v1.Pod prepPod *v1.Pod
f *framework.Framework
} }
var _ testsuites.TestDriver = &hostPathSymlinkDriver{} var _ testsuites.TestDriver = &hostPathSymlinkDriver{}
@ -796,9 +772,9 @@ func (h *hostPathSymlinkDriver) GetDriverInfo() *testsuites.DriverInfo {
func (h *hostPathSymlinkDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern) { func (h *hostPathSymlinkDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern) {
} }
func (h *hostPathSymlinkDriver) GetVolumeSource(readOnly bool, fsType string, testResource interface{}) *v1.VolumeSource { func (h *hostPathSymlinkDriver) GetVolumeSource(readOnly bool, fsType string, volume testsuites.TestVolume) *v1.VolumeSource {
htr, ok := testResource.(*hostPathSymlinkTestResource) hv, ok := volume.(*hostPathSymlinkVolume)
Expect(ok).To(BeTrue(), "Failed to cast test resource to Hostpath Symlink Test Resource") Expect(ok).To(BeTrue(), "Failed to cast test volume to Hostpath Symlink test volume")
// hostPathSymlink doesn't support readOnly volume // hostPathSymlink doesn't support readOnly volume
if readOnly { if readOnly {
@ -806,7 +782,7 @@ func (h *hostPathSymlinkDriver) GetVolumeSource(readOnly bool, fsType string, te
} }
return &v1.VolumeSource{ return &v1.VolumeSource{
HostPath: &v1.HostPathVolumeSource{ HostPath: &v1.HostPathVolumeSource{
Path: htr.targetPath, Path: hv.targetPath,
}, },
} }
} }
@ -817,7 +793,7 @@ func (h *hostPathSymlinkDriver) CreateDriver() {
func (h *hostPathSymlinkDriver) CleanupDriver() { func (h *hostPathSymlinkDriver) CleanupDriver() {
} }
func (h *hostPathSymlinkDriver) CreateVolume(volType testpatterns.TestVolType) interface{} { func (h *hostPathSymlinkDriver) CreateVolume(volType testpatterns.TestVolType) testsuites.TestVolume {
f := h.driverInfo.Config.Framework f := h.driverInfo.Config.Framework
cs := f.ClientSet cs := f.ClientSet
@ -878,23 +854,21 @@ func (h *hostPathSymlinkDriver) CreateVolume(volType testpatterns.TestVolType) i
err = framework.DeletePodWithWait(f, f.ClientSet, pod) err = framework.DeletePodWithWait(f, f.ClientSet, pod)
Expect(err).ToNot(HaveOccurred(), "while deleting hostPath init pod") Expect(err).ToNot(HaveOccurred(), "while deleting hostPath init pod")
return &hostPathSymlinkTestResource{ return &hostPathSymlinkVolume{
sourcePath: sourcePath, sourcePath: sourcePath,
targetPath: targetPath, targetPath: targetPath,
prepPod: prepPod, prepPod: prepPod,
f: f,
} }
} }
func (h *hostPathSymlinkDriver) DeleteVolume(volType testpatterns.TestVolType, testResource interface{}) { func (v *hostPathSymlinkVolume) DeleteVolume() {
f := h.driverInfo.Config.Framework f := v.f
htr, ok := testResource.(*hostPathSymlinkTestResource) cmd := fmt.Sprintf("rm -rf %v&& rm -rf %v", v.targetPath, v.sourcePath)
Expect(ok).To(BeTrue(), "Failed to cast test resource to Hostpath Symlink Test Resource") v.prepPod.Spec.Containers[0].Command = []string{"/bin/sh", "-ec", cmd}
cmd := fmt.Sprintf("rm -rf %v&& rm -rf %v", htr.targetPath, htr.sourcePath) pod, err := f.ClientSet.CoreV1().Pods(f.Namespace.Name).Create(v.prepPod)
htr.prepPod.Spec.Containers[0].Command = []string{"/bin/sh", "-ec", cmd}
pod, err := f.ClientSet.CoreV1().Pods(f.Namespace.Name).Create(htr.prepPod)
Expect(err).ToNot(HaveOccurred(), "while creating hostPath teardown pod") Expect(err).ToNot(HaveOccurred(), "while creating hostPath teardown pod")
err = framework.WaitForPodSuccessInNamespace(f.ClientSet, pod.Name, pod.Namespace) err = framework.WaitForPodSuccessInNamespace(f.ClientSet, pod.Name, pod.Namespace)
@ -938,7 +912,7 @@ func (e *emptydirDriver) GetDriverInfo() *testsuites.DriverInfo {
func (e *emptydirDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern) { func (e *emptydirDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern) {
} }
func (e *emptydirDriver) GetVolumeSource(readOnly bool, fsType string, testResource interface{}) *v1.VolumeSource { func (e *emptydirDriver) GetVolumeSource(readOnly bool, fsType string, volume testsuites.TestVolume) *v1.VolumeSource {
// emptydir doesn't support readOnly volume // emptydir doesn't support readOnly volume
if readOnly { if readOnly {
return nil return nil
@ -948,13 +922,10 @@ func (e *emptydirDriver) GetVolumeSource(readOnly bool, fsType string, testResou
} }
} }
func (e *emptydirDriver) CreateVolume(volType testpatterns.TestVolType) interface{} { func (e *emptydirDriver) CreateVolume(volType testpatterns.TestVolType) testsuites.TestVolume {
return nil return nil
} }
func (e *emptydirDriver) DeleteVolume(volType testpatterns.TestVolType, testResource interface{}) {
}
func (e *emptydirDriver) CreateDriver() { func (e *emptydirDriver) CreateDriver() {
} }
@ -970,7 +941,7 @@ type cinderDriver struct {
driverInfo testsuites.DriverInfo driverInfo testsuites.DriverInfo
} }
type cinderTestResource struct { type cinderVolume struct {
volumeName string volumeName string
volumeID string volumeID string
} }
@ -1010,13 +981,13 @@ func (c *cinderDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern) {
framework.SkipUnlessProviderIs("openstack") framework.SkipUnlessProviderIs("openstack")
} }
func (c *cinderDriver) GetVolumeSource(readOnly bool, fsType string, testResource interface{}) *v1.VolumeSource { func (c *cinderDriver) GetVolumeSource(readOnly bool, fsType string, volume testsuites.TestVolume) *v1.VolumeSource {
ctr, ok := testResource.(*cinderTestResource) cv, ok := volume.(*cinderVolume)
Expect(ok).To(BeTrue(), "Failed to cast test resource to Cinder Test Resource") Expect(ok).To(BeTrue(), "Failed to cast test volume to Cinder test volume")
volSource := v1.VolumeSource{ volSource := v1.VolumeSource{
Cinder: &v1.CinderVolumeSource{ Cinder: &v1.CinderVolumeSource{
VolumeID: ctr.volumeID, VolumeID: cv.volumeID,
ReadOnly: readOnly, ReadOnly: readOnly,
}, },
} }
@ -1026,13 +997,13 @@ func (c *cinderDriver) GetVolumeSource(readOnly bool, fsType string, testResourc
return &volSource return &volSource
} }
func (c *cinderDriver) GetPersistentVolumeSource(readOnly bool, fsType string, testResource interface{}) (*v1.PersistentVolumeSource, *v1.VolumeNodeAffinity) { func (c *cinderDriver) GetPersistentVolumeSource(readOnly bool, fsType string, volume testsuites.TestVolume) (*v1.PersistentVolumeSource, *v1.VolumeNodeAffinity) {
ctr, ok := testResource.(*cinderTestResource) cv, ok := volume.(*cinderVolume)
Expect(ok).To(BeTrue(), "Failed to cast test resource to Cinder Test Resource") Expect(ok).To(BeTrue(), "Failed to cast test volume to Cinder test volume")
pvSource := v1.PersistentVolumeSource{ pvSource := v1.PersistentVolumeSource{
Cinder: &v1.CinderPersistentVolumeSource{ Cinder: &v1.CinderPersistentVolumeSource{
VolumeID: ctr.volumeID, VolumeID: cv.volumeID,
ReadOnly: readOnly, ReadOnly: readOnly,
}, },
} }
@ -1064,7 +1035,7 @@ func (c *cinderDriver) CreateDriver() {
func (c *cinderDriver) CleanupDriver() { func (c *cinderDriver) CleanupDriver() {
} }
func (c *cinderDriver) CreateVolume(volType testpatterns.TestVolType) interface{} { func (c *cinderDriver) CreateVolume(volType testpatterns.TestVolType) testsuites.TestVolume {
f := c.driverInfo.Config.Framework f := c.driverInfo.Config.Framework
ns := f.Namespace ns := f.Namespace
@ -1095,20 +1066,15 @@ func (c *cinderDriver) CreateVolume(volType testpatterns.TestVolType) interface{
} }
framework.Logf("Volume ID: %s", volumeID) framework.Logf("Volume ID: %s", volumeID)
Expect(volumeID).NotTo(Equal("")) Expect(volumeID).NotTo(Equal(""))
return &cinderTestResource{ return &cinderVolume{
volumeName: volumeName, volumeName: volumeName,
volumeID: volumeID, volumeID: volumeID,
} }
} }
func (c *cinderDriver) DeleteVolume(volType testpatterns.TestVolType, testResource interface{}) { func (v *cinderVolume) DeleteVolume() {
ctr, ok := testResource.(*cinderTestResource) name := v.volumeName
Expect(ok).To(BeTrue(), "Failed to cast test resource to Cinder Test Resource")
deleteCinderVolume(ctr.volumeName)
}
func deleteCinderVolume(name string) error {
// Try to delete the volume for several seconds - it takes // Try to delete the volume for several seconds - it takes
// a while for the plugin to detach it. // a while for the plugin to detach it.
var output []byte var output []byte
@ -1120,12 +1086,11 @@ func deleteCinderVolume(name string) error {
output, err = exec.Command("cinder", "delete", name).CombinedOutput() output, err = exec.Command("cinder", "delete", name).CombinedOutput()
if err == nil { if err == nil {
framework.Logf("Cinder volume %s deleted", name) framework.Logf("Cinder volume %s deleted", name)
return nil return
} }
framework.Logf("Failed to delete volume %s: %v", name, err) framework.Logf("Failed to delete volume %s: %v", name, err)
} }
framework.Logf("Giving up deleting volume %s: %v\n%s", name, err, string(output[:])) framework.Logf("Giving up deleting volume %s: %v\n%s", name, err, string(output[:]))
return err
} }
// GCE // GCE
@ -1133,7 +1098,7 @@ type gcePdDriver struct {
driverInfo testsuites.DriverInfo driverInfo testsuites.DriverInfo
} }
type gcePdTestResource struct { type gcePdVolume struct {
volumeName string volumeName string
} }
@ -1177,12 +1142,12 @@ func (g *gcePdDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern) {
framework.SkipUnlessProviderIs("gce", "gke") framework.SkipUnlessProviderIs("gce", "gke")
} }
func (g *gcePdDriver) GetVolumeSource(readOnly bool, fsType string, testResource interface{}) *v1.VolumeSource { func (g *gcePdDriver) GetVolumeSource(readOnly bool, fsType string, volume testsuites.TestVolume) *v1.VolumeSource {
gtr, ok := testResource.(*gcePdTestResource) gv, ok := volume.(*gcePdVolume)
Expect(ok).To(BeTrue(), "Failed to cast test resource to GCE PD Test Resource") Expect(ok).To(BeTrue(), "Failed to cast test volume to GCE PD test volume")
volSource := v1.VolumeSource{ volSource := v1.VolumeSource{
GCEPersistentDisk: &v1.GCEPersistentDiskVolumeSource{ GCEPersistentDisk: &v1.GCEPersistentDiskVolumeSource{
PDName: gtr.volumeName, PDName: gv.volumeName,
ReadOnly: readOnly, ReadOnly: readOnly,
}, },
} }
@ -1192,12 +1157,12 @@ func (g *gcePdDriver) GetVolumeSource(readOnly bool, fsType string, testResource
return &volSource return &volSource
} }
func (g *gcePdDriver) GetPersistentVolumeSource(readOnly bool, fsType string, testResource interface{}) (*v1.PersistentVolumeSource, *v1.VolumeNodeAffinity) { func (g *gcePdDriver) GetPersistentVolumeSource(readOnly bool, fsType string, volume testsuites.TestVolume) (*v1.PersistentVolumeSource, *v1.VolumeNodeAffinity) {
gtr, ok := testResource.(*gcePdTestResource) gv, ok := volume.(*gcePdVolume)
Expect(ok).To(BeTrue(), "Failed to cast test resource to GCE PD Test Resource") Expect(ok).To(BeTrue(), "Failed to cast test volume to GCE PD test volume")
pvSource := v1.PersistentVolumeSource{ pvSource := v1.PersistentVolumeSource{
GCEPersistentDisk: &v1.GCEPersistentDiskVolumeSource{ GCEPersistentDisk: &v1.GCEPersistentDiskVolumeSource{
PDName: gtr.volumeName, PDName: gv.volumeName,
ReadOnly: readOnly, ReadOnly: readOnly,
}, },
} }
@ -1229,7 +1194,7 @@ func (g *gcePdDriver) CreateDriver() {
func (g *gcePdDriver) CleanupDriver() { func (g *gcePdDriver) CleanupDriver() {
} }
func (g *gcePdDriver) CreateVolume(volType testpatterns.TestVolType) interface{} { func (g *gcePdDriver) CreateVolume(volType testpatterns.TestVolType) testsuites.TestVolume {
if volType == testpatterns.InlineVolume { if volType == testpatterns.InlineVolume {
// PD will be created in framework.TestContext.CloudConfig.Zone zone, // PD will be created in framework.TestContext.CloudConfig.Zone zone,
// so pods should be also scheduled there. // so pods should be also scheduled there.
@ -1240,15 +1205,13 @@ func (g *gcePdDriver) CreateVolume(volType testpatterns.TestVolType) interface{}
By("creating a test gce pd volume") By("creating a test gce pd volume")
vname, err := framework.CreatePDWithRetry() vname, err := framework.CreatePDWithRetry()
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())
return &gcePdTestResource{ return &gcePdVolume{
volumeName: vname, volumeName: vname,
} }
} }
func (g *gcePdDriver) DeleteVolume(volType testpatterns.TestVolType, testResource interface{}) { func (v *gcePdVolume) DeleteVolume() {
gtr, ok := testResource.(*gcePdTestResource) framework.DeletePDWithRetry(v.volumeName)
Expect(ok).To(BeTrue(), "Failed to cast test resource to GCE PD Test Resource")
framework.DeletePDWithRetry(gtr.volumeName)
} }
// vSphere // vSphere
@ -1256,7 +1219,7 @@ type vSphereDriver struct {
driverInfo testsuites.DriverInfo driverInfo testsuites.DriverInfo
} }
type vSphereTestResource struct { type vSphereVolume struct {
volumePath string volumePath string
nodeInfo *vspheretest.NodeInfo nodeInfo *vspheretest.NodeInfo
} }
@ -1295,9 +1258,9 @@ func (v *vSphereDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern) {
framework.SkipUnlessProviderIs("vsphere") framework.SkipUnlessProviderIs("vsphere")
} }
func (v *vSphereDriver) GetVolumeSource(readOnly bool, fsType string, testResource interface{}) *v1.VolumeSource { func (v *vSphereDriver) GetVolumeSource(readOnly bool, fsType string, volume testsuites.TestVolume) *v1.VolumeSource {
vtr, ok := testResource.(*vSphereTestResource) vsv, ok := volume.(*vSphereVolume)
Expect(ok).To(BeTrue(), "Failed to cast test resource to vSphere Test Resource") Expect(ok).To(BeTrue(), "Failed to cast test volume to vSphere test volume")
// vSphere driver doesn't seem to support readOnly volume // vSphere driver doesn't seem to support readOnly volume
// TODO: check if it is correct // TODO: check if it is correct
@ -1306,7 +1269,7 @@ func (v *vSphereDriver) GetVolumeSource(readOnly bool, fsType string, testResour
} }
volSource := v1.VolumeSource{ volSource := v1.VolumeSource{
VsphereVolume: &v1.VsphereVirtualDiskVolumeSource{ VsphereVolume: &v1.VsphereVirtualDiskVolumeSource{
VolumePath: vtr.volumePath, VolumePath: vsv.volumePath,
}, },
} }
if fsType != "" { if fsType != "" {
@ -1315,9 +1278,9 @@ func (v *vSphereDriver) GetVolumeSource(readOnly bool, fsType string, testResour
return &volSource return &volSource
} }
func (v *vSphereDriver) GetPersistentVolumeSource(readOnly bool, fsType string, testResource interface{}) (*v1.PersistentVolumeSource, *v1.VolumeNodeAffinity) { func (v *vSphereDriver) GetPersistentVolumeSource(readOnly bool, fsType string, volume testsuites.TestVolume) (*v1.PersistentVolumeSource, *v1.VolumeNodeAffinity) {
vtr, ok := testResource.(*vSphereTestResource) vsv, ok := volume.(*vSphereVolume)
Expect(ok).To(BeTrue(), "Failed to cast test resource to vSphere Test Resource") Expect(ok).To(BeTrue(), "Failed to cast test volume to vSphere test volume")
// vSphere driver doesn't seem to support readOnly volume // vSphere driver doesn't seem to support readOnly volume
// TODO: check if it is correct // TODO: check if it is correct
@ -1326,7 +1289,7 @@ func (v *vSphereDriver) GetPersistentVolumeSource(readOnly bool, fsType string,
} }
pvSource := v1.PersistentVolumeSource{ pvSource := v1.PersistentVolumeSource{
VsphereVolume: &v1.VsphereVirtualDiskVolumeSource{ VsphereVolume: &v1.VsphereVirtualDiskVolumeSource{
VolumePath: vtr.volumePath, VolumePath: vsv.volumePath,
}, },
} }
if fsType != "" { if fsType != "" {
@ -1357,23 +1320,20 @@ func (v *vSphereDriver) CreateDriver() {
func (v *vSphereDriver) CleanupDriver() { func (v *vSphereDriver) CleanupDriver() {
} }
func (v *vSphereDriver) CreateVolume(volType testpatterns.TestVolType) interface{} { func (v *vSphereDriver) CreateVolume(volType testpatterns.TestVolType) testsuites.TestVolume {
f := v.driverInfo.Config.Framework f := v.driverInfo.Config.Framework
vspheretest.Bootstrap(f) vspheretest.Bootstrap(f)
nodeInfo := vspheretest.GetReadySchedulableRandomNodeInfo() nodeInfo := vspheretest.GetReadySchedulableRandomNodeInfo()
volumePath, err := nodeInfo.VSphere.CreateVolume(&vspheretest.VolumeOptions{}, nodeInfo.DataCenterRef) volumePath, err := nodeInfo.VSphere.CreateVolume(&vspheretest.VolumeOptions{}, nodeInfo.DataCenterRef)
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())
return &vSphereTestResource{ return &vSphereVolume{
volumePath: volumePath, volumePath: volumePath,
nodeInfo: nodeInfo, nodeInfo: nodeInfo,
} }
} }
func (v *vSphereDriver) DeleteVolume(volType testpatterns.TestVolType, testResource interface{}) { func (v *vSphereVolume) DeleteVolume() {
vtr, ok := testResource.(*vSphereTestResource) v.nodeInfo.VSphere.DeleteVolume(v.volumePath, v.nodeInfo.DataCenterRef)
Expect(ok).To(BeTrue(), "Failed to cast test resource to vSphere Test Resource")
vtr.nodeInfo.VSphere.DeleteVolume(vtr.volumePath, vtr.nodeInfo.DataCenterRef)
} }
// Azure // Azure
@ -1381,7 +1341,7 @@ type azureDriver struct {
driverInfo testsuites.DriverInfo driverInfo testsuites.DriverInfo
} }
type azureTestResource struct { type azureVolume struct {
volumeName string volumeName string
} }
@ -1421,16 +1381,16 @@ func (a *azureDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern) {
framework.SkipUnlessProviderIs("azure") framework.SkipUnlessProviderIs("azure")
} }
func (a *azureDriver) GetVolumeSource(readOnly bool, fsType string, testResource interface{}) *v1.VolumeSource { func (a *azureDriver) GetVolumeSource(readOnly bool, fsType string, volume testsuites.TestVolume) *v1.VolumeSource {
atr, ok := testResource.(*azureTestResource) av, ok := volume.(*azureVolume)
Expect(ok).To(BeTrue(), "Failed to cast test resource to Azure Test Resource") Expect(ok).To(BeTrue(), "Failed to cast test volume to Azure test volume")
diskName := atr.volumeName[(strings.LastIndex(atr.volumeName, "/") + 1):] diskName := av.volumeName[(strings.LastIndex(av.volumeName, "/") + 1):]
volSource := v1.VolumeSource{ volSource := v1.VolumeSource{
AzureDisk: &v1.AzureDiskVolumeSource{ AzureDisk: &v1.AzureDiskVolumeSource{
DiskName: diskName, DiskName: diskName,
DataDiskURI: atr.volumeName, DataDiskURI: av.volumeName,
ReadOnly: &readOnly, ReadOnly: &readOnly,
}, },
} }
@ -1440,16 +1400,16 @@ func (a *azureDriver) GetVolumeSource(readOnly bool, fsType string, testResource
return &volSource return &volSource
} }
func (a *azureDriver) GetPersistentVolumeSource(readOnly bool, fsType string, testResource interface{}) (*v1.PersistentVolumeSource, *v1.VolumeNodeAffinity) { func (a *azureDriver) GetPersistentVolumeSource(readOnly bool, fsType string, volume testsuites.TestVolume) (*v1.PersistentVolumeSource, *v1.VolumeNodeAffinity) {
atr, ok := testResource.(*azureTestResource) av, ok := volume.(*azureVolume)
Expect(ok).To(BeTrue(), "Failed to cast test resource to Azure Test Resource") Expect(ok).To(BeTrue(), "Failed to cast test volume to Azure test volume")
diskName := atr.volumeName[(strings.LastIndex(atr.volumeName, "/") + 1):] diskName := av.volumeName[(strings.LastIndex(av.volumeName, "/") + 1):]
pvSource := v1.PersistentVolumeSource{ pvSource := v1.PersistentVolumeSource{
AzureDisk: &v1.AzureDiskVolumeSource{ AzureDisk: &v1.AzureDiskVolumeSource{
DiskName: diskName, DiskName: diskName,
DataDiskURI: atr.volumeName, DataDiskURI: av.volumeName,
ReadOnly: &readOnly, ReadOnly: &readOnly,
}, },
} }
@ -1481,20 +1441,17 @@ func (a *azureDriver) CreateDriver() {
func (a *azureDriver) CleanupDriver() { func (a *azureDriver) CleanupDriver() {
} }
func (a *azureDriver) CreateVolume(volType testpatterns.TestVolType) interface{} { func (a *azureDriver) CreateVolume(volType testpatterns.TestVolType) testsuites.TestVolume {
By("creating a test azure disk volume") By("creating a test azure disk volume")
volumeName, err := framework.CreatePDWithRetry() volumeName, err := framework.CreatePDWithRetry()
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())
return &azureTestResource{ return &azureVolume{
volumeName: volumeName, volumeName: volumeName,
} }
} }
func (a *azureDriver) DeleteVolume(volType testpatterns.TestVolType, testResource interface{}) { func (v *azureVolume) DeleteVolume() {
atr, ok := testResource.(*azureTestResource) framework.DeletePDWithRetry(v.volumeName)
Expect(ok).To(BeTrue(), "Failed to cast test resource to Azure Test Resource")
framework.DeletePDWithRetry(atr.volumeName)
} }
// AWS // AWS
@ -1545,7 +1502,7 @@ func (a *awsDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern) {
// TODO: Fix authorization error in attach operation and uncomment below // TODO: Fix authorization error in attach operation and uncomment below
/* /*
func (a *awsDriver) GetVolumeSource(readOnly bool, fsType string, testResource interface{}) *v1.VolumeSource { func (a *awsDriver) GetVolumeSource(readOnly bool, fsType string, volume testsuites.TestVolume) *v1.VolumeSource {
volSource := v1.VolumeSource{ volSource := v1.VolumeSource{
AWSElasticBlockStore: &v1.AWSElasticBlockStoreVolumeSource{ AWSElasticBlockStore: &v1.AWSElasticBlockStoreVolumeSource{
VolumeID: a.volumeName, VolumeID: a.volumeName,
@ -1558,7 +1515,7 @@ func (a *awsDriver) GetVolumeSource(readOnly bool, fsType string, testResource i
return &volSource return &volSource
} }
func (a *awsDriver) GetPersistentVolumeSource(readOnly bool, fsType string, testResource interface{}) (*v1.PersistentVolumeSource, *v1.VolumeNodeAffinity) { func (a *awsDriver) GetPersistentVolumeSource(readOnly bool, fsType string, volume testsuites.TestVolume) (*v1.PersistentVolumeSource, *v1.VolumeNodeAffinity) {
pvSource := v1.PersistentVolumeSource{ pvSource := v1.PersistentVolumeSource{
AWSElasticBlockStore: &v1.AWSElasticBlockStoreVolumeSource{ AWSElasticBlockStore: &v1.AWSElasticBlockStoreVolumeSource{
VolumeID: a.volumeName, VolumeID: a.volumeName,
@ -1596,14 +1553,14 @@ func (a *awsDriver) CleanupDriver() {
// TODO: Fix authorization error in attach operation and uncomment below // TODO: Fix authorization error in attach operation and uncomment below
/* /*
func (a *awsDriver) CreateVolume(volType testpatterns.TestVolType) interface{} { func (a *awsDriver) CreateVolume(volType testpatterns.TestVolType) testsuites.TestVolume {
By("creating a test aws volume") By("creating a test aws volume")
var err error var err error
a.volumeName, err = framework.CreatePDWithRetry() a.volumeName, err = framework.CreatePDWithRetry()
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())
} }
func (a *awsDriver) DeleteVolume(volType testpatterns.TestVolType, testResource interface{}) { DeleteVolume() {
framework.DeletePDWithRetry(a.volumeName) framework.DeletePDWithRetry(a.volumeName)
} }
*/ */
@ -1619,6 +1576,11 @@ type localDriver struct {
ltrMgr utils.LocalTestResourceManager ltrMgr utils.LocalTestResourceManager
} }
type localVolume struct {
ltrMgr utils.LocalTestResourceManager
ltr *utils.LocalTestResource
}
var ( var (
// capabilities // capabilities
defaultLocalVolumeCapabilities = map[testsuites.Capability]bool{ defaultLocalVolumeCapabilities = map[testsuites.Capability]bool{
@ -1727,29 +1689,24 @@ func (l *localDriver) randomNode() *v1.Node {
return &node return &node
} }
func (l *localDriver) CreateVolume(volType testpatterns.TestVolType) interface{} { func (l *localDriver) CreateVolume(volType testpatterns.TestVolType) testsuites.TestVolume {
switch volType { switch volType {
case testpatterns.PreprovisionedPV: case testpatterns.PreprovisionedPV:
node := l.node node := l.node
// assign this to schedule pod on this node // assign this to schedule pod on this node
l.driverInfo.Config.ClientNodeName = node.Name l.driverInfo.Config.ClientNodeName = node.Name
return l.ltrMgr.Create(node, l.volumeType, nil) return &localVolume{
ltrMgr: l.ltrMgr,
ltr: l.ltrMgr.Create(node, l.volumeType, nil),
}
default: default:
framework.Failf("Unsupported volType: %v is specified", volType) framework.Failf("Unsupported volType: %v is specified", volType)
} }
return nil return nil
} }
func (l *localDriver) DeleteVolume(volType testpatterns.TestVolType, testResource interface{}) { func (v *localVolume) DeleteVolume() {
ltr, ok := testResource.(*utils.LocalTestResource) v.ltrMgr.Remove(v.ltr)
Expect(ok).To(BeTrue(), "Failed to cast test resource to local Test Resource")
switch volType {
case testpatterns.PreprovisionedPV:
l.ltrMgr.Remove(ltr)
default:
framework.Failf("Unsupported volType: %v is specified", volType)
}
return
} }
func (l *localDriver) nodeAffinityForNode(node *v1.Node) *v1.VolumeNodeAffinity { func (l *localDriver) nodeAffinityForNode(node *v1.Node) *v1.VolumeNodeAffinity {
@ -1778,13 +1735,13 @@ func (l *localDriver) nodeAffinityForNode(node *v1.Node) *v1.VolumeNodeAffinity
} }
} }
func (l *localDriver) GetPersistentVolumeSource(readOnly bool, fsType string, testResource interface{}) (*v1.PersistentVolumeSource, *v1.VolumeNodeAffinity) { func (l *localDriver) GetPersistentVolumeSource(readOnly bool, fsType string, volume testsuites.TestVolume) (*v1.PersistentVolumeSource, *v1.VolumeNodeAffinity) {
ltr, ok := testResource.(*utils.LocalTestResource) lv, ok := volume.(*localVolume)
Expect(ok).To(BeTrue(), "Failed to cast test resource to local Test Resource") Expect(ok).To(BeTrue(), "Failed to cast test volume to local test volume")
return &v1.PersistentVolumeSource{ return &v1.PersistentVolumeSource{
Local: &v1.LocalVolumeSource{ Local: &v1.LocalVolumeSource{
Path: ltr.Path, Path: lv.ltr.Path,
FSType: &fsType, FSType: &fsType,
}, },
}, l.nodeAffinityForNode(ltr.Node) }, l.nodeAffinityForNode(lv.ltr.Node)
} }

View File

@ -147,7 +147,7 @@ type genericVolumeTestResource struct {
pv *v1.PersistentVolume pv *v1.PersistentVolume
sc *storagev1.StorageClass sc *storagev1.StorageClass
driverTestResource interface{} volume TestVolume
} }
var _ TestResource = &genericVolumeTestResource{} var _ TestResource = &genericVolumeTestResource{}
@ -162,19 +162,19 @@ func (r *genericVolumeTestResource) setupResource(driver TestDriver, pattern tes
volType := pattern.VolType volType := pattern.VolType
// Create volume for pre-provisioned volume tests // Create volume for pre-provisioned volume tests
r.driverTestResource = CreateVolume(driver, volType) r.volume = CreateVolume(driver, volType)
switch volType { switch volType {
case testpatterns.InlineVolume: case testpatterns.InlineVolume:
framework.Logf("Creating resource for inline volume") framework.Logf("Creating resource for inline volume")
if iDriver, ok := driver.(InlineVolumeTestDriver); ok { if iDriver, ok := driver.(InlineVolumeTestDriver); ok {
r.volSource = iDriver.GetVolumeSource(false, fsType, r.driverTestResource) r.volSource = iDriver.GetVolumeSource(false, fsType, r.volume)
r.volType = dInfo.Name r.volType = dInfo.Name
} }
case testpatterns.PreprovisionedPV: case testpatterns.PreprovisionedPV:
framework.Logf("Creating resource for pre-provisioned PV") framework.Logf("Creating resource for pre-provisioned PV")
if pDriver, ok := driver.(PreprovisionedPVTestDriver); ok { if pDriver, ok := driver.(PreprovisionedPVTestDriver); ok {
pvSource, volumeNodeAffinity := pDriver.GetPersistentVolumeSource(false, fsType, r.driverTestResource) pvSource, volumeNodeAffinity := pDriver.GetPersistentVolumeSource(false, fsType, r.volume)
if pvSource != nil { if pvSource != nil {
r.volSource, r.pv, r.pvc = createVolumeSourceWithPVCPV(f, dInfo.Name, pvSource, volumeNodeAffinity, false) r.volSource, r.pv, r.pvc = createVolumeSourceWithPVCPV(f, dInfo.Name, pvSource, volumeNodeAffinity, false)
} }
@ -241,7 +241,9 @@ func (r *genericVolumeTestResource) cleanupResource(driver TestDriver, pattern t
} }
// Cleanup volume for pre-provisioned volume tests // Cleanup volume for pre-provisioned volume tests
DeleteVolume(driver, volType, r.driverTestResource) if r.volume != nil {
r.volume.DeleteVolume()
}
} }
func createVolumeSourceWithPVCPV( func createVolumeSourceWithPVCPV(

View File

@ -37,7 +37,7 @@ func GetDriverNameWithFeatureTags(driver TestDriver) string {
} }
// CreateVolume creates volume for test unless dynamicPV test // CreateVolume creates volume for test unless dynamicPV test
func CreateVolume(driver TestDriver, volType testpatterns.TestVolType) interface{} { func CreateVolume(driver TestDriver, volType testpatterns.TestVolType) TestVolume {
switch volType { switch volType {
case testpatterns.InlineVolume: case testpatterns.InlineVolume:
fallthrough fallthrough
@ -53,22 +53,6 @@ func CreateVolume(driver TestDriver, volType testpatterns.TestVolType) interface
return nil return nil
} }
// DeleteVolume deletes volume for test unless dynamicPV test
func DeleteVolume(driver TestDriver, volType testpatterns.TestVolType, testResource interface{}) {
switch volType {
case testpatterns.InlineVolume:
fallthrough
case testpatterns.PreprovisionedPV:
if pDriver, ok := driver.(PreprovisionedVolumeTestDriver); ok {
pDriver.DeleteVolume(volType, testResource)
}
case testpatterns.DynamicPV:
// No need to delete volume
default:
framework.Failf("Invalid volType specified: %v", volType)
}
}
// GetStorageClass constructs a new StorageClass instance // GetStorageClass constructs a new StorageClass instance
// with a unique name that is based on namespace + suffix. // with a unique name that is based on namespace + suffix.
func GetStorageClass( func GetStorageClass(

View File

@ -150,7 +150,7 @@ func (s *subPathTestResource) setupResource(driver TestDriver, pattern testpatte
switch volType { switch volType {
case testpatterns.InlineVolume: case testpatterns.InlineVolume:
if iDriver, ok := driver.(InlineVolumeTestDriver); ok { if iDriver, ok := driver.(InlineVolumeTestDriver); ok {
s.roVolSource = iDriver.GetVolumeSource(true, fsType, s.genericVolumeTestResource.driverTestResource) s.roVolSource = iDriver.GetVolumeSource(true, fsType, s.genericVolumeTestResource.volume)
} }
case testpatterns.PreprovisionedPV: case testpatterns.PreprovisionedPV:
s.roVolSource = &v1.VolumeSource{ s.roVolSource = &v1.VolumeSource{

View File

@ -38,22 +38,28 @@ type TestDriver interface {
SkipUnsupportedTest(testpatterns.TestPattern) SkipUnsupportedTest(testpatterns.TestPattern)
} }
// TestVolume is the result of PreprovisionedVolumeTestDriver.CreateVolume.
// The only common functionality is to delete it. Individual driver interfaces
// have additional methods that work with volumes created by them.
type TestVolume interface {
DeleteVolume()
}
// PreprovisionedVolumeTestDriver represents an interface for a TestDriver that has pre-provisioned volume // PreprovisionedVolumeTestDriver represents an interface for a TestDriver that has pre-provisioned volume
type PreprovisionedVolumeTestDriver interface { type PreprovisionedVolumeTestDriver interface {
TestDriver TestDriver
// CreateVolume creates a pre-provisioned volume. // CreateVolume creates a pre-provisioned volume of the desired volume type.
CreateVolume(testpatterns.TestVolType) interface{} CreateVolume(volumeType testpatterns.TestVolType) TestVolume
// DeleteVolume deletes a volume that is created in CreateVolume
DeleteVolume(testpatterns.TestVolType, interface{})
} }
// InlineVolumeTestDriver represents an interface for a TestDriver that supports InlineVolume // InlineVolumeTestDriver represents an interface for a TestDriver that supports InlineVolume
type InlineVolumeTestDriver interface { type InlineVolumeTestDriver interface {
PreprovisionedVolumeTestDriver PreprovisionedVolumeTestDriver
// GetVolumeSource returns a volumeSource for inline volume. // GetVolumeSource returns a volumeSource for inline volume.
// It will set readOnly and fsType to the volumeSource, if TestDriver supports both of them. // It will set readOnly and fsType to the volumeSource, if TestDriver supports both of them.
// It will return nil, if the TestDriver doesn't support either of the parameters. // It will return nil, if the TestDriver doesn't support either of the parameters.
GetVolumeSource(readOnly bool, fsType string, testResource interface{}) *v1.VolumeSource GetVolumeSource(readOnly bool, fsType string, testVolume TestVolume) *v1.VolumeSource
} }
// PreprovisionedPVTestDriver represents an interface for a TestDriver that supports PreprovisionedPV // PreprovisionedPVTestDriver represents an interface for a TestDriver that supports PreprovisionedPV
@ -63,7 +69,7 @@ type PreprovisionedPVTestDriver interface {
// It will set readOnly and fsType to the PersistentVolumeSource, if TestDriver supports both of them. // It will set readOnly and fsType to the PersistentVolumeSource, if TestDriver supports both of them.
// It will return nil, if the TestDriver doesn't support either of the parameters. // It will return nil, if the TestDriver doesn't support either of the parameters.
// Volume node affinity is optional, it will be nil for volumes which does not have volume node affinity. // Volume node affinity is optional, it will be nil for volumes which does not have volume node affinity.
GetPersistentVolumeSource(readOnly bool, fsType string, testResource interface{}) (*v1.PersistentVolumeSource, *v1.VolumeNodeAffinity) GetPersistentVolumeSource(readOnly bool, fsType string, testVolume TestVolume) (*v1.PersistentVolumeSource, *v1.VolumeNodeAffinity)
} }
// DynamicPVTestDriver represents an interface for a TestDriver that supports DynamicPV // DynamicPVTestDriver represents an interface for a TestDriver that supports DynamicPV

View File

@ -146,7 +146,7 @@ type volumeModeTestResource struct {
pvc *v1.PersistentVolumeClaim pvc *v1.PersistentVolumeClaim
pv *v1.PersistentVolume pv *v1.PersistentVolume
driverTestResource interface{} volume TestVolume
} }
var _ TestResource = &volumeModeTestResource{} var _ TestResource = &volumeModeTestResource{}
@ -168,7 +168,7 @@ func (s *volumeModeTestResource) setupResource(driver TestDriver, pattern testpa
) )
// Create volume for pre-provisioned volume tests // Create volume for pre-provisioned volume tests
s.driverTestResource = CreateVolume(driver, volType) s.volume = CreateVolume(driver, volType)
switch volType { switch volType {
case testpatterns.PreprovisionedPV: case testpatterns.PreprovisionedPV:
@ -178,7 +178,7 @@ func (s *volumeModeTestResource) setupResource(driver TestDriver, pattern testpa
scName = fmt.Sprintf("%s-%s-sc-for-file", ns.Name, dInfo.Name) scName = fmt.Sprintf("%s-%s-sc-for-file", ns.Name, dInfo.Name)
} }
if pDriver, ok := driver.(PreprovisionedPVTestDriver); ok { if pDriver, ok := driver.(PreprovisionedPVTestDriver); ok {
pvSource, volumeNodeAffinity = pDriver.GetPersistentVolumeSource(false, fsType, s.driverTestResource) pvSource, volumeNodeAffinity = pDriver.GetPersistentVolumeSource(false, fsType, s.volume)
if pvSource == nil { if pvSource == nil {
framework.Skipf("Driver %q does not define PersistentVolumeSource - skipping", dInfo.Name) framework.Skipf("Driver %q does not define PersistentVolumeSource - skipping", dInfo.Name)
} }
@ -211,7 +211,6 @@ func (s *volumeModeTestResource) cleanupResource(driver TestDriver, pattern test
f := dInfo.Config.Framework f := dInfo.Config.Framework
cs := f.ClientSet cs := f.ClientSet
ns := f.Namespace ns := f.Namespace
volType := pattern.VolType
By("Deleting pv and pvc") By("Deleting pv and pvc")
errs := framework.PVPVCCleanup(cs, ns.Name, s.pv, s.pvc) errs := framework.PVPVCCleanup(cs, ns.Name, s.pv, s.pvc)
@ -224,7 +223,9 @@ func (s *volumeModeTestResource) cleanupResource(driver TestDriver, pattern test
} }
// Cleanup volume for pre-provisioned volume tests // Cleanup volume for pre-provisioned volume tests
DeleteVolume(driver, volType, s.driverTestResource) if s.volume != nil {
s.volume.DeleteVolume()
}
} }
type volumeModeTestInput struct { type volumeModeTestInput struct {