Fix a BSA bug and refactor some unit tests (#2291)

* Refactor a few BSA unit tests

Added a few helpers for managing reserved list in tests and updated the
tests to use them.

Also fixed a bug: when quering for newly created domains, the query
should be restricted to bsa-enrolled tlds.
This commit is contained in:
Weimin Yu
2024-01-18 16:12:59 -05:00
committed by GitHub
parent 2621b2d679
commit 432871add9
23 changed files with 283 additions and 169 deletions
@@ -0,0 +1,65 @@
// Copyright 2024 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.bsa;
import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import google.registry.model.tld.Tld;
import google.registry.model.tld.label.ReservationType;
import google.registry.model.tld.label.ReservedList;
import google.registry.model.tld.label.ReservedList.ReservedListEntry;
import google.registry.model.tld.label.ReservedListDao;
/** Helpers for setting up reserved lists in tests. */
public final class ReservedDomainsTestingUtils {
private ReservedDomainsTestingUtils() {}
public static void createReservedList(
String listName, ImmutableMap<String, ReservationType> reservedLabels) {
ImmutableMap<String, ReservedListEntry> entries =
ImmutableMap.copyOf(
Maps.transformEntries(
reservedLabels, (key, value) -> ReservedListEntry.create(key, value, "")));
ReservedListDao.save(
new ReservedList.Builder()
.setName(listName)
.setCreationTimestamp(START_OF_TIME)
.setShouldPublish(true)
.setReservedListMap(entries)
.build());
}
public static void createReservedList(
String listName, String label, ReservationType reservationType) {
createReservedList(listName, ImmutableMap.of(label, reservationType));
}
public static void addReservedListsToTld(String tldStr, ImmutableList<String> listNames) {
Tld tld = Tld.get(tldStr);
ImmutableSet<String> reservedLists =
new ImmutableSet.Builder<String>()
.addAll(tld.getReservedListNames())
.addAll(listNames)
.build();
persistResource(tld.asBuilder().setReservedListsByName(reservedLists).build());
}
}
@@ -15,6 +15,8 @@
package google.registry.bsa;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.bsa.ReservedDomainsTestingUtils.addReservedListsToTld;
import static google.registry.bsa.ReservedDomainsTestingUtils.createReservedList;
import static google.registry.bsa.ReservedDomainsUtils.getAllReservedDomainsInTld;
import static google.registry.model.tld.Tld.TldState.GENERAL_AVAILABILITY;
import static google.registry.model.tld.Tld.TldState.START_DATE_SUNRISE;
@@ -26,13 +28,10 @@ import static google.registry.model.tld.label.ReservationType.RESERVED_FOR_SPECI
import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.persistResource;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedMap;
import google.registry.model.tld.Tld;
import google.registry.model.tld.label.ReservedList;
import google.registry.model.tld.label.ReservedList.ReservedListEntry;
import google.registry.model.tld.label.ReservedListDao;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationWithCoverageExtension;
import google.registry.testing.FakeClock;
@@ -51,41 +50,19 @@ class ReservedDomainsUtilsTest {
@BeforeEach
void setup() {
ImmutableMap<String, ReservedListEntry> byType =
createReservedList(
"testlist",
ImmutableMap.of(
"sunrise",
ReservedListEntry.create("sunrise", ALLOWED_IN_SUNRISE, ""),
"specific",
ReservedListEntry.create("specific", RESERVED_FOR_SPECIFIC_USE, ""),
"anchor",
ReservedListEntry.create("anchor", RESERVED_FOR_ANCHOR_TENANT, ""),
"fully",
ReservedListEntry.create("fully", FULLY_BLOCKED, ""),
"name",
ReservedListEntry.create("name", NAME_COLLISION, ""));
ImmutableMap<String, ReservedListEntry> altList =
"sunrise", ALLOWED_IN_SUNRISE,
"specific", RESERVED_FOR_SPECIFIC_USE,
"anchor", RESERVED_FOR_ANCHOR_TENANT,
"fully", FULLY_BLOCKED,
"name", NAME_COLLISION));
createReservedList(
"testlist2",
ImmutableMap.of(
"anchor",
ReservedListEntry.create("anchor", RESERVED_FOR_ANCHOR_TENANT, ""),
"somethingelse",
ReservedListEntry.create("somethingelse", RESERVED_FOR_ANCHOR_TENANT, ""));
ReservedListDao.save(
new ReservedList.Builder()
.setName("testlist")
.setCreationTimestamp(fakeClock.nowUtc())
.setShouldPublish(false)
.setReservedListMap(byType)
.build());
ReservedListDao.save(
new ReservedList.Builder()
.setName("testlist2")
.setCreationTimestamp(fakeClock.nowUtc())
.setShouldPublish(false)
.setReservedListMap(altList)
.build());
"anchor", RESERVED_FOR_ANCHOR_TENANT,
"somethingelse", RESERVED_FOR_ANCHOR_TENANT));
createTld("tld");
persistResource(
@@ -95,15 +72,11 @@ class ReservedDomainsUtilsTest {
ImmutableSortedMap.of(
fakeClock.nowUtc(), START_DATE_SUNRISE,
fakeClock.nowUtc().plusMillis(1), GENERAL_AVAILABILITY))
.setReservedListsByName(ImmutableSet.of("testlist"))
.build());
addReservedListsToTld("tld", ImmutableList.of("testlist"));
createTld("tld2");
persistResource(
Tld.get("tld2")
.asBuilder()
.setReservedListsByName(ImmutableSet.of("testlist", "testlist2"))
.build());
addReservedListsToTld("tld2", ImmutableList.of("testlist", "testlist2"));
}
@Test
@@ -50,7 +50,7 @@ public class BsaLabelUtilsTest {
@Test
void isLabelBlocked_yes() {
persistBsaLabel("abc", fakeClock.nowUtc());
persistBsaLabel("abc");
assertThat(isLabelBlocked("abc")).isTrue();
}
@@ -26,10 +26,13 @@ public final class BsaTestingUtils {
public static final Duration DEFAULT_DOWNLOAD_INTERVAL = Duration.standardHours(1);
public static final Duration DEFAULT_NOP_INTERVAL = Duration.standardDays(1);
/** An arbitrary point of time used as BsaLabels' creation time. */
public static final DateTime BSA_LABEL_CREATION_TIME = DateTime.parse("2023-12-31T00:00:00Z");
private BsaTestingUtils() {}
public static void persistBsaLabel(String domainLabel, DateTime creationTime) {
tm().transact(() -> tm().put(new BsaLabel(domainLabel, creationTime)));
public static void persistBsaLabel(String domainLabel) {
tm().transact(() -> tm().put(new BsaLabel(domainLabel, BSA_LABEL_CREATION_TIME)));
}
public static DownloadScheduler createDownloadScheduler(Clock clock) {
@@ -15,7 +15,8 @@
package google.registry.bsa.persistence;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.bsa.BsaTransactions.bsaTransact;
import static google.registry.bsa.ReservedDomainsTestingUtils.addReservedListsToTld;
import static google.registry.bsa.ReservedDomainsTestingUtils.createReservedList;
import static google.registry.bsa.persistence.BsaTestingUtils.persistBsaLabel;
import static google.registry.model.tld.label.ReservationType.RESERVED_FOR_SPECIFIC_USE;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
@@ -24,15 +25,11 @@ import static google.registry.testing.DatabaseHelper.newDomain;
import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableList;
import google.registry.bsa.api.UnblockableDomain;
import google.registry.bsa.api.UnblockableDomainChange;
import google.registry.bsa.persistence.BsaUnblockableDomain.Reason;
import google.registry.model.tld.Tld;
import google.registry.model.tld.label.ReservedList;
import google.registry.model.tld.label.ReservedList.ReservedListEntry;
import google.registry.model.tld.label.ReservedListDao;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationWithCoverageExtension;
import google.registry.testing.FakeClock;
@@ -44,7 +41,7 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
/** Unit tests for {@link DomainsRefresher}. */
public class DomainRefresherTest {
public class DomainsRefresherTest {
FakeClock fakeClock = new FakeClock(DateTime.parse("2023-11-09T02:08:57.880Z"));
@@ -66,52 +63,54 @@ public class DomainRefresherTest {
}
@Test
void staleUnblockableRemoved_wasRegistered() {
persistBsaLabel("label", fakeClock.nowUtc().minus(Duration.standardDays(1)));
void registeredUnblockable_removed_afterDomainIsDeleted() {
persistBsaLabel("label");
tm().transact(() -> tm().insert(BsaUnblockableDomain.of("label.tld", Reason.REGISTERED)));
assertThat(bsaTransact(refresher::refreshStaleUnblockables))
assertThat(refresher.refreshStaleUnblockables())
.containsExactly(
UnblockableDomainChange.ofDeleted(
UnblockableDomain.of("label.tld", UnblockableDomain.Reason.REGISTERED)));
}
@Test
void staleUnblockableRemoved_wasReserved() {
persistBsaLabel("label", fakeClock.nowUtc().minus(Duration.standardDays(1)));
void reservedUnblockable_removed_whenReservedLabelIsRemoved() {
persistBsaLabel("label");
tm().transact(() -> tm().insert(BsaUnblockableDomain.of("label.tld", Reason.RESERVED)));
assertThat(bsaTransact(refresher::refreshStaleUnblockables))
assertThat(refresher.refreshStaleUnblockables())
.containsExactly(
UnblockableDomainChange.ofDeleted(
UnblockableDomain.of("label.tld", UnblockableDomain.Reason.RESERVED)));
}
@Test
void newUnblockableAdded_isRegistered() {
void regsiteredUnblockable_added_whenDomainIsAdded() {
persistResource(newDomain("label.tld"));
persistBsaLabel("label", fakeClock.nowUtc().minus(Duration.standardDays(1)));
assertThat(bsaTransact(refresher::getNewUnblockables))
persistBsaLabel("label");
assertThat(refresher.getNewUnblockables())
.containsExactly(
UnblockableDomainChange.ofNew(
UnblockableDomain.of("label.tld", UnblockableDomain.Reason.REGISTERED)));
}
@Test
void newUnblockableAdded_isReserved() {
persistBsaLabel("label", fakeClock.nowUtc().minus(Duration.standardDays(1)));
setReservedList("label");
assertThat(bsaTransact(refresher::getNewUnblockables))
void reservedUnblockable_added_whenReservedLabelIsAdded() {
persistBsaLabel("label");
createReservedList("reservedList", "label", RESERVED_FOR_SPECIFIC_USE);
addReservedListsToTld("tld", ImmutableList.of("reservedList"));
assertThat(refresher.getNewUnblockables())
.containsExactly(
UnblockableDomainChange.ofNew(
UnblockableDomain.of("label.tld", UnblockableDomain.Reason.RESERVED)));
}
@Test
void staleUnblockableDowngraded_registeredToReserved() {
persistBsaLabel("label", fakeClock.nowUtc().minus(Duration.standardDays(1)));
setReservedList("label");
void registeredUnblockable_changedToReserved_whenDomainIsDeletedButLabelIsReserved() {
persistBsaLabel("label");
createReservedList("reservedList", "label", RESERVED_FOR_SPECIFIC_USE);
addReservedListsToTld("tld", ImmutableList.of("reservedList"));
tm().transact(() -> tm().insert(BsaUnblockableDomain.of("label.tld", Reason.REGISTERED)));
assertThat(bsaTransact(refresher::refreshStaleUnblockables))
assertThat(refresher.refreshStaleUnblockables())
.containsExactly(
UnblockableDomainChange.ofChanged(
UnblockableDomain.of("label.tld", UnblockableDomain.Reason.REGISTERED),
@@ -119,12 +118,12 @@ public class DomainRefresherTest {
}
@Test
void staleUnblockableUpgraded_reservedToRegisteredButNotReserved() {
persistBsaLabel("label", fakeClock.nowUtc().minus(Duration.standardDays(1)));
void reservedUnblockableUpgraded_changedToRegistered_whenDomainIsCreatedButNoLongerReserved() {
persistBsaLabel("label");
tm().transact(() -> tm().insert(BsaUnblockableDomain.of("label.tld", Reason.RESERVED)));
persistResource(newDomain("label.tld"));
assertThat(bsaTransact(refresher::refreshStaleUnblockables))
assertThat(refresher.refreshStaleUnblockables())
.containsExactly(
UnblockableDomainChange.ofChanged(
UnblockableDomain.of("label.tld", UnblockableDomain.Reason.RESERVED),
@@ -132,31 +131,17 @@ public class DomainRefresherTest {
}
@Test
void staleUnblockableUpgraded_wasReserved_isReservedAndRegistered() {
persistBsaLabel("label", fakeClock.nowUtc().minus(Duration.standardDays(1)));
setReservedList("label");
void reservedUnblockableUpgraded_changedToRegistered_whenDomainIsCreatedAndStillReserved() {
persistBsaLabel("label");
createReservedList("reservedList", "label", RESERVED_FOR_SPECIFIC_USE);
addReservedListsToTld("tld", ImmutableList.of("reservedList"));
tm().transact(() -> tm().insert(BsaUnblockableDomain.of("label.tld", Reason.RESERVED)));
persistResource(newDomain("label.tld"));
assertThat(bsaTransact(refresher::refreshStaleUnblockables))
assertThat(refresher.refreshStaleUnblockables())
.containsExactly(
UnblockableDomainChange.ofChanged(
UnblockableDomain.of("label.tld", UnblockableDomain.Reason.RESERVED),
UnblockableDomain.Reason.REGISTERED));
}
private void setReservedList(String label) {
ImmutableMap<String, ReservedListEntry> reservedNameMap =
ImmutableMap.of(label, ReservedListEntry.create(label, RESERVED_FOR_SPECIFIC_USE, ""));
ReservedListDao.save(
new ReservedList.Builder()
.setName("testlist")
.setCreationTimestamp(fakeClock.nowUtc())
.setShouldPublish(false)
.setReservedListMap(reservedNameMap)
.build());
persistResource(
Tld.get("tld").asBuilder().setReservedListsByName(ImmutableSet.of("testlist")).build());
}
}
@@ -16,10 +16,11 @@ package google.registry.bsa.persistence;
import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.bsa.BsaTransactions.bsaQuery;
import static google.registry.bsa.persistence.Queries.deleteBsaLabelByLabels;
import static google.registry.bsa.persistence.Queries.queryBsaLabelByLabels;
import static google.registry.bsa.persistence.Queries.queryBsaUnblockableDomainByLabels;
import static google.registry.bsa.persistence.Queries.queryLivesDomains;
import static google.registry.bsa.persistence.Queries.queryNewlyCreatedDomains;
import static google.registry.bsa.persistence.Queries.queryUnblockablesByNames;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.createTlds;
@@ -182,7 +183,7 @@ class QueriesTest {
}
@Test
void queryLivesDomains_onlyLiveDomainsReturned() {
void queryNewlyCreatedDomains_onlyLiveDomainsReturned() {
DateTime testStartTime = fakeClock.nowUtc();
createTlds("tld");
persistNewRegistrar("TheRegistrar");
@@ -199,7 +200,29 @@ class QueriesTest {
newDomain("d2.tld").asBuilder().setCreationTimeForTest(fakeClock.nowUtc()).build());
fakeClock.advanceOneMilli();
// Now is time 2
assertThat(tm().transact(() -> queryLivesDomains(testStartTime, fakeClock.nowUtc())))
assertThat(
bsaQuery(
() ->
queryNewlyCreatedDomains(
ImmutableList.of("tld"), testStartTime, fakeClock.nowUtc())))
.containsExactly("d1.tld", "d2.tld");
}
@Test
void queryNewlyCreatedDomains_onlyDomainsInRequestedTldsReturned() {
DateTime testStartTime = fakeClock.nowUtc();
createTlds("tld", "tld2");
persistNewRegistrar("TheRegistrar");
persistResource(
newDomain("d1.tld").asBuilder().setCreationTimeForTest(fakeClock.nowUtc()).build());
persistResource(
newDomain("d2.tld2").asBuilder().setCreationTimeForTest(fakeClock.nowUtc()).build());
fakeClock.advanceOneMilli();
assertThat(
bsaQuery(
() ->
queryNewlyCreatedDomains(
ImmutableList.of("tld"), testStartTime, fakeClock.nowUtc())))
.containsExactly("d1.tld");
}
}
@@ -288,7 +288,7 @@ class CheckApiActionTest {
@Test
void testSuccess_blockedByBsa() {
BsaTestingUtils.persistBsaLabel("rich", START_OF_TIME);
BsaTestingUtils.persistBsaLabel("rich");
persistResource(
Tld.get("example").asBuilder().setBsaEnrollStartTime(Optional.of(START_OF_TIME)).build());
assertThat(getCheckResponse("rich.example"))
@@ -14,6 +14,7 @@
package google.registry.flows.domain;
import static google.registry.bsa.persistence.BsaTestingUtils.persistBsaLabel;
import static google.registry.model.billing.BillingBase.RenewalPriceBehavior.DEFAULT;
import static google.registry.model.billing.BillingBase.RenewalPriceBehavior.NONPREMIUM;
import static google.registry.model.billing.BillingBase.RenewalPriceBehavior.SPECIFIED;
@@ -44,7 +45,6 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedMap;
import com.google.common.collect.Ordering;
import google.registry.bsa.persistence.BsaTestingUtils;
import google.registry.flows.EppException;
import google.registry.flows.FlowUtils.NotLoggedInException;
import google.registry.flows.FlowUtils.UnknownCurrencyEppException;
@@ -160,7 +160,7 @@ class DomainCheckFlowTest extends ResourceCheckFlowTestCase<DomainCheckFlow, Dom
@Test
void testSuccess_bsaBlocked_otherwiseAvailable_blocked() throws Exception {
BsaTestingUtils.persistBsaLabel("example1", clock.nowUtc());
persistBsaLabel("example1");
doCheckTest(
create(false, "example1.tld", "Blocked by a GlobalBlock service"),
create(true, "example2.tld", null),
@@ -169,7 +169,7 @@ class DomainCheckFlowTest extends ResourceCheckFlowTestCase<DomainCheckFlow, Dom
@Test
void testSuccess_bsaBlocked_alsoRegistered_registered() throws Exception {
BsaTestingUtils.persistBsaLabel("example1", clock.nowUtc());
persistBsaLabel("example1");
persistActiveDomain("example1.tld");
doCheckTest(
create(false, "example1.tld", "In use"),
@@ -179,8 +179,8 @@ class DomainCheckFlowTest extends ResourceCheckFlowTestCase<DomainCheckFlow, Dom
@Test
void testSuccess_bsaBlocked_alsoReserved_reserved() throws Exception {
BsaTestingUtils.persistBsaLabel("reserved", clock.nowUtc());
BsaTestingUtils.persistBsaLabel("allowedinsunrise", clock.nowUtc());
persistBsaLabel("reserved");
persistBsaLabel("allowedinsunrise");
setEppInput("domain_check_one_tld_reserved.xml");
doCheckTest(
create(false, "reserved.tld", "Reserved"),
@@ -2575,7 +2575,7 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
@Test
void testSuccess_bsaLabelMatch_notEnrolled() throws Exception {
persistResource(Tld.get("tld").asBuilder().setBsaEnrollStartTime(Optional.empty()).build());
persistBsaLabel("example", clock.nowUtc());
persistBsaLabel("example");
persistContactsAndHosts();
doSuccessfulTest();
}
@@ -2587,7 +2587,7 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
.asBuilder()
.setBsaEnrollStartTime(Optional.of(clock.nowUtc().plusSeconds(1)))
.build());
persistBsaLabel("example", clock.nowUtc());
persistBsaLabel("example");
persistContactsAndHosts();
doSuccessfulTest();
}
@@ -2599,7 +2599,7 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
.asBuilder()
.setBsaEnrollStartTime(Optional.of(clock.nowUtc().minusSeconds(1)))
.build());
persistBsaLabel("example", clock.nowUtc());
persistBsaLabel("example");
persistContactsAndHosts();
EppException thrown = assertThrows(DomainLabelBlockedByBsaException.class, this::runFlow);
assertAboutEppExceptions()
@@ -174,7 +174,7 @@ public class WhoisActionTest {
.asBuilder()
.setBsaEnrollStartTime(Optional.of(clock.nowUtc().minusDays(1)))
.build());
persistBsaLabel("cat", clock.nowUtc());
persistBsaLabel("cat");
Registrar registrar = persistResource(makeRegistrar("evilregistrar", "Yes Virginia", ACTIVE));
persistResource(makeDomainWithRegistrar(registrar));
@@ -191,7 +191,7 @@ public class WhoisActionTest {
.asBuilder()
.setBsaEnrollStartTime(Optional.of(clock.nowUtc().minusDays(1)))
.build());
persistBsaLabel("cat", clock.nowUtc());
persistBsaLabel("cat");
newWhoisAction("domain cat.lol\r\n").run();
assertThat(response.getStatus()).isEqualTo(200);
@@ -225,7 +225,7 @@ class WhoisHttpActionTest {
.asBuilder()
.setBsaEnrollStartTime(Optional.of(clock.nowUtc().minusDays(1)))
.build());
persistBsaLabel("cat", clock.nowUtc());
persistBsaLabel("cat");
Registrar registrar = persistResource(makeRegistrar("evilregistrar", "Yes Virginia", ACTIVE));
persistResource(
@@ -256,7 +256,7 @@ class WhoisHttpActionTest {
.asBuilder()
.setBsaEnrollStartTime(Optional.of(clock.nowUtc().minusDays(1)))
.build());
persistBsaLabel("cat", clock.nowUtc());
persistBsaLabel("cat");
newWhoisHttpAction("domain cat.lol\r\n").run();
assertThat(response.getStatus()).isEqualTo(404);