framework.ExpectNoError(err, "failed to list DaemonSets") framework.ExpectEqual(len(dsList.Items), 0, "filtered list should have no daemonset") }) <ins> ginkgo.It("should verify changes to a daemon set status", func() { label := map[string]string{daemonsetNameLabel: dsName} labelSelector := labels.SelectorFromSet(label).String() dsClient := f.ClientSet.AppsV1().DaemonSets(ns) cs := f.ClientSet w := &cache.ListWatch{ WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { options.LabelSelector = labelSelector return dsClient.Watch(context.TODO(), options) }, } dsList, err := cs.AppsV1().DaemonSets("").List(context.TODO(), metav1.ListOptions{LabelSelector: labelSelector}) framework.ExpectNoError(err, "failed to list Daemon Sets") ginkgo.By(fmt.Sprintf("Creating simple DaemonSet %q", dsName)) testDaemonset, err := c.AppsV1().DaemonSets(ns).Create(context.TODO(), newDaemonSetWithLabel(dsName, image, label), metav1.CreateOptions{}) framework.ExpectNoError(err) ginkgo.By("Check that daemon pods launch on every node of the cluster.") err = wait.PollImmediate(dsRetryPeriod, dsRetryTimeout, checkRunningOnAllNodes(f, testDaemonset)) framework.ExpectNoError(err, "error waiting for daemon pod to start") err = checkDaemonStatus(f, dsName) framework.ExpectNoError(err) ginkgo.By("Getting /status") dsResource := schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "daemonsets"} dsStatusUnstructured, err := f.DynamicClient.Resource(dsResource).Namespace(ns).Get(context.TODO(), dsName, metav1.GetOptions{}, "status") framework.ExpectNoError(err, "Failed to fetch the status of daemon set %s in namespace %s", dsName, ns) dsStatusBytes, err := json.Marshal(dsStatusUnstructured) framework.ExpectNoError(err, "Failed to marshal unstructured response. %v", err) var dsStatus appsv1.DaemonSet err = json.Unmarshal(dsStatusBytes, &dsStatus) framework.ExpectNoError(err, "Failed to unmarshal JSON bytes to a daemon set object type") framework.Logf("Daemon Set %s has Conditions: %v", dsName, dsStatus.Status.Conditions) ginkgo.By("updating the DaemonSet Status") var statusToUpdate, updatedStatus *appsv1.DaemonSet err = retry.RetryOnConflict(retry.DefaultRetry, func() error { statusToUpdate, err = dsClient.Get(context.TODO(), dsName, metav1.GetOptions{}) framework.ExpectNoError(err, "Unable to retrieve daemon set %s", dsName) statusToUpdate.Status.Conditions = append(statusToUpdate.Status.Conditions, appsv1.DaemonSetCondition{ Type:    "StatusUpdate", Status:  "True", Reason:  "E2E", Message: "Set from e2e test", }) updatedStatus, err = dsClient.UpdateStatus(context.TODO(), statusToUpdate, metav1.UpdateOptions{}) return err }) framework.ExpectNoError(err, "Failed to update status. %v", err) framework.Logf("updatedStatus.Conditions: %#v", updatedStatus.Status.Conditions) ginkgo.By("watching for the daemon set status to be updated") ctx, cancel := context.WithTimeout(context.Background(), dsRetryTimeout) defer cancel() _, err = watchtools.Until(ctx, dsList.ResourceVersion, w, func(event watch.Event) (bool, error) { if ds, ok := event.Object.(*appsv1.DaemonSet); ok { found := ds.ObjectMeta.Name == testDaemonset.ObjectMeta.Name && ds.ObjectMeta.Namespace == testDaemonset.ObjectMeta.Namespace && ds.Labels[daemonsetNameLabel] == dsName if !found { framework.Logf("Observed daemon set %v in namespace %v with annotations: %v & Conditions: %v", ds.ObjectMeta.Name, ds.ObjectMeta.Namespace, ds.Annotations, ds.Status.Conditions) return false, nil } for _, cond := range ds.Status.Conditions { if cond.Type == "StatusUpdate" && cond.Reason == "E2E" && cond.Message == "Set from e2e test" { framework.Logf("Found daemon set %v in namespace %v with labels: %v annotations: %v & Conditions: %v", ds.ObjectMeta.Name, ds.ObjectMeta.Namespace, ds.ObjectMeta.Labels, ds.Annotations, ds.Status.Conditions) return found, nil } framework.Logf("Observed daemon set %v in namespace %v with annotations: %v & Conditions: %v", ds.ObjectMeta.Name, ds.ObjectMeta.Namespace, ds.Annotations, ds.Status.Conditions) } } object := strings.Split(fmt.Sprintf("%v", event.Object), "{")[0] framework.Logf("Observed %v event: %+v", object, event.Type) return false, nil }) framework.ExpectNoError(err, "failed to locate daemon set %v in namespace %v", testDaemonset.ObjectMeta.Name, ns) framework.Logf("Daemon set %s has an updated status", dsName) ginkgo.By("patching the DaemonSet Status") daemonSetStatusPatch := appsv1.DaemonSet{ Status: appsv1.DaemonSetStatus{ Conditions: []appsv1.DaemonSetCondition{ { Type:   "StatusPatched", Status: "True", }, }, }, } payload, err := json.Marshal(daemonSetStatusPatch) framework.ExpectNoError(err, "Failed to marshal JSON. %v", err) _, err = dsClient.Patch(context.TODO(), dsName, types.MergePatchType, payload, metav1.PatchOptions{}, "status") framework.ExpectNoError(err, "Failed to patch daemon set status", err) ginkgo.By("watching for the daemon set status to be patched") ctx, cancel = context.WithTimeout(context.Background(), dsRetryTimeout) defer cancel() _, err = watchtools.Until(ctx, dsList.ResourceVersion, w, func(event watch.Event) (bool, error) { if ds, ok := event.Object.(*appsv1.DaemonSet); ok { found := ds.ObjectMeta.Name == testDaemonset.ObjectMeta.Name && ds.ObjectMeta.Namespace == testDaemonset.ObjectMeta.Namespace && ds.Labels[daemonsetNameLabel] == dsName if !found { framework.Logf("Observed daemon set %v in namespace %v with annotations: %v & Conditions: %v", ds.ObjectMeta.Name, ds.ObjectMeta.Namespace, ds.Annotations, ds.Status.Conditions) return false, nil } for _, cond := range ds.Status.Conditions { if cond.Type == "StatusPatched" { framework.Logf("Found daemon set %v in namespace %v with labels: %v annotations: %v & Conditions: %v", ds.ObjectMeta.Name, ds.ObjectMeta.Namespace, ds.ObjectMeta.Labels, ds.Annotations, ds.Status.Conditions) return found, nil } framework.Logf("Observed daemon set %v in namespace %v with annotations: %v & Conditions: %v", ds.ObjectMeta.Name, ds.ObjectMeta.Namespace, ds.Annotations, ds.Status.Conditions) } } object := strings.Split(fmt.Sprintf("%v", event.Object), "{")[0] framework.Logf("Observed %v event: %v", object, event.Type) return false, nil }) framework.ExpectNoError(err, "failed to locate daemon set %v in namespace %v", testDaemonset.ObjectMeta.Name, ns) framework.Logf("Daemon set %s has a patched status", dsName) }) </ins> }) // randomPod selects a random pod within pods that causes fn to return true, or nil