diff --git a/test/e2e/basic_test.go b/test/e2e/basic_test.go index 734fb537b..252b6d46d 100644 --- a/test/e2e/basic_test.go +++ b/test/e2e/basic_test.go @@ -10,6 +10,8 @@ import ( "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/kubernetes/pkg/kubelet/apis/stats/v1alpha1" + + "github.com/virtual-kubelet/virtual-kubelet/vkubelet" ) const ( @@ -210,6 +212,11 @@ func TestCreatePodWithOptionalInexistentSecrets(t *testing.T) { t.Fatal(err) } + // Wait for an event concerning the missing secret to be reported on the pod. + if err := f.WaitUntilPodEventWithReason(pod, vkubelet.ReasonOptionalSecretNotFound); err != nil { + t.Fatal(err) + } + // Check that the pod is known to the provider. stats, err := f.GetStatsSummary() if err != nil { @@ -236,9 +243,10 @@ func TestCreatePodWithMandatoryInexistentSecrets(t *testing.T) { } }() - // Wait for a small period so we can later assert the pod is not running. - // TODO (@pires) Wait for event to be reported. - time.Sleep(5 * time.Second) + // Wait for an event concerning the missing secret to be reported on the pod. + if err := f.WaitUntilPodEventWithReason(pod, vkubelet.ReasonMandatorySecretNotFound); err != nil { + t.Fatal(err) + } // Check that the pod is NOT known to the provider. stats, err := f.GetStatsSummary() @@ -271,6 +279,11 @@ func TestCreatePodWithOptionalInexistentConfigMap(t *testing.T) { t.Fatal(err) } + // Wait for an event concerning the missing config map to be reported on the pod. + if err := f.WaitUntilPodEventWithReason(pod, vkubelet.ReasonOptionalConfigMapNotFound); err != nil { + t.Fatal(err) + } + // Check that the pod is known to the provider. stats, err := f.GetStatsSummary() if err != nil { @@ -297,9 +310,10 @@ func TestCreatePodWithMandatoryInexistentConfigMap(t *testing.T) { } }() - // Wait for a small period so we can later assert the pod is not running. - // TODO (@pires) Wait for event to be reported. - time.Sleep(5 * time.Second) + // Wait for an event concerning the missing config map to be reported on the pod. + if err := f.WaitUntilPodEventWithReason(pod, vkubelet.ReasonMandatoryConfigMapNotFound); err != nil { + t.Fatal(err) + } // Check that the pod is NOT known to the provider. stats, err := f.GetStatsSummary() diff --git a/test/e2e/framework/pod.go b/test/e2e/framework/pod.go index 7fa416db1..fd8676b0a 100644 --- a/test/e2e/framework/pod.go +++ b/test/e2e/framework/pod.go @@ -117,3 +117,41 @@ func (f *Framework) WaitUntilPodDeleted(namespace, name string) error { return event.Type == watchapi.Deleted || pod.DeletionTimestamp != nil, nil }) } + +// WaitUntilPodEventWithReason establishes a watch on events involving the specified pod. +// Then, it waits for an event with the specified reason to be created/updated. +func (f *Framework) WaitUntilPodEventWithReason(pod *corev1.Pod, reason string) error { + // Create a field selector that matches Event resources involving the specified pod. + fs := fields.ParseSelectorOrDie(fmt.Sprintf("involvedObject.kind==Pod,involvedObject.uid==%s", pod.UID)) + // Create a ListWatch so we can receive events for the matched Event resource. + lw := &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + options.FieldSelector = fs.String() + return f.KubeClient.CoreV1().Events(pod.Namespace).List(options) + }, + WatchFunc: func(options metav1.ListOptions) (watchapi.Interface, error) { + options.FieldSelector = fs.String() + return f.KubeClient.CoreV1().Events(pod.Namespace).Watch(options) + }, + } + // Watch for updates to the Event resource until fn is satisfied, or until the timeout is reached. + ctx, cfn := context.WithTimeout(context.Background(), defaultWatchTimeout) + defer cfn() + last, err := watch.UntilWithSync(ctx, lw, &corev1.Event{}, nil, func(event watchapi.Event) (b bool, e error) { + switch event.Type { + case watchapi.Error: + fallthrough + case watchapi.Deleted: + return false, fmt.Errorf("got event of unexpected type %q", event.Type) + default: + return event.Object.(*corev1.Event).Reason == reason, nil + } + }) + if err != nil { + return err + } + if last == nil { + return fmt.Errorf("no events involving pod \"%s/%s\" have been seen", pod.Namespace, pod.Name) + } + return nil +}