e2e storage: check NodeUnpublishVolume in csi-mock tests

Once we have deleted the pod and the volume, we want to be sure that
NodeUnpublishVolume was called for it. The main motivation was to
check this for inline ephemeral volumes, but the same additional check
also makes sense for other volumes.
This commit is contained in:
Patrick Ohly 2019-07-30 16:17:33 +02:00
parent cf125a2db3
commit 55334fb9e9

View File

@ -370,10 +370,14 @@ var _ = utils.SIGDescribe("CSI mock volume", func() {
framework.ExpectNoError(err, "failed to test for CSIInlineVolumes") framework.ExpectNoError(err, "failed to test for CSIInlineVolumes")
} }
ginkgo.By("Deleting the previously created pod")
err = e2epod.DeletePodWithWait(m.cs, pod)
framework.ExpectNoError(err, "while deleting")
ginkgo.By("Checking CSI driver logs") ginkgo.By("Checking CSI driver logs")
// The driver is deployed as a statefulset with stable pod names // The driver is deployed as a statefulset with stable pod names
driverPodName := "csi-mockplugin-0" driverPodName := "csi-mockplugin-0"
err = checkPodInfo(m.cs, f.Namespace.Name, driverPodName, "mock", pod, test.expectPodInfo, test.expectEphemeral, csiInlineVolumesEnabled) err = checkPodLogs(m.cs, f.Namespace.Name, driverPodName, "mock", pod, test.expectPodInfo, test.expectEphemeral, csiInlineVolumesEnabled)
framework.ExpectNoError(err) framework.ExpectNoError(err)
}) })
} }
@ -719,8 +723,9 @@ func startPausePodWithVolumeSource(cs clientset.Interface, volumeSource v1.Volum
return cs.CoreV1().Pods(ns).Create(pod) return cs.CoreV1().Pods(ns).Create(pod)
} }
// checkPodInfo tests that NodePublish was called with expected volume_context // checkPodLogs tests that NodePublish was called with expected volume_context and (for ephemeral inline volumes)
func checkPodInfo(cs clientset.Interface, namespace, driverPodName, driverContainerName string, pod *v1.Pod, expectPodInfo, ephemeralVolume, csiInlineVolumesEnabled bool) error { // has the matching NodeUnpublish
func checkPodLogs(cs clientset.Interface, namespace, driverPodName, driverContainerName string, pod *v1.Pod, expectPodInfo, ephemeralVolume, csiInlineVolumesEnabled bool) error {
expectedAttributes := map[string]string{ expectedAttributes := map[string]string{
"csi.storage.k8s.io/pod.name": pod.Name, "csi.storage.k8s.io/pod.name": pod.Name,
"csi.storage.k8s.io/pod.namespace": namespace, "csi.storage.k8s.io/pod.namespace": namespace,
@ -741,6 +746,8 @@ func checkPodInfo(cs clientset.Interface, namespace, driverPodName, driverContai
// Find NodePublish in the logs // Find NodePublish in the logs
foundAttributes := sets.NewString() foundAttributes := sets.NewString()
logLines := strings.Split(log, "\n") logLines := strings.Split(log, "\n")
numNodePublishVolume := 0
numNodeUnpublishVolume := 0
for _, line := range logLines { for _, line := range logLines {
if !strings.HasPrefix(line, "gRPCCall:") { if !strings.HasPrefix(line, "gRPCCall:") {
continue continue
@ -759,10 +766,11 @@ func checkPodInfo(cs clientset.Interface, namespace, driverPodName, driverContai
e2elog.Logf("Could not parse CSI driver log line %q: %s", line, err) e2elog.Logf("Could not parse CSI driver log line %q: %s", line, err)
continue continue
} }
if call.Method != "/csi.v1.Node/NodePublishVolume" { switch call.Method {
continue case "/csi.v1.Node/NodePublishVolume":
} numNodePublishVolume++
// Check that NodePublish had expected attributes if numNodePublishVolume == 1 {
// Check that NodePublish had expected attributes for first volume
for k, v := range expectedAttributes { for k, v := range expectedAttributes {
vv, found := call.Request.VolumeContext[k] vv, found := call.Request.VolumeContext[k]
if found && v == vv { if found && v == vv {
@ -770,8 +778,11 @@ func checkPodInfo(cs clientset.Interface, namespace, driverPodName, driverContai
e2elog.Logf("Found volume attribute %s: %s", k, v) e2elog.Logf("Found volume attribute %s: %s", k, v)
} }
} }
// Process just the first NodePublish, the rest of the log is useless. }
break case "/csi.v1.Node/NodeUnpublishVolume":
e2elog.Logf("Found NodeUnpublishVolume: %+v", call)
numNodeUnpublishVolume++
}
} }
if expectPodInfo { if expectPodInfo {
if foundAttributes.Len() != len(expectedAttributes) { if foundAttributes.Len() != len(expectedAttributes) {
@ -782,6 +793,9 @@ func checkPodInfo(cs clientset.Interface, namespace, driverPodName, driverContai
if foundAttributes.Len() != 0 { if foundAttributes.Len() != 0 {
return fmt.Errorf("some unexpected volume attributes were found: %+v", foundAttributes.List()) return fmt.Errorf("some unexpected volume attributes were found: %+v", foundAttributes.List())
} }
if numNodePublishVolume != numNodeUnpublishVolume {
return fmt.Errorf("number of NodePublishVolume %d != number of NodeUnpublishVolume %d", numNodePublishVolume, numNodeUnpublishVolume)
}
return nil return nil
} }