Change:
Tracking bug for /sig storage /important-longterm /assign
/sig storage /triage accepted
/priority important-longterm

Discussion:
type hostpathCSIDriver struct { driverInfo       storageframework.DriverInfo manifests        []string <del> cleanupHandle    framework.CleanupActionHandle </del> volumeAttributes []map[string]string }

func (h *hostpathCSIDriver) PrepareTest(f *framework.Framework) (*storageframework.PerTestConfig, func()) { // Create secondary namespace which will be used for creating driver driverNamespace := utils.CreateDriverNamespace(f) <del> ns2 := driverNamespace.Name ns1 := f.Namespace.Name </del> <ins> driverns := driverNamespace.Name testns := f.Namespace.Name </ins> ginkgo.By(fmt.Sprintf("deploying %s driver", h.driverInfo.Name)) cancelLogging := utils.StartPodLogs(f, driverNamespace)

framework.Failf("deploying %s driver: %v", h.driverInfo.Name, err) } <del> // Cleanup CSI driver and namespaces. This function needs to be idempotent and can be // concurrently called from defer (or AfterEach) and AfterSuite action hooks. cleanupFunc := func() { ginkgo.By(fmt.Sprintf("deleting the test namespace: %s", ns1)) // Delete the primary namespace but its okay to fail here because this namespace will // also be deleted by framework.Aftereach hook tryFunc(func() { f.DeleteNamespace(ns1) }) ginkgo.By("uninstalling csi mock driver") tryFunc(cleanup) tryFunc(cancelLogging) ginkgo.By(fmt.Sprintf("deleting the driver namespace: %s", ns2)) tryFunc(func() { f.DeleteNamespace(ns2) }) // cleanup function has already ran and hence we don't need to run it again. // We do this as very last action because in-case defer(or AfterEach) races // with AfterSuite and test routine gets killed then this block still // runs in AfterSuite framework.RemoveCleanupAction(h.cleanupHandle) } h.cleanupHandle = framework.AddCleanupAction(cleanupFunc) </del> <ins> cleanupFunc := generateDriverCleanupFunc( f, h.driverInfo.Name, testns, driverns, cleanup, cancelLogging) </ins> return config, cleanupFunc }

attachLimit         int enableTopology      bool enableNodeExpansion bool <del> cleanupHandle       framework.CleanupActionHandle </del> javascriptHooks     map[string]string tokenRequests       []storagev1.TokenRequest requiresRepublish   *bool

func (m *mockCSIDriver) PrepareTest(f *framework.Framework) (*storageframework.PerTestConfig, func()) { // Create secondary namespace which will be used for creating driver driverNamespace := utils.CreateDriverNamespace(f) <del> ns2 := driverNamespace.Name ns1 := f.Namespace.Name </del> <ins> driverns := driverNamespace.Name testns := f.Namespace.Name </ins> ginkgo.By("deploying csi mock driver") cancelLogging := utils.StartPodLogs(f, driverNamespace)

}, } <del> _, err = f.ClientSet.CoreV1().ConfigMaps(ns2).Create(context.TODO(), hooks, metav1.CreateOptions{}) </del> <ins> _, err = f.ClientSet.CoreV1().ConfigMaps(driverns).Create(context.TODO(), hooks, metav1.CreateOptions{}) </ins> framework.ExpectNoError(err) if len(m.javascriptHooks) > 0 {

framework.Failf("deploying csi mock driver: %v", err) } <del> // Cleanup CSI driver and namespaces. This function needs to be idempotent and can be // concurrently called from defer (or AfterEach) and AfterSuite action hooks. cleanupFunc := func() { ginkgo.By(fmt.Sprintf("deleting the test namespace: %s", ns1)) // Delete the primary namespace but its okay to fail here because this namespace will // also be deleted by framework.Aftereach hook tryFunc(func() { f.DeleteNamespace(ns1) }) ginkgo.By("uninstalling csi mock driver") tryFunc(func() { err := f.ClientSet.CoreV1().ConfigMaps(ns2).Delete(context.TODO(), hooksConfigMapName, metav1.DeleteOptions{}) if err != nil { framework.Logf("deleting failed: %s", err) } }) tryFunc(cleanup) tryFunc(cancelLogging) ginkgo.By(fmt.Sprintf("deleting the driver namespace: %s", ns2)) tryFunc(func() { f.DeleteNamespace(ns2) }) // cleanup function has already ran and hence we don't need to run it again. // We do this as very last action because in-case defer(or AfterEach) races // with AfterSuite and test routine gets killed then this block still // runs in AfterSuite framework.RemoveCleanupAction(m.cleanupHandle) } m.cleanupHandle = framework.AddCleanupAction(cleanupFunc) </del> <ins> cleanupFunc := generateDriverCleanupFunc( f, "mock", testns, driverns, cleanup, cancelLogging) </ins> return config, cleanupFunc } // gce-pd type gcePDCSIDriver struct { <del> driverInfo    storageframework.DriverInfo cleanupHandle framework.CleanupActionHandle </del> <ins> driverInfo storageframework.DriverInfo </ins> } var _ storageframework.TestDriver = &gcePDCSIDriver{}

framework.Failf("waiting for csi driver node registration on: %v", err) } <del> // Cleanup CSI driver and namespaces. This function needs to be idempotent and can be // concurrently called from defer (or AfterEach) and AfterSuite action hooks. cleanupFunc := func() { ginkgo.By(fmt.Sprintf("deleting the test namespace: %s", testns)) // Delete the primary namespace but it's okay to fail here because this namespace will // also be deleted by framework.Aftereach hook tryFunc(func() { f.DeleteNamespace(testns) }) ginkgo.By("uninstalling csi gce-pd driver") tryFunc(cleanup) tryFunc(cancelLogging) ginkgo.By(fmt.Sprintf("deleting the driver namespace: %s", driverns)) tryFunc(func() { f.DeleteNamespace(driverns) }) // cleanup function has already ran and hence we don't need to run it again. // We do this as very last action because in-case defer(or AfterEach) races // with AfterSuite and test routine gets killed then this block still // runs in AfterSuite framework.RemoveCleanupAction(g.cleanupHandle) } g.cleanupHandle = framework.AddCleanupAction(cleanupFunc) </del> <ins> cleanupFunc := generateDriverCleanupFunc( f, "gce-pd", testns, driverns, cleanup, cancelLogging) </ins> return &storageframework.PerTestConfig{ Driver:          g,

f() return err } <ins> func generateDriverCleanupFunc( f *framework.Framework, driverName, testns, driverns string, driverCleanup, cancelLogging func()) func() { cleanupHandle := new(framework.CleanupActionHandle) // Cleanup CSI driver and namespaces. This function needs to be idempotent and can be // concurrently called from defer (or AfterEach) and AfterSuite action hooks. cleanupFunc := func() { ginkgo.By(fmt.Sprintf("deleting the test namespace: %s", testns)) // Delete the primary namespace but it's okay to fail here because this namespace will // also be deleted by framework.Aftereach hook tryFunc(func() { f.DeleteNamespace(testns) }) ginkgo.By(fmt.Sprintf("uninstalling csi %s driver", driverName)) tryFunc(driverCleanup) tryFunc(cancelLogging) ginkgo.By(fmt.Sprintf("deleting the driver namespace: %s", driverns)) tryFunc(func() { f.DeleteNamespace(driverns) }) // cleanup function has already ran and hence we don't need to run it again. // We do this as very last action because in-case defer(or AfterEach) races // with AfterSuite and test routine gets killed then this block still // runs in AfterSuite framework.RemoveCleanupAction(*cleanupHandle) } *cleanupHandle = framework.AddCleanupAction(cleanupFunc) return cleanupFunc } </ins>