Skip to content

Commit a812bd5

Browse files
authored
Merge pull request #166 from wallrj/fix-flakey-tests
Fix flakey tests and improve the test log output
2 parents 1fb2bcf + bb9f2c1 commit a812bd5

File tree

1 file changed

+68
-21
lines changed
  • pkg/internal/controllers/test

1 file changed

+68
-21
lines changed

pkg/internal/controllers/test/util.go

Lines changed: 68 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package test
1919
import (
2020
"context"
2121
"crypto/x509"
22+
"fmt"
2223
"time"
2324

2425
apiutil "github.com/cert-manager/cert-manager/pkg/api/util"
@@ -28,7 +29,7 @@ import (
2829
corev1 "k8s.io/api/core/v1"
2930
rbacv1 "k8s.io/api/rbac/v1"
3031
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
31-
"k8s.io/klog/v2/klogr"
32+
"k8s.io/klog/v2/ktesting"
3233
ctrl "sigs.k8s.io/controller-runtime"
3334
"sigs.k8s.io/controller-runtime/pkg/client"
3435

@@ -122,48 +123,94 @@ func waitForNotReady(ctx context.Context, cl client.Client, name string) {
122123
// created namespace as well as a shutdown function to stop the controllers is
123124
// returned.
124125
func startControllers(registry *registry.Registry) (context.Context, func(), corev1.Namespace) {
125-
ctx, cancel := context.WithCancel(context.Background())
126+
// A logr which will print log messages interspersed with the Ginkgo
127+
// progress messages to make it easy to understand the context of the log
128+
// messages.
129+
// The logger is also added to the context so that it will be used by code
130+
// that uses logr.FromContext.
131+
log, ctx := ktesting.NewTestContext(GinkgoT())
132+
ctx, cancel := context.WithCancel(ctx)
126133

127134
namespace := corev1.Namespace{
128135
ObjectMeta: metav1.ObjectMeta{
129136
GenerateName: "test-policy-",
130137
},
131138
}
139+
By("Creating Policy Namespace: " + namespace.Name)
132140
Expect(env.AdminClient.Create(ctx, &namespace)).NotTo(HaveOccurred())
133-
By("Created Policy Namespace: " + namespace.Name)
134141

142+
// A channel which will be closed after the controller-manager stops and
143+
// just before its goroutine exits.
144+
mgrStopped := make(chan struct{})
145+
146+
// shutdown stops the controller-manager and then cleans up most of the
147+
// resources from previous tests.
148+
// NB: The test namespace can not be deleted because envtest does not run
149+
// the garbage collection controller which is required to empty the
150+
// namespace before it is deleted. See:
151+
// * https://github.com/kubernetes-sigs/controller-runtime/issues/880
152+
// * https://book.kubebuilder.io/reference/envtest.html#testing-considerations
135153
shutdown := func() {
136-
By("Deleting all CertificateRequests after test")
137-
env.AdminClient.DeleteAllOf(ctx, new(cmapi.CertificateRequest))
138-
139-
By("Deleting all CertificateRequestPolicies after test")
140-
env.AdminClient.DeleteAllOf(ctx, new(policyapi.CertificateRequestPolicy))
141-
142-
By("Deleting Policy Namespace: " + namespace.Name)
143-
env.AdminClient.Delete(ctx, &namespace)
144-
154+
// Cancel the context and wait for the manager goroutine to exit before
155+
// cleaning up the test resources to avoid distracting messages from the
156+
// controllers when they attempt to re-reconcile the deleted resources.
145157
cancel()
158+
<-mgrStopped
159+
160+
// A new context for use by the cleanup clients because the previous
161+
// context has already been cancelled.
162+
ctx := context.Background()
163+
164+
By("Waiting for all CertificateRequest resources to be deleted")
165+
{
166+
// DeleteAllOf can't be used to delete resources in all namespaces,
167+
// but List does return resources from all namespaces by default,
168+
// so we delete each item in that list.
169+
// https://github.com/kubernetes-sigs/controller-runtime/issues/1842
170+
var l cmapi.CertificateRequestList
171+
Expect(env.AdminClient.List(ctx, &l)).To(Succeed())
172+
for i, o := range l.Items {
173+
By(fmt.Sprintf("Deleting: %s", client.ObjectKeyFromObject(&o).String()))
174+
Expect(env.AdminClient.Delete(ctx, &l.Items[i])).To(Succeed())
175+
}
176+
}
177+
178+
By("Waiting for all CertificateRequestPolicy resources to be deleted")
179+
// CertificateRequestPolicy is a cluster-scoped resource, so DeleteAllOf
180+
// can be used in this case.
181+
Expect(
182+
client.IgnoreNotFound(
183+
env.AdminClient.DeleteAllOf(ctx, new(policyapi.CertificateRequestPolicy)),
184+
),
185+
).To(Succeed())
146186
}
147187

148-
log := klogr.New().WithName("testing")
149188
mgr, err := ctrl.NewManager(env.Config, ctrl.Options{
150-
Scheme: policyapi.GlobalScheme,
151-
LeaderElection: true,
152-
MetricsBindAddress: "0",
153-
LeaderElectionNamespace: namespace.Name,
189+
Scheme: policyapi.GlobalScheme,
190+
LeaderElection: true,
191+
MetricsBindAddress: "0",
192+
// Use the default namespace for leader election lock to further avoid
193+
// the possibility of running parallel controller-managers in case a
194+
// previous controller-manager is somehow still running.
195+
LeaderElectionNamespace: "default",
154196
LeaderElectionID: "cert-manager-approver-policy",
155197
LeaderElectionReleaseOnCancel: true,
156-
Logger: log,
198+
Logger: log.WithName("manager"),
157199
})
158200
Expect(err).NotTo(HaveOccurred())
159201

160202
Expect(controllers.AddControllers(ctx, controllers.Options{
161-
Log: log, Manager: mgr,
162-
Evaluators: registry.Evaluators(), Reconcilers: registry.Reconcilers(),
203+
Log: log.WithName("controllers"),
204+
Manager: mgr,
205+
Evaluators: registry.Evaluators(),
206+
Reconcilers: registry.Reconcilers(),
163207
})).NotTo(HaveOccurred())
164208

165209
By("Running Policy controller")
166-
go mgr.Start(ctx)
210+
go func() {
211+
Expect(mgr.Start(ctx)).To(Succeed())
212+
close(mgrStopped)
213+
}()
167214

168215
By("Waiting for Leader Election")
169216
<-mgr.Elected()

0 commit comments

Comments
 (0)