Skip to content

Commit 0739870

Browse files
Check that failing libvirt connection is reflected
1 parent e338118 commit 0739870

2 files changed

Lines changed: 29 additions & 8 deletions

File tree

internal/controller/hypervisor_controller.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,13 +355,14 @@ func (r *HypervisorReconciler) Start(ctx context.Context) error {
355355
log.Error(err, "unable to connect to libvirt")
356356
// Set the hypervisor's LibVirtType condition to false with the
357357
// error message, so that it's visible in the status.
358+
base := hypervisor.DeepCopy()
358359
meta.SetStatusCondition(&hypervisor.Status.Conditions, metav1.Condition{
359360
Type: LibVirtType, // TODO: This should be a kvmv1 condition.
360361
Status: metav1.ConditionFalse,
361362
Message: fmt.Sprintf("unable to connect to libvirt: %v", err),
362363
Reason: "ConnectFailed",
363364
})
364-
patch := client.MergeFromWithOptions(hypervisor.DeepCopy(), client.MergeFromWithOptimisticLock{})
365+
patch := client.MergeFromWithOptions(base, client.MergeFromWithOptimisticLock{})
365366
if err := r.Status().Patch(ctx, &hypervisor, patch); err != nil {
366367
log.Error(err, "unable to update hypervisor status after failed libvirt connection")
367368
}

internal/controller/hypervisor_controller_test.go

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ package controller
2020
import (
2121
"context"
2222
"errors"
23+
"strings"
2324
"time"
2425

2526
kvmv1 "github.com/cobaltcore-dev/openstack-hypervisor-operator/api/v1"
@@ -88,7 +89,7 @@ var _ = Describe("Hypervisor Controller", func() {
8889
})
8990

9091
It("should fail when libvirt connection fails", func() {
91-
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
92+
ctx, cancel := context.WithCancel(context.Background())
9293
defer cancel()
9394

9495
// Create a hypervisor resource for this test
@@ -128,16 +129,35 @@ var _ = Describe("Hypervisor Controller", func() {
128129
done <- controllerReconciler.Start(ctx)
129130
}()
130131

131-
// Wait for either completion or context cancellation
132+
// Wait for the hypervisor status to reflect the failed libvirt connection
133+
// This must happen BEFORE we cancel the context to ensure the Start method
134+
// had time to attempt connection and update the status
135+
var updatedHypervisor kvmv1.Hypervisor
136+
Eventually(func() bool {
137+
err := k8sClient.Get(context.Background(), types.NamespacedName{Name: hypervisorName}, &updatedHypervisor)
138+
if err != nil {
139+
return false
140+
}
141+
for _, condition := range updatedHypervisor.Status.Conditions {
142+
if condition.Type == "LibVirtConnection" {
143+
return condition.Status == metav1.ConditionFalse &&
144+
condition.Reason == "ConnectFailed" &&
145+
strings.Contains(condition.Message, "connection failed")
146+
}
147+
}
148+
return false
149+
}, 5*time.Second, 100*time.Millisecond).Should(BeTrue(), "hypervisor status should reflect failed libvirt connection")
150+
151+
// Cancel the context to stop the Start method
152+
cancel()
153+
154+
// Wait for Start to return with context cancellation error
132155
select {
133-
case <-ctx.Done():
134-
// Context was cancelled, which is expected since the Start method
135-
// retries indefinitely until connected. The test passes because
136-
// we verified the connection fails and retries.
137156
case err := <-done:
138-
// If Start returns, it should be due to context cancellation
139157
Expect(err).To(HaveOccurred())
140158
Expect(err.Error()).To(ContainSubstring("context done while trying to connect to libvirt"))
159+
case <-time.After(2 * time.Second):
160+
Fail("timeout waiting for Start to return after context cancellation")
141161
}
142162
})
143163

0 commit comments

Comments
 (0)