tests: observe pod events
Signed-off-by: Paulo Pires <pjpires@gmail.com>
This commit is contained in:
@@ -10,6 +10,8 @@ import (
|
|||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/apis/stats/v1alpha1"
|
"k8s.io/kubernetes/pkg/kubelet/apis/stats/v1alpha1"
|
||||||
|
|
||||||
|
"github.com/virtual-kubelet/virtual-kubelet/vkubelet"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -210,6 +212,11 @@ func TestCreatePodWithOptionalInexistentSecrets(t *testing.T) {
|
|||||||
t.Fatal(err)
|
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.
|
// Check that the pod is known to the provider.
|
||||||
stats, err := f.GetStatsSummary()
|
stats, err := f.GetStatsSummary()
|
||||||
if err != nil {
|
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.
|
// Wait for an event concerning the missing secret to be reported on the pod.
|
||||||
// TODO (@pires) Wait for event to be reported.
|
if err := f.WaitUntilPodEventWithReason(pod, vkubelet.ReasonMandatorySecretNotFound); err != nil {
|
||||||
time.Sleep(5 * time.Second)
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
// Check that the pod is NOT known to the provider.
|
// Check that the pod is NOT known to the provider.
|
||||||
stats, err := f.GetStatsSummary()
|
stats, err := f.GetStatsSummary()
|
||||||
@@ -271,6 +279,11 @@ func TestCreatePodWithOptionalInexistentConfigMap(t *testing.T) {
|
|||||||
t.Fatal(err)
|
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.
|
// Check that the pod is known to the provider.
|
||||||
stats, err := f.GetStatsSummary()
|
stats, err := f.GetStatsSummary()
|
||||||
if err != nil {
|
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.
|
// Wait for an event concerning the missing config map to be reported on the pod.
|
||||||
// TODO (@pires) Wait for event to be reported.
|
if err := f.WaitUntilPodEventWithReason(pod, vkubelet.ReasonMandatoryConfigMapNotFound); err != nil {
|
||||||
time.Sleep(5 * time.Second)
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
// Check that the pod is NOT known to the provider.
|
// Check that the pod is NOT known to the provider.
|
||||||
stats, err := f.GetStatsSummary()
|
stats, err := f.GetStatsSummary()
|
||||||
|
|||||||
@@ -117,3 +117,41 @@ func (f *Framework) WaitUntilPodDeleted(namespace, name string) error {
|
|||||||
return event.Type == watchapi.Deleted || pod.DeletionTimestamp != nil, nil
|
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
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user