Skip to content

Commit 3dd3fff

Browse files
oilbeaterclaude
andauthored
fix(e2e): wait for DNSNameResolver ready before CNP connectivity checks (#6349)
* fix(e2e): wait for DNSNameResolver ready before CNP connectivity checks The CNP domain-based e2e test was flaky because connectivity checks started before the async DNS resolution chain completed. When CNP rules are created/updated, the OVN ACL address sets may be empty initially since the external dnsnameresolver component needs time to resolve domains and populate DNSNameResolver CR Status. Add waitForDNSResolversReady() to explicitly wait for all DNSNameResolver CRs to have resolved addresses before running connectivity checks. Also increase default retry parameters from 20×2s to 30×3s as a safety net for slow DNS resolution. Signed-off-by: Mengxin Liu <liumengxinfly@gmail.com> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Mengxin Liu <liumengxinfly@gmail.com> * fix(e2e): wait for DNSNameResolver CR creation instead of status population The dnsnameresolver CoreDNS plugin populates Status.ResolvedNames reactively (only when actual DNS queries flow through CoreDNS), not proactively. The previous waitForDNSResolversReady checked for non-empty Status.ResolvedNames before any connectivity test, creating a deadlock: no DNS query happens → Status never populated → 60s timeout → test fails. Replace with waitForDNSResolversCreated that only verifies the CR exists, ensuring the controller has processed the CNP. The connectivity retry logic (30 attempts × 3s) naturally handles the async chain: DNS query → plugin intercepts → Status updated → address set updated → ACL applied. Signed-off-by: Mengxin Liu <liumengxinfly@gmail.com> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Mengxin Liu <liumengxinfly@gmail.com> --------- Signed-off-by: Mengxin Liu <liumengxinfly@gmail.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 53b0946 commit 3dd3fff

File tree

1 file changed

+34
-1
lines changed

1 file changed

+34
-1
lines changed

test/e2e/cnp-domain/e2e_test.go

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,32 @@ var _ = framework.SerialDescribe("[group:cluster-network-policy]", func() {
111111
}
112112

113113
testNetworkConnectivity := func(target string, shouldSucceed bool, description string) {
114-
testNetworkConnectivityWithRetry(target, shouldSucceed, description, 20, 2*time.Second)
114+
testNetworkConnectivityWithRetry(target, shouldSucceed, description, 30, 3*time.Second)
115+
}
116+
117+
// waitForDNSResolversCreated waits for DNSNameResolver CRs associated with a CNP
118+
// to be created. This ensures the controller has processed the CNP and created the
119+
// DNSNameResolver CRs, so the CoreDNS dnsnameresolver plugin can intercept DNS
120+
// queries for the configured domains.
121+
// Note: We intentionally do NOT check Status.ResolvedNames here because the
122+
// dnsnameresolver CoreDNS plugin populates it reactively (only when actual DNS
123+
// queries flow through CoreDNS), not proactively. The connectivity retry logic
124+
// in testNetworkConnectivity handles the async chain:
125+
// DNS query → plugin intercepts → Status updated → address set updated → ACL applied.
126+
waitForDNSResolversCreated := func(name string, expectedCount int) {
127+
ginkgo.By(fmt.Sprintf("Waiting for %d DNSNameResolver(s) to be created for CNP %s", expectedCount, name))
128+
dnsClient := f.DNSNameResolverClient()
129+
labelSelector := fmt.Sprintf("anp=%s", name)
130+
131+
framework.WaitUntil(2*time.Second, 30*time.Second, func(_ context.Context) (bool, error) {
132+
resolverList := dnsClient.ListByLabel(labelSelector)
133+
if len(resolverList.Items) < expectedCount {
134+
framework.Logf("Found %d/%d DNSNameResolver(s) for CNP %s", len(resolverList.Items), expectedCount, name)
135+
return false, nil
136+
}
137+
framework.Logf("All %d DNSNameResolver(s) created for CNP %s", expectedCount, name)
138+
return true, nil
139+
}, fmt.Sprintf("DNSNameResolvers for CNP %s to be created", name))
115140
}
116141

117142
framework.ConformanceIt("should create CNP with domainName deny rule and verify connectivity behavior", func() {
@@ -158,6 +183,7 @@ var _ = framework.SerialDescribe("[group:cluster-network-policy]", func() {
158183
framework.ExpectEqual(cnp.Spec.Priority, int32(55))
159184
framework.ExpectEqual(cnp.Spec.Subject.Namespaces.MatchLabels["kubernetes.io/metadata.name"], namespaceName)
160185

186+
waitForDNSResolversCreated(cnpName, 1)
161187
testNetworkConnectivity("https://www.baidu.com", false, "Testing connectivity to baidu.com after applying CNP (should be blocked)")
162188

163189
ginkgo.By("Deleting ClusterNetworkPolicy " + cnpName)
@@ -229,6 +255,8 @@ var _ = framework.SerialDescribe("[group:cluster-network-policy]", func() {
229255
framework.ExpectEqual(string(peer2.DomainNames[0]), "*.google.com.")
230256
framework.ExpectEqual(cnp2.Spec.Priority, int32(45))
231257

258+
waitForDNSResolversCreated(cnpName, 1)
259+
waitForDNSResolversCreated(cnpName2, 1)
232260
testNetworkConnectivity("https://www.baidu.com", false, "Testing connectivity to baidu.com after applying both CNPs (should be blocked)")
233261
testNetworkConnectivity("https://www.google.com", true, "Testing connectivity to google.com after applying both CNPs (should be allowed)")
234262

@@ -288,6 +316,7 @@ var _ = framework.SerialDescribe("[group:cluster-network-policy]", func() {
288316
updatedCNP, _ := cnpClient.Update(context.TODO(), createdCNP, metav1.UpdateOptions{})
289317
framework.Logf("Successfully updated ClusterNetworkPolicy with baidu.com deny rule: %s", updatedCNP.Name)
290318

319+
waitForDNSResolversCreated(cnpName, 1)
291320
testNetworkConnectivity("https://www.baidu.com", false, "Testing connectivity to baidu.com after adding deny rule (should be blocked)")
292321
testNetworkConnectivity("https://www.google.com", true, "Testing connectivity to google.com after adding baidu.com deny rule (should still succeed)")
293322

@@ -299,6 +328,8 @@ var _ = framework.SerialDescribe("[group:cluster-network-policy]", func() {
299328
updatedcnp2, _ := cnpClient.Update(context.TODO(), updatedCNP, metav1.UpdateOptions{})
300329
framework.Logf("Successfully updated ClusterNetworkPolicy with both deny rules: %s", updatedcnp2.Name)
301330

331+
waitForDNSResolversCreated(cnpName, 2)
332+
302333
testNetworkConnectivity("https://www.baidu.com", false, "Testing connectivity to baidu.com after adding both deny rules (should be blocked)")
303334
testNetworkConnectivity("https://www.google.com", false, "Testing connectivity to google.com after adding both deny rules (should be blocked)")
304335

@@ -373,6 +404,7 @@ var _ = framework.SerialDescribe("[group:cluster-network-policy]", func() {
373404
framework.ExpectEqual(len(cnp.Spec.Egress), 2)
374405
framework.ExpectEqual(cnp.Spec.Priority, int32(80))
375406

407+
waitForDNSResolversCreated(cnpName, 1)
376408
testNetworkConnectivity("https://www.baidu.com", false, "Testing connectivity to baidu.com after applying cnp (should be blocked)")
377409
testNetworkConnectivity("https://www.google.com", true, "Testing connectivity to google.com after applying cnp (should be allowed)")
378410
testNetworkConnectivity("https://8.8.8.8", false, "Testing connectivity to 8.8.8.8 after applying cnp (should be blocked by CIDR rule)")
@@ -421,6 +453,7 @@ var _ = framework.SerialDescribe("[group:cluster-network-policy]", func() {
421453
framework.ExpectEqual(len(cnp.Spec.Egress), 1)
422454
framework.ExpectEqual(cnp.Spec.Priority, int32(85))
423455

456+
waitForDNSResolversCreated(cnpName, 1)
424457
testNetworkConnectivity("https://www.baidu.com", false, "Testing connectivity to www.baidu.com after applying cnp (should be blocked by wildcard)")
425458
testNetworkConnectivity("https://api.baidu.com", false, "Testing connectivity to api.baidu.com after applying cnp (should be blocked by wildcard)")
426459
testNetworkConnectivity("https://news.baidu.com", false, "Testing connectivity to news.baidu.com after applying cnp (should be blocked by wildcard)")

0 commit comments

Comments
 (0)