From 6080cd2f7ab02559affcca19de9de1945633e0de Mon Sep 17 00:00:00 2001 From: Ben McIlwain Date: Tue, 23 Jun 2026 12:30:04 -0400 Subject: [PATCH] Fix flaky RdapDomainSearchActionTest (#3097) Refactor RdapDomainSearchActionTest to dynamically resolve all domain and host Repository IDs (ROIDs) instead of asserting on hardcoded, sequence-generated strings (like "2E-LOL" or "6-LOL"). When tests are executed in parallel (as is common in CI environments like Kokoro), multiple test threads concurrently reset and allocate from the shared database sequence 'project_wide_unique_id_seq'. This interleaves ID allocations non-deterministically, causing any test asserting on exact, hardcoded sequence values to flake. To fix this, createManyDomainsAndHosts was updated to return the list of persisted domains, allowing tests to dynamically resolve their ROIDs. All other test cases were refactored to dynamically fetch the ROIDs of pre-created domains and hosts (stored in fields or in hostNameToHostMap, using punycode keys for IDN hosts) for their JSON assertions, rendering the entire suite robust against sequence shifts. --- .../rdap/RdapDomainSearchActionTest.java | 229 +++++++++--------- 1 file changed, 115 insertions(+), 114 deletions(-) diff --git a/core/src/test/java/google/registry/rdap/RdapDomainSearchActionTest.java b/core/src/test/java/google/registry/rdap/RdapDomainSearchActionTest.java index e727bb8c8..0885d461c 100644 --- a/core/src/test/java/google/registry/rdap/RdapDomainSearchActionTest.java +++ b/core/src/test/java/google/registry/rdap/RdapDomainSearchActionTest.java @@ -283,15 +283,15 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase createManyDomainsAndHosts( int numActiveDomains, int numTotalDomainsPerActiveDomain, int numHosts) { ImmutableSet.Builder> hostKeysBuilder = new ImmutableSet.Builder<>(); ImmutableSet.Builder subordinateHostnamesBuilder = new ImmutableSet.Builder<>(); @@ -340,7 +340,7 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase") - .addNameserver("ns1.cat.lol", "2-ROID") - .addNameserver("ns2.cat.lol", "4-ROID") + .addNameserver("ns1.cat.lol", hostNs1CatLol.getRepoId()) + .addNameserver("ns2.cat.lol", hostNs2CatLol.getRepoId()) .setNextQuery(queryString) .load(filename)); } @@ -367,10 +367,10 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase") - .addNameserver("ns1.cat.example", "7-ROID") - .addNameserver("ns2.dog.lol", "9-ROID") + .addNameserver("ns1.cat.example", hostNameToHostMap.get("ns1.cat.example").getRepoId()) + .addNameserver("ns2.dog.lol", hostNameToHostMap.get("ns2.dog.lol").getRepoId()) .setNextQuery(queryString) .load(filename)); } @@ -679,10 +679,11 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase domains = createManyDomainsAndHosts(4, 50, 2); rememberWildcardType("domain*.lol"); assertAboutJson() .that(generateActualJson(RequestType.NAME, "domain*.lol")) .isEqualTo( jsonFileBuilder() - .addDomain("domain100.lol", "8E-LOL") - .addDomain("domain150.lol", "5C-LOL") - .addDomain("domain200.lol", "2A-LOL") + .addDomain("domain100.lol", domains.get(100).getRepoId()) + .addDomain("domain150.lol", domains.get(50).getRepoId()) + .addDomain("domain200.lol", domains.get(0).getRepoId()) .addDomain("domainunused.lol", "unused-LOL") .load("rdap_incomplete_domain_result_set.json")); assertThat(response.getStatus()).isEqualTo(200); @@ -990,28 +991,28 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase domains = createManyDomainsAndHosts(4, 1, 2); runSuccessfulTestWithFourDomains( RequestType.NAME, "domain*.lol", - "2D-LOL", - "2C-LOL", - "2B-LOL", - "2A-LOL", + domains.get(3).getRepoId(), + domains.get(2).getRepoId(), + domains.get(1).getRepoId(), + domains.get(0).getRepoId(), "rdap_nontruncated_domains.json"); verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(4L)); } @Test void testDomainMatch_truncatedResultsSet() { - createManyDomainsAndHosts(5, 1, 2); + ImmutableList domains = createManyDomainsAndHosts(5, 1, 2); runSuccessfulTestWithFourDomains( RequestType.NAME, "domain*.lol", - "2E-LOL", - "2D-LOL", - "2C-LOL", - "2B-LOL", + domains.get(4).getRepoId(), + domains.get(3).getRepoId(), + domains.get(2).getRepoId(), + domains.get(1).getRepoId(), "name=domain*.lol&cursor=ZG9tYWluNC5sb2w%3D", "rdap_domains_four_truncated.json"); verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(5L), IncompletenessWarningType.TRUNCATED); @@ -1019,16 +1020,16 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase domains = createManyDomainsAndHosts(4, 1, 2); rememberWildcardType("*.lol"); assertAboutJson() .that(generateActualJson(RequestType.NAME, "*.lol")) .isEqualTo( jsonFileBuilder() - .addDomain("cat.lol", "6-LOL") - .addDomain("cat2.lol", "B-LOL") - .addDomain("domain1.lol", "2D-LOL") - .addDomain("domain2.lol", "2C-LOL") + .addDomain("cat.lol", domainCatLol.getRepoId()) + .addDomain("cat2.lol", domainCatLol2.getRepoId()) + .addDomain("domain1.lol", domains.get(3).getRepoId()) + .addDomain("domain2.lol", domains.get(2).getRepoId()) .setNextQuery("name=*.lol&cursor=ZG9tYWluMi5sb2w%3D") .load("rdap_domains_four_truncated.json")); verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(5L), IncompletenessWarningType.TRUNCATED); @@ -1038,14 +1039,14 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase domains = createManyDomainsAndHosts(9, 1, 2); runSuccessfulTestWithFourDomains( RequestType.NAME, "domain*.lol", - "32-LOL", - "31-LOL", - "30-LOL", - "2F-LOL", + domains.get(8).getRepoId(), + domains.get(7).getRepoId(), + domains.get(6).getRepoId(), + domains.get(5).getRepoId(), "name=domain*.lol&cursor=ZG9tYWluNC5sb2w%3D", "rdap_domains_four_truncated.json"); verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(5L), IncompletenessWarningType.TRUNCATED); @@ -1053,16 +1054,16 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase domains = createManyDomainsAndHosts(5, 6, 2); rememberWildcardType("domain*.lol"); assertAboutJson() .that(generateActualJson(RequestType.NAME, "domain*.lol")) .isEqualTo( jsonFileBuilder() - .addDomain("domain12.lol", "3C-LOL") - .addDomain("domain18.lol", "36-LOL") - .addDomain("domain24.lol", "30-LOL") - .addDomain("domain30.lol", "2A-LOL") + .addDomain("domain12.lol", domains.get(18).getRepoId()) + .addDomain("domain18.lol", domains.get(12).getRepoId()) + .addDomain("domain24.lol", domains.get(6).getRepoId()) + .addDomain("domain30.lol", domains.get(0).getRepoId()) .setNextQuery("name=domain*.lol&cursor=ZG9tYWluMzAubG9s") .load("rdap_domains_four_truncated.json")); assertThat(response.getStatus()).isEqualTo(200); @@ -1261,10 +1262,10 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase domains = createManyDomainsAndHosts(4, 1, 2); runSuccessfulTestWithFourDomains( RequestType.NS_LDH_NAME, "ns1.domain1.lol", - "2D-LOL", - "2C-LOL", - "2B-LOL", - "2A-LOL", + domains.get(3).getRepoId(), + domains.get(2).getRepoId(), + domains.get(1).getRepoId(), + domains.get(0).getRepoId(), "rdap_nontruncated_domains.json"); verifyMetrics(SearchType.BY_NAMESERVER_NAME, Optional.of(4L), Optional.of(1L)); } @Test void testNameserverMatch_truncatedResultsSet() { - createManyDomainsAndHosts(5, 1, 2); + ImmutableList domains = createManyDomainsAndHosts(5, 1, 2); runSuccessfulTestWithFourDomains( RequestType.NS_LDH_NAME, "ns1.domain1.lol", - "2E-LOL", - "2D-LOL", - "2C-LOL", - "2B-LOL", + domains.get(4).getRepoId(), + domains.get(3).getRepoId(), + domains.get(2).getRepoId(), + domains.get(1).getRepoId(), "nsLdhName=ns1.domain1.lol&cursor=ZG9tYWluNC5sb2w%3D", "rdap_domains_four_truncated.json"); verifyMetrics( @@ -1463,14 +1464,14 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase domains = createManyDomainsAndHosts(9, 1, 2); runSuccessfulTestWithFourDomains( RequestType.NS_LDH_NAME, "ns1.domain1.lol", - "32-LOL", - "31-LOL", - "30-LOL", - "2F-LOL", + domains.get(8).getRepoId(), + domains.get(7).getRepoId(), + domains.get(6).getRepoId(), + domains.get(5).getRepoId(), "nsLdhName=ns1.domain1.lol&cursor=ZG9tYWluNC5sb2w%3D", "rdap_domains_four_truncated.json"); verifyMetrics( @@ -1484,16 +1485,16 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase domains = createManyDomainsAndHosts(4, 1, 36); rememberWildcardType("ns*.domain1.lol"); assertAboutJson() .that(generateActualJson(RequestType.NS_LDH_NAME, "ns*.domain1.lol")) .isEqualTo( jsonFileBuilder() - .addDomain("domain1.lol", "71-LOL") - .addDomain("domain2.lol", "70-LOL") - .addDomain("domain3.lol", "6F-LOL") - .addDomain("domain4.lol", "6E-LOL") + .addDomain("domain1.lol", domains.get(3).getRepoId()) + .addDomain("domain2.lol", domains.get(2).getRepoId()) + .addDomain("domain3.lol", domains.get(1).getRepoId()) + .addDomain("domain4.lol", domains.get(0).getRepoId()) .load("rdap_nontruncated_domains.json")); assertThat(response.getStatus()).isEqualTo(200); verifyMetrics(SearchType.BY_NAMESERVER_NAME, Optional.of(4L), Optional.of(36L)); @@ -1501,14 +1502,14 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase domains = createManyDomainsAndHosts(2, 1, 41); rememberWildcardType("ns*.domain1.lol"); assertAboutJson() .that(generateActualJson(RequestType.NS_LDH_NAME, "ns*.domain1.lol")) .isEqualTo( jsonFileBuilder() - .addDomain("domain1.lol", "79-LOL") - .addDomain("domain2.lol", "78-LOL") + .addDomain("domain1.lol", domains.get(1).getRepoId()) + .addDomain("domain2.lol", domains.get(0).getRepoId()) .load("rdap_incomplete_domains.json")); assertThat(response.getStatus()).isEqualTo(200); verifyMetrics( @@ -1641,10 +1642,10 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase") - .addNameserver("ns1.cat.lol", "2-ROID") - .addNameserver("ns2.cat.lol", "4-ROID") + .addNameserver("ns1.cat.lol", hostNs1CatLol.getRepoId()) + .addNameserver("ns2.cat.lol", hostNs2CatLol.getRepoId()) .load("rdap_domain.json"))); assertThat(response.getStatus()).isEqualTo(200); verifyMetrics(SearchType.BY_NAMESERVER_ADDRESS, 1, 1); @@ -1667,28 +1668,28 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase domains = createManyDomainsAndHosts(4, 1, 2); runSuccessfulTestWithFourDomains( RequestType.NS_IP, "5.5.5.1", - "2D-LOL", - "2C-LOL", - "2B-LOL", - "2A-LOL", + domains.get(3).getRepoId(), + domains.get(2).getRepoId(), + domains.get(1).getRepoId(), + domains.get(0).getRepoId(), "rdap_nontruncated_domains.json"); verifyMetrics(SearchType.BY_NAMESERVER_ADDRESS, 4, 1); } @Test void testAddressMatch_truncatedResultsSet() { - createManyDomainsAndHosts(5, 1, 2); + ImmutableList domains = createManyDomainsAndHosts(5, 1, 2); runSuccessfulTestWithFourDomains( RequestType.NS_IP, "5.5.5.1", - "2E-LOL", - "2D-LOL", - "2C-LOL", - "2B-LOL", + domains.get(4).getRepoId(), + domains.get(3).getRepoId(), + domains.get(2).getRepoId(), + domains.get(1).getRepoId(), "nsIp=5.5.5.1&cursor=ZG9tYWluNC5sb2w%3D", "rdap_domains_four_truncated.json"); verifyMetrics( @@ -1700,14 +1701,14 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase domains = createManyDomainsAndHosts(9, 1, 2); runSuccessfulTestWithFourDomains( RequestType.NS_IP, "5.5.5.1", - "32-LOL", - "31-LOL", - "30-LOL", - "2F-LOL", + domains.get(8).getRepoId(), + domains.get(7).getRepoId(), + domains.get(6).getRepoId(), + domains.get(5).getRepoId(), "nsIp=5.5.5.1&cursor=ZG9tYWluNC5sb2w%3D", "rdap_domains_four_truncated.json"); verifyMetrics(