Skip to content

De-normalize tests and ensure clean state before each It() run#516

Merged
afritzler merged 2 commits intomainfrom
enh/tests
Nov 7, 2025
Merged

De-normalize tests and ensure clean state before each It() run#516
afritzler merged 2 commits intomainfrom
enh/tests

Conversation

@afritzler
Copy link
Member

@afritzler afritzler commented Nov 3, 2025

Proposed Changes

  • Use RunnableFunc to start registry in manager
  • Denormalize tests by ensuring each It() block leaves the API server clean

In future we should run EnsureCleanState after each It() block for new tests to ensure that we have a clean state to start the tests. The problem in our tests are ClusterScoped objects which might cause side effects when left around.

For that reason we are having now a:

AfterEach(func(ctx SpecContext) {
        ...
	EnsureCleanState()
})

Additionally: We should postpone the introduction of complex helper methods for now even when that means that we have code duplication in our tests.

@github-actions github-actions bot added size/XXL enhancement New feature or request labels Nov 3, 2025
@afritzler afritzler force-pushed the enh/tests branch 2 times, most recently from 7348d54 to 4f32a62 Compare November 3, 2025 08:32
Copy link
Contributor

@nagadeesh-nagaraja nagadeesh-nagaraja left a comment

Choose a reason for hiding this comment

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

took a brief look, looks like this is still not yet ready?

By("Ensuring that the Server is in available state")
Eventually(UpdateStatus(server, func() {
server.Status.State = metalv1alpha1.ServerStateAvailable
})).To(Succeed())
Copy link
Contributor

Choose a reason for hiding this comment

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

are we going back to patching the state of server and not allowing it to transition to Available?

I have seen that this might cause flakiness in server state later. and cause the server Status to not be populated..

Copy link
Member Author

Choose a reason for hiding this comment

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

I would do the transitioning via agent and registry setup in the BMC and Server reconciler as this is their core responsibility. Repeating this test in other controllers seems arbitrary. Ideally the BIOS/BMCSettings/Version controller only rely on the contract that a Server has to be available.

Copy link
Contributor

Choose a reason for hiding this comment

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

But I think we are trying to divert the issue. what is the problem allowing it to transition to Available state?
is the helper doing something wrong, then lets fix it. is it flaky do to some other reason, lets root cause it and fix it.

taking a shortcut will only solve the problem for so long.

Copy link
Member Author

Choose a reason for hiding this comment

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

The overall idea is as mentioned in the PR message is to reduce the helper function code and make each It block more explicit.

Comment on lines +76 to +79

Expect(k8sClient.Delete(ctx, bmcSecret)).To(Succeed())
Expect(k8sClient.Delete(ctx, server)).To(Succeed())
EnsureCleanState()
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we need to come up with a better plan to clean up?
example:
server is not allowed to delete in Maintenance state..
biosSettings and other maintenance resource also do not go well with delete when inProgress

we need to make sure its deleted properly? else rest of the tests will hit issue nevertheless..

Copy link
Member Author

Choose a reason for hiding this comment

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

Well the idea of that PR is, that each It block is responsible for leaving a clean state. Yes that will be tricky in the beginning but we can think about later how we can fix that issue by improving the controller coding. In this PR I didn't want to touch any reconciler logic at all.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think it will be beneficial to have a common helper which can be called which will make sure all the resources are deleted..
just need to make sure that the helper handles all cases.. force delete the resources if necessary.
and we can also make sure that the test in the beginning will clean by calling the same function :)

Copy link
Member Author

Choose a reason for hiding this comment

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

But force deleting means, that somehow there is a problem in the deletion flow. I think we should rather ensure that we catch problems in a deletion flow if a graceful removal is not possible.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think cleaning up after each It block sounds good and we would be checking Delete reconciles as well.

Comment on lines -250 to +279
TransitionServerToReservedState(ctx, k8sClient, serverClaim, server, ns.Name)
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),
)
Copy link
Contributor

Choose a reason for hiding this comment

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

why this revert? can update the common helper function itself?

many tests use it and is very helpful.

Comment on lines +394 to +422
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),
)
Copy link
Contributor

Choose a reason for hiding this comment

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

same as above?

Comment on lines +118 to +121
Expect(k8sClient.Delete(ctx, server01)).To(Succeed())
Expect(k8sClient.Delete(ctx, server02)).To(Succeed())
Expect(k8sClient.Delete(ctx, server03)).To(Succeed())
Expect(k8sClient.Delete(ctx, bmcSecret)).To(Succeed())
Copy link
Contributor

Choose a reason for hiding this comment

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

how is this different from the DeleteAllMetalResources(ctx, ns.Name) funtion helper?

@afritzler afritzler force-pushed the enh/tests branch 9 times, most recently from be88bbf to 19eba2d Compare November 5, 2025 16:11
@afritzler afritzler force-pushed the enh/tests branch 4 times, most recently from 2ef792d to ef4b7c1 Compare November 6, 2025 12:05
- Use `RunnableFunc` to start registry in `manager`
- Denormalize tests by ensuring each `It()` block leaves the API server
  clean
Copy link
Contributor

@Nuckal777 Nuckal777 left a comment

Choose a reason for hiding this comment

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

Thanks. 👍

Expect(k8sClient.Delete(ctx, &maintenance)).To(Succeed())
}

server01 := &metalv1alpha1.Server{
Copy link
Contributor

Choose a reason for hiding this comment

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

I would argue that the BMC and Server cleanup could be moved in the AfterEach block for deduplication, because the BMCs are setup in the BeforeEach block.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks for pointing this out. Moved the server cleanup for both It blocks to the AfterEach.

Expect(k8sClient.Delete(ctx, &maintenance)).To(Succeed())
}

server01 := &metalv1alpha1.Server{
Copy link
Contributor

Choose a reason for hiding this comment

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

I would argue that the BMC and Server cleanup could be moved in the AfterEach block for deduplication, because the BMCs are setup in the BeforeEach block.

@afritzler afritzler merged commit fe4f215 into main Nov 7, 2025
15 checks passed
@afritzler afritzler deleted the enh/tests branch November 7, 2025 15:46
@github-project-automation github-project-automation bot moved this to Done in Roadmap Nov 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

5 participants