diff --git a/cmd/infra/aws/util/sts_test.go b/cmd/infra/aws/util/sts_test.go index 63f7a4861bdc..a02e5ed13211 100644 --- a/cmd/infra/aws/util/sts_test.go +++ b/cmd/infra/aws/util/sts_test.go @@ -317,12 +317,8 @@ func TestParseSTSCredentialsFileV2_RealWorldFormat(t *testing.T) { } creds, err := ParseSTSCredentialsFileV2(tmpFile.Name()) - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } - - if creds == nil { - t.Fatal("Expected non-nil credentials") + if err != nil || creds == nil { + t.Fatalf("Unexpected error or nil credentials: err=%v, creds=%v", err, creds) } expectedAccessKey := "ASIAIOSFODNN7EXAMPLE" diff --git a/test/e2e/create_cluster_test.go b/test/e2e/create_cluster_test.go index d2ff7e486a2d..6e7e94b24fcf 100644 --- a/test/e2e/create_cluster_test.go +++ b/test/e2e/create_cluster_test.go @@ -68,9 +68,10 @@ func TestOnCreateAPIUX(t *testing.T) { g.Expect(err).NotTo(HaveOccurred(), "couldn't get client") testCases := []struct { - name string - file string - validations []struct { + name string + file string + platformType hyperv1.PlatformType // empty = use globalOpts.Platform + validations []struct { name string mutateInput func(*hyperv1.HostedCluster) expectedErrorSubstring string @@ -319,8 +320,9 @@ func TestOnCreateAPIUX(t *testing.T) { }, }, { - name: "when GCP project/region validation is applied it should handle formats", - file: "hostedcluster-base.yaml", + name: "when GCP project/region validation is applied it should handle formats", + file: "hostedcluster-base.yaml", + platformType: hyperv1.GCPPlatform, validations: []struct { name string mutateInput func(*hyperv1.HostedCluster) @@ -359,8 +361,9 @@ func TestOnCreateAPIUX(t *testing.T) { }, }, { - name: "when GCP network configuration is not valid it should fail", - file: "hostedcluster-base.yaml", + name: "when GCP network configuration is not valid it should fail", + file: "hostedcluster-base.yaml", + platformType: hyperv1.GCPPlatform, validations: []struct { name string mutateInput func(*hyperv1.HostedCluster) @@ -1363,8 +1366,9 @@ func TestOnCreateAPIUX(t *testing.T) { }, }, { - name: "when Azure authentication configuration is not properly configured it should fail", - file: "hostedcluster-base.yaml", + name: "when Azure authentication configuration is not properly configured it should fail", + file: "hostedcluster-base.yaml", + platformType: hyperv1.AzurePlatform, validations: []struct { name string mutateInput func(*hyperv1.HostedCluster) @@ -1373,7 +1377,6 @@ func TestOnCreateAPIUX(t *testing.T) { { name: "when azureAuthenticationConfigType is ManagedIdentities but managedIdentities field is missing it should fail", mutateInput: func(hc *hyperv1.HostedCluster) { - hc.Spec.Platform.Type = hyperv1.AzurePlatform hc.Spec.Platform.Azure = &hyperv1.AzurePlatformSpec{ Location: "eastus", ResourceGroupName: "test-rg", @@ -1393,7 +1396,6 @@ func TestOnCreateAPIUX(t *testing.T) { { name: "when azureAuthenticationConfigType is WorkloadIdentities but workloadIdentities field is missing it should fail", mutateInput: func(hc *hyperv1.HostedCluster) { - hc.Spec.Platform.Type = hyperv1.AzurePlatform hc.Spec.Platform.Azure = &hyperv1.AzurePlatformSpec{ Location: "eastus", ResourceGroupName: "test-rg", @@ -1413,7 +1415,6 @@ func TestOnCreateAPIUX(t *testing.T) { { name: "when azureAuthenticationConfigType is ManagedIdentities but workloadIdentities field is present it should fail", mutateInput: func(hc *hyperv1.HostedCluster) { - hc.Spec.Platform.Type = hyperv1.AzurePlatform hc.Spec.Platform.Azure = &hyperv1.AzurePlatformSpec{ Location: "eastus", ResourceGroupName: "test-rg", @@ -1441,7 +1442,6 @@ func TestOnCreateAPIUX(t *testing.T) { { name: "when azureAuthenticationConfigType is WorkloadIdentities but managedIdentities field is present it should fail", mutateInput: func(hc *hyperv1.HostedCluster) { - hc.Spec.Platform.Type = hyperv1.AzurePlatform hc.Spec.Platform.Azure = &hyperv1.AzurePlatformSpec{ Location: "eastus", ResourceGroupName: "test-rg", @@ -1634,13 +1634,19 @@ func TestOnCreateAPIUX(t *testing.T) { t.Logf("Running validation %q", v.name) hostedCluster := assets.ShouldHostedCluster(content.ReadFile, fmt.Sprintf("assets/%s", tc.file)) + // Set platform type: explicit per test case, or fall back to environment + if tc.platformType != "" { + hostedCluster.Spec.Platform.Type = tc.platformType + } else { + hostedCluster.Spec.Platform.Type = globalOpts.Platform + } // Generate unique name to avoid "already exists" race condition hostedCluster.Name = fmt.Sprintf("test-%d-%d", time.Now().UnixNano(), i) defer client.Delete(ctx, hostedCluster) v.mutateInput(hostedCluster) // Skip GCP validations outside TechPreviewNoUpgrade - if hostedCluster.Spec.Platform.Type == hyperv1.GCPPlatform && os.Getenv("TECH_PREVIEW_NO_UPGRADE") != "true" { + if tc.platformType == hyperv1.GCPPlatform && os.Getenv("TECH_PREVIEW_NO_UPGRADE") != "true" { t.Logf("Skipping GCP validation outside TechPreviewNoUpgrade: %s", v.name) continue } @@ -2426,7 +2432,7 @@ func TestCreateCluster(t *testing.T) { clusterOpts := globalOpts.DefaultClusterOptions(t) zones := strings.Split(globalOpts.ConfigurableClusterOptions.Zone.String(), ",") - if len(zones) >= 3 { + if len(zones) >= 3 && globalOpts.Platform == hyperv1.AWSPlatform { // CreateCluster also tests multi-zone workers work properly if a sufficient number of zones are configured t.Logf("Sufficient zones available for InfrastructureAvailabilityPolicy HighlyAvailable") clusterOpts.AWSPlatform.Zones = zones diff --git a/test/e2e/util/hypershift_framework.go b/test/e2e/util/hypershift_framework.go index 3a8318186920..9dda7febe82c 100644 --- a/test/e2e/util/hypershift_framework.go +++ b/test/e2e/util/hypershift_framework.go @@ -85,6 +85,23 @@ func (h *hypershiftTest) WithAssetReader(reader assets.AssetReader) *hypershiftT return h } +// numExpectedNodes returns the number of nodes expected for a cluster based on platform. +// On AWS and Azure, nodes are spread across zones, so the count is replicas * zones. +// On all other platforms, the count is just replicas. +func numExpectedNodes(opts *PlatformAgnosticOptions, platform hyperv1.PlatformType) int32 { + switch platform { + case hyperv1.AWSPlatform: + if len(opts.AWSPlatform.Zones) > 0 { + return opts.NodePoolReplicas * int32(len(opts.AWSPlatform.Zones)) + } + case hyperv1.AzurePlatform: + if len(opts.AzurePlatform.AvailabilityZones) > 0 { + return opts.NodePoolReplicas * int32(len(opts.AzurePlatform.AvailabilityZones)) + } + } + return opts.NodePoolReplicas +} + func (h *hypershiftTest) Execute(opts *PlatformAgnosticOptions, platform hyperv1.PlatformType, artifactDir, name string, serviceAccountSigningKey []byte) { artifactDir = filepath.Join(artifactDir, artifactSubdirFor(h.T)) @@ -124,7 +141,7 @@ func (h *hypershiftTest) Execute(opts *PlatformAgnosticOptions, platform hyperv1 h.after(hostedCluster, platform) if h.Failed() { - numNodes := opts.NodePoolReplicas * int32(len(opts.AWSPlatform.Zones)) + numNodes := numExpectedNodes(opts, platform) h.Logf("Summarizing unexpected conditions for HostedCluster %s ", hostedCluster.Name) ValidateHostedClusterConditions(h.T, h.ctx, h.client, hostedCluster, numNodes > 0, 2*time.Second) } @@ -134,7 +151,8 @@ func (h *hypershiftTest) Execute(opts *PlatformAgnosticOptions, platform hyperv1 func (h *hypershiftTest) before(hostedCluster *hyperv1.HostedCluster, opts *PlatformAgnosticOptions, platform hyperv1.PlatformType) { h.Run("ValidateHostedCluster", func(t *testing.T) { if platform != hyperv1.NonePlatform && hostedCluster.Spec.Networking.NetworkType != hyperv1.Other { - if opts.AWSPlatform.EndpointAccess == string(hyperv1.Private) { + isPrivate := platform == hyperv1.AWSPlatform && opts.AWSPlatform.EndpointAccess == string(hyperv1.Private) + if isPrivate { ValidatePrivateCluster(t, h.ctx, h.client, hostedCluster, opts) } else { ValidatePublicCluster(t, h.ctx, h.client, hostedCluster, opts) diff --git a/test/e2e/util/util.go b/test/e2e/util/util.go index bf8afe1dc9cf..5c2b8b1783b2 100644 --- a/test/e2e/util/util.go +++ b/test/e2e/util/util.go @@ -2857,7 +2857,7 @@ func ValidatePublicCluster(t *testing.T, ctx context.Context, client crclient.Cl } // Wait for Nodes to be Ready - numNodes := clusterOpts.NodePoolReplicas * int32(len(clusterOpts.AWSPlatform.Zones)) + numNodes := numExpectedNodes(clusterOpts, hostedCluster.Spec.Platform.Type) WaitForNReadyNodes(t, ctx, guestClient, numNodes, hostedCluster.Spec.Platform.Type) // rollout will not complete if there are no worker nodes. @@ -2910,7 +2910,7 @@ func ValidatePrivateCluster(t *testing.T, ctx context.Context, client crclient.C // Ensure NodePools have all Nodes ready. WaitForNodePoolDesiredNodes(t, ctx, client, hostedCluster) - numNodes := clusterOpts.NodePoolReplicas * int32(len(clusterOpts.AWSPlatform.Zones)) + numNodes := numExpectedNodes(clusterOpts, hostedCluster.Spec.Platform.Type) // rollout will not complete if there are no worker nodes. if numNodes > 0 { WaitForImageRollout(t, ctx, client, hostedCluster)