diff --git a/test/e2e/topology_updater_test.go b/test/e2e/topology_updater_test.go index 53fc83ebf0..94da9dbaa3 100644 --- a/test/e2e/topology_updater_test.go +++ b/test/e2e/topology_updater_test.go @@ -29,6 +29,7 @@ import ( "github.com/k8stopologyawareschedwg/noderesourcetopology-api/pkg/apis/topology/v1alpha2" topologyclientset "github.com/k8stopologyawareschedwg/noderesourcetopology-api/pkg/generated/clientset/versioned" + "github.com/k8stopologyawareschedwg/podfingerprint" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" @@ -304,8 +305,74 @@ excludeList: }, 1*time.Minute, 10*time.Second).Should(BeFalse()) }) }) + When("topology-updater configure to compute pod fingerprint", func() { + BeforeEach(func() { + cfg, err := testutils.GetConfig() + Expect(err).ToNot(HaveOccurred()) + + kcfg := cfg.GetKubeletConfig() + By(fmt.Sprintf("Using config (%#v)", kcfg)) + + podSpecOpts := []testpod.SpecOption{ + testpod.SpecWithContainerImage(dockerImage()), + testpod.SpecWithContainerExtraArgs("-pods-fingerprint"), + } + topologyUpdaterDaemonSet = testds.NFDTopologyUpdater(kcfg, podSpecOpts...) + }) + It("noderesourcetopology should advertise pod fingerprint in top-level attribute", func() { + Eventually(func() bool { + // get node topology + nodeTopology := testutils.GetNodeTopology(topologyClient, topologyUpdaterNode.Name) + + // look for attribute + podFingerprintAttribute, err := findAttribute(nodeTopology.Attributes, podfingerprint.Attribute) + if err != nil { + framework.Logf("podFingerprint attributte %q not found: %v", podfingerprint.Attribute, err) + return false + } + // get pods in node + pods, err := f.ClientSet.CoreV1().Pods("").List(context.TODO(), metav1.ListOptions{FieldSelector: "spec.nodeName=" + topologyUpdaterNode.Name}) + if err != nil { + framework.Logf("podFingerprint error while recovering %q node pods: %v", topologyUpdaterNode.Name, err) + return false + } + if len(pods.Items) == 0 { + framework.Logf("podFingerprint No pods in node %q", topologyUpdaterNode.Name) + return false + } + + // compute expected value + pf := podfingerprint.NewFingerprint(len(pods.Items)) + for _, pod := range pods.Items { + err = pf.Add(pod.Namespace, pod.Name) + if err != nil { + framework.Logf("error while computing expected podFingerprint %v", err) + return false + } + } + expectedPodFingerprint := pf.Sign() + + if podFingerprintAttribute.Value != expectedPodFingerprint { + framework.Logf("podFingerprint attributte error expected: %q actual: %q", expectedPodFingerprint, podFingerprintAttribute.Value) + return false + } + + return true + + }, 1*time.Minute, 10*time.Second).Should(BeTrue()) + }) + }) }) +func findAttribute(attributes v1alpha2.AttributeList, attributeName string) (v1alpha2.AttributeInfo, error) { + for _, attrInfo := range attributes { + if attrInfo.Name == attributeName { + return attrInfo, nil + } + } + return v1alpha2.AttributeInfo{}, fmt.Errorf("attribute %q not found", attributeName) +} + // lessAllocatableResources specialize CompareAllocatableResources for this specific e2e use case. func lessAllocatableResources(expected, got map[string]corev1.ResourceList) (string, string, bool) { zoneName, resName, cmp, ok := testutils.CompareAllocatableResources(expected, got)