From 910fd1953edfb10828ad7cccdea58cc573519352 Mon Sep 17 00:00:00 2001 From: hangaoshuai Date: Tue, 24 Apr 2018 10:41:11 +0800 Subject: [PATCH] fixtodo:validate events on PVCs in integration volume binding test --- test/integration/scheduler/BUILD | 2 + .../scheduler/volume_binding_test.go | 69 ++++++++++++++----- 2 files changed, 53 insertions(+), 18 deletions(-) diff --git a/test/integration/scheduler/BUILD b/test/integration/scheduler/BUILD index 5f268ed8f8a..3e87624a62a 100644 --- a/test/integration/scheduler/BUILD +++ b/test/integration/scheduler/BUILD @@ -29,6 +29,7 @@ go_test( "//pkg/client/clientset_generated/internalclientset:go_default_library", "//pkg/client/informers/informers_generated/internalversion:go_default_library", "//pkg/controller/nodelifecycle:go_default_library", + "//pkg/controller/volume/events:go_default_library", "//pkg/controller/volume/persistentvolume:go_default_library", "//pkg/features:go_default_library", "//pkg/kubeapiserver/admission:go_default_library", @@ -59,6 +60,7 @@ go_test( "//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library", "//vendor/k8s.io/client-go/informers:go_default_library", "//vendor/k8s.io/client-go/kubernetes:go_default_library", + "//vendor/k8s.io/client-go/kubernetes/scheme:go_default_library", "//vendor/k8s.io/client-go/kubernetes/typed/core/v1:go_default_library", "//vendor/k8s.io/client-go/listers/core/v1:go_default_library", "//vendor/k8s.io/client-go/rest:go_default_library", diff --git a/test/integration/scheduler/volume_binding_test.go b/test/integration/scheduler/volume_binding_test.go index 99941e83925..ebd594023c8 100644 --- a/test/integration/scheduler/volume_binding_test.go +++ b/test/integration/scheduler/volume_binding_test.go @@ -35,6 +35,11 @@ import ( "k8s.io/apimachinery/pkg/util/wait" utilfeature "k8s.io/apiserver/pkg/util/feature" clientset "k8s.io/client-go/kubernetes" + "k8s.io/client-go/kubernetes/scheme" + v1core "k8s.io/client-go/kubernetes/typed/core/v1" + "k8s.io/client-go/tools/record" + "k8s.io/kubernetes/pkg/api/legacyscheme" + "k8s.io/kubernetes/pkg/controller/volume/events" "k8s.io/kubernetes/pkg/controller/volume/persistentvolume" ) @@ -73,9 +78,10 @@ type testPV struct { } type testPVC struct { - name string - scMode storagev1.VolumeBindingMode - preboundPV string + name string + scMode storagev1.VolumeBindingMode + preboundPV string + eventsReason string } func TestVolumeBinding(t *testing.T) { @@ -94,42 +100,42 @@ func TestVolumeBinding(t *testing.T) { "immediate can bind": { pod: makePod("pod-i-canbind", config.ns, []string{"pvc-i-canbind"}), pvs: []*testPV{{"pv-i-canbind", modeImmediate, "", node1}}, - pvcs: []*testPVC{{"pvc-i-canbind", modeImmediate, ""}}, + pvcs: []*testPVC{{"pvc-i-canbind", modeImmediate, "", ""}}, }, "immediate cannot bind": { pod: makePod("pod-i-cannotbind", config.ns, []string{"pvc-i-cannotbind"}), - unboundPvcs: []*testPVC{{"pvc-i-cannotbind", modeImmediate, ""}}, + unboundPvcs: []*testPVC{{"pvc-i-cannotbind", modeImmediate, "", events.ProvisioningFailed}}, shouldFail: true, }, "immediate pvc prebound": { pod: makePod("pod-i-pvc-prebound", config.ns, []string{"pvc-i-prebound"}), pvs: []*testPV{{"pv-i-pvc-prebound", modeImmediate, "", node1}}, - pvcs: []*testPVC{{"pvc-i-prebound", modeImmediate, "pv-i-pvc-prebound"}}, + pvcs: []*testPVC{{"pvc-i-prebound", modeImmediate, "pv-i-pvc-prebound", ""}}, }, "immediate pv prebound": { pod: makePod("pod-i-pv-prebound", config.ns, []string{"pvc-i-pv-prebound"}), pvs: []*testPV{{"pv-i-prebound", modeImmediate, "pvc-i-pv-prebound", node1}}, - pvcs: []*testPVC{{"pvc-i-pv-prebound", modeImmediate, ""}}, + pvcs: []*testPVC{{"pvc-i-pv-prebound", modeImmediate, "", ""}}, }, "wait can bind": { pod: makePod("pod-w-canbind", config.ns, []string{"pvc-w-canbind"}), pvs: []*testPV{{"pv-w-canbind", modeWait, "", node1}}, - pvcs: []*testPVC{{"pvc-w-canbind", modeWait, ""}}, + pvcs: []*testPVC{{"pvc-w-canbind", modeWait, "", events.WaitForFirstConsumer}}, }, "wait cannot bind": { pod: makePod("pod-w-cannotbind", config.ns, []string{"pvc-w-cannotbind"}), - unboundPvcs: []*testPVC{{"pvc-w-cannotbind", modeWait, ""}}, + unboundPvcs: []*testPVC{{"pvc-w-cannotbind", modeWait, "", events.WaitForFirstConsumer}}, shouldFail: true, }, "wait pvc prebound": { pod: makePod("pod-w-pvc-prebound", config.ns, []string{"pvc-w-prebound"}), pvs: []*testPV{{"pv-w-pvc-prebound", modeWait, "", node1}}, - pvcs: []*testPVC{{"pvc-w-prebound", modeWait, "pv-w-pvc-prebound"}}, + pvcs: []*testPVC{{"pvc-w-prebound", modeWait, "pv-w-pvc-prebound", events.WaitForFirstConsumer}}, }, "wait pv prebound": { pod: makePod("pod-w-pv-prebound", config.ns, []string{"pvc-w-pv-prebound"}), pvs: []*testPV{{"pv-w-prebound", modeWait, "pvc-w-pv-prebound", node1}}, - pvcs: []*testPVC{{"pvc-w-pv-prebound", modeWait, ""}}, + pvcs: []*testPVC{{"pvc-w-pv-prebound", modeWait, "", events.WaitForFirstConsumer}}, }, "wait can bind two": { pod: makePod("pod-w-canbind-2", config.ns, []string{"pvc-w-canbind-2", "pvc-w-canbind-3"}), @@ -138,8 +144,8 @@ func TestVolumeBinding(t *testing.T) { {"pv-w-canbind-3", modeWait, "", node2}, }, pvcs: []*testPVC{ - {"pvc-w-canbind-2", modeWait, ""}, - {"pvc-w-canbind-3", modeWait, ""}, + {"pvc-w-canbind-2", modeWait, "", events.WaitForFirstConsumer}, + {"pvc-w-canbind-3", modeWait, "", events.WaitForFirstConsumer}, }, unboundPvs: []*testPV{ {"pv-w-canbind-5", modeWait, "", node1}, @@ -148,8 +154,8 @@ func TestVolumeBinding(t *testing.T) { "wait cannot bind two": { pod: makePod("pod-w-cannotbind-2", config.ns, []string{"pvc-w-cannotbind-1", "pvc-w-cannotbind-2"}), unboundPvcs: []*testPVC{ - {"pvc-w-cannotbind-1", modeWait, ""}, - {"pvc-w-cannotbind-2", modeWait, ""}, + {"pvc-w-cannotbind-1", modeWait, "", events.WaitForFirstConsumer}, + {"pvc-w-cannotbind-2", modeWait, "", events.WaitForFirstConsumer}, }, unboundPvs: []*testPV{ {"pv-w-cannotbind-1", modeWait, "", node2}, @@ -164,8 +170,8 @@ func TestVolumeBinding(t *testing.T) { {"pv-i-canbind-2", modeImmediate, "", node1}, }, pvcs: []*testPVC{ - {"pvc-w-canbind-4", modeWait, ""}, - {"pvc-i-canbind-2", modeImmediate, ""}, + {"pvc-w-canbind-4", modeWait, "", events.WaitForFirstConsumer}, + {"pvc-i-canbind-2", modeImmediate, "", ""}, }, }, } @@ -230,9 +236,11 @@ func TestVolumeBinding(t *testing.T) { // Validate PVC/PV binding for _, pvc := range test.pvcs { validatePVCPhase(t, config.client, pvc.name, config.ns, v1.ClaimBound) + validatePVCEvent(t, config.client, pvc.name, config.ns, pvc.eventsReason) } for _, pvc := range test.unboundPvcs { validatePVCPhase(t, config.client, pvc.name, config.ns, v1.ClaimPending) + validatePVCEvent(t, config.client, pvc.name, config.ns, pvc.eventsReason) } for _, pv := range test.pvs { validatePVPhase(t, config.client, pv.name, v1.VolumeBound) @@ -375,6 +383,10 @@ func setupCluster(t *testing.T, nsName string, numberOfNodes int) *testConfig { ns := context.ns.Name informers := context.informerFactory + broadcaster := record.NewBroadcaster() + broadcaster.StartLogging(glog.Infof) + broadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: clientset.CoreV1().Events("")}) + eventRecorder := broadcaster.NewRecorder(scheme.Scheme, v1.EventSource{Component: "test-persistentvolume-controller"}) // Start PV controller for volume binding. params := persistentvolume.ControllerParameters{ KubeClient: clientset, @@ -386,7 +398,7 @@ func setupCluster(t *testing.T, nsName string, numberOfNodes int) *testConfig { ClaimInformer: informers.Core().V1().PersistentVolumeClaims(), ClassInformer: informers.Storage().V1().StorageClasses(), PodInformer: informers.Core().V1().Pods(), - EventRecorder: nil, // TODO: add one so we can test PV events + EventRecorder: eventRecorder, EnableDynamicProvisioning: true, } ctrl, err := persistentvolume.NewController(params) @@ -571,6 +583,27 @@ func validatePVCPhase(t *testing.T, client clientset.Interface, pvcName string, } } +func validatePVCEvent(t *testing.T, client clientset.Interface, pvcName string, ns string, reason string) { + claim, err := client.CoreV1().PersistentVolumeClaims(ns).Get(pvcName, metav1.GetOptions{}) + if err != nil { + t.Errorf("Failed to get PVC %v/%v: %v", ns, pvcName, err) + } + + pvcEvents, err := client.CoreV1().Events(ns).Search(legacyscheme.Scheme, claim) + if err != nil { + t.Errorf("Failed to get PVC events %v/%v: %v", ns, pvcName, err) + } + + if len(pvcEvents.Items) > 0 { + for _, e := range pvcEvents.Items { + if e.Reason == reason { + return + } + } + t.Errorf("Failed to get PVC %v/%v events reason:%s", ns, pvcName, reason) + } +} + func validatePVPhase(t *testing.T, client clientset.Interface, pvName string, phase v1.PersistentVolumePhase) { pv, err := client.CoreV1().PersistentVolumes().Get(pvName, metav1.GetOptions{}) if err != nil {