Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions bmc/mock/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ func (s *MockServer) redfishHandler(w http.ResponseWriter, r *http.Request) {
s.handleRedfishPOST(w, r)
case http.MethodPatch:
s.handleRedfishPATCH(w, r)
case http.MethodDelete:
s.handleRedfishDELETE(w, r)
default:
http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
}
Expand Down Expand Up @@ -155,6 +157,42 @@ func (s *MockServer) handleRedfishPATCH(w http.ResponseWriter, r *http.Request)
w.WriteHeader(http.StatusNoContent)
}

func (s *MockServer) handleRedfishDELETE(w http.ResponseWriter, r *http.Request) {
s.log.Info("Received request", "method", r.Method, "path", r.URL.Path, "address", s.addr)

urlPath := resolvePath(r.URL.Path)

// Load existing resource: from override if exists, else embedded
base, err := fetchCurrentDataForPath(s, urlPath)
if err != nil {
switch {
case strings.Contains(err.Error(), "resource not found"):
http.NotFound(w, r)
return
case strings.Contains(err.Error(), "corrupt embedded JSON"):
http.Error(w, err.Error(), http.StatusInternalServerError)
return
default:
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}

// If it's a Collection (has "Members"), reject
if _, isCollection := base["Members"]; isCollection {
http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
return
}

s.mu.Lock()
defer s.mu.Unlock()

// Remove the override to revert to embedded JSON
delete(s.overrides, urlPath)

w.WriteHeader(http.StatusNoContent)
}

func deepCopy(m map[string]any) map[string]any {
c := make(map[string]any)
for k, v := range m {
Expand Down
18 changes: 16 additions & 2 deletions internal/controller/biossettings_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,8 @@ func (r *BIOSSettingsReconciler) handleSettingPendingState(ctx context.Context,
}

if len(pendingSettings) > 0 {
log.V(1).Info("Pending BIOS setting tasks found", "TaskCound", len(pendingSettings))
log.V(1).Info("Pending BIOS setting tasks found", "TaskCount", len(pendingSettings))

pendingSettingStateCheckCondition, err := GetCondition(r.Conditions, settings.Status.Conditions, BIOSPendingSettingConditionCheck)
if err != nil {
return ctrl.Result{}, fmt.Errorf("failed to get Condition for pending BIOSSettings state %w", err)
Expand Down Expand Up @@ -964,8 +965,21 @@ func (r *BIOSSettingsReconciler) handleFailedState(ctx context.Context, log logr
return ctrl.Result{}, nil
}

// todo: revisit this logic to either create maintenance if not present, put server in Error state on failed bios settings maintenance
log.V(1).Info("Failed to update BIOS settings", "Server", server.Name)

// Create maintenance object only if failure is due to pending settings and maintenance not already present
if settings.Spec.ServerMaintenanceRef == nil {
// Check if the failure is due to pending settings
for _, condition := range settings.Status.Conditions {
if condition.Type == BIOSPendingSettingConditionCheck && condition.Status == metav1.ConditionTrue {
if _, err := r.requestMaintenanceForServer(ctx, log, settings, server); err != nil {
return ctrl.Result{}, err
}
break
}
}
}

return ctrl.Result{}, nil
}

Expand Down
144 changes: 138 additions & 6 deletions internal/controller/biossettings_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
package controller

import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"time"

"github.com/ironcore-dev/controller-utils/metautils"
Expand Down Expand Up @@ -56,9 +59,9 @@ var _ = Describe("BIOSSettings Controller", func() {
BMC: &metalv1alpha1.BMCAccess{
Protocol: metalv1alpha1.Protocol{
Name: metalv1alpha1.ProtocolRedfishLocal,
Port: 8000,
Port: MockServerPort,
},
Address: "127.0.0.1",
Address: MockServerIP,
BMCSecretRef: v1.LocalObjectReference{
Name: bmcSecret.Name,
},
Expand Down Expand Up @@ -907,12 +910,12 @@ var _ = Describe("BIOSSettings Controller with BMCRef BMC", func() {
},
Spec: metalv1alpha1.BMCSpec{
Endpoint: &metalv1alpha1.InlineEndpoint{
IP: metalv1alpha1.MustParseIP("127.0.0.1"),
IP: metalv1alpha1.MustParseIP(MockServerIP),
MACAddress: "23:11:8A:33:CF:EA",
},
Protocol: metalv1alpha1.Protocol{
Name: metalv1alpha1.ProtocolRedfishLocal,
Port: 8000,
Port: MockServerPort,
},
BMCSecretRef: v1.LocalObjectReference{
Name: bmcSecret.Name,
Expand Down Expand Up @@ -1090,6 +1093,135 @@ var _ = Describe("BIOSSettings Controller with BMCRef BMC", func() {
HaveField("Status.State", Not(Equal(metalv1alpha1.ServerStateReserved))),
))
})

It("Should fail and create maintenance when pending settings exist", func(ctx SpecContext) {
By("Ensuring BMC is in Enabled state")
Eventually(UpdateStatus(bmcObj, func() {
bmcObj.Status.State = metalv1alpha1.BMCStateEnabled
})).To(Succeed())

biosSetting := make(map[string]string)
biosSetting["EmbeddedSata"] = "Raid"

By("Creating an Ignition secret")
ignitionSecret := &v1.Secret{
ObjectMeta: metav1.ObjectMeta{
Namespace: ns.Name,
GenerateName: "test-",
},
Data: nil,
}
Expect(k8sClient.Create(ctx, ignitionSecret)).To(Succeed())

By("Creating a ServerClaim")
serverClaim := &metalv1alpha1.ServerClaim{
ObjectMeta: metav1.ObjectMeta{
Namespace: ns.Name,
GenerateName: "test-",
},
Spec: metalv1alpha1.ServerClaimSpec{
Power: metalv1alpha1.PowerOff,
ServerRef: &v1.LocalObjectReference{Name: server.Name},
IgnitionSecretRef: &v1.LocalObjectReference{Name: ignitionSecret.Name},
Image: "foo:bar",
},
}
Expect(k8sClient.Create(ctx, serverClaim)).To(Succeed())

By("Ensuring that the Server has been claimed")
Eventually(Object(server)).Should(
HaveField("Status.State", metalv1alpha1.ServerStateReserved),
)

By("Creating pending changes on the mock server via HTTP PATCH")
pendingSettingsURL := fmt.Sprintf("http://%s:%d/redfish/v1/Systems/437XR1138R2/Bios/Settings", MockServerIP, MockServerPort)
pendingData := map[string]any{
"Attributes": map[string]any{
"PendingSetting1": "PendingValue1",
},
}
pendingBody, err := json.Marshal(pendingData)
Expect(err).NotTo(HaveOccurred())

req, err := http.NewRequestWithContext(ctx, http.MethodPatch, pendingSettingsURL, bytes.NewReader(pendingBody))
Expect(err).NotTo(HaveOccurred())
req.Header.Set("Content-Type", "application/json")

client := &http.Client{
Timeout: 5 * time.Second,
}
Comment thread
xkonni marked this conversation as resolved.
resp, err := client.Do(req)
Expect(err).NotTo(HaveOccurred())
DeferCleanup(resp.Body.Close)
Expect(resp.StatusCode).To(BeElementOf(http.StatusOK, http.StatusNoContent, http.StatusAccepted))

By("Creating BIOSSettings to apply new changes")
biosSettings := &metalv1alpha1.BIOSSettings{
ObjectMeta: metav1.ObjectMeta{
GenerateName: "test-pending-changes",
Namespace: ns.Name,
},
Spec: metalv1alpha1.BIOSSettingsSpec{
BIOSSettingsTemplate: metalv1alpha1.BIOSSettingsTemplate{
Version: defaultMockUpServerBiosVersion,
SettingsFlow: []metalv1alpha1.SettingsFlowItem{{
Settings: biosSetting,
Priority: 1,
Name: "one",
}},
ServerMaintenancePolicy: metalv1alpha1.ServerMaintenancePolicyOwnerApproval,
},
ServerRef: &v1.LocalObjectReference{Name: server.Name},
},
}
Expect(k8sClient.Create(ctx, biosSettings)).To(Succeed())

By("Ensuring BIOSSettings transitions to Failed state")
Eventually(Object(biosSettings)).Should(
HaveField("Status.State", metalv1alpha1.BIOSSettingsStateFailed),
)

By("Verifying ServerMaintenance object was created")
serverMaintenance := &metalv1alpha1.ServerMaintenance{
ObjectMeta: metav1.ObjectMeta{
Namespace: ns.Name,
Name: biosSettings.Name,
},
}
Eventually(Get(serverMaintenance)).Should(Succeed())

By("Verifying BIOSSettings has maintenance reference")
Eventually(Object(biosSettings)).Should(
HaveField("Spec.ServerMaintenanceRef", Not(BeNil())),
)

By("Clearing pending changes on the mock server via HTTP DELETE")
clearPendingURL := fmt.Sprintf("http://%s:%d/redfish/v1/Systems/437XR1138R2/Bios/Settings", MockServerIP, MockServerPort)
clearReq, err := http.NewRequestWithContext(ctx, http.MethodDelete, clearPendingURL, nil)
Expect(err).NotTo(HaveOccurred())

clearResp, err := client.Do(clearReq)
Expect(err).NotTo(HaveOccurred())
DeferCleanup(clearResp.Body.Close)
Expect(clearResp.StatusCode).To(BeElementOf(http.StatusOK, http.StatusNoContent, http.StatusAccepted))

By("Cleaning up BIOSSettings")
Expect(k8sClient.Delete(ctx, biosSettings)).To(Succeed())

By("Cleaning up ServerMaintenance")
Expect(k8sClient.Delete(ctx, serverMaintenance)).Should(Succeed())

By("Waiting for Server to exit Maintenance state")
Eventually(Object(server)).Should(
HaveField("Status.State", Not(Equal(metalv1alpha1.ServerStateMaintenance))),
)

By("Cleaning up ServerClaim")
Expect(k8sClient.Delete(ctx, serverClaim)).Should(Succeed())

By("Cleaning up Ignition secret")
Expect(k8sClient.Delete(ctx, ignitionSecret)).Should(Succeed())
})
Comment on lines +1097 to +1224
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Make the new test deterministic: wait for mock server readiness + make cleanup NotFound-safe.

Right now the HTTP PATCH/DELETE are single-shot; if the mock server isn’t listening yet, this can flake. Also, explicitly deleting ServerMaintenance can race controller cleanup and fail with NotFound. As per coding guidelines, tests must be deterministic and not rely on timing assumptions.

Suggested adjustments (minimal, local to this test)
-		client := &http.Client{
+		httpClient := &http.Client{
 			Timeout: 5 * time.Second,
 		}
-		resp, err := client.Do(req)
+
+		By("Waiting for mock server readiness")
+		Eventually(func() error {
+			readyURL := fmt.Sprintf("http://%s:%d/redfish/v1/", MockServerIP, MockServerPort)
+			readyReq, err := http.NewRequestWithContext(ctx, http.MethodGet, readyURL, nil)
+			if err != nil {
+				return err
+			}
+			readyResp, err := httpClient.Do(readyReq)
+			if err != nil {
+				return err
+			}
+			_ = readyResp.Body.Close()
+			if readyResp.StatusCode >= 400 {
+				return fmt.Errorf("mock server not ready: %d", readyResp.StatusCode)
+			}
+			return nil
+		}).Should(Succeed())
+
+		resp, err := httpClient.Do(req)
 		Expect(err).NotTo(HaveOccurred())
 		defer resp.Body.Close()
-		Expect(resp.StatusCode).To(BeElementOf(http.StatusOK, http.StatusNoContent, http.StatusAccepted))
+		Expect(resp.StatusCode).To(Equal(http.StatusNoContent))
@@
-		clearResp, err := client.Do(clearReq)
+		clearResp, err := httpClient.Do(clearReq)
 		Expect(err).NotTo(HaveOccurred())
 		defer clearResp.Body.Close()
-		Expect(clearResp.StatusCode).To(BeElementOf(http.StatusOK, http.StatusNoContent, http.StatusAccepted))
+		Expect(clearResp.StatusCode).To(Equal(http.StatusNoContent))
@@
-		By("Cleaning up ServerMaintenance")
-		Expect(k8sClient.Delete(ctx, serverMaintenance)).Should(Succeed())
+		By("Cleaning up ServerMaintenance")
+		if err := k8sClient.Delete(ctx, serverMaintenance); err != nil && !apierrors.IsNotFound(err) {
+			Expect(err).NotTo(HaveOccurred())
+		}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
It("Should fail and create maintenance when pending settings exist", func(ctx SpecContext) {
By("Ensuring BMC is in Enabled state")
Eventually(UpdateStatus(bmcObj, func() {
bmcObj.Status.State = metalv1alpha1.BMCStateEnabled
})).To(Succeed())
biosSetting := make(map[string]string)
biosSetting["EmbeddedSata"] = "Raid"
By("Creating an Ignition secret")
ignitionSecret := &v1.Secret{
ObjectMeta: metav1.ObjectMeta{
Namespace: ns.Name,
GenerateName: "test-",
},
Data: nil,
}
Expect(k8sClient.Create(ctx, ignitionSecret)).To(Succeed())
By("Creating a ServerClaim")
serverClaim := &metalv1alpha1.ServerClaim{
ObjectMeta: metav1.ObjectMeta{
Namespace: ns.Name,
GenerateName: "test-",
},
Spec: metalv1alpha1.ServerClaimSpec{
Power: metalv1alpha1.PowerOff,
ServerRef: &v1.LocalObjectReference{Name: server.Name},
IgnitionSecretRef: &v1.LocalObjectReference{Name: ignitionSecret.Name},
Image: "foo:bar",
},
}
Expect(k8sClient.Create(ctx, serverClaim)).To(Succeed())
By("Ensuring that the Server has been claimed")
Eventually(Object(server)).Should(
HaveField("Status.State", metalv1alpha1.ServerStateReserved),
)
By("Creating pending changes on the mock server via HTTP PATCH")
pendingSettingsURL := fmt.Sprintf("http://%s:%d/redfish/v1/Systems/437XR1138R2/Bios/Settings", MockServerIP, MockServerPort)
pendingData := map[string]interface{}{
"Attributes": map[string]interface{}{
"PendingSetting1": "PendingValue1",
},
}
pendingBody, err := json.Marshal(pendingData)
Expect(err).NotTo(HaveOccurred())
req, err := http.NewRequestWithContext(ctx, http.MethodPatch, pendingSettingsURL, bytes.NewReader(pendingBody))
Expect(err).NotTo(HaveOccurred())
req.Header.Set("Content-Type", "application/json")
client := &http.Client{
Timeout: 5 * time.Second,
}
resp, err := client.Do(req)
Expect(err).NotTo(HaveOccurred())
defer resp.Body.Close()
Expect(resp.StatusCode).To(BeElementOf(http.StatusOK, http.StatusNoContent, http.StatusAccepted))
By("Creating BIOSSettings to apply new changes")
biosSettings := &metalv1alpha1.BIOSSettings{
ObjectMeta: metav1.ObjectMeta{
GenerateName: "test-pending-changes",
Namespace: ns.Name,
},
Spec: metalv1alpha1.BIOSSettingsSpec{
BIOSSettingsTemplate: metalv1alpha1.BIOSSettingsTemplate{
Version: defaultMockUpServerBiosVersion,
SettingsFlow: []metalv1alpha1.SettingsFlowItem{{
Settings: biosSetting,
Priority: 1,
Name: "one",
}},
ServerMaintenancePolicy: metalv1alpha1.ServerMaintenancePolicyOwnerApproval,
},
ServerRef: &v1.LocalObjectReference{Name: server.Name},
},
}
Expect(k8sClient.Create(ctx, biosSettings)).To(Succeed())
By("Approving the ServerClaim maintenance")
Eventually(Update(serverClaim, func() {
metautils.SetAnnotation(serverClaim, metalv1alpha1.ServerMaintenanceApprovalKey, "true")
})).Should(Succeed())
By("Ensuring BIOSSettings transitions to Failed state")
Eventually(Object(biosSettings)).Should(
HaveField("Status.State", metalv1alpha1.BIOSSettingsStateFailed),
)
By("Verifying ServerMaintenance object was created")
serverMaintenance := &metalv1alpha1.ServerMaintenance{
ObjectMeta: metav1.ObjectMeta{
Namespace: ns.Name,
Name: biosSettings.Name,
},
}
Eventually(Get(serverMaintenance)).Should(Succeed())
By("Verifying BIOSSettings has maintenance reference")
Eventually(Object(biosSettings)).Should(
HaveField("Spec.ServerMaintenanceRef", Not(BeNil())),
)
By("Clearing pending changes on the mock server via HTTP DELETE")
clearPendingURL := fmt.Sprintf("http://%s:%d/redfish/v1/Systems/437XR1138R2/Bios/Settings", MockServerIP, MockServerPort)
clearReq, err := http.NewRequestWithContext(ctx, http.MethodDelete, clearPendingURL, nil)
Expect(err).NotTo(HaveOccurred())
clearResp, err := client.Do(clearReq)
Expect(err).NotTo(HaveOccurred())
defer clearResp.Body.Close()
Expect(clearResp.StatusCode).To(BeElementOf(http.StatusOK, http.StatusNoContent, http.StatusAccepted))
By("Cleaning up BIOSSettings")
Expect(k8sClient.Delete(ctx, biosSettings)).To(Succeed())
By("Cleaning up ServerMaintenance")
Expect(k8sClient.Delete(ctx, serverMaintenance)).Should(Succeed())
By("Waiting for Server to exit Maintenance state")
Eventually(Object(server)).Should(
HaveField("Status.State", Not(Equal(metalv1alpha1.ServerStateMaintenance))),
)
By("Cleaning up ServerClaim")
Expect(k8sClient.Delete(ctx, serverClaim)).Should(Succeed())
By("Cleaning up Ignition secret")
Expect(k8sClient.Delete(ctx, ignitionSecret)).Should(Succeed())
})
It("Should fail and create maintenance when pending settings exist", func(ctx SpecContext) {
By("Ensuring BMC is in Enabled state")
Eventually(UpdateStatus(bmcObj, func() {
bmcObj.Status.State = metalv1alpha1.BMCStateEnabled
})).To(Succeed())
biosSetting := make(map[string]string)
biosSetting["EmbeddedSata"] = "Raid"
By("Creating an Ignition secret")
ignitionSecret := &v1.Secret{
ObjectMeta: metav1.ObjectMeta{
Namespace: ns.Name,
GenerateName: "test-",
},
Data: nil,
}
Expect(k8sClient.Create(ctx, ignitionSecret)).To(Succeed())
By("Creating a ServerClaim")
serverClaim := &metalv1alpha1.ServerClaim{
ObjectMeta: metav1.ObjectMeta{
Namespace: ns.Name,
GenerateName: "test-",
},
Spec: metalv1alpha1.ServerClaimSpec{
Power: metalv1alpha1.PowerOff,
ServerRef: &v1.LocalObjectReference{Name: server.Name},
IgnitionSecretRef: &v1.LocalObjectReference{Name: ignitionSecret.Name},
Image: "foo:bar",
},
}
Expect(k8sClient.Create(ctx, serverClaim)).To(Succeed())
By("Ensuring that the Server has been claimed")
Eventually(Object(server)).Should(
HaveField("Status.State", metalv1alpha1.ServerStateReserved),
)
By("Creating pending changes on the mock server via HTTP PATCH")
pendingSettingsURL := fmt.Sprintf("http://%s:%d/redfish/v1/Systems/437XR1138R2/Bios/Settings", MockServerIP, MockServerPort)
pendingData := map[string]interface{}{
"Attributes": map[string]interface{}{
"PendingSetting1": "PendingValue1",
},
}
pendingBody, err := json.Marshal(pendingData)
Expect(err).NotTo(HaveOccurred())
req, err := http.NewRequestWithContext(ctx, http.MethodPatch, pendingSettingsURL, bytes.NewReader(pendingBody))
Expect(err).NotTo(HaveOccurred())
req.Header.Set("Content-Type", "application/json")
httpClient := &http.Client{
Timeout: 5 * time.Second,
}
By("Waiting for mock server readiness")
Eventually(func() error {
readyURL := fmt.Sprintf("http://%s:%d/redfish/v1/", MockServerIP, MockServerPort)
readyReq, err := http.NewRequestWithContext(ctx, http.MethodGet, readyURL, nil)
if err != nil {
return err
}
readyResp, err := httpClient.Do(readyReq)
if err != nil {
return err
}
_ = readyResp.Body.Close()
if readyResp.StatusCode >= 400 {
return fmt.Errorf("mock server not ready: %d", readyResp.StatusCode)
}
return nil
}).Should(Succeed())
resp, err := httpClient.Do(req)
Expect(err).NotTo(HaveOccurred())
defer resp.Body.Close()
Expect(resp.StatusCode).To(Equal(http.StatusNoContent))
By("Creating BIOSSettings to apply new changes")
biosSettings := &metalv1alpha1.BIOSSettings{
ObjectMeta: metav1.ObjectMeta{
GenerateName: "test-pending-changes",
Namespace: ns.Name,
},
Spec: metalv1alpha1.BIOSSettingsSpec{
BIOSSettingsTemplate: metalv1alpha1.BIOSSettingsTemplate{
Version: defaultMockUpServerBiosVersion,
SettingsFlow: []metalv1alpha1.SettingsFlowItem{{
Settings: biosSetting,
Priority: 1,
Name: "one",
}},
ServerMaintenancePolicy: metalv1alpha1.ServerMaintenancePolicyOwnerApproval,
},
ServerRef: &v1.LocalObjectReference{Name: server.Name},
},
}
Expect(k8sClient.Create(ctx, biosSettings)).To(Succeed())
By("Approving the ServerClaim maintenance")
Eventually(Update(serverClaim, func() {
metautils.SetAnnotation(serverClaim, metalv1alpha1.ServerMaintenanceApprovalKey, "true")
})).Should(Succeed())
By("Ensuring BIOSSettings transitions to Failed state")
Eventually(Object(biosSettings)).Should(
HaveField("Status.State", metalv1alpha1.BIOSSettingsStateFailed),
)
By("Verifying ServerMaintenance object was created")
serverMaintenance := &metalv1alpha1.ServerMaintenance{
ObjectMeta: metav1.ObjectMeta{
Namespace: ns.Name,
Name: biosSettings.Name,
},
}
Eventually(Get(serverMaintenance)).Should(Succeed())
By("Verifying BIOSSettings has maintenance reference")
Eventually(Object(biosSettings)).Should(
HaveField("Spec.ServerMaintenanceRef", Not(BeNil())),
)
By("Clearing pending changes on the mock server via HTTP DELETE")
clearPendingURL := fmt.Sprintf("http://%s:%d/redfish/v1/Systems/437XR1138R2/Bios/Settings", MockServerIP, MockServerPort)
clearReq, err := http.NewRequestWithContext(ctx, http.MethodDelete, clearPendingURL, nil)
Expect(err).NotTo(HaveOccurred())
clearResp, err := httpClient.Do(clearReq)
Expect(err).NotTo(HaveOccurred())
defer clearResp.Body.Close()
Expect(clearResp.StatusCode).To(Equal(http.StatusNoContent))
By("Cleaning up BIOSSettings")
Expect(k8sClient.Delete(ctx, biosSettings)).To(Succeed())
By("Cleaning up ServerMaintenance")
if err := k8sClient.Delete(ctx, serverMaintenance); err != nil && !apierrors.IsNotFound(err) {
Expect(err).NotTo(HaveOccurred())
}
By("Waiting for Server to exit Maintenance state")
Eventually(Object(server)).Should(
HaveField("Status.State", Not(Equal(metalv1alpha1.ServerStateMaintenance))),
)
By("Cleaning up ServerClaim")
Expect(k8sClient.Delete(ctx, serverClaim)).Should(Succeed())
By("Cleaning up Ignition secret")
Expect(k8sClient.Delete(ctx, ignitionSecret)).Should(Succeed())
})

})

var _ = Describe("BIOSSettings Sequence Controller", func() {
Expand Down Expand Up @@ -1125,9 +1257,9 @@ var _ = Describe("BIOSSettings Sequence Controller", func() {
BMC: &metalv1alpha1.BMCAccess{
Protocol: metalv1alpha1.Protocol{
Name: metalv1alpha1.ProtocolRedfishLocal,
Port: 8000,
Port: MockServerPort,
},
Address: "127.0.0.1",
Address: MockServerIP,
BMCSecretRef: v1.LocalObjectReference{
Name: bmcSecret.Name,
},
Expand Down
6 changes: 4 additions & 2 deletions internal/controller/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ const (
pollingInterval = 50 * time.Millisecond
eventuallyTimeout = 5 * time.Second
consistentlyDuration = 1 * time.Second
MockServerIP = "127.0.0.1"
MockServerPort = 8000
)

var (
Expand Down Expand Up @@ -138,7 +140,7 @@ func SetupTest(redfishMockServers []netip.AddrPort) *corev1.Namespace {
MacPrefix: "23",
Manufacturer: "Foo",
Protocol: "RedfishLocal",
Port: 8000,
Port: MockServerPort,
Type: "bmc",
DefaultCredentials: []macdb.Credential{
{
Expand Down Expand Up @@ -309,7 +311,7 @@ func SetupTest(redfishMockServers []netip.AddrPort) *corev1.Namespace {
} else {
By("Starting the default mock Redfish server")
Expect(k8sManager.Add(manager.RunnableFunc(func(ctx context.Context) error {
mockServer := server.NewMockServer(GinkgoLogr, ":8000")
mockServer := server.NewMockServer(GinkgoLogr, fmt.Sprintf(":%d", MockServerPort))
if err := mockServer.Start(ctx); err != nil {
return fmt.Errorf("failed to start mock Redfish server: %w", err)
}
Expand Down
Loading