From 8ebc1427c4e7a297b99e15d0342c753c3a4a9e0d Mon Sep 17 00:00:00 2001 From: Devan Goodwin Date: Mon, 15 Jun 2026 19:58:11 -0300 Subject: [PATCH 1/5] Add a monitortest for cluster region/zone/instance type autodl data --- pkg/defaultmonitortests/types.go | 2 + .../clusterinstancetypes/monitortest.go | 258 ++++++++++++++++++ .../clusterinstancetypes/monitortest_test.go | 129 +++++++++ 3 files changed, 389 insertions(+) create mode 100644 pkg/monitortests/testframework/clusterinstancetypes/monitortest.go create mode 100644 pkg/monitortests/testframework/clusterinstancetypes/monitortest_test.go diff --git a/pkg/defaultmonitortests/types.go b/pkg/defaultmonitortests/types.go index 84f95b5debdc..8af15cbfc74b 100644 --- a/pkg/defaultmonitortests/types.go +++ b/pkg/defaultmonitortests/types.go @@ -46,6 +46,7 @@ import ( "github.com/openshift/origin/pkg/monitortests/testframework/additionaleventscollector" "github.com/openshift/origin/pkg/monitortests/testframework/alertanalyzer" "github.com/openshift/origin/pkg/monitortests/testframework/clusterinfoserializer" + "github.com/openshift/origin/pkg/monitortests/testframework/clusterinstancetypes" "github.com/openshift/origin/pkg/monitortests/testframework/cpumetriccollector" "github.com/openshift/origin/pkg/monitortests/testframework/disruptionexternalawscloudservicemonitoring" "github.com/openshift/origin/pkg/monitortests/testframework/disruptionexternalazurecloudservicemonitoring" @@ -208,6 +209,7 @@ func newUniversalMonitorTests(info monitortestframework.MonitorTestInitializatio monitorTestRegistry.AddMonitorTestOrDie("interval-serializer", "Test Framework", intervalserializer.NewIntervalSerializer()) monitorTestRegistry.AddMonitorTestOrDie("tracked-resources-serializer", "Test Framework", trackedresourcesserializer.NewTrackedResourcesSerializer()) monitorTestRegistry.AddMonitorTestOrDie("cluster-info-serializer", "Test Framework", clusterinfoserializer.NewClusterInfoSerializer()) + monitorTestRegistry.AddMonitorTestOrDie("cluster-instance-types", "Test Framework", clusterinstancetypes.NewClusterInstanceTypes()) monitorTestRegistry.AddMonitorTestOrDie("additional-events-collector", "Test Framework", additionaleventscollector.NewIntervalSerializer()) monitorTestRegistry.AddMonitorTestOrDie("known-image-checker", "Test Framework", knownimagechecker.NewEnsureValidImages()) monitorTestRegistry.AddMonitorTestOrDie("e2e-test-analyzer", "Test Framework", e2etestanalyzer.NewAnalyzer()) diff --git a/pkg/monitortests/testframework/clusterinstancetypes/monitortest.go b/pkg/monitortests/testframework/clusterinstancetypes/monitortest.go new file mode 100644 index 000000000000..04b9a94e855a --- /dev/null +++ b/pkg/monitortests/testframework/clusterinstancetypes/monitortest.go @@ -0,0 +1,258 @@ +package clusterinstancetypes + +import ( + "context" + "encoding/json" + "fmt" + "os" + "path/filepath" + "sort" + "strings" + "time" + + configv1 "github.com/openshift/api/config/v1" + machinev1beta1 "github.com/openshift/api/machine/v1beta1" + configclient "github.com/openshift/client-go/config/clientset/versioned" + machineclient "github.com/openshift/client-go/machine/clientset/versioned" + "github.com/openshift/origin/pkg/dataloader" + "github.com/openshift/origin/pkg/monitor/monitorapi" + "github.com/openshift/origin/pkg/monitortestframework" + "github.com/openshift/origin/pkg/test/ginkgo/junitapi" + "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" +) + +type clusterInstanceTypes struct { + adminRESTConfig *rest.Config + data []instanceTypeRow +} + +type instanceTypeRow struct { + Platform string `json:"platform"` + Region string `json:"region"` + Role string `json:"role"` + InstanceType string `json:"instance_type"` +} + +func NewClusterInstanceTypes() monitortestframework.MonitorTest { + return &clusterInstanceTypes{} +} + +func (w *clusterInstanceTypes) PrepareCollection(ctx context.Context, adminRESTConfig *rest.Config, recorder monitorapi.RecorderWriter) error { + return nil +} + +func (w *clusterInstanceTypes) StartCollection(ctx context.Context, adminRESTConfig *rest.Config, recorder monitorapi.RecorderWriter) error { + w.adminRESTConfig = adminRESTConfig + return nil +} + +func (w *clusterInstanceTypes) CollectData(ctx context.Context, storageDir string, beginning, end time.Time) (monitorapi.Intervals, []*junitapi.JUnitTestCase, error) { + logger := logrus.WithField("MonitorTest", "ClusterInstanceTypes") + + data, err := w.collect(ctx) + if err != nil { + logger.WithError(err).Warn("failed to collect instance type data") + return nil, nil, nil + } + w.data = data + return nil, nil, nil +} + +func (*clusterInstanceTypes) ConstructComputedIntervals(ctx context.Context, startingIntervals monitorapi.Intervals, recordedResources monitorapi.ResourcesMap, beginning, end time.Time) (monitorapi.Intervals, error) { + return nil, nil +} + +func (*clusterInstanceTypes) EvaluateTestsFromConstructedIntervals(ctx context.Context, finalIntervals monitorapi.Intervals) ([]*junitapi.JUnitTestCase, error) { + return nil, nil +} + +func (w *clusterInstanceTypes) WriteContentToStorage(ctx context.Context, storageDir, timeSuffix string, finalIntervals monitorapi.Intervals, finalResourceState monitorapi.ResourcesMap) error { + if len(w.data) == 0 { + return nil + } + + rows := make([]map[string]string, 0, len(w.data)) + for _, r := range w.data { + rows = append(rows, map[string]string{ + "Platform": r.Platform, + "Region": r.Region, + "Role": r.Role, + "InstanceType": r.InstanceType, + }) + } + + dataFile := dataloader.DataFile{ + TableName: "cluster_instance_types", + Schema: map[string]dataloader.DataType{ + "Platform": dataloader.DataTypeString, + "Region": dataloader.DataTypeString, + "Role": dataloader.DataTypeString, + "InstanceType": dataloader.DataTypeString, + }, + Rows: rows, + } + + fileName := filepath.Join(storageDir, fmt.Sprintf("cluster-instance-types%s-%s", timeSuffix, dataloader.AutoDataLoaderSuffix)) + if err := dataloader.WriteDataFile(fileName, dataFile); err != nil { + return fmt.Errorf("failed to write instance types autodl: %w", err) + } + + jsonContent, err := json.MarshalIndent(w.data, "", " ") + if err != nil { + return fmt.Errorf("failed to marshal instance type data: %w", err) + } + jsonFileName := filepath.Join(storageDir, fmt.Sprintf("cluster-instance-types%s.json", timeSuffix)) + if err := os.WriteFile(jsonFileName, jsonContent, 0644); err != nil { + return fmt.Errorf("failed to write instance types JSON: %w", err) + } + + return nil +} + +func (*clusterInstanceTypes) Cleanup(ctx context.Context) error { + return nil +} + +func (w *clusterInstanceTypes) collect(ctx context.Context) ([]instanceTypeRow, error) { + configClient, err := configclient.NewForConfig(w.adminRESTConfig) + if err != nil { + return nil, fmt.Errorf("failed to create config client: %w", err) + } + + infra, err := configClient.ConfigV1().Infrastructures().Get(ctx, "cluster", metav1.GetOptions{}) + if err != nil { + return nil, fmt.Errorf("failed to get infrastructure: %w", err) + } + + if infra.Status.PlatformStatus == nil { + logrus.Info("skipping instance type collection: platform status not set") + return nil, nil + } + + platform := strings.ToLower(string(infra.Status.PlatformStatus.Type)) + if platform != "aws" && platform != "azure" && platform != "gcp" { + logrus.WithField("platform", platform).Info("skipping instance type collection for unsupported platform") + return nil, nil + } + + // Azure doesn't expose region in Infrastructure CR, so we always fall back to node labels + region := getRegionFromInfrastructure(infra) + if region == "" { + kubeClient, err := kubernetes.NewForConfig(w.adminRESTConfig) + if err != nil { + logrus.WithError(err).Warn("failed to create kube client for region fallback") + } else { + nodes, err := kubeClient.CoreV1().Nodes().List(ctx, metav1.ListOptions{}) + if err != nil { + logrus.WithError(err).Warn("failed to list nodes for region fallback") + } else if len(nodes.Items) > 0 { + region = nodes.Items[0].Labels["topology.kubernetes.io/region"] + } + } + } + + machineClientSet, err := machineclient.NewForConfig(w.adminRESTConfig) + if err != nil { + return nil, fmt.Errorf("failed to create machine client: %w", err) + } + + machines, err := machineClientSet.MachineV1beta1().Machines("openshift-machine-api").List(ctx, metav1.ListOptions{}) + if err != nil { + return nil, fmt.Errorf("failed to list machines: %w", err) + } + + return buildRows(platform, region, machines.Items), nil +} + +func buildRows(platform, region string, machines []machinev1beta1.Machine) []instanceTypeRow { + seen := map[string]bool{} + var result []instanceTypeRow + + for i := range machines { + machine := &machines[i] + role := "worker" + if isMaster(machine) { + role = "control-plane" + } + instanceType := extractInstanceType(platform, machine) + if instanceType == "" { + continue + } + key := role + "/" + instanceType + if seen[key] { + continue + } + seen[key] = true + result = append(result, instanceTypeRow{ + Platform: platform, + Region: region, + Role: role, + InstanceType: instanceType, + }) + } + + sort.Slice(result, func(i, j int) bool { + if result[i].Role != result[j].Role { + return result[i].Role < result[j].Role + } + return result[i].InstanceType < result[j].InstanceType + }) + + return result +} + +func getRegionFromInfrastructure(infra *configv1.Infrastructure) string { + if infra.Status.PlatformStatus == nil { + return "" + } + switch infra.Status.PlatformStatus.Type { + case configv1.AWSPlatformType: + if infra.Status.PlatformStatus.AWS != nil { + return infra.Status.PlatformStatus.AWS.Region + } + case configv1.GCPPlatformType: + if infra.Status.PlatformStatus.GCP != nil { + return infra.Status.PlatformStatus.GCP.Region + } + } + return "" +} + +func isMaster(machine *machinev1beta1.Machine) bool { + return machine.Labels["machine.openshift.io/cluster-api-machine-role"] == "master" +} + +func extractInstanceType(platform string, machine *machinev1beta1.Machine) string { + if machine.Spec.ProviderSpec.Value == nil { + return "" + } + raw := machine.Spec.ProviderSpec.Value.Raw + + switch platform { + case "aws": + var spec machinev1beta1.AWSMachineProviderConfig + if err := json.Unmarshal(raw, &spec); err != nil { + logrus.WithError(err).WithField("machine", machine.Name).Warn("failed to unmarshal AWS provider spec") + return "" + } + return spec.InstanceType + case "azure": + var spec machinev1beta1.AzureMachineProviderSpec + if err := json.Unmarshal(raw, &spec); err != nil { + logrus.WithError(err).WithField("machine", machine.Name).Warn("failed to unmarshal Azure provider spec") + return "" + } + return spec.VMSize + case "gcp": + var spec machinev1beta1.GCPMachineProviderSpec + if err := json.Unmarshal(raw, &spec); err != nil { + logrus.WithError(err).WithField("machine", machine.Name).Warn("failed to unmarshal GCP provider spec") + return "" + } + return spec.MachineType + } + return "" +} diff --git a/pkg/monitortests/testframework/clusterinstancetypes/monitortest_test.go b/pkg/monitortests/testframework/clusterinstancetypes/monitortest_test.go new file mode 100644 index 000000000000..0de105b05f7d --- /dev/null +++ b/pkg/monitortests/testframework/clusterinstancetypes/monitortest_test.go @@ -0,0 +1,129 @@ +package clusterinstancetypes + +import ( + "encoding/json" + "testing" + + machinev1beta1 "github.com/openshift/api/machine/v1beta1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +func awsMachine(t *testing.T, name, role, instanceType string) machinev1beta1.Machine { + t.Helper() + providerSpec := machinev1beta1.AWSMachineProviderConfig{ + InstanceType: instanceType, + } + raw, err := json.Marshal(providerSpec) + if err != nil { + t.Fatalf("failed to marshal provider spec: %v", err) + } + return machinev1beta1.Machine{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Labels: map[string]string{"machine.openshift.io/cluster-api-machine-role": role}, + }, + Spec: machinev1beta1.MachineSpec{ + ProviderSpec: machinev1beta1.ProviderSpec{ + Value: &runtime.RawExtension{Raw: raw}, + }, + }, + } +} + +func TestBuildRowsDeduplicates(t *testing.T) { + machines := []machinev1beta1.Machine{ + awsMachine(t, "master-0", "master", "m6i.xlarge"), + awsMachine(t, "master-1", "master", "m6i.xlarge"), + awsMachine(t, "master-2", "master", "m6i.xlarge"), + awsMachine(t, "worker-0", "worker", "m6i.2xlarge"), + awsMachine(t, "worker-1", "worker", "m6i.2xlarge"), + awsMachine(t, "worker-2", "worker", "m6i.2xlarge"), + } + + rows := buildRows("aws", "us-east-1", machines) + + if len(rows) != 2 { + t.Fatalf("expected 2 deduplicated rows, got %d: %+v", len(rows), rows) + } + if rows[0].Role != "control-plane" || rows[0].InstanceType != "m6i.xlarge" { + t.Errorf("unexpected control-plane row: %+v", rows[0]) + } + if rows[1].Role != "worker" || rows[1].InstanceType != "m6i.2xlarge" { + t.Errorf("unexpected worker row: %+v", rows[1]) + } +} + +func TestBuildRowsMixedWorkerTypes(t *testing.T) { + machines := []machinev1beta1.Machine{ + awsMachine(t, "master-0", "master", "m6i.xlarge"), + awsMachine(t, "worker-0", "worker", "m5.xlarge"), + awsMachine(t, "worker-1", "worker", "m6i.2xlarge"), + awsMachine(t, "worker-2", "worker", "m5.xlarge"), + } + + rows := buildRows("aws", "us-east-1", machines) + + if len(rows) != 3 { + t.Fatalf("expected 3 rows (1 cp + 2 distinct worker types), got %d: %+v", len(rows), rows) + } + if rows[0].Role != "control-plane" { + t.Errorf("first row should be control-plane, got %+v", rows[0]) + } + workerTypes := map[string]bool{} + for _, r := range rows[1:] { + if r.Role != "worker" { + t.Errorf("expected worker role, got %+v", r) + } + workerTypes[r.InstanceType] = true + } + if !workerTypes["m5.xlarge"] || !workerTypes["m6i.2xlarge"] { + t.Errorf("expected both worker types present, got %v", workerTypes) + } +} + +func TestBuildRowsSortsControlPlaneFirst(t *testing.T) { + machines := []machinev1beta1.Machine{ + awsMachine(t, "worker-0", "worker", "m5.xlarge"), + awsMachine(t, "master-0", "master", "m6i.xlarge"), + } + + rows := buildRows("aws", "us-east-1", machines) + + if len(rows) != 2 { + t.Fatalf("expected 2 rows, got %d", len(rows)) + } + if rows[0].Role != "control-plane" { + t.Errorf("control-plane should sort first, got %+v", rows[0]) + } +} + +func TestBuildRowsPropagatesPlatformAndRegion(t *testing.T) { + machines := []machinev1beta1.Machine{ + awsMachine(t, "master-0", "master", "m6i.xlarge"), + } + + rows := buildRows("aws", "eu-west-1", machines) + + if rows[0].Platform != "aws" || rows[0].Region != "eu-west-1" { + t.Errorf("expected platform=aws region=eu-west-1, got %+v", rows[0]) + } +} + +func TestBuildRowsSkipsEmptyProviderSpec(t *testing.T) { + machines := []machinev1beta1.Machine{ + awsMachine(t, "master-0", "master", "m6i.xlarge"), + { + ObjectMeta: metav1.ObjectMeta{ + Name: "worker-no-spec", + Labels: map[string]string{"machine.openshift.io/cluster-api-machine-role": "worker"}, + }, + }, + } + + rows := buildRows("aws", "us-east-1", machines) + + if len(rows) != 1 { + t.Fatalf("expected 1 row (worker with no spec skipped), got %d: %+v", len(rows), rows) + } +} From 57eb894fb390ab40be8abad843b34d73f084084b Mon Sep 17 00:00:00 2001 From: Devan Goodwin Date: Wed, 17 Jun 2026 14:23:07 -0300 Subject: [PATCH 2/5] Remove redundant json file --- .../testframework/clusterinstancetypes/monitortest.go | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/pkg/monitortests/testframework/clusterinstancetypes/monitortest.go b/pkg/monitortests/testframework/clusterinstancetypes/monitortest.go index 04b9a94e855a..0288d37640ae 100644 --- a/pkg/monitortests/testframework/clusterinstancetypes/monitortest.go +++ b/pkg/monitortests/testframework/clusterinstancetypes/monitortest.go @@ -4,7 +4,6 @@ import ( "context" "encoding/json" "fmt" - "os" "path/filepath" "sort" "strings" @@ -100,15 +99,6 @@ func (w *clusterInstanceTypes) WriteContentToStorage(ctx context.Context, storag return fmt.Errorf("failed to write instance types autodl: %w", err) } - jsonContent, err := json.MarshalIndent(w.data, "", " ") - if err != nil { - return fmt.Errorf("failed to marshal instance type data: %w", err) - } - jsonFileName := filepath.Join(storageDir, fmt.Sprintf("cluster-instance-types%s.json", timeSuffix)) - if err := os.WriteFile(jsonFileName, jsonContent, 0644); err != nil { - return fmt.Errorf("failed to write instance types JSON: %w", err) - } - return nil } From 438b534657dc92cbb152014fabf7f84082aa801c Mon Sep 17 00:00:00 2001 From: Devan Goodwin Date: Tue, 23 Jun 2026 08:58:56 -0300 Subject: [PATCH 3/5] Simplify and use node labels for all clouds --- .../clusterinstancetypes/monitortest.go | 104 +++----------- .../clusterinstancetypes/monitortest_test.go | 128 ++++++++++++------ 2 files changed, 105 insertions(+), 127 deletions(-) diff --git a/pkg/monitortests/testframework/clusterinstancetypes/monitortest.go b/pkg/monitortests/testframework/clusterinstancetypes/monitortest.go index 0288d37640ae..bd336077a4f3 100644 --- a/pkg/monitortests/testframework/clusterinstancetypes/monitortest.go +++ b/pkg/monitortests/testframework/clusterinstancetypes/monitortest.go @@ -2,22 +2,19 @@ package clusterinstancetypes import ( "context" - "encoding/json" "fmt" "path/filepath" "sort" "strings" "time" - configv1 "github.com/openshift/api/config/v1" - machinev1beta1 "github.com/openshift/api/machine/v1beta1" configclient "github.com/openshift/client-go/config/clientset/versioned" - machineclient "github.com/openshift/client-go/machine/clientset/versioned" "github.com/openshift/origin/pkg/dataloader" "github.com/openshift/origin/pkg/monitor/monitorapi" "github.com/openshift/origin/pkg/monitortestframework" "github.com/openshift/origin/pkg/test/ginkgo/junitapi" "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" @@ -128,49 +125,35 @@ func (w *clusterInstanceTypes) collect(ctx context.Context) ([]instanceTypeRow, return nil, nil } - // Azure doesn't expose region in Infrastructure CR, so we always fall back to node labels - region := getRegionFromInfrastructure(infra) - if region == "" { - kubeClient, err := kubernetes.NewForConfig(w.adminRESTConfig) - if err != nil { - logrus.WithError(err).Warn("failed to create kube client for region fallback") - } else { - nodes, err := kubeClient.CoreV1().Nodes().List(ctx, metav1.ListOptions{}) - if err != nil { - logrus.WithError(err).Warn("failed to list nodes for region fallback") - } else if len(nodes.Items) > 0 { - region = nodes.Items[0].Labels["topology.kubernetes.io/region"] - } - } - } - - machineClientSet, err := machineclient.NewForConfig(w.adminRESTConfig) + kubeClient, err := kubernetes.NewForConfig(w.adminRESTConfig) if err != nil { - return nil, fmt.Errorf("failed to create machine client: %w", err) + return nil, fmt.Errorf("failed to create kube client: %w", err) } - machines, err := machineClientSet.MachineV1beta1().Machines("openshift-machine-api").List(ctx, metav1.ListOptions{}) + nodes, err := kubeClient.CoreV1().Nodes().List(ctx, metav1.ListOptions{}) if err != nil { - return nil, fmt.Errorf("failed to list machines: %w", err) + return nil, fmt.Errorf("failed to list nodes: %w", err) } - return buildRows(platform, region, machines.Items), nil + return buildRows(platform, nodes.Items), nil } -func buildRows(platform, region string, machines []machinev1beta1.Machine) []instanceTypeRow { +func buildRows(platform string, nodes []corev1.Node) []instanceTypeRow { seen := map[string]bool{} var result []instanceTypeRow - for i := range machines { - machine := &machines[i] - role := "worker" - if isMaster(machine) { - role = "control-plane" - } - instanceType := extractInstanceType(platform, machine) + for i := range nodes { + node := &nodes[i] + labels := node.Labels + + instanceType := labels["node.kubernetes.io/instance-type"] if instanceType == "" { continue } + + region := labels["topology.kubernetes.io/region"] + role := nodeRole(labels) + key := role + "/" + instanceType if seen[key] { continue @@ -194,55 +177,12 @@ func buildRows(platform, region string, machines []machinev1beta1.Machine) []ins return result } -func getRegionFromInfrastructure(infra *configv1.Infrastructure) string { - if infra.Status.PlatformStatus == nil { - return "" +func nodeRole(labels map[string]string) string { + if _, ok := labels["node-role.kubernetes.io/master"]; ok { + return "control-plane" } - switch infra.Status.PlatformStatus.Type { - case configv1.AWSPlatformType: - if infra.Status.PlatformStatus.AWS != nil { - return infra.Status.PlatformStatus.AWS.Region - } - case configv1.GCPPlatformType: - if infra.Status.PlatformStatus.GCP != nil { - return infra.Status.PlatformStatus.GCP.Region - } - } - return "" -} - -func isMaster(machine *machinev1beta1.Machine) bool { - return machine.Labels["machine.openshift.io/cluster-api-machine-role"] == "master" -} - -func extractInstanceType(platform string, machine *machinev1beta1.Machine) string { - if machine.Spec.ProviderSpec.Value == nil { - return "" - } - raw := machine.Spec.ProviderSpec.Value.Raw - - switch platform { - case "aws": - var spec machinev1beta1.AWSMachineProviderConfig - if err := json.Unmarshal(raw, &spec); err != nil { - logrus.WithError(err).WithField("machine", machine.Name).Warn("failed to unmarshal AWS provider spec") - return "" - } - return spec.InstanceType - case "azure": - var spec machinev1beta1.AzureMachineProviderSpec - if err := json.Unmarshal(raw, &spec); err != nil { - logrus.WithError(err).WithField("machine", machine.Name).Warn("failed to unmarshal Azure provider spec") - return "" - } - return spec.VMSize - case "gcp": - var spec machinev1beta1.GCPMachineProviderSpec - if err := json.Unmarshal(raw, &spec); err != nil { - logrus.WithError(err).WithField("machine", machine.Name).Warn("failed to unmarshal GCP provider spec") - return "" - } - return spec.MachineType + if _, ok := labels["node-role.kubernetes.io/control-plane"]; ok { + return "control-plane" } - return "" + return "worker" } diff --git a/pkg/monitortests/testframework/clusterinstancetypes/monitortest_test.go b/pkg/monitortests/testframework/clusterinstancetypes/monitortest_test.go index 0de105b05f7d..edc71b6d1b25 100644 --- a/pkg/monitortests/testframework/clusterinstancetypes/monitortest_test.go +++ b/pkg/monitortests/testframework/clusterinstancetypes/monitortest_test.go @@ -1,47 +1,42 @@ package clusterinstancetypes import ( - "encoding/json" "testing" - machinev1beta1 "github.com/openshift/api/machine/v1beta1" + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" ) -func awsMachine(t *testing.T, name, role, instanceType string) machinev1beta1.Machine { - t.Helper() - providerSpec := machinev1beta1.AWSMachineProviderConfig{ - InstanceType: instanceType, +func makeNode(name, role, instanceType, region string) corev1.Node { + labels := map[string]string{ + "node.kubernetes.io/instance-type": instanceType, + "topology.kubernetes.io/region": region, } - raw, err := json.Marshal(providerSpec) - if err != nil { - t.Fatalf("failed to marshal provider spec: %v", err) + if role == "master" { + labels["node-role.kubernetes.io/master"] = "" + labels["node-role.kubernetes.io/control-plane"] = "" + } else { + labels["node-role.kubernetes.io/worker"] = "" } - return machinev1beta1.Machine{ + return corev1.Node{ ObjectMeta: metav1.ObjectMeta{ Name: name, - Labels: map[string]string{"machine.openshift.io/cluster-api-machine-role": role}, - }, - Spec: machinev1beta1.MachineSpec{ - ProviderSpec: machinev1beta1.ProviderSpec{ - Value: &runtime.RawExtension{Raw: raw}, - }, + Labels: labels, }, } } func TestBuildRowsDeduplicates(t *testing.T) { - machines := []machinev1beta1.Machine{ - awsMachine(t, "master-0", "master", "m6i.xlarge"), - awsMachine(t, "master-1", "master", "m6i.xlarge"), - awsMachine(t, "master-2", "master", "m6i.xlarge"), - awsMachine(t, "worker-0", "worker", "m6i.2xlarge"), - awsMachine(t, "worker-1", "worker", "m6i.2xlarge"), - awsMachine(t, "worker-2", "worker", "m6i.2xlarge"), + nodes := []corev1.Node{ + makeNode("master-0", "master", "m6i.xlarge", "us-east-1"), + makeNode("master-1", "master", "m6i.xlarge", "us-east-1"), + makeNode("master-2", "master", "m6i.xlarge", "us-east-1"), + makeNode("worker-0", "worker", "m6i.2xlarge", "us-east-1"), + makeNode("worker-1", "worker", "m6i.2xlarge", "us-east-1"), + makeNode("worker-2", "worker", "m6i.2xlarge", "us-east-1"), } - rows := buildRows("aws", "us-east-1", machines) + rows := buildRows("aws", nodes) if len(rows) != 2 { t.Fatalf("expected 2 deduplicated rows, got %d: %+v", len(rows), rows) @@ -55,14 +50,14 @@ func TestBuildRowsDeduplicates(t *testing.T) { } func TestBuildRowsMixedWorkerTypes(t *testing.T) { - machines := []machinev1beta1.Machine{ - awsMachine(t, "master-0", "master", "m6i.xlarge"), - awsMachine(t, "worker-0", "worker", "m5.xlarge"), - awsMachine(t, "worker-1", "worker", "m6i.2xlarge"), - awsMachine(t, "worker-2", "worker", "m5.xlarge"), + nodes := []corev1.Node{ + makeNode("master-0", "master", "m6i.xlarge", "us-east-1"), + makeNode("worker-0", "worker", "m5.xlarge", "us-east-1"), + makeNode("worker-1", "worker", "m6i.2xlarge", "us-east-1"), + makeNode("worker-2", "worker", "m5.xlarge", "us-east-1"), } - rows := buildRows("aws", "us-east-1", machines) + rows := buildRows("aws", nodes) if len(rows) != 3 { t.Fatalf("expected 3 rows (1 cp + 2 distinct worker types), got %d: %+v", len(rows), rows) @@ -83,12 +78,12 @@ func TestBuildRowsMixedWorkerTypes(t *testing.T) { } func TestBuildRowsSortsControlPlaneFirst(t *testing.T) { - machines := []machinev1beta1.Machine{ - awsMachine(t, "worker-0", "worker", "m5.xlarge"), - awsMachine(t, "master-0", "master", "m6i.xlarge"), + nodes := []corev1.Node{ + makeNode("worker-0", "worker", "m5.xlarge", "us-east-1"), + makeNode("master-0", "master", "m6i.xlarge", "us-east-1"), } - rows := buildRows("aws", "us-east-1", machines) + rows := buildRows("aws", nodes) if len(rows) != 2 { t.Fatalf("expected 2 rows, got %d", len(rows)) @@ -99,31 +94,74 @@ func TestBuildRowsSortsControlPlaneFirst(t *testing.T) { } func TestBuildRowsPropagatesPlatformAndRegion(t *testing.T) { - machines := []machinev1beta1.Machine{ - awsMachine(t, "master-0", "master", "m6i.xlarge"), + nodes := []corev1.Node{ + makeNode("master-0", "master", "m6i.xlarge", "eu-west-1"), } - rows := buildRows("aws", "eu-west-1", machines) + rows := buildRows("aws", nodes) if rows[0].Platform != "aws" || rows[0].Region != "eu-west-1" { t.Errorf("expected platform=aws region=eu-west-1, got %+v", rows[0]) } } -func TestBuildRowsSkipsEmptyProviderSpec(t *testing.T) { - machines := []machinev1beta1.Machine{ - awsMachine(t, "master-0", "master", "m6i.xlarge"), +func TestBuildRowsSkipsNodesWithoutInstanceType(t *testing.T) { + nodes := []corev1.Node{ + makeNode("master-0", "master", "m6i.xlarge", "us-east-1"), { ObjectMeta: metav1.ObjectMeta{ - Name: "worker-no-spec", - Labels: map[string]string{"machine.openshift.io/cluster-api-machine-role": "worker"}, + Name: "worker-no-labels", + Labels: map[string]string{ + "node-role.kubernetes.io/worker": "", + }, }, }, } - rows := buildRows("aws", "us-east-1", machines) + rows := buildRows("aws", nodes) if len(rows) != 1 { - t.Fatalf("expected 1 row (worker with no spec skipped), got %d: %+v", len(rows), rows) + t.Fatalf("expected 1 row (node without instance-type skipped), got %d: %+v", len(rows), rows) + } +} + +func TestNodeRole(t *testing.T) { + tests := []struct { + name string + labels map[string]string + expected string + }{ + { + name: "master label", + labels: map[string]string{"node-role.kubernetes.io/master": ""}, + expected: "control-plane", + }, + { + name: "control-plane label", + labels: map[string]string{"node-role.kubernetes.io/control-plane": ""}, + expected: "control-plane", + }, + { + name: "both labels", + labels: map[string]string{"node-role.kubernetes.io/master": "", "node-role.kubernetes.io/control-plane": ""}, + expected: "control-plane", + }, + { + name: "worker label", + labels: map[string]string{"node-role.kubernetes.io/worker": ""}, + expected: "worker", + }, + { + name: "no role labels", + labels: map[string]string{}, + expected: "worker", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := nodeRole(tt.labels); got != tt.expected { + t.Errorf("nodeRole() = %q, want %q", got, tt.expected) + } + }) } } From 5d138408a4e6436657eb919cd33fff7d50be8f3e Mon Sep 17 00:00:00 2001 From: Devan Goodwin Date: Wed, 24 Jun 2026 14:44:00 -0300 Subject: [PATCH 4/5] Add zone tracking to support AWS wavelength and edge compute pools Deduplicates rows on (role, instanceType, zone) instead of just (role, instanceType), so each availability zone and wavelength zone gets its own row. This addresses reviewer feedback to collect topology.kubernetes.io/zone for edge compute visibility. Co-Authored-By: Claude Opus 4.6 --- .../clusterinstancetypes/monitortest.go | 7 +- .../clusterinstancetypes/monitortest_test.go | 77 +++++++++++++------ 2 files changed, 58 insertions(+), 26 deletions(-) diff --git a/pkg/monitortests/testframework/clusterinstancetypes/monitortest.go b/pkg/monitortests/testframework/clusterinstancetypes/monitortest.go index bd336077a4f3..8e05a5db5b21 100644 --- a/pkg/monitortests/testframework/clusterinstancetypes/monitortest.go +++ b/pkg/monitortests/testframework/clusterinstancetypes/monitortest.go @@ -28,6 +28,7 @@ type clusterInstanceTypes struct { type instanceTypeRow struct { Platform string `json:"platform"` Region string `json:"region"` + Zone string `json:"zone"` Role string `json:"role"` InstanceType string `json:"instance_type"` } @@ -75,6 +76,7 @@ func (w *clusterInstanceTypes) WriteContentToStorage(ctx context.Context, storag rows = append(rows, map[string]string{ "Platform": r.Platform, "Region": r.Region, + "Zone": r.Zone, "Role": r.Role, "InstanceType": r.InstanceType, }) @@ -85,6 +87,7 @@ func (w *clusterInstanceTypes) WriteContentToStorage(ctx context.Context, storag Schema: map[string]dataloader.DataType{ "Platform": dataloader.DataTypeString, "Region": dataloader.DataTypeString, + "Zone": dataloader.DataTypeString, "Role": dataloader.DataTypeString, "InstanceType": dataloader.DataTypeString, }, @@ -152,9 +155,10 @@ func buildRows(platform string, nodes []corev1.Node) []instanceTypeRow { } region := labels["topology.kubernetes.io/region"] + zone := labels["topology.kubernetes.io/zone"] role := nodeRole(labels) - key := role + "/" + instanceType + key := role + "/" + instanceType + "/" + zone if seen[key] { continue } @@ -162,6 +166,7 @@ func buildRows(platform string, nodes []corev1.Node) []instanceTypeRow { result = append(result, instanceTypeRow{ Platform: platform, Region: region, + Zone: zone, Role: role, InstanceType: instanceType, }) diff --git a/pkg/monitortests/testframework/clusterinstancetypes/monitortest_test.go b/pkg/monitortests/testframework/clusterinstancetypes/monitortest_test.go index edc71b6d1b25..523b3ddfd16e 100644 --- a/pkg/monitortests/testframework/clusterinstancetypes/monitortest_test.go +++ b/pkg/monitortests/testframework/clusterinstancetypes/monitortest_test.go @@ -7,10 +7,11 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -func makeNode(name, role, instanceType, region string) corev1.Node { +func makeNode(name, role, instanceType, region, zone string) corev1.Node { labels := map[string]string{ "node.kubernetes.io/instance-type": instanceType, "topology.kubernetes.io/region": region, + "topology.kubernetes.io/zone": zone, } if role == "master" { labels["node-role.kubernetes.io/master"] = "" @@ -28,33 +29,33 @@ func makeNode(name, role, instanceType, region string) corev1.Node { func TestBuildRowsDeduplicates(t *testing.T) { nodes := []corev1.Node{ - makeNode("master-0", "master", "m6i.xlarge", "us-east-1"), - makeNode("master-1", "master", "m6i.xlarge", "us-east-1"), - makeNode("master-2", "master", "m6i.xlarge", "us-east-1"), - makeNode("worker-0", "worker", "m6i.2xlarge", "us-east-1"), - makeNode("worker-1", "worker", "m6i.2xlarge", "us-east-1"), - makeNode("worker-2", "worker", "m6i.2xlarge", "us-east-1"), + makeNode("master-0", "master", "m6i.xlarge", "us-east-1", "us-east-1a"), + makeNode("master-1", "master", "m6i.xlarge", "us-east-1", "us-east-1b"), + makeNode("master-2", "master", "m6i.xlarge", "us-east-1", "us-east-1c"), + makeNode("worker-0", "worker", "m6i.2xlarge", "us-east-1", "us-east-1a"), + makeNode("worker-1", "worker", "m6i.2xlarge", "us-east-1", "us-east-1b"), + makeNode("worker-2", "worker", "m6i.2xlarge", "us-east-1", "us-east-1a"), } rows := buildRows("aws", nodes) - if len(rows) != 2 { - t.Fatalf("expected 2 deduplicated rows, got %d: %+v", len(rows), rows) - } - if rows[0].Role != "control-plane" || rows[0].InstanceType != "m6i.xlarge" { - t.Errorf("unexpected control-plane row: %+v", rows[0]) + // 3 CP zones + 2 distinct worker zones = 5 rows + if len(rows) != 5 { + t.Fatalf("expected 5 deduplicated rows, got %d: %+v", len(rows), rows) } - if rows[1].Role != "worker" || rows[1].InstanceType != "m6i.2xlarge" { - t.Errorf("unexpected worker row: %+v", rows[1]) + for _, r := range rows { + if r.Zone == "" { + t.Errorf("expected zone to be set: %+v", r) + } } } func TestBuildRowsMixedWorkerTypes(t *testing.T) { nodes := []corev1.Node{ - makeNode("master-0", "master", "m6i.xlarge", "us-east-1"), - makeNode("worker-0", "worker", "m5.xlarge", "us-east-1"), - makeNode("worker-1", "worker", "m6i.2xlarge", "us-east-1"), - makeNode("worker-2", "worker", "m5.xlarge", "us-east-1"), + makeNode("master-0", "master", "m6i.xlarge", "us-east-1", "us-east-1a"), + makeNode("worker-0", "worker", "m5.xlarge", "us-east-1", "us-east-1a"), + makeNode("worker-1", "worker", "m6i.2xlarge", "us-east-1", "us-east-1a"), + makeNode("worker-2", "worker", "m5.xlarge", "us-east-1", "us-east-1a"), } rows := buildRows("aws", nodes) @@ -79,8 +80,8 @@ func TestBuildRowsMixedWorkerTypes(t *testing.T) { func TestBuildRowsSortsControlPlaneFirst(t *testing.T) { nodes := []corev1.Node{ - makeNode("worker-0", "worker", "m5.xlarge", "us-east-1"), - makeNode("master-0", "master", "m6i.xlarge", "us-east-1"), + makeNode("worker-0", "worker", "m5.xlarge", "us-east-1", "us-east-1a"), + makeNode("master-0", "master", "m6i.xlarge", "us-east-1", "us-east-1a"), } rows := buildRows("aws", nodes) @@ -93,21 +94,47 @@ func TestBuildRowsSortsControlPlaneFirst(t *testing.T) { } } -func TestBuildRowsPropagatesPlatformAndRegion(t *testing.T) { +func TestBuildRowsPropagatesPlatformRegionAndZone(t *testing.T) { nodes := []corev1.Node{ - makeNode("master-0", "master", "m6i.xlarge", "eu-west-1"), + makeNode("master-0", "master", "m6i.xlarge", "eu-west-1", "eu-west-1a"), } rows := buildRows("aws", nodes) - if rows[0].Platform != "aws" || rows[0].Region != "eu-west-1" { - t.Errorf("expected platform=aws region=eu-west-1, got %+v", rows[0]) + if rows[0].Platform != "aws" || rows[0].Region != "eu-west-1" || rows[0].Zone != "eu-west-1a" { + t.Errorf("expected platform=aws region=eu-west-1 zone=eu-west-1a, got %+v", rows[0]) + } +} + +func TestBuildRowsWavelengthZones(t *testing.T) { + nodes := []corev1.Node{ + makeNode("master-0", "master", "m6i.xlarge", "us-east-1", "us-east-1a"), + makeNode("worker-0", "worker", "m6i.2xlarge", "us-east-1", "us-east-1a"), + makeNode("worker-edge-0", "worker", "r5.2xlarge", "us-east-1", "us-east-1-wl1-bos-wlz-1"), + } + + rows := buildRows("aws", nodes) + + if len(rows) != 3 { + t.Fatalf("expected 3 rows (1 cp + 1 regular worker + 1 wavelength worker), got %d: %+v", len(rows), rows) + } + foundWavelength := false + for _, r := range rows { + if r.Zone == "us-east-1-wl1-bos-wlz-1" { + foundWavelength = true + if r.InstanceType != "r5.2xlarge" { + t.Errorf("expected wavelength node instance type r5.2xlarge, got %s", r.InstanceType) + } + } + } + if !foundWavelength { + t.Errorf("expected wavelength zone row, got %+v", rows) } } func TestBuildRowsSkipsNodesWithoutInstanceType(t *testing.T) { nodes := []corev1.Node{ - makeNode("master-0", "master", "m6i.xlarge", "us-east-1"), + makeNode("master-0", "master", "m6i.xlarge", "us-east-1", "us-east-1a"), { ObjectMeta: metav1.ObjectMeta{ Name: "worker-no-labels", From 7abc599008f9dffcd7350f9b0e6cd174151bf08a Mon Sep 17 00:00:00 2001 From: Devan Goodwin Date: Wed, 24 Jun 2026 14:53:48 -0300 Subject: [PATCH 5/5] Track suite name tested as well --- .../openshift-tests/run-upgrade/options.go | 1 + pkg/cmd/openshift-tests/run/options.go | 1 + pkg/defaultmonitortests/types.go | 2 +- pkg/monitortestframework/types.go | 3 +++ .../clusterinstancetypes/monitortest.go | 15 +++++++++++---- .../clusterinstancetypes/monitortest_test.go | 19 ++++++++++--------- 6 files changed, 27 insertions(+), 14 deletions(-) diff --git a/pkg/cmd/openshift-tests/run-upgrade/options.go b/pkg/cmd/openshift-tests/run-upgrade/options.go index 193e14402ea2..ceb787e56ef3 100644 --- a/pkg/cmd/openshift-tests/run-upgrade/options.go +++ b/pkg/cmd/openshift-tests/run-upgrade/options.go @@ -125,6 +125,7 @@ func (o *RunUpgradeSuiteOptions) Run(ctx context.Context) error { UpgradeTargetPayloadImagePullSpec: last, ExactMonitorTests: o.GinkgoRunSuiteOptions.ExactMonitorTests, DisableMonitorTests: o.GinkgoRunSuiteOptions.DisableMonitorTests, + SuiteName: o.Suite.Name, } o.GinkgoRunSuiteOptions.CommandEnv = o.TestCommandEnvironment() diff --git a/pkg/cmd/openshift-tests/run/options.go b/pkg/cmd/openshift-tests/run/options.go index c5f9715a47f4..85f31e0fae1f 100644 --- a/pkg/cmd/openshift-tests/run/options.go +++ b/pkg/cmd/openshift-tests/run/options.go @@ -97,6 +97,7 @@ func (o *RunSuiteOptions) Run(ctx context.Context) error { ClusterStabilityDuringTest: monitortestframework.ClusterStabilityDuringTest(stabilitySetting), ExactMonitorTests: o.GinkgoRunSuiteOptions.ExactMonitorTests, DisableMonitorTests: o.GinkgoRunSuiteOptions.DisableMonitorTests, + SuiteName: o.Suite.Name, } o.GinkgoRunSuiteOptions.CommandEnv = o.TestCommandEnvironment() diff --git a/pkg/defaultmonitortests/types.go b/pkg/defaultmonitortests/types.go index 8af15cbfc74b..db4cd0c5dc4b 100644 --- a/pkg/defaultmonitortests/types.go +++ b/pkg/defaultmonitortests/types.go @@ -209,7 +209,7 @@ func newUniversalMonitorTests(info monitortestframework.MonitorTestInitializatio monitorTestRegistry.AddMonitorTestOrDie("interval-serializer", "Test Framework", intervalserializer.NewIntervalSerializer()) monitorTestRegistry.AddMonitorTestOrDie("tracked-resources-serializer", "Test Framework", trackedresourcesserializer.NewTrackedResourcesSerializer()) monitorTestRegistry.AddMonitorTestOrDie("cluster-info-serializer", "Test Framework", clusterinfoserializer.NewClusterInfoSerializer()) - monitorTestRegistry.AddMonitorTestOrDie("cluster-instance-types", "Test Framework", clusterinstancetypes.NewClusterInstanceTypes()) + monitorTestRegistry.AddMonitorTestOrDie("cluster-instance-types", "Test Framework", clusterinstancetypes.NewClusterInstanceTypes(info)) monitorTestRegistry.AddMonitorTestOrDie("additional-events-collector", "Test Framework", additionaleventscollector.NewIntervalSerializer()) monitorTestRegistry.AddMonitorTestOrDie("known-image-checker", "Test Framework", knownimagechecker.NewEnsureValidImages()) monitorTestRegistry.AddMonitorTestOrDie("e2e-test-analyzer", "Test Framework", e2etestanalyzer.NewAnalyzer()) diff --git a/pkg/monitortestframework/types.go b/pkg/monitortestframework/types.go index 87e83c8a27ab..c93da77ad17c 100644 --- a/pkg/monitortestframework/types.go +++ b/pkg/monitortestframework/types.go @@ -34,6 +34,9 @@ type MonitorTestInitializationInfo struct { // DisableMonitorTests will remove any monitor tests contained in the provided list DisableMonitorTests []string + + // SuiteName is the name of the test suite being run (e.g. "kubernetes/conformance", "openshift/conformance/parallel"). + SuiteName string } type OpenshiftTestImageGetterFunc func(ctx context.Context, adminRESTConfig *rest.Config) (imagePullSpec string, notSupportedReason string, err error) diff --git a/pkg/monitortests/testframework/clusterinstancetypes/monitortest.go b/pkg/monitortests/testframework/clusterinstancetypes/monitortest.go index 8e05a5db5b21..d48e41f22b22 100644 --- a/pkg/monitortests/testframework/clusterinstancetypes/monitortest.go +++ b/pkg/monitortests/testframework/clusterinstancetypes/monitortest.go @@ -22,6 +22,7 @@ import ( type clusterInstanceTypes struct { adminRESTConfig *rest.Config + suiteName string data []instanceTypeRow } @@ -31,10 +32,13 @@ type instanceTypeRow struct { Zone string `json:"zone"` Role string `json:"role"` InstanceType string `json:"instance_type"` + Suite string `json:"suite"` } -func NewClusterInstanceTypes() monitortestframework.MonitorTest { - return &clusterInstanceTypes{} +func NewClusterInstanceTypes(info monitortestframework.MonitorTestInitializationInfo) monitortestframework.MonitorTest { + return &clusterInstanceTypes{ + suiteName: info.SuiteName, + } } func (w *clusterInstanceTypes) PrepareCollection(ctx context.Context, adminRESTConfig *rest.Config, recorder monitorapi.RecorderWriter) error { @@ -79,6 +83,7 @@ func (w *clusterInstanceTypes) WriteContentToStorage(ctx context.Context, storag "Zone": r.Zone, "Role": r.Role, "InstanceType": r.InstanceType, + "Suite": r.Suite, }) } @@ -90,6 +95,7 @@ func (w *clusterInstanceTypes) WriteContentToStorage(ctx context.Context, storag "Zone": dataloader.DataTypeString, "Role": dataloader.DataTypeString, "InstanceType": dataloader.DataTypeString, + "Suite": dataloader.DataTypeString, }, Rows: rows, } @@ -138,10 +144,10 @@ func (w *clusterInstanceTypes) collect(ctx context.Context) ([]instanceTypeRow, return nil, fmt.Errorf("failed to list nodes: %w", err) } - return buildRows(platform, nodes.Items), nil + return buildRows(platform, w.suiteName, nodes.Items), nil } -func buildRows(platform string, nodes []corev1.Node) []instanceTypeRow { +func buildRows(platform, suite string, nodes []corev1.Node) []instanceTypeRow { seen := map[string]bool{} var result []instanceTypeRow @@ -169,6 +175,7 @@ func buildRows(platform string, nodes []corev1.Node) []instanceTypeRow { Zone: zone, Role: role, InstanceType: instanceType, + Suite: suite, }) } diff --git a/pkg/monitortests/testframework/clusterinstancetypes/monitortest_test.go b/pkg/monitortests/testframework/clusterinstancetypes/monitortest_test.go index 523b3ddfd16e..9bed2e7f1f42 100644 --- a/pkg/monitortests/testframework/clusterinstancetypes/monitortest_test.go +++ b/pkg/monitortests/testframework/clusterinstancetypes/monitortest_test.go @@ -37,7 +37,7 @@ func TestBuildRowsDeduplicates(t *testing.T) { makeNode("worker-2", "worker", "m6i.2xlarge", "us-east-1", "us-east-1a"), } - rows := buildRows("aws", nodes) + rows := buildRows("aws", "openshift/conformance/parallel", nodes) // 3 CP zones + 2 distinct worker zones = 5 rows if len(rows) != 5 { @@ -58,7 +58,7 @@ func TestBuildRowsMixedWorkerTypes(t *testing.T) { makeNode("worker-2", "worker", "m5.xlarge", "us-east-1", "us-east-1a"), } - rows := buildRows("aws", nodes) + rows := buildRows("aws", "openshift/conformance/parallel", nodes) if len(rows) != 3 { t.Fatalf("expected 3 rows (1 cp + 2 distinct worker types), got %d: %+v", len(rows), rows) @@ -84,7 +84,7 @@ func TestBuildRowsSortsControlPlaneFirst(t *testing.T) { makeNode("master-0", "master", "m6i.xlarge", "us-east-1", "us-east-1a"), } - rows := buildRows("aws", nodes) + rows := buildRows("aws", "openshift/conformance/parallel", nodes) if len(rows) != 2 { t.Fatalf("expected 2 rows, got %d", len(rows)) @@ -94,15 +94,16 @@ func TestBuildRowsSortsControlPlaneFirst(t *testing.T) { } } -func TestBuildRowsPropagatesPlatformRegionAndZone(t *testing.T) { +func TestBuildRowsPropagatesAllFields(t *testing.T) { nodes := []corev1.Node{ makeNode("master-0", "master", "m6i.xlarge", "eu-west-1", "eu-west-1a"), } - rows := buildRows("aws", nodes) + rows := buildRows("aws", "openshift/conformance/parallel", nodes) - if rows[0].Platform != "aws" || rows[0].Region != "eu-west-1" || rows[0].Zone != "eu-west-1a" { - t.Errorf("expected platform=aws region=eu-west-1 zone=eu-west-1a, got %+v", rows[0]) + r := rows[0] + if r.Platform != "aws" || r.Region != "eu-west-1" || r.Zone != "eu-west-1a" || r.Suite != "openshift/conformance/parallel" { + t.Errorf("expected platform=aws region=eu-west-1 zone=eu-west-1a suite=openshift/conformance/parallel, got %+v", r) } } @@ -113,7 +114,7 @@ func TestBuildRowsWavelengthZones(t *testing.T) { makeNode("worker-edge-0", "worker", "r5.2xlarge", "us-east-1", "us-east-1-wl1-bos-wlz-1"), } - rows := buildRows("aws", nodes) + rows := buildRows("aws", "openshift/conformance/parallel", nodes) if len(rows) != 3 { t.Fatalf("expected 3 rows (1 cp + 1 regular worker + 1 wavelength worker), got %d: %+v", len(rows), rows) @@ -145,7 +146,7 @@ func TestBuildRowsSkipsNodesWithoutInstanceType(t *testing.T) { }, } - rows := buildRows("aws", nodes) + rows := buildRows("aws", "openshift/conformance/parallel", nodes) if len(rows) != 1 { t.Fatalf("expected 1 row (node without instance-type skipped), got %d: %+v", len(rows), rows)