Repository: metal3-io/baremetal-operator

Issue:
Enable "forcetypeassert" linter in golangci-lint
Enable "forcetypeassert" linter in golangci-lint. Fix any warnings enabling it causes.

/area ci
/help
/triage accepted

Hints from issue comments:
@metal3-io-bot: @tuminoid: 
	This request has been marked as needing help from a contributor.

Please ensure the request meets the requirements listed [here](https://git.k8s.io/community/contributors/guide/help-wanted.md).

If this request no longer meets these requirements, the label can be removed
by commenting with the `/remove-help` command.


<details>

In response to [this](https://github.com/metal3-io/baremetal-operator/issues/2357):

>Enable "forcetypeassert" linter in golangci-lint. Fix any warnings enabling it causes.
>
>/area ci
>/help
>/triage accepted


Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes-sigs/prow](https://github.com/kubernetes-sigs/prow/issues/new?title=Prow%20issue:) repository.
</details>@metal3-io-bot: @tuminoid: The label(s) `area/ci` cannot be applied, because the repository doesn't have them.

<details>

In response to [this](https://github.com/metal3-io/baremetal-operator/issues/2357):

>Enable "forcetypeassert" linter in golangci-lint. Fix any warnings enabling it causes.
>
>/area ci
>/help
>/triage accepted


Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes-sigs/prow](https://github.com/kubernetes-sigs/prow/issues/new?title=Prow%20issue:) repository.
</details>

Solution patch:
diff --git a/.golangci.yaml b/.golangci.yaml
index 5d6ae292..03d57a45 100644
--- a/.golangci.yaml
+++ b/.golangci.yaml
@@ -25,7 +25,7 @@ linters:
   - exptostd
   - fatcontext
   - forbidigo
-  #- forcetypeassert
+  - forcetypeassert
   - gci
   - ginkgolinter
   - gocheckcompilerdirectives
diff --git a/pkg/provisioner/ironic/capabilities.go b/pkg/provisioner/ironic/capabilities.go
index 7b11240c..ca20c098 100644
--- a/pkg/provisioner/ironic/capabilities.go
+++ b/pkg/provisioner/ironic/capabilities.go
@@ -30,7 +30,12 @@ func buildCapabilitiesValue(ironicNode *nodes.Node, bootMode metal3api.BootMode)
 		// There is no existing capabilities value
 		return bootModeCapabilities[bootMode]
 	}
-	existingCapabilities := capabilities.(string)
+	existingCapabilities, ok := capabilities.(string)
+	if !ok {
+		// The existing value is not a string, so we can replace
+		// the whole thing.
+		return bootModeCapabilities[bootMode]
+	}
 
 	if existingCapabilities == "" {
 		// The existing value is empty so we can replace the whole



Test patch:
diff --git a/internal/controller/metal3.io/baremetalhost_controller_test.go b/internal/controller/metal3.io/baremetalhost_controller_test.go
index 2f07aece..d206dec6 100644
--- a/internal/controller/metal3.io/baremetalhost_controller_test.go
+++ b/internal/controller/metal3.io/baremetalhost_controller_test.go
@@ -136,10 +136,13 @@ func newDefaultHost(t *testing.T) *metal3api.BareMetalHost {
 	return newDefaultNamedHost(t, t.Name())
 }
 
-func newTestReconcilerWithFixture(fix *fixture.Fixture, initObjs ...runtime.Object) *BareMetalHostReconciler {
+func newTestReconcilerWithFixture(t *testing.T, fix *fixture.Fixture, initObjs ...runtime.Object) *BareMetalHostReconciler {
+	t.Helper()
 	clientBuilder := fakeclient.NewClientBuilder().WithRuntimeObjects(initObjs...)
 	for _, v := range initObjs {
-		clientBuilder = clientBuilder.WithStatusSubresource(v.(client.Object))
+		object, ok := v.(client.Object)
+		require.True(t, ok, "failed to cast object to client.Object")
+		clientBuilder = clientBuilder.WithStatusSubresource(object)
 	}
 	c := clientBuilder.Build()
 	// Add a default secret that can be used by most hosts.
@@ -154,9 +157,10 @@ func newTestReconcilerWithFixture(fix *fixture.Fixture, initObjs ...runtime.Obje
 	}
 }
 
-func newTestReconciler(initObjs ...runtime.Object) *BareMetalHostReconciler {
+func newTestReconciler(t *testing.T, initObjs ...runtime.Object) *BareMetalHostReconciler {
+	t.Helper()
 	fix := fixture.Fixture{}
-	return newTestReconcilerWithFixture(&fix, initObjs...)
+	return newTestReconcilerWithFixture(t, &fix, initObjs...)
 }
 
 type DoneFunc func(host *metal3api.BareMetalHost, result reconcile.Result) bool
@@ -257,7 +261,7 @@ func TestHardwareDetails_EmptyStatus(t *testing.T) {
 		metal3api.HardwareDetailsAnnotation: hwdAnnotation,
 	}
 
-	r := newTestReconciler(host)
+	r := newTestReconciler(t, host)
 
 	tryReconcile(t, r, host,
 		func(host *metal3api.BareMetalHost, result reconcile.Result) bool {
@@ -283,7 +287,7 @@ func TestHardwareDetails_StatusPresent(t *testing.T) {
 	hwd.Hostname = "existinghost"
 	host.Status.HardwareDetails = &hwd
 
-	r := newTestReconciler(host)
+	r := newTestReconciler(t, host)
 
 	tryReconcile(t, r, host,
 		func(host *metal3api.BareMetalHost, result reconcile.Result) bool {
@@ -311,7 +315,7 @@ func TestHardwareDetails_StatusPresentInspectDisabled(t *testing.T) {
 	hwd.Hostname = "existinghost"
 	host.Status.HardwareDetails = &hwd
 
-	r := newTestReconciler(host)
+	r := newTestReconciler(t, host)
 
 	tryReconcile(t, r, host,
 		func(host *metal3api.BareMetalHost, result reconcile.Result) bool {
@@ -339,7 +343,7 @@ func TestHardwareDetails_Invalid(t *testing.T) {
 	hwd.Hostname = "existinghost"
 	host.Status.HardwareDetails = &hwd
 
-	r := newTestReconciler(host)
+	r := newTestReconciler(t, host)
 	request := newRequest(host)
 	_, err := r.Reconcile(context.Background(), request)
 	expectedErr := "json: unknown field"
@@ -356,7 +360,7 @@ func TestStatusAnnotation_EmptyStatus(t *testing.T) {
 	host.Spec.Online = true
 	host.Spec.Image = &metal3api.Image{URL: "foo", Checksum: "123"}
 
-	r := newTestReconciler(host)
+	r := newTestReconciler(t, host)
 
 	tryReconcile(t, r, host,
 		func(host *metal3api.BareMetalHost, result reconcile.Result) bool {
@@ -380,7 +384,7 @@ func TestStatusAnnotation_StatusPresent(t *testing.T) {
 	time := metav1.Now()
 	host.Status.LastUpdated = &time
 	host.Status.Provisioning.Image = metal3api.Image{URL: "foo", Checksum: "123"}
-	r := newTestReconciler(host)
+	r := newTestReconciler(t, host)
 
 	tryReconcile(t, r, host,
 		func(host *metal3api.BareMetalHost, result reconcile.Result) bool {
@@ -418,7 +422,7 @@ func TestStatusAnnotation_Partial(t *testing.T) {
 	host.Spec.Online = true
 	host.Spec.Image = &metal3api.Image{URL: "foo", Checksum: "123"}
 
-	r := newTestReconciler(host)
+	r := newTestReconciler(t, host)
 
 	tryReconcile(t, r, host,
 		func(host *metal3api.BareMetalHost, result reconcile.Result) bool {
@@ -454,7 +458,7 @@ func TestHardwareDataExist(t *testing.T) {
 		},
 	}
 
-	r := newTestReconciler(host, hardwareData)
+	r := newTestReconciler(t, host, hardwareData)
 
 	tryReconcile(t, r, host,
 		func(host *metal3api.BareMetalHost, result reconcile.Result) bool {
@@ -473,7 +477,7 @@ func TestPause(t *testing.T) {
 	host.Annotations = map[string]string{
 		metal3api.PausedAnnotation: "true",
 	}
-	r := newTestReconciler(host)
+	r := newTestReconciler(t, host)
 
 	tryReconcile(t, r, host,
 		func(host *metal3api.BareMetalHost, result reconcile.Result) bool {
@@ -495,7 +499,7 @@ func TestInspectDisabled(t *testing.T) {
 	host.Annotations = map[string]string{
 		metal3api.InspectAnnotationPrefix: "disabled",
 	}
-	r := newTestReconciler(host)
+	r := newTestReconciler(t, host)
 	waitForProvisioningState(t, r, host, metal3api.StatePreparing)
 	assert.Nil(t, host.Status.HardwareDetails)
 }
@@ -503,7 +507,7 @@ func TestInspectDisabled(t *testing.T) {
 // TestInspectEnabled ensures that Inspection is completed when not disabled.
 func TestInspectEnabled(t *testing.T) {
 	host := newDefaultHost(t)
-	r := newTestReconciler(host)
+	r := newTestReconciler(t, host)
 	waitForProvisioningState(t, r, host, metal3api.StatePreparing)
 	assert.NotNil(t, host.Status.HardwareDetails)
 }
@@ -512,7 +516,7 @@ func TestInspectEnabled(t *testing.T) {
 // updated as part of reconciling it.
 func TestAddFinalizers(t *testing.T) {
 	host := newDefaultHost(t)
-	r := newTestReconciler(host)
+	r := newTestReconciler(t, host)
 
 	tryReconcile(t, r, host,
 		func(host *metal3api.BareMetalHost, result reconcile.Result) bool {
@@ -534,7 +538,7 @@ func TestAddFinalizers(t *testing.T) {
 // then the secret finalizer is not added again.
 func TestDoNotAddSecretFinalizersDuringDelete(t *testing.T) {
 	host := newDefaultHost(t)
-	r := newTestReconciler(host)
+	r := newTestReconciler(t, host)
 
 	// Let the host reach the available state before deleting it
 	waitForProvisioningState(t, r, host, metal3api.StateAvailable)
@@ -578,7 +582,7 @@ func TestDoNotAddSecretFinalizersDuringDelete(t *testing.T) {
 // status is set to a non-zero value during reconciliation.
 func TestSetLastUpdated(t *testing.T) {
 	host := newDefaultHost(t)
-	r := newTestReconciler(host)
+	r := newTestReconciler(t, host)
 
 	tryReconcile(t, r, host,
 		func(host *metal3api.BareMetalHost, result reconcile.Result) bool {
@@ -718,7 +722,7 @@ func TestRebootWithSuffixlessAnnotation(t *testing.T) {
 	host.Spec.Image.URL = "foo"
 	host.Status.Provisioning.Image.URL = "foo"
 
-	r := newTestReconciler(host)
+	r := newTestReconciler(t, host)
 
 	tryReconcile(t, r, host,
 		func(host *metal3api.BareMetalHost, result reconcile.Result) bool {
@@ -764,7 +768,7 @@ func TestRebootWithSuffixedAnnotation(t *testing.T) {
 	host.Spec.Image.URL = "foo"
 	host.Status.Provisioning.Image.URL = "foo"
 
-	r := newTestReconciler(host)
+	r := newTestReconciler(t, host)
 
 	tryReconcile(t, r, host,
 		func(host *metal3api.BareMetalHost, result reconcile.Result) bool {
@@ -810,7 +814,7 @@ func TestRebootWithSuffixedAnnotationPowerOffDisabled(t *testing.T) {
 	host.Spec.DisablePowerOff = true
 
 	fix := fixture.Fixture{DisablePowerOff: true, PoweredOn: true}
-	r := newTestReconcilerWithFixture(&fix, host)
+	r := newTestReconcilerWithFixture(t, &fix, host)
 
 	// bmh reconcils until credentials are verified as valid
 	tryReconcile(t, r, host,
@@ -867,7 +871,7 @@ func TestRebootWithServicing(t *testing.T) {
 		},
 	}
 
-	r := newTestReconciler(host, hup)
+	r := newTestReconciler(t, host, hup)
 
 	tryReconcile(t, r, host,
 		func(host *metal3api.BareMetalHost, result reconcile.Result) bool {
@@ -923,7 +927,7 @@ func TestRebootWithoutServicing(t *testing.T) {
 		VirtualizationEnabled: ptr.To(true),
 	}
 
-	r := newTestReconciler(host)
+	r := newTestReconciler(t, host)
 
 	tryReconcile(t, r, host,
 		func(host *metal3api.BareMetalHost, result reconcile.Result) bool {
@@ -971,7 +975,7 @@ func getHostSecret(t *testing.T, r *BareMetalHostReconciler, host *metal3api.Bar
 
 func TestSecretUpdateOwnerRefAndEnvironmentLabelOnStartup(t *testing.T) {
 	host := newDefaultHost(t)
-	r := newTestReconciler(host)
+	r := newTestReconciler(t, host)
 
 	secret := getHostSecret(t, r, host)
 	assert.Empty(t, secret.OwnerReferences)
@@ -992,7 +996,7 @@ func TestSecretUpdateOwnerRefAndEnvironmentLabelOnStartup(t *testing.T) {
 // when the secret used exists and has all of the right fields.
 func TestUpdateCredentialsSecretSuccessFields(t *testing.T) {
 	host := newDefaultHost(t)
-	r := newTestReconciler(host)
+	r := newTestReconciler(t, host)
 
 	tryReconcile(t, r, host,
 		func(host *metal3api.BareMetalHost, result reconcile.Result) bool {
@@ -1008,7 +1012,7 @@ func TestUpdateCredentialsSecretSuccessFields(t *testing.T) {
 // changed to another secret that is also good.
 func TestUpdateGoodCredentialsOnNewSecret(t *testing.T) {
 	host := newDefaultHost(t)
-	r := newTestReconciler(host)
+	r := newTestReconciler(t, host)
 
 	tryReconcile(t, r, host,
 		func(host *metal3api.BareMetalHost, result reconcile.Result) bool {
@@ -1049,7 +1053,7 @@ func TestUpdateGoodCredentialsOnNewSecret(t *testing.T) {
 func TestUpdateGoodCredentialsOnBadSecret(t *testing.T) {
 	host := newDefaultHost(t)
 	badSecret := newBMCCredsSecret("bmc-creds-no-user", "", "Pass")
-	r := newTestReconciler(host, badSecret)
+	r := newTestReconciler(t, host, badSecret)
 
 	tryReconcile(t, r, host,
 		func(host *metal3api.BareMetalHost, result reconcile.Result) bool {
@@ -1090,7 +1094,7 @@ func TestDiscoveredHost(t *testing.T) {
 				CredentialsName: "",
 			},
 		})
-	r := newTestReconciler(noAddressOrSecret)
+	r := newTestReconciler(t, noAddressOrSecret)
 	waitForStatus(t, r, noAddressOrSecret, metal3api.OperationalStatusDiscovered)
 	if noAddressOrSecret.Status.ErrorType != "" {
 		t.Errorf("Unexpected error type %s", noAddressOrSecret.Status.ErrorType)
@@ -1171,7 +1175,7 @@ func TestMissingBMCParameters(t *testing.T) {
 
 	for _, tc := range testCases {
 		t.Run(tc.Scenario, func(t *testing.T) {
-			r := newTestReconciler(tc.Secret, tc.Host)
+			r := newTestReconciler(t, tc.Secret, tc.Host)
 			waitForError(t, r, tc.Host)
 			if tc.Host.Status.OperationalStatus != metal3api.OperationalStatusError {
 				t.Errorf("Unexpected operational status %s", tc.Host.Status.OperationalStatus)
@@ -1194,7 +1198,7 @@ func TestFixSecret(t *testing.T) {
 				CredentialsName: "bmc-creds-no-user",
 			},
 		})
-	r := newTestReconciler(host, secret)
+	r := newTestReconciler(t, host, secret)
 	waitForError(t, r, host)
 
 	secret = &corev1.Secret{}
@@ -1228,7 +1232,7 @@ func TestBreakThenFixSecret(t *testing.T) {
 				CredentialsName: "bmc-creds-toggle-user",
 			},
 		})
-	r := newTestReconciler(host, secret)
+	r := newTestReconciler(t, host, secret)
 	tryReconcile(t, r, host,
 		func(host *metal3api.BareMetalHost, result reconcile.Result) bool {
 			id := host.Status.Provisioning.ID
@@ -1275,7 +1279,7 @@ func TestBreakThenFixSecret(t *testing.T) {
 // the hardware profile name.
 func TestSetHardwareProfile(t *testing.T) {
 	host := newDefaultHost(t)
-	r := newTestReconciler(host)
+	r := newTestReconciler(t, host)
 
 	tryReconcile(t, r, host,
 		func(host *metal3api.BareMetalHost, result reconcile.Result) bool {
@@ -1289,7 +1293,7 @@ func TestSetHardwareProfile(t *testing.T) {
 // of the status block is filled in for new hosts.
 func TestCreateHardwareDetails(t *testing.T) {
 	host := newDefaultHost(t)
-	r := newTestReconciler(host)
+	r := newTestReconciler(t, host)
 
 	tryReconcile(t, r, host,
 		func(host *metal3api.BareMetalHost, result reconcile.Result) bool {
@@ -1410,7 +1414,7 @@ func TestProvision(t *testing.T) {
 		Checksum: "12345",
 	}
 	host.Spec.Online = true
-	r := newTestReconciler(host)
+	r := newTestReconciler(t, host)
 
 	tryReconcile(t, r, host,
 		func(host *metal3api.BareMetalHost, result reconcile.Result) bool {
@@ -1430,7 +1434,7 @@ func TestProvisionCustomDeploy(t *testing.T) {
 		Method: "install_everything",
 	}
 	host.Spec.Online = true
-	r := newTestReconciler(host)
+	r := newTestReconciler(t, host)
 
 	tryReconcile(t, r, host,
 		func(host *metal3api.BareMetalHost, result reconcile.Result) bool {
@@ -1454,7 +1458,7 @@ func TestProvisionCustomDeployWithURL(t *testing.T) {
 		Checksum: "12345",
 	}
 	host.Spec.Online = true
-	r := newTestReconciler(host)
+	r := newTestReconciler(t, host)
 
 	tryReconcile(t, r, host,
 		func(host *metal3api.BareMetalHost, result reconcile.Result) bool {
@@ -1477,7 +1481,7 @@ func TestExternallyProvisionedTransitions(t *testing.T) {
 		host.Spec.Online = true
 		host.Spec.ConsumerRef = &corev1.ObjectReference{} // it doesn't have to point to a real object
 		host.Spec.ExternallyProvisioned = true
-		r := newTestReconciler(host)
+		r := newTestReconciler(t, host)
 
 		waitForProvisioningState(t, r, host, metal3api.StateExternallyProvisioned)
 	})
@@ -1486,7 +1490,7 @@ func TestExternallyProvisionedTransitions(t *testing.T) {
 		host := newDefaultHost(t)
 		host.Spec.Online = true
 		host.Spec.ExternallyProvisioned = true
-		r := newTestReconciler(host)
+		r := newTestReconciler(t, host)
 
 		waitForProvisioningState(t, r, host, metal3api.StateExternallyProvisioned)
 
@@ -1503,7 +1507,7 @@ func TestExternallyProvisionedTransitions(t *testing.T) {
 	t.Run("preparing to externally provisioned", func(t *testing.T) {
 		host := newDefaultHost(t)
 		host.Spec.Online = true
-		r := newTestReconciler(host)
+		r := newTestReconciler(t, host)
 
 		waitForProvisioningState(t, r, host, metal3api.StatePreparing)
 
@@ -1523,7 +1527,7 @@ func TestExternallyProvisionedTransitions(t *testing.T) {
 func TestPowerOn(t *testing.T) {
 	host := newDefaultHost(t)
 	host.Spec.Online = true
-	r := newTestReconciler(host)
+	r := newTestReconciler(t, host)
 
 	tryReconcile(t, r, host,
 		func(host *metal3api.BareMetalHost, result reconcile.Result) bool {
@@ -1538,7 +1542,7 @@ func TestPowerOn(t *testing.T) {
 func TestPowerOff(t *testing.T) {
 	host := newDefaultHost(t)
 	host.Spec.Online = false
-	r := newTestReconciler(host)
+	r := newTestReconciler(t, host)
 
 	tryReconcile(t, r, host,
 		func(host *metal3api.BareMetalHost, result reconcile.Result) bool {
@@ -1609,7 +1613,7 @@ func TestDeleteHost(t *testing.T) {
 			host.Status.Provisioning.ID = "made-up-id"
 			badSecret := newBMCCredsSecret("bmc-creds-no-user", "", "Pass")
 			fix := fixture.Fixture{}
-			r := newTestReconcilerWithFixture(&fix, host, badSecret)
+			r := newTestReconcilerWithFixture(t, &fix, host, badSecret)
 
 			tryReconcile(t, r, host,
 				func(host *metal3api.BareMetalHost, result reconcile.Result) bool {
@@ -1816,7 +1820,7 @@ func TestProvisionerIsReady(t *testing.T) {
 	host := newDefaultHost(t)
 
 	fix := fixture.Fixture{BecomeReadyCounter: 5}
-	r := newTestReconcilerWithFixture(&fix, host)
+	r := newTestReconcilerWithFixture(t, &fix, host)
 
 	assert.InDelta(t, 0.0, promutil.ToFloat64(provisionerNotReady), 0.01)
 	tryReconcile(t, r, host,
@@ -1960,7 +1964,7 @@ func TestUpdateEventHandler(t *testing.T) {
 
 	for _, tc := range cases {
 		t.Run(tc.name, func(t *testing.T) {
-			r := newTestReconciler()
+			r := newTestReconciler(t)
 			assert.Equal(t, tc.expectedProcess, r.updateEventHandler(tc.event))
 		})
 	}
@@ -2266,7 +2270,7 @@ func TestInvalidBMHCanBeDeleted(t *testing.T) {
 	host.Spec.BMC.Address = fmt.Sprintf("%s%s%s", "<", host.Spec.BMC.Address, ">")
 
 	var fix fixture.Fixture
-	r := newTestReconcilerWithFixture(&fix, host)
+	r := newTestReconcilerWithFixture(t, &fix, host)
 
 	fix.SetValidateError("malformed url")
 	waitForError(t, r, host)
@@ -2413,7 +2417,7 @@ func TestGetHostArchitecture(t *testing.T) {
 
 func TestGetPreprovImageNoFormats(t *testing.T) {
 	host := newDefaultHost(t)
-	r := newTestReconciler(host)
+	r := newTestReconciler(t, host)
 	i := makeReconcileInfo(host)
 
 	imgData, err := r.getPreprovImage(i, nil)
@@ -2440,7 +2444,7 @@ func TestGetPreprovImageCreateUpdate(t *testing.T) {
 	host.Labels = map[string]string{
 		"answer.metal3.io": "42",
 	}
-	r := newTestReconciler(host, newSecret(secretName, nil))
+	r := newTestReconciler(t, host, newSecret(secretName, nil))
 	i := makeReconcileInfo(host)
 
 	imgData, err := r.getPreprovImage(i, []metal3api.ImageFormat{"iso"})
@@ -2504,7 +2508,7 @@ func TestGetPreprovImage(t *testing.T) {
 			},
 		},
 	}
-	r := newTestReconciler(host, image)
+	r := newTestReconciler(t, host, image)
 	i := makeReconcileInfo(host)
 
 	imgData, err := r.getPreprovImage(i, acceptFormats)
@@ -2541,7 +2545,7 @@ func TestGetPreprovImageNotCurrent(t *testing.T) {
 			},
 		},
 	}
-	r := newTestReconciler(host, image)
+	r := newTestReconciler(t, host, image)
 	i := makeReconcileInfo(host)
 
 	imgData, err := r.getPreprovImage(i, []metal3api.ImageFormat{metal3api.ImageFormatISO})
@@ -2551,7 +2555,7 @@ func TestGetPreprovImageNotCurrent(t *testing.T) {
 
 func TestPreprovImageAvailable(t *testing.T) {
 	host := newDefaultHost(t)
-	r := newTestReconciler(host, newSecret("network_secret_1", nil))
+	r := newTestReconciler(t, host, newSecret("network_secret_1", nil))
 
 	testCases := []struct {
 		Scenario   string
@@ -2891,7 +2895,7 @@ func TestHostFirmwareSettings(t *testing.T) {
 	for _, tc := range testCases {
 		t.Run(tc.Scenario, func(t *testing.T) {
 			host := newDefaultHost(t)
-			r := newTestReconciler(host)
+			r := newTestReconciler(t, host)
 			i := makeReconcileInfo(host)
 			i.request = newRequest(host)
 
@@ -2915,7 +2919,7 @@ func TestBMHTransitionToPreparing(t *testing.T) {
 	host.Spec.Online = true
 	host.Spec.ExternallyProvisioned = false
 	host.Spec.ConsumerRef = &corev1.ObjectReference{}
-	r := newTestReconciler(host)
+	r := newTestReconciler(t, host)
 
 	waitForProvisioningState(t, r, host, metal3api.StateAvailable)
 
@@ -2942,7 +2946,7 @@ func TestHFSTransitionToPreparing(t *testing.T) {
 	host.Spec.Online = true
 	host.Spec.ConsumerRef = &corev1.ObjectReference{}
 	host.Spec.ExternallyProvisioned = false
-	r := newTestReconciler(host)
+	r := newTestReconciler(t, host)
 
 	waitForProvisioningState(t, r, host, metal3api.StateAvailable)
 
@@ -2979,7 +2983,7 @@ func TestHFSEmptyStatusSettings(t *testing.T) {
 	host.Spec.Online = true
 	host.Spec.ConsumerRef = &corev1.ObjectReference{}
 	host.Spec.ExternallyProvisioned = false
-	r := newTestReconciler(host)
+	r := newTestReconciler(t, host)
 
 	waitForProvisioningState(t, r, host, metal3api.StatePreparing)
 
diff --git a/internal/controller/metal3.io/bmceventsubscription_controller_test.go b/internal/controller/metal3.io/bmceventsubscription_controller_test.go
index 052b99d0..a49c17af 100644
--- a/internal/controller/metal3.io/bmceventsubscription_controller_test.go
+++ b/internal/controller/metal3.io/bmceventsubscription_controller_test.go
@@ -7,6 +7,7 @@ import (
 	metal3api "github.com/metal3-io/baremetal-operator/apis/metal3.io/v1alpha1"
 	"github.com/metal3-io/baremetal-operator/pkg/provisioner/fixture"
 	"github.com/metal3-io/baremetal-operator/pkg/utils"
+	"github.com/stretchr/testify/require"
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
@@ -17,10 +18,13 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/reconcile"
 )
 
-func newBMCTestReconcilerWithFixture(fix *fixture.Fixture, initObjs ...runtime.Object) *BMCEventSubscriptionReconciler {
+func newBMCTestReconcilerWithFixture(t *testing.T, fix *fixture.Fixture, initObjs ...runtime.Object) *BMCEventSubscriptionReconciler {
+	t.Helper()
 	clientBuilder := fakeclient.NewClientBuilder().WithRuntimeObjects(initObjs...)
 	for _, v := range initObjs {
-		clientBuilder = clientBuilder.WithStatusSubresource(v.(client.Object))
+		object, ok := v.(client.Object)
+		require.True(t, ok, "failed to cast object to client.Object")
+		clientBuilder = clientBuilder.WithStatusSubresource(object)
 	}
 	c := clientBuilder.Build()
 	// Add a default secret that can be used by most subscriptions.
@@ -39,9 +43,10 @@ func newBMCTestReconcilerWithFixture(fix *fixture.Fixture, initObjs ...runtime.O
 
 type BMCDoneFunc func(subscription *metal3api.BMCEventSubscription, result reconcile.Result) bool
 
-func newBMCTestReconciler(initObjs ...runtime.Object) *BMCEventSubscriptionReconciler {
+func newBMCTestReconciler(t *testing.T, initObjs ...runtime.Object) *BMCEventSubscriptionReconciler {
+	t.Helper()
 	fix := fixture.Fixture{}
-	return newBMCTestReconcilerWithFixture(&fix, initObjs...)
+	return newBMCTestReconcilerWithFixture(t, &fix, initObjs...)
 }
 
 func newBMCRequest(subscription *metal3api.BMCEventSubscription) ctrl.Request {
@@ -95,7 +100,7 @@ func HostWithProvisioningID(t *testing.T, host *metal3api.BareMetalHost) *metal3
 func TestBMCAddFinalizers(t *testing.T) {
 	host := newDefaultHost(t)
 	subscription := newDefaultSubscription(t)
-	r := newBMCTestReconciler(subscription, host)
+	r := newBMCTestReconciler(t, subscription, host)
 	err := r.addFinalizer(context.Background(), subscription)
 	if err != nil {
 		t.Error(err)
@@ -110,7 +115,7 @@ func TestBMCGetProvisioner(t *testing.T) {
 	host := newDefaultHost(t)
 	subscription := newDefaultSubscription(t)
 	request := newBMCRequest(subscription)
-	r := newBMCTestReconciler(subscription, host)
+	r := newBMCTestReconciler(t, subscription, host)
 	for _, tc := range []struct {
 		Scenario string
 		Host     *metal3api.BareMetalHost
@@ -145,7 +150,7 @@ func TestGetHTTPHeaders(t *testing.T) {
 	// The secret is automatically created by newBMCTestReconciler.
 	host := newDefaultHost(t)
 	subscription := newDefaultSubscription(t)
-	r := newBMCTestReconciler(subscription, host)
+	r := newBMCTestReconciler(t, subscription, host)
 
 	for _, tc := range []struct {
 		Scenario      string
diff --git a/internal/controller/metal3.io/demo_test.go b/internal/controller/metal3.io/demo_test.go
index e849eba4..c05406c1 100644
--- a/internal/controller/metal3.io/demo_test.go
+++ b/internal/controller/metal3.io/demo_test.go
@@ -6,6 +6,7 @@ import (
 
 	metal3api "github.com/metal3-io/baremetal-operator/apis/metal3.io/v1alpha1"
 	"github.com/metal3-io/baremetal-operator/pkg/provisioner/demo"
+	"github.com/stretchr/testify/require"
 	"k8s.io/apimachinery/pkg/runtime"
 	ctrl "sigs.k8s.io/controller-runtime"
 	"sigs.k8s.io/controller-runtime/pkg/client"
@@ -13,10 +14,13 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/reconcile"
 )
 
-func newDemoReconciler(initObjs ...runtime.Object) *BareMetalHostReconciler {
+func newDemoReconciler(t *testing.T, initObjs ...runtime.Object) *BareMetalHostReconciler {
+	t.Helper()
 	clientBuilder := fakeclient.NewClientBuilder().WithRuntimeObjects(initObjs...)
 	for _, v := range initObjs {
-		clientBuilder = clientBuilder.WithStatusSubresource(v.(client.Object))
+		object, ok := v.(client.Object)
+		require.True(t, ok, "Failed to cast object to client.Object")
+		clientBuilder = clientBuilder.WithStatusSubresource(object)
 	}
 	c := clientBuilder.Build()
 
@@ -35,7 +39,7 @@ func newDemoReconciler(initObjs ...runtime.Object) *BareMetalHostReconciler {
 // a registration error.
 func TestDemoRegistrationError(t *testing.T) {
 	host := newDefaultNamedHost(t, demo.RegistrationErrorHost)
-	r := newDemoReconciler(host)
+	r := newDemoReconciler(t, host)
 
 	tryReconcile(t, r, host,
 		func(host *metal3api.BareMetalHost, result reconcile.Result) bool {
@@ -53,7 +57,7 @@ func TestDemoRegistrationError(t *testing.T) {
 // that it is being registered.
 func TestDemoRegistering(t *testing.T) {
 	host := newDefaultNamedHost(t, demo.RegisteringHost)
-	r := newDemoReconciler(host)
+	r := newDemoReconciler(t, host)
 
 	tryReconcile(t, r, host,
 		func(host *metal3api.BareMetalHost, result reconcile.Result) bool {
@@ -71,7 +75,7 @@ func TestDemoRegistering(t *testing.T) {
 // that it is being inspected.
 func TestDemoInspecting(t *testing.T) {
 	host := newDefaultNamedHost(t, demo.InspectingHost)
-	r := newDemoReconciler(host)
+	r := newDemoReconciler(t, host)
 
 	tryReconcile(t, r, host,
 		func(host *metal3api.BareMetalHost, result reconcile.Result) bool {
@@ -92,7 +96,7 @@ func TestDemoPreparing(t *testing.T) {
 		Checksum: "a-checksum",
 	}
 	host.Spec.Online = true
-	r := newDemoReconciler(host)
+	r := newDemoReconciler(t, host)
 
 	tryReconcile(t, r, host,
 		func(host *metal3api.BareMetalHost, result reconcile.Result) bool {
@@ -113,7 +117,7 @@ func TestDemoPreparingError(t *testing.T) {
 		Checksum: "a-checksum",
 	}
 	host.Spec.Online = true
-	r := newDemoReconciler(host)
+	r := newDemoReconciler(t, host)
 
 	tryReconcile(t, r, host,
 		func(host *metal3api.BareMetalHost, result reconcile.Result) bool {
@@ -131,7 +135,7 @@ func TestDemoPreparingError(t *testing.T) {
 // that it is available to be provisioned.
 func TestDemoAvailable(t *testing.T) {
 	host := newDefaultNamedHost(t, demo.AvailableHost)
-	r := newDemoReconciler(host)
+	r := newDemoReconciler(t, host)
 
 	tryReconcile(t, r, host,
 		func(host *metal3api.BareMetalHost, result reconcile.Result) bool {
@@ -154,7 +158,7 @@ func TestDemoProvisioning(t *testing.T) {
 		Checksum: "a-checksum",
 	}
 	host.Spec.Online = true
-	r := newDemoReconciler(host)
+	r := newDemoReconciler(t, host)
 
 	tryReconcile(t, r, host,
 		func(host *metal3api.BareMetalHost, result reconcile.Result) bool {
@@ -177,7 +181,7 @@ func TestDemoProvisioned(t *testing.T) {
 		Checksum: "a-checksum",
 	}
 	host.Spec.Online = true
-	r := newDemoReconciler(host)
+	r := newDemoReconciler(t, host)
 
 	tryReconcile(t, r, host,
 		func(host *metal3api.BareMetalHost, result reconcile.Result) bool {
@@ -200,7 +204,7 @@ func TestDemoValidationError(t *testing.T) {
 		Checksum: "a-checksum",
 	}
 	host.Spec.Online = true
-	r := newDemoReconciler(host)
+	r := newDemoReconciler(t, host)
 
 	tryReconcile(t, r, host,
 		func(host *metal3api.BareMetalHost, result reconcile.Result) bool {
diff --git a/internal/controller/metal3.io/host_state_machine_test.go b/internal/controller/metal3.io/host_state_machine_test.go
index e6204016..d9ba7142 100644
--- a/internal/controller/metal3.io/host_state_machine_test.go
+++ b/internal/controller/metal3.io/host_state_machine_test.go
@@ -18,8 +18,9 @@ import (
 	logf "sigs.k8s.io/controller-runtime/pkg/log"
 )
 
-func testStateMachine(host *metal3api.BareMetalHost) *hostStateMachine {
-	r := newTestReconciler()
+func testStateMachine(t *testing.T, host *metal3api.BareMetalHost) *hostStateMachine {
+	t.Helper()
+	r := newTestReconciler(t)
 	p, _ := r.ProvisionerFactory.NewProvisioner(context.TODO(), provisioner.BuildHostData(*host, bmc.Credentials{}),
 		func(reason, message string) {})
 	return newHostStateMachine(host, r, p, true)
@@ -841,7 +842,7 @@ func TestProvisioningCancelled(t *testing.T) {
 	for _, tc := range testCases {
 		t.Run(tc.Scenario, func(t *testing.T) {
 			host := tc.Host
-			hsm := testStateMachine(&host)
+			hsm := testStateMachine(t, &host)
 			actual := hsm.provisioningCancelled()
 			if tc.Expected && !actual {
 				t.Error("expected to need deprovisioning")
diff --git a/pkg/provisioner/ironic/clients/updateopts_test.go b/pkg/provisioner/ironic/clients/updateopts_test.go
index 6a7a23f9..8193f71c 100644
--- a/pkg/provisioner/ironic/clients/updateopts_test.go
+++ b/pkg/provisioner/ironic/clients/updateopts_test.go
@@ -7,6 +7,7 @@ import (
 	"github.com/go-logr/logr"
 	"github.com/gophercloud/gophercloud/v2/openstack/baremetal/v1/nodes"
 	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 	logf "sigs.k8s.io/controller-runtime/pkg/log"
 )
 
@@ -365,10 +366,13 @@ func TestGetUpdateOperation(t *testing.T) {
 
 			switch c.ExpectedOp {
 			case nodes.AddOp, nodes.ReplaceOp:
+				var ev string
+				var ok bool
 				assert.NotNil(t, updateOp)
-				ev := c.ExpectedValue
+				ev = c.ExpectedValue
 				if ev == "" {
-					ev = c.NewValue.(string)
+					ev, ok = c.NewValue.(string)
+					require.True(t, ok, "expected NewValue to be a string")
 				}
 				assert.Equal(t, c.ExpectedOp, updateOp.Op)
 				assert.Equal(t, ev, updateOp.Value)
@@ -389,7 +393,8 @@ func TestTopLevelUpdateOpt(t *testing.T) {
 	u.SetTopLevelOpt("foo", "baz", "bar")
 	ops := u.Updates
 	assert.Len(t, ops, 1)
-	op := ops[0].(nodes.UpdateOperation)
+	op, ok := ops[0].(nodes.UpdateOperation)
+	require.True(t, ok, "expected UpdateOperation")
 	assert.Equal(t, nodes.AddOp, op.Op)
 	assert.Equal(t, "baz", op.Value)
 	assert.Equal(t, "/foo", op.Path)
@@ -414,7 +419,8 @@ func TestPropertiesUpdateOpts(t *testing.T) {
 	u.SetPropertiesOpts(newValues, &node)
 	ops := u.Updates
 	assert.Len(t, ops, 1)
-	op := ops[0].(nodes.UpdateOperation)
+	op, ok := ops[0].(nodes.UpdateOperation)
+	require.True(t, ok, "expected UpdateOperation")
 	assert.Equal(t, nodes.AddOp, op.Op)
 	assert.Equal(t, "quux", op.Value)
 	assert.Equal(t, "/properties/baz", op.Path)
@@ -435,7 +441,8 @@ func TestInstanceInfoUpdateOpts(t *testing.T) {
 	u.SetInstanceInfoOpts(newValues, &node)
 	ops := u.Updates
 	assert.Len(t, ops, 1)
-	op := ops[0].(nodes.UpdateOperation)
+	op, ok := ops[0].(nodes.UpdateOperation)
+	require.True(t, ok, "expected UpdateOperation")
 	assert.Equal(t, nodes.AddOp, op.Op)
 	assert.Equal(t, "quux", op.Value)
 	assert.Equal(t, "/instance_info/baz", op.Path)
diff --git a/pkg/provisioner/ironic/provision_test.go b/pkg/provisioner/ironic/provision_test.go
index 72ee57b7..d94066ce 100644
--- a/pkg/provisioner/ironic/provision_test.go
+++ b/pkg/provisioner/ironic/provision_test.go
@@ -744,8 +744,10 @@ func TestGetUpdateOptsForNodeWithRootHints(t *testing.T) {
 		t.Run(e.Path, func(t *testing.T) {
 			t.Logf("expected: %v", e)
 			var update nodes.UpdateOperation
+			var ok bool
 			for _, patch := range patches {
-				update = patch.(nodes.UpdateOperation)
+				update, ok = patch.(nodes.UpdateOperation)
+				require.True(t, ok, "expected patch to be UpdateOperation")
 				if update.Path == e.Path {
 					break
 				}
@@ -846,8 +848,10 @@ func TestGetUpdateOptsForNodeVirtual(t *testing.T) {
 		t.Run(e.Path, func(t *testing.T) {
 			t.Logf("expected: %v", e)
 			var update nodes.UpdateOperation
+			var ok bool
 			for _, patch := range patches {
-				update = patch.(nodes.UpdateOperation)
+				update, ok = patch.(nodes.UpdateOperation)
+				require.True(t, ok, "expected patch to be UpdateOperation")
 				if update.Path == e.Path {
 					break
 				}
@@ -940,8 +944,10 @@ func TestGetUpdateOptsForNodeDell(t *testing.T) {
 		t.Run(e.Path, func(t *testing.T) {
 			t.Logf("expected: %v", e)
 			var update nodes.UpdateOperation
+			var ok bool
 			for _, patch := range patches {
-				update = patch.(nodes.UpdateOperation)
+				update, ok = patch.(nodes.UpdateOperation)
+				require.True(t, ok, "expected patch to be UpdateOperation")
 				if update.Path == e.Path {
 					break
 				}
@@ -1001,8 +1007,10 @@ func TestGetUpdateOptsForNodeLiveIso(t *testing.T) {
 		t.Run(e.Path, func(t *testing.T) {
 			t.Logf("expected: %v", e)
 			var update nodes.UpdateOperation
+			var ok bool
 			for _, patch := range patches {
-				update = patch.(nodes.UpdateOperation)
+				update, ok = patch.(nodes.UpdateOperation)
+				require.True(t, ok, "expected patch to be UpdateOperation")
 				if update.Path == e.Path {
 					break
 				}
@@ -1076,8 +1084,10 @@ func TestGetUpdateOptsForNodeImageToLiveIso(t *testing.T) {
 		t.Run(e.Path, func(t *testing.T) {
 			t.Logf("expected: %v", e)
 			var update nodes.UpdateOperation
+			var ok bool
 			for _, patch := range patches {
-				update = patch.(nodes.UpdateOperation)
+				update, ok = patch.(nodes.UpdateOperation)
+				require.True(t, ok, "expected patch to be UpdateOperation")
 				if update.Path == e.Path {
 					break
 				}
@@ -1155,8 +1165,10 @@ func TestGetUpdateOptsForNodeLiveIsoToImage(t *testing.T) {
 		t.Run(e.Path, func(t *testing.T) {
 			t.Logf("expected: %v", e)
 			var update nodes.UpdateOperation
+			var ok bool
 			for _, patch := range patches {
-				update = patch.(nodes.UpdateOperation)
+				update, ok = patch.(nodes.UpdateOperation)
+				require.True(t, ok, "expected patch to be UpdateOperation")
 				if update.Path == e.Path {
 					break
 				}
@@ -1213,8 +1225,10 @@ func TestGetUpdateOptsForNodeCustomDeploy(t *testing.T) {
 		t.Run(e.Path, func(t *testing.T) {
 			t.Logf("expected: %v", e)
 			var update nodes.UpdateOperation
+			var ok bool
 			for _, patch := range patches {
-				update = patch.(nodes.UpdateOperation)
+				update, ok = patch.(nodes.UpdateOperation)
+				require.True(t, ok, "expected patch to be UpdateOperation")
 				if update.Path == e.Path {
 					break
 				}
@@ -1274,8 +1288,10 @@ func TestGetUpdateOptsForNodeCustomDeployWithImage(t *testing.T) {
 		t.Run(e.Path, func(t *testing.T) {
 			t.Logf("expected: %v", e)
 			var update nodes.UpdateOperation
+			var ok bool
 			for _, patch := range patches {
-				update = patch.(nodes.UpdateOperation)
+				update, ok = patch.(nodes.UpdateOperation)
+				require.True(t, ok, "expected patch to be UpdateOperation")
 				if update.Path == e.Path {
 					break
 				}
@@ -1345,8 +1361,10 @@ func TestGetUpdateOptsForNodeImageToCustomDeploy(t *testing.T) {
 		t.Run(e.Path, func(t *testing.T) {
 			t.Logf("expected: %v", e)
 			var update nodes.UpdateOperation
+			var ok bool
 			for _, patch := range patches {
-				update = patch.(nodes.UpdateOperation)
+				update, ok = patch.(nodes.UpdateOperation)
+				require.True(t, ok, "expected patch to be UpdateOperation")
 				if update.Path == e.Path {
 					break
 				}
@@ -1430,8 +1448,10 @@ func TestGetUpdateOptsForNodeSecureBoot(t *testing.T) {
 		t.Run(e.Path, func(t *testing.T) {
 			t.Logf("expected: %v", e)
 			var update nodes.UpdateOperation
+			var ok bool
 			for _, patch := range patches {
-				update = patch.(nodes.UpdateOperation)
+				update, ok = patch.(nodes.UpdateOperation)
+				require.True(t, ok, "expected patch to be UpdateOperation")
 				if update.Path == e.Path {
 					break
 				}
diff --git a/pkg/provisioner/ironic/register_test.go b/pkg/provisioner/ironic/register_test.go
index e6c302b5..9f4b44ad 100644
--- a/pkg/provisioner/ironic/register_test.go
+++ b/pkg/provisioner/ironic/register_test.go
@@ -655,7 +655,8 @@ func TestRegisterNewCredentials(t *testing.T) {
 
 	updates := ironic.GetLastNodeUpdateRequestFor("uuid")
 	assert.Equal(t, "/driver_info", updates[0].Path)
-	newValues := updates[0].Value.(map[string]interface{})
+	newValues, ok := updates[0].Value.(map[string]interface{})
+	require.True(t, ok, "expected to be a map")
 	assert.Equal(t, "test.bmc", newValues["test_address"])
 }
 
@@ -940,7 +941,8 @@ func TestRegisterUpdateBMCAddressIP(t *testing.T) {
 
 	updates := ironic.GetLastNodeUpdateRequestFor("uuid")
 	assert.Equal(t, "/driver_info", updates[0].Path)
-	newValues := updates[0].Value.(map[string]interface{})
+	newValues, ok := updates[0].Value.(map[string]interface{})
+	require.True(t, ok, "expected to be a map")
 	assert.Equal(t, "192.168.122.10", newValues["ipmi_address"])
 }
 
@@ -1001,7 +1003,8 @@ func TestRegisterUpdateBMCAddressProtocol(t *testing.T) {
 
 	updates := ironic.GetLastNodeUpdateRequestFor("uuid")
 	assert.Equal(t, "/driver_info", updates[0].Path)
-	newValues := updates[0].Value.(map[string]interface{})
+	newValues, ok := updates[0].Value.(map[string]interface{})
+	require.True(t, ok, "expected to be a map")
 	assert.Equal(t, "https://192.168.122.1:623", newValues["redfish_address"])
 }