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
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 283 additions and 169 deletions

View file

@ -65,7 +65,7 @@ public class BsaRefreshAction implements Runnable {
GcsClient gcsClient, GcsClient gcsClient,
BsaReportSender bsaReportSender, BsaReportSender bsaReportSender,
@Config("bsaTxnBatchSize") int transactionBatchSize, @Config("bsaTxnBatchSize") int transactionBatchSize,
@Config("domainTxnMaxDuration") Duration domainTxnMaxDuration, @Config("domainCreateTxnCommitTimeLag") Duration domainTxnMaxDuration,
BsaLock bsaLock, BsaLock bsaLock,
Clock clock, Clock clock,
Response response) { Response response) {

View file

@ -14,7 +14,10 @@
package google.registry.bsa; package google.registry.bsa;
import static com.google.common.base.Verify.verify;
import static google.registry.persistence.PersistenceModule.TransactionIsolationLevel.TRANSACTION_REPEATABLE_READ; import static google.registry.persistence.PersistenceModule.TransactionIsolationLevel.TRANSACTION_REPEATABLE_READ;
import static google.registry.persistence.transaction.JpaTransactionManagerImpl.isInTransaction;
import static google.registry.persistence.transaction.TransactionManagerFactory.replicaTm;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm; import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import com.google.errorprone.annotations.CanIgnoreReturnValue; import com.google.errorprone.annotations.CanIgnoreReturnValue;
@ -23,19 +26,23 @@ import java.util.concurrent.Callable;
/** /**
* Helpers for executing JPA transactions for BSA processing. * Helpers for executing JPA transactions for BSA processing.
* *
* <p>All mutating transactions for BSA may be executed at the {@code TRANSACTION_REPEATABLE_READ} * <p>All mutating transactions for BSA are executed at the {@code TRANSACTION_REPEATABLE_READ}
* level. * level since the global {@link BsaLock} ensures there is a single writer at any time.
*
* <p>All domain and label queries can use the replica since all processing are snapshot based.
*/ */
public final class BsaTransactions { public final class BsaTransactions {
@CanIgnoreReturnValue @CanIgnoreReturnValue
public static <T> T bsaTransact(Callable<T> work) { public static <T> T bsaTransact(Callable<T> work) {
verify(!isInTransaction(), "May only be used for top-level transactions.");
return tm().transact(work, TRANSACTION_REPEATABLE_READ); return tm().transact(work, TRANSACTION_REPEATABLE_READ);
} }
@CanIgnoreReturnValue @CanIgnoreReturnValue
public static <T> T bsaQuery(Callable<T> work) { public static <T> T bsaQuery(Callable<T> work) {
return tm().transact(work, TRANSACTION_REPEATABLE_READ); verify(!isInTransaction(), "May only be used for top-level transactions.");
return replicaTm().transact(work, TRANSACTION_REPEATABLE_READ);
} }
private BsaTransactions() {} private BsaTransactions() {}

View file

@ -19,6 +19,7 @@ import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static google.registry.bsa.BsaStringUtils.DOMAIN_JOINER; import static google.registry.bsa.BsaStringUtils.DOMAIN_JOINER;
import static google.registry.flows.domain.DomainFlowUtils.isReserved; import static google.registry.flows.domain.DomainFlowUtils.isReserved;
import static google.registry.model.tld.Tlds.findTldForName; import static google.registry.model.tld.Tlds.findTldForName;
import static google.registry.model.tld.label.ReservedList.loadReservedLists;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.net.InternetDomainName; import com.google.common.net.InternetDomainName;
@ -51,12 +52,9 @@ public final class ReservedDomainsUtils {
.flatMap(ImmutableSet::stream); .flatMap(ImmutableSet::stream);
} }
/** Returns */ /** Returns all reserved domains in a given {@code tld} as of {@code now}. */
static ImmutableSet<String> getAllReservedDomainsInTld(Tld tld, DateTime now) { static ImmutableSet<String> getAllReservedDomainsInTld(Tld tld, DateTime now) {
return tld.getReservedListNames().stream() return loadReservedLists(tld.getReservedListNames()).stream()
.map(ReservedList::get)
.filter(Optional::isPresent)
.map(Optional::get)
.map(ReservedList::getReservedListEntries) .map(ReservedList::getReservedListEntries)
.map(Map::keySet) .map(Map::keySet)
.flatMap(Set::stream) .flatMap(Set::stream)

View file

@ -206,12 +206,10 @@ public class UploadBsaUnavailableDomainsAction implements Runnable {
new ImmutableSortedSet.Builder<>(Ordering.natural()); new ImmutableSortedSet.Builder<>(Ordering.natural());
for (Tld tld : bsaEnabledTlds) { for (Tld tld : bsaEnabledTlds) {
for (ReservedList reservedList : loadReservedLists(tld.getReservedListNames())) { for (ReservedList reservedList : loadReservedLists(tld.getReservedListNames())) {
if (reservedList.getShouldPublish()) {
unavailableDomains.addAll( unavailableDomains.addAll(
reservedList.getReservedListEntries().keySet().stream() reservedList.getReservedListEntries().keySet().stream()
.map(label -> toDomain(label, tld)) .map(label -> toDomain(label, tld))
.collect(toImmutableSet())); .collect(toImmutableSet()));
}
} }
} }

View file

@ -17,9 +17,14 @@ package google.registry.bsa.persistence;
import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.collect.ImmutableMap.toImmutableMap; import static com.google.common.collect.ImmutableMap.toImmutableMap;
import static com.google.common.collect.ImmutableSet.toImmutableSet; import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static google.registry.bsa.BsaTransactions.bsaQuery;
import static google.registry.bsa.ReservedDomainsUtils.getAllReservedNames; import static google.registry.bsa.ReservedDomainsUtils.getAllReservedNames;
import static google.registry.bsa.ReservedDomainsUtils.isReservedDomain; import static google.registry.bsa.ReservedDomainsUtils.isReservedDomain;
import static google.registry.bsa.persistence.Queries.queryLivesDomains; import static google.registry.bsa.persistence.Queries.batchReadUnblockables;
import static google.registry.bsa.persistence.Queries.queryBsaLabelByLabels;
import static google.registry.bsa.persistence.Queries.queryNewlyCreatedDomains;
import static google.registry.model.tld.Tld.isEnrolledWithBsa;
import static google.registry.model.tld.Tlds.getTldEntitiesOfType;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm; import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static java.util.stream.Collectors.groupingBy; import static java.util.stream.Collectors.groupingBy;
@ -36,6 +41,8 @@ import google.registry.bsa.api.UnblockableDomain.Reason;
import google.registry.bsa.api.UnblockableDomainChange; import google.registry.bsa.api.UnblockableDomainChange;
import google.registry.model.ForeignKeyUtils; import google.registry.model.ForeignKeyUtils;
import google.registry.model.domain.Domain; import google.registry.model.domain.Domain;
import google.registry.model.tld.Tld;
import google.registry.model.tld.Tld.TldType;
import google.registry.util.BatchedStreams; import google.registry.util.BatchedStreams;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -124,7 +131,7 @@ public final class DomainsRefresher {
ImmutableList<BsaUnblockableDomain> batch; ImmutableList<BsaUnblockableDomain> batch;
Optional<BsaUnblockableDomain> lastRead = Optional.empty(); Optional<BsaUnblockableDomain> lastRead = Optional.empty();
do { do {
batch = Queries.batchReadUnblockables(lastRead, transactionBatchSize); batch = batchReadUnblockables(lastRead, transactionBatchSize);
if (!batch.isEmpty()) { if (!batch.isEmpty()) {
lastRead = Optional.of(batch.get(batch.size() - 1)); lastRead = Optional.of(batch.get(batch.size() - 1));
changes.addAll(recheckStaleDomainsBatch(batch)); changes.addAll(recheckStaleDomainsBatch(batch));
@ -191,22 +198,33 @@ public final class DomainsRefresher {
} }
public ImmutableList<UnblockableDomainChange> getNewUnblockables() { public ImmutableList<UnblockableDomainChange> getNewUnblockables() {
ImmutableSet<String> newCreated = getNewlyCreatedUnblockables(prevRefreshStartTime, now); return bsaQuery(
ImmutableSet<String> newReserved = getNewlyReservedUnblockables(now, transactionBatchSize); () -> {
SetView<String> reservedNotCreated = Sets.difference(newReserved, newCreated); // TODO(weiminyu): both methods below use `queryBsaLabelByLabels`. Should combine.
return Streams.concat( ImmutableSet<String> newCreated = getNewlyCreatedUnblockables(prevRefreshStartTime, now);
newCreated.stream() ImmutableSet<String> newReserved =
.map(name -> UnblockableDomain.of(name, Reason.REGISTERED)) getNewlyReservedUnblockables(now, transactionBatchSize);
.map(UnblockableDomainChange::ofNew), SetView<String> reservedNotCreated = Sets.difference(newReserved, newCreated);
reservedNotCreated.stream() return Streams.concat(
.map(name -> UnblockableDomain.of(name, Reason.RESERVED)) newCreated.stream()
.map(UnblockableDomainChange::ofNew)) .map(name -> UnblockableDomain.of(name, Reason.REGISTERED))
.collect(toImmutableList()); .map(UnblockableDomainChange::ofNew),
reservedNotCreated.stream()
.map(name -> UnblockableDomain.of(name, Reason.RESERVED))
.map(UnblockableDomainChange::ofNew))
.collect(toImmutableList());
});
} }
static ImmutableSet<String> getNewlyCreatedUnblockables( static ImmutableSet<String> getNewlyCreatedUnblockables(
DateTime prevRefreshStartTime, DateTime now) { DateTime prevRefreshStartTime, DateTime now) {
ImmutableSet<String> liveDomains = queryLivesDomains(prevRefreshStartTime, now); ImmutableSet<String> bsaEnabledTlds =
getTldEntitiesOfType(TldType.REAL).stream()
.filter(tld -> isEnrolledWithBsa(tld, now))
.map(Tld::getTldStr)
.collect(toImmutableSet());
ImmutableSet<String> liveDomains =
queryNewlyCreatedDomains(bsaEnabledTlds, prevRefreshStartTime, now);
return getUnblockedDomainNames(liveDomains); return getUnblockedDomainNames(liveDomains);
} }
@ -222,7 +240,7 @@ public final class DomainsRefresher {
Map<String, List<String>> labelToNames = Map<String, List<String>> labelToNames =
domainNames.stream().collect(groupingBy(BsaStringUtils::getLabelInDomain)); domainNames.stream().collect(groupingBy(BsaStringUtils::getLabelInDomain));
ImmutableSet<String> bsaLabels = ImmutableSet<String> bsaLabels =
Queries.queryBsaLabelByLabels(ImmutableSet.copyOf(labelToNames.keySet())) queryBsaLabelByLabels(ImmutableSet.copyOf(labelToNames.keySet()))
.map(BsaLabel::getLabel) .map(BsaLabel::getLabel)
.collect(toImmutableSet()); .collect(toImmutableSet());
return labelToNames.entrySet().stream() return labelToNames.entrySet().stream()

View file

@ -16,14 +16,13 @@ package google.registry.bsa.persistence;
import static com.google.common.base.Verify.verify; import static com.google.common.base.Verify.verify;
import static google.registry.bsa.BsaStringUtils.DOMAIN_SPLITTER; import static google.registry.bsa.BsaStringUtils.DOMAIN_SPLITTER;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm; import static google.registry.bsa.BsaTransactions.bsaQuery;
import static google.registry.persistence.transaction.JpaTransactionManagerImpl.em;
import com.google.common.collect.ImmutableCollection; import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import google.registry.model.CreateAutoTimestamp; import google.registry.model.CreateAutoTimestamp;
import google.registry.model.ForeignKeyUtils;
import google.registry.model.domain.Domain;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -36,15 +35,14 @@ class Queries {
private Queries() {} private Queries() {}
private static Object detach(Object obj) { private static Object detach(Object obj) {
tm().getEntityManager().detach(obj); em().detach(obj);
return obj; return obj;
} }
static Stream<BsaUnblockableDomain> queryBsaUnblockableDomainByLabels( static Stream<BsaUnblockableDomain> queryBsaUnblockableDomainByLabels(
ImmutableCollection<String> labels) { ImmutableCollection<String> labels) {
return ((Stream<?>) return ((Stream<?>)
tm().getEntityManager() em().createQuery("FROM BsaUnblockableDomain WHERE label in (:labels)")
.createQuery("FROM BsaUnblockableDomain WHERE label in (:labels)")
.setParameter("labels", labels) .setParameter("labels", labels)
.getResultStream()) .getResultStream())
.map(Queries::detach) .map(Queries::detach)
@ -53,8 +51,7 @@ class Queries {
static Stream<BsaLabel> queryBsaLabelByLabels(ImmutableCollection<String> labels) { static Stream<BsaLabel> queryBsaLabelByLabels(ImmutableCollection<String> labels) {
return ((Stream<?>) return ((Stream<?>)
tm().getEntityManager() em().createQuery("FROM BsaLabel where label in (:labels)")
.createQuery("FROM BsaLabel where label in (:labels)")
.setParameter("labels", labels) .setParameter("labels", labels)
.getResultStream()) .getResultStream())
.map(Queries::detach) .map(Queries::detach)
@ -62,8 +59,7 @@ class Queries {
} }
static int deleteBsaLabelByLabels(ImmutableCollection<String> labels) { static int deleteBsaLabelByLabels(ImmutableCollection<String> labels) {
return tm().getEntityManager() return em().createQuery("DELETE FROM BsaLabel where label IN (:deleted_labels)")
.createQuery("DELETE FROM BsaLabel where label IN (:deleted_labels)")
.setParameter("deleted_labels", labels) .setParameter("deleted_labels", labels)
.executeUpdate(); .executeUpdate();
} }
@ -71,14 +67,15 @@ class Queries {
static ImmutableList<BsaUnblockableDomain> batchReadUnblockables( static ImmutableList<BsaUnblockableDomain> batchReadUnblockables(
Optional<BsaUnblockableDomain> lastRead, int batchSize) { Optional<BsaUnblockableDomain> lastRead, int batchSize) {
return ImmutableList.copyOf( return ImmutableList.copyOf(
tm().getEntityManager() bsaQuery(
.createQuery( () ->
"FROM BsaUnblockableDomain d WHERE d.label > :label OR (d.label = :label AND d.tld" em().createQuery(
+ " > :tld) ORDER BY d.tld, d.label ") "FROM BsaUnblockableDomain d WHERE d.label > :label OR (d.label = :label"
.setParameter("label", lastRead.map(d -> d.label).orElse("")) + " AND d.tld > :tld) ORDER BY d.tld, d.label ")
.setParameter("tld", lastRead.map(d -> d.tld).orElse("")) .setParameter("label", lastRead.map(d -> d.label).orElse(""))
.setMaxResults(batchSize) .setParameter("tld", lastRead.map(d -> d.tld).orElse(""))
.getResultList()); .setMaxResults(batchSize)
.getResultList()));
} }
static ImmutableSet<String> queryUnblockablesByNames(ImmutableSet<String> domains) { static ImmutableSet<String> queryUnblockablesByNames(ImmutableSet<String> domains) {
@ -96,17 +93,20 @@ class Queries {
"SELECT CONCAT(d.label, '.', d.tld) FROM \"BsaUnblockableDomain\" d " "SELECT CONCAT(d.label, '.', d.tld) FROM \"BsaUnblockableDomain\" d "
+ "WHERE (d.label, d.tld) IN (%s)", + "WHERE (d.label, d.tld) IN (%s)",
labelTldParis); labelTldParis);
return ImmutableSet.copyOf(tm().getEntityManager().createNativeQuery(sql).getResultList()); return ImmutableSet.copyOf(em().createNativeQuery(sql).getResultList());
} }
static ImmutableSet<String> queryLivesDomains(DateTime minCreationTime, DateTime now) { static ImmutableSet<String> queryNewlyCreatedDomains(
ImmutableSet<String> candidates = ImmutableCollection<String> tlds, DateTime minCreationTime, DateTime now) {
ImmutableSet.copyOf( return ImmutableSet.copyOf(
tm().getEntityManager() em().createQuery(
.createQuery( "SELECT domainName FROM Domain WHERE creationTime >= :minCreationTime "
"SELECT domainName FROM Domain WHERE creationTime >= :time ", String.class) + "AND deletionTime > :now "
.setParameter("time", CreateAutoTimestamp.create(minCreationTime)) + "AND tld in (:tlds)",
.getResultList()); String.class)
return ImmutableSet.copyOf(ForeignKeyUtils.load(Domain.class, candidates, now).keySet()); .setParameter("minCreationTime", CreateAutoTimestamp.create(minCreationTime))
.setParameter("now", now)
.setParameter("tlds", tlds)
.getResultList());
} }
} }

View file

@ -1472,9 +1472,9 @@ public final class RegistryConfig {
} }
@Provides @Provides
@Config("domainTxnMaxDuration") @Config("domainCreateTxnCommitTimeLag")
public static Duration provideDomainTxnMaxDuration(RegistryConfigSettings config) { public static Duration provideDomainCreateTxnCommitTimeLag(RegistryConfigSettings config) {
return Duration.standardSeconds(config.bsa.domainTxnMaxDurationSeconds); return Duration.standardSeconds(config.bsa.domainCreateTxnCommitTimeLagSeconds);
} }
@Provides @Provides

View file

@ -273,7 +273,7 @@ public class RegistryConfigSettings {
public int bsaDownloadIntervalMinutes; public int bsaDownloadIntervalMinutes;
public int bsaMaxNopIntervalHours; public int bsaMaxNopIntervalHours;
public int bsaTxnBatchSize; public int bsaTxnBatchSize;
public int domainTxnMaxDurationSeconds; public int domainCreateTxnCommitTimeLagSeconds;
public String authUrl; public String authUrl;
public int authTokenExpirySeconds; public int authTokenExpirySeconds;
public Map<String, String> dataUrls; public Map<String, String> dataUrls;

View file

@ -624,9 +624,18 @@ bsa:
# Max time period during which downloads can be skipped because checksums have # Max time period during which downloads can be skipped because checksums have
# not changed from the previous one. # not changed from the previous one.
bsaMaxNopIntervalHours: 24 bsaMaxNopIntervalHours: 24
# A very lax upper bound of the time it takes to execute a transaction that # A very lax upper bound of the lag between a domain-creating transaction's
# mutates a domain. Please See `BsaRefreshAction` for use case. # recorded and actual commit time. In Nomulus, a domain's creation time is the
domainTxnMaxDurationSeconds: 60 # start time of the transaction, while the domain is only visible after the
# transaction commits. Let `l` represents this lag, then at any point of time
# `t`, a query of domains by creation time is only guaranteed to find those
# created before `t - l`. Please See `BsaRefreshAction` for use case.
#
# The value below is decided by finding the longest domain-creation EPP
# request over the past 3 months (60 seconds, which is much longer than the
# transaction time), and add to it the maximum allowed replication lag (30
# seconds).
domainCreateTxnCommitTimeLagSeconds: 90
# Number of entities (labels and unblockable domains) to process in a single # Number of entities (labels and unblockable domains) to process in a single
# DB transaction. # DB transaction.
bsaTxnBatchSize: 1000 bsaTxnBatchSize: 1000

View file

@ -35,7 +35,13 @@ public interface JpaTransactionManager extends TransactionManager {
* Returns the {@link EntityManager} for the current request. * Returns the {@link EntityManager} for the current request.
* *
* <p>The returned instance is closed when the current transaction completes. * <p>The returned instance is closed when the current transaction completes.
*
* @deprecated Use the static {@link JpaTransactionManagerImpl#em} method for now. In current
* implementation the entity manager is obtained from a static {@code ThreadLocal} object that
* is set up by the outermost {@link #transact} call. As an instance method, this method gives
* the illusion that the call site has control over which database instance to use.
*/ */
@Deprecated // See Javadoc above.
EntityManager getEntityManager(); EntityManager getEntityManager();
/** /**

View file

@ -91,6 +91,26 @@ public class JpaTransactionManagerImpl implements JpaTransactionManager {
private static final ThreadLocal<TransactionInfo> transactionInfo = private static final ThreadLocal<TransactionInfo> transactionInfo =
ThreadLocal.withInitial(TransactionInfo::new); ThreadLocal.withInitial(TransactionInfo::new);
/** Returns true if inside a transaction; returns false otherwise. */
public static boolean isInTransaction() {
return transactionInfo.get().inTransaction;
}
/**
* Returns the {@link EntityManager} for the current database transaction.
*
* <p>This method must be call from inside a transaction.
*/
public static EntityManager em() {
EntityManager entityManager = transactionInfo.get().entityManager;
if (entityManager == null) {
throw new PersistenceException(
"No EntityManager has been initialized. getEntityManager() must be invoked in the scope"
+ " of a transaction");
}
return entityManager;
}
public JpaTransactionManagerImpl(EntityManagerFactory emf, Clock clock, boolean readOnly) { public JpaTransactionManagerImpl(EntityManagerFactory emf, Clock clock, boolean readOnly) {
this.emf = emf; this.emf = emf;
this.clock = clock; this.clock = clock;
@ -111,6 +131,7 @@ public class JpaTransactionManagerImpl implements JpaTransactionManager {
return emf.createEntityManager(); return emf.createEntityManager();
} }
@Deprecated // See Javadoc of interface method.
@Override @Override
public EntityManager getEntityManager() { public EntityManager getEntityManager() {
EntityManager entityManager = transactionInfo.get().entityManager; EntityManager entityManager = transactionInfo.get().entityManager;
@ -137,6 +158,7 @@ public class JpaTransactionManagerImpl implements JpaTransactionManager {
return getEntityManager().createQuery(sqlString); return getEntityManager().createQuery(sqlString);
} }
@Deprecated // See Javadoc of instance method.
@Override @Override
public boolean inTransaction() { public boolean inTransaction() {
return transactionInfo.get().inTransaction; return transactionInfo.get().inTransaction;

View file

@ -36,7 +36,14 @@ public interface TransactionManager {
* *
* <p>Note that this function is kept for backward compatibility. We will review the use case * <p>Note that this function is kept for backward compatibility. We will review the use case
* later when adding the cloud sql implementation. * later when adding the cloud sql implementation.
*
* @deprecated Use the static {@link JpaTransactionManagerImpl#isInTransaction()} method for now.
* In current implementation the entity manager is obtained from a static {@code ThreadLocal}
* object that is set up by the outermost {@link #transact} call. As an instance method, this
* method gives the illusion that the call site has control over which database instance to
* use.
*/ */
@Deprecated // See Javadoc above.
boolean inTransaction(); boolean inTransaction();
/** /**

View file

@ -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());
}
}

View file

@ -15,6 +15,8 @@
package google.registry.bsa; package google.registry.bsa;
import static com.google.common.truth.Truth.assertThat; 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.bsa.ReservedDomainsUtils.getAllReservedDomainsInTld;
import static google.registry.model.tld.Tld.TldState.GENERAL_AVAILABILITY; import static google.registry.model.tld.Tld.TldState.GENERAL_AVAILABILITY;
import static google.registry.model.tld.Tld.TldState.START_DATE_SUNRISE; 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.createTld;
import static google.registry.testing.DatabaseHelper.persistResource; import static google.registry.testing.DatabaseHelper.persistResource;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedMap; import com.google.common.collect.ImmutableSortedMap;
import google.registry.model.tld.Tld; 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;
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationWithCoverageExtension; import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationWithCoverageExtension;
import google.registry.testing.FakeClock; import google.registry.testing.FakeClock;
@ -51,41 +50,19 @@ class ReservedDomainsUtilsTest {
@BeforeEach @BeforeEach
void setup() { void setup() {
ImmutableMap<String, ReservedListEntry> byType = createReservedList(
"testlist",
ImmutableMap.of( ImmutableMap.of(
"sunrise", "sunrise", ALLOWED_IN_SUNRISE,
ReservedListEntry.create("sunrise", ALLOWED_IN_SUNRISE, ""), "specific", RESERVED_FOR_SPECIFIC_USE,
"specific", "anchor", RESERVED_FOR_ANCHOR_TENANT,
ReservedListEntry.create("specific", RESERVED_FOR_SPECIFIC_USE, ""), "fully", FULLY_BLOCKED,
"anchor", "name", NAME_COLLISION));
ReservedListEntry.create("anchor", RESERVED_FOR_ANCHOR_TENANT, ""), createReservedList(
"fully", "testlist2",
ReservedListEntry.create("fully", FULLY_BLOCKED, ""),
"name",
ReservedListEntry.create("name", NAME_COLLISION, ""));
ImmutableMap<String, ReservedListEntry> altList =
ImmutableMap.of( ImmutableMap.of(
"anchor", "anchor", RESERVED_FOR_ANCHOR_TENANT,
ReservedListEntry.create("anchor", RESERVED_FOR_ANCHOR_TENANT, ""), "somethingelse", 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());
createTld("tld"); createTld("tld");
persistResource( persistResource(
@ -95,15 +72,11 @@ class ReservedDomainsUtilsTest {
ImmutableSortedMap.of( ImmutableSortedMap.of(
fakeClock.nowUtc(), START_DATE_SUNRISE, fakeClock.nowUtc(), START_DATE_SUNRISE,
fakeClock.nowUtc().plusMillis(1), GENERAL_AVAILABILITY)) fakeClock.nowUtc().plusMillis(1), GENERAL_AVAILABILITY))
.setReservedListsByName(ImmutableSet.of("testlist"))
.build()); .build());
addReservedListsToTld("tld", ImmutableList.of("testlist"));
createTld("tld2"); createTld("tld2");
persistResource( addReservedListsToTld("tld2", ImmutableList.of("testlist", "testlist2"));
Tld.get("tld2")
.asBuilder()
.setReservedListsByName(ImmutableSet.of("testlist", "testlist2"))
.build());
} }
@Test @Test

View file

@ -50,7 +50,7 @@ public class BsaLabelUtilsTest {
@Test @Test
void isLabelBlocked_yes() { void isLabelBlocked_yes() {
persistBsaLabel("abc", fakeClock.nowUtc()); persistBsaLabel("abc");
assertThat(isLabelBlocked("abc")).isTrue(); assertThat(isLabelBlocked("abc")).isTrue();
} }

View file

@ -26,10 +26,13 @@ public final class BsaTestingUtils {
public static final Duration DEFAULT_DOWNLOAD_INTERVAL = Duration.standardHours(1); public static final Duration DEFAULT_DOWNLOAD_INTERVAL = Duration.standardHours(1);
public static final Duration DEFAULT_NOP_INTERVAL = Duration.standardDays(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() {} private BsaTestingUtils() {}
public static void persistBsaLabel(String domainLabel, DateTime creationTime) { public static void persistBsaLabel(String domainLabel) {
tm().transact(() -> tm().put(new BsaLabel(domainLabel, creationTime))); tm().transact(() -> tm().put(new BsaLabel(domainLabel, BSA_LABEL_CREATION_TIME)));
} }
public static DownloadScheduler createDownloadScheduler(Clock clock) { public static DownloadScheduler createDownloadScheduler(Clock clock) {

View file

@ -15,7 +15,8 @@
package google.registry.bsa.persistence; package google.registry.bsa.persistence;
import static com.google.common.truth.Truth.assertThat; 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.bsa.persistence.BsaTestingUtils.persistBsaLabel;
import static google.registry.model.tld.label.ReservationType.RESERVED_FOR_SPECIFIC_USE; import static google.registry.model.tld.label.ReservationType.RESERVED_FOR_SPECIFIC_USE;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm; 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.testing.DatabaseHelper.persistResource;
import static google.registry.util.DateTimeUtils.START_OF_TIME; import static google.registry.util.DateTimeUtils.START_OF_TIME;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import google.registry.bsa.api.UnblockableDomain; import google.registry.bsa.api.UnblockableDomain;
import google.registry.bsa.api.UnblockableDomainChange; import google.registry.bsa.api.UnblockableDomainChange;
import google.registry.bsa.persistence.BsaUnblockableDomain.Reason; import google.registry.bsa.persistence.BsaUnblockableDomain.Reason;
import google.registry.model.tld.Tld; 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;
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationWithCoverageExtension; import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationWithCoverageExtension;
import google.registry.testing.FakeClock; import google.registry.testing.FakeClock;
@ -44,7 +41,7 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.jupiter.api.extension.RegisterExtension;
/** Unit tests for {@link DomainsRefresher}. */ /** Unit tests for {@link DomainsRefresher}. */
public class DomainRefresherTest { public class DomainsRefresherTest {
FakeClock fakeClock = new FakeClock(DateTime.parse("2023-11-09T02:08:57.880Z")); FakeClock fakeClock = new FakeClock(DateTime.parse("2023-11-09T02:08:57.880Z"));
@ -66,52 +63,54 @@ public class DomainRefresherTest {
} }
@Test @Test
void staleUnblockableRemoved_wasRegistered() { void registeredUnblockable_removed_afterDomainIsDeleted() {
persistBsaLabel("label", fakeClock.nowUtc().minus(Duration.standardDays(1))); persistBsaLabel("label");
tm().transact(() -> tm().insert(BsaUnblockableDomain.of("label.tld", Reason.REGISTERED))); tm().transact(() -> tm().insert(BsaUnblockableDomain.of("label.tld", Reason.REGISTERED)));
assertThat(bsaTransact(refresher::refreshStaleUnblockables)) assertThat(refresher.refreshStaleUnblockables())
.containsExactly( .containsExactly(
UnblockableDomainChange.ofDeleted( UnblockableDomainChange.ofDeleted(
UnblockableDomain.of("label.tld", UnblockableDomain.Reason.REGISTERED))); UnblockableDomain.of("label.tld", UnblockableDomain.Reason.REGISTERED)));
} }
@Test @Test
void staleUnblockableRemoved_wasReserved() { void reservedUnblockable_removed_whenReservedLabelIsRemoved() {
persistBsaLabel("label", fakeClock.nowUtc().minus(Duration.standardDays(1))); persistBsaLabel("label");
tm().transact(() -> tm().insert(BsaUnblockableDomain.of("label.tld", Reason.RESERVED))); tm().transact(() -> tm().insert(BsaUnblockableDomain.of("label.tld", Reason.RESERVED)));
assertThat(bsaTransact(refresher::refreshStaleUnblockables)) assertThat(refresher.refreshStaleUnblockables())
.containsExactly( .containsExactly(
UnblockableDomainChange.ofDeleted( UnblockableDomainChange.ofDeleted(
UnblockableDomain.of("label.tld", UnblockableDomain.Reason.RESERVED))); UnblockableDomain.of("label.tld", UnblockableDomain.Reason.RESERVED)));
} }
@Test @Test
void newUnblockableAdded_isRegistered() { void regsiteredUnblockable_added_whenDomainIsAdded() {
persistResource(newDomain("label.tld")); persistResource(newDomain("label.tld"));
persistBsaLabel("label", fakeClock.nowUtc().minus(Duration.standardDays(1))); persistBsaLabel("label");
assertThat(bsaTransact(refresher::getNewUnblockables)) assertThat(refresher.getNewUnblockables())
.containsExactly( .containsExactly(
UnblockableDomainChange.ofNew( UnblockableDomainChange.ofNew(
UnblockableDomain.of("label.tld", UnblockableDomain.Reason.REGISTERED))); UnblockableDomain.of("label.tld", UnblockableDomain.Reason.REGISTERED)));
} }
@Test @Test
void newUnblockableAdded_isReserved() { void reservedUnblockable_added_whenReservedLabelIsAdded() {
persistBsaLabel("label", fakeClock.nowUtc().minus(Duration.standardDays(1))); persistBsaLabel("label");
setReservedList("label"); createReservedList("reservedList", "label", RESERVED_FOR_SPECIFIC_USE);
assertThat(bsaTransact(refresher::getNewUnblockables)) addReservedListsToTld("tld", ImmutableList.of("reservedList"));
assertThat(refresher.getNewUnblockables())
.containsExactly( .containsExactly(
UnblockableDomainChange.ofNew( UnblockableDomainChange.ofNew(
UnblockableDomain.of("label.tld", UnblockableDomain.Reason.RESERVED))); UnblockableDomain.of("label.tld", UnblockableDomain.Reason.RESERVED)));
} }
@Test @Test
void staleUnblockableDowngraded_registeredToReserved() { void registeredUnblockable_changedToReserved_whenDomainIsDeletedButLabelIsReserved() {
persistBsaLabel("label", fakeClock.nowUtc().minus(Duration.standardDays(1))); persistBsaLabel("label");
setReservedList("label"); createReservedList("reservedList", "label", RESERVED_FOR_SPECIFIC_USE);
addReservedListsToTld("tld", ImmutableList.of("reservedList"));
tm().transact(() -> tm().insert(BsaUnblockableDomain.of("label.tld", Reason.REGISTERED))); tm().transact(() -> tm().insert(BsaUnblockableDomain.of("label.tld", Reason.REGISTERED)));
assertThat(bsaTransact(refresher::refreshStaleUnblockables)) assertThat(refresher.refreshStaleUnblockables())
.containsExactly( .containsExactly(
UnblockableDomainChange.ofChanged( UnblockableDomainChange.ofChanged(
UnblockableDomain.of("label.tld", UnblockableDomain.Reason.REGISTERED), UnblockableDomain.of("label.tld", UnblockableDomain.Reason.REGISTERED),
@ -119,12 +118,12 @@ public class DomainRefresherTest {
} }
@Test @Test
void staleUnblockableUpgraded_reservedToRegisteredButNotReserved() { void reservedUnblockableUpgraded_changedToRegistered_whenDomainIsCreatedButNoLongerReserved() {
persistBsaLabel("label", fakeClock.nowUtc().minus(Duration.standardDays(1))); persistBsaLabel("label");
tm().transact(() -> tm().insert(BsaUnblockableDomain.of("label.tld", Reason.RESERVED))); tm().transact(() -> tm().insert(BsaUnblockableDomain.of("label.tld", Reason.RESERVED)));
persistResource(newDomain("label.tld")); persistResource(newDomain("label.tld"));
assertThat(bsaTransact(refresher::refreshStaleUnblockables)) assertThat(refresher.refreshStaleUnblockables())
.containsExactly( .containsExactly(
UnblockableDomainChange.ofChanged( UnblockableDomainChange.ofChanged(
UnblockableDomain.of("label.tld", UnblockableDomain.Reason.RESERVED), UnblockableDomain.of("label.tld", UnblockableDomain.Reason.RESERVED),
@ -132,31 +131,17 @@ public class DomainRefresherTest {
} }
@Test @Test
void staleUnblockableUpgraded_wasReserved_isReservedAndRegistered() { void reservedUnblockableUpgraded_changedToRegistered_whenDomainIsCreatedAndStillReserved() {
persistBsaLabel("label", fakeClock.nowUtc().minus(Duration.standardDays(1))); persistBsaLabel("label");
setReservedList("label"); createReservedList("reservedList", "label", RESERVED_FOR_SPECIFIC_USE);
addReservedListsToTld("tld", ImmutableList.of("reservedList"));
tm().transact(() -> tm().insert(BsaUnblockableDomain.of("label.tld", Reason.RESERVED))); tm().transact(() -> tm().insert(BsaUnblockableDomain.of("label.tld", Reason.RESERVED)));
persistResource(newDomain("label.tld")); persistResource(newDomain("label.tld"));
assertThat(bsaTransact(refresher::refreshStaleUnblockables)) assertThat(refresher.refreshStaleUnblockables())
.containsExactly( .containsExactly(
UnblockableDomainChange.ofChanged( UnblockableDomainChange.ofChanged(
UnblockableDomain.of("label.tld", UnblockableDomain.Reason.RESERVED), UnblockableDomain.of("label.tld", UnblockableDomain.Reason.RESERVED),
UnblockableDomain.Reason.REGISTERED)); 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());
}
} }

View file

@ -16,10 +16,11 @@ package google.registry.bsa.persistence;
import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.truth.Truth.assertThat; 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.deleteBsaLabelByLabels;
import static google.registry.bsa.persistence.Queries.queryBsaLabelByLabels; import static google.registry.bsa.persistence.Queries.queryBsaLabelByLabels;
import static google.registry.bsa.persistence.Queries.queryBsaUnblockableDomainByLabels; 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.bsa.persistence.Queries.queryUnblockablesByNames;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm; import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.createTlds; import static google.registry.testing.DatabaseHelper.createTlds;
@ -182,7 +183,7 @@ class QueriesTest {
} }
@Test @Test
void queryLivesDomains_onlyLiveDomainsReturned() { void queryNewlyCreatedDomains_onlyLiveDomainsReturned() {
DateTime testStartTime = fakeClock.nowUtc(); DateTime testStartTime = fakeClock.nowUtc();
createTlds("tld"); createTlds("tld");
persistNewRegistrar("TheRegistrar"); persistNewRegistrar("TheRegistrar");
@ -199,7 +200,29 @@ class QueriesTest {
newDomain("d2.tld").asBuilder().setCreationTimeForTest(fakeClock.nowUtc()).build()); newDomain("d2.tld").asBuilder().setCreationTimeForTest(fakeClock.nowUtc()).build());
fakeClock.advanceOneMilli(); fakeClock.advanceOneMilli();
// Now is time 2 // 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"); .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");
}
} }

View file

@ -288,7 +288,7 @@ class CheckApiActionTest {
@Test @Test
void testSuccess_blockedByBsa() { void testSuccess_blockedByBsa() {
BsaTestingUtils.persistBsaLabel("rich", START_OF_TIME); BsaTestingUtils.persistBsaLabel("rich");
persistResource( persistResource(
Tld.get("example").asBuilder().setBsaEnrollStartTime(Optional.of(START_OF_TIME)).build()); Tld.get("example").asBuilder().setBsaEnrollStartTime(Optional.of(START_OF_TIME)).build());
assertThat(getCheckResponse("rich.example")) assertThat(getCheckResponse("rich.example"))

View file

@ -14,6 +14,7 @@
package google.registry.flows.domain; 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.DEFAULT;
import static google.registry.model.billing.BillingBase.RenewalPriceBehavior.NONPREMIUM; import static google.registry.model.billing.BillingBase.RenewalPriceBehavior.NONPREMIUM;
import static google.registry.model.billing.BillingBase.RenewalPriceBehavior.SPECIFIED; 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.ImmutableSet;
import com.google.common.collect.ImmutableSortedMap; import com.google.common.collect.ImmutableSortedMap;
import com.google.common.collect.Ordering; import com.google.common.collect.Ordering;
import google.registry.bsa.persistence.BsaTestingUtils;
import google.registry.flows.EppException; import google.registry.flows.EppException;
import google.registry.flows.FlowUtils.NotLoggedInException; import google.registry.flows.FlowUtils.NotLoggedInException;
import google.registry.flows.FlowUtils.UnknownCurrencyEppException; import google.registry.flows.FlowUtils.UnknownCurrencyEppException;
@ -160,7 +160,7 @@ class DomainCheckFlowTest extends ResourceCheckFlowTestCase<DomainCheckFlow, Dom
@Test @Test
void testSuccess_bsaBlocked_otherwiseAvailable_blocked() throws Exception { void testSuccess_bsaBlocked_otherwiseAvailable_blocked() throws Exception {
BsaTestingUtils.persistBsaLabel("example1", clock.nowUtc()); persistBsaLabel("example1");
doCheckTest( doCheckTest(
create(false, "example1.tld", "Blocked by a GlobalBlock service"), create(false, "example1.tld", "Blocked by a GlobalBlock service"),
create(true, "example2.tld", null), create(true, "example2.tld", null),
@ -169,7 +169,7 @@ class DomainCheckFlowTest extends ResourceCheckFlowTestCase<DomainCheckFlow, Dom
@Test @Test
void testSuccess_bsaBlocked_alsoRegistered_registered() throws Exception { void testSuccess_bsaBlocked_alsoRegistered_registered() throws Exception {
BsaTestingUtils.persistBsaLabel("example1", clock.nowUtc()); persistBsaLabel("example1");
persistActiveDomain("example1.tld"); persistActiveDomain("example1.tld");
doCheckTest( doCheckTest(
create(false, "example1.tld", "In use"), create(false, "example1.tld", "In use"),
@ -179,8 +179,8 @@ class DomainCheckFlowTest extends ResourceCheckFlowTestCase<DomainCheckFlow, Dom
@Test @Test
void testSuccess_bsaBlocked_alsoReserved_reserved() throws Exception { void testSuccess_bsaBlocked_alsoReserved_reserved() throws Exception {
BsaTestingUtils.persistBsaLabel("reserved", clock.nowUtc()); persistBsaLabel("reserved");
BsaTestingUtils.persistBsaLabel("allowedinsunrise", clock.nowUtc()); persistBsaLabel("allowedinsunrise");
setEppInput("domain_check_one_tld_reserved.xml"); setEppInput("domain_check_one_tld_reserved.xml");
doCheckTest( doCheckTest(
create(false, "reserved.tld", "Reserved"), create(false, "reserved.tld", "Reserved"),

View file

@ -2575,7 +2575,7 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
@Test @Test
void testSuccess_bsaLabelMatch_notEnrolled() throws Exception { void testSuccess_bsaLabelMatch_notEnrolled() throws Exception {
persistResource(Tld.get("tld").asBuilder().setBsaEnrollStartTime(Optional.empty()).build()); persistResource(Tld.get("tld").asBuilder().setBsaEnrollStartTime(Optional.empty()).build());
persistBsaLabel("example", clock.nowUtc()); persistBsaLabel("example");
persistContactsAndHosts(); persistContactsAndHosts();
doSuccessfulTest(); doSuccessfulTest();
} }
@ -2587,7 +2587,7 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
.asBuilder() .asBuilder()
.setBsaEnrollStartTime(Optional.of(clock.nowUtc().plusSeconds(1))) .setBsaEnrollStartTime(Optional.of(clock.nowUtc().plusSeconds(1)))
.build()); .build());
persistBsaLabel("example", clock.nowUtc()); persistBsaLabel("example");
persistContactsAndHosts(); persistContactsAndHosts();
doSuccessfulTest(); doSuccessfulTest();
} }
@ -2599,7 +2599,7 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
.asBuilder() .asBuilder()
.setBsaEnrollStartTime(Optional.of(clock.nowUtc().minusSeconds(1))) .setBsaEnrollStartTime(Optional.of(clock.nowUtc().minusSeconds(1)))
.build()); .build());
persistBsaLabel("example", clock.nowUtc()); persistBsaLabel("example");
persistContactsAndHosts(); persistContactsAndHosts();
EppException thrown = assertThrows(DomainLabelBlockedByBsaException.class, this::runFlow); EppException thrown = assertThrows(DomainLabelBlockedByBsaException.class, this::runFlow);
assertAboutEppExceptions() assertAboutEppExceptions()

View file

@ -174,7 +174,7 @@ public class WhoisActionTest {
.asBuilder() .asBuilder()
.setBsaEnrollStartTime(Optional.of(clock.nowUtc().minusDays(1))) .setBsaEnrollStartTime(Optional.of(clock.nowUtc().minusDays(1)))
.build()); .build());
persistBsaLabel("cat", clock.nowUtc()); persistBsaLabel("cat");
Registrar registrar = persistResource(makeRegistrar("evilregistrar", "Yes Virginia", ACTIVE)); Registrar registrar = persistResource(makeRegistrar("evilregistrar", "Yes Virginia", ACTIVE));
persistResource(makeDomainWithRegistrar(registrar)); persistResource(makeDomainWithRegistrar(registrar));
@ -191,7 +191,7 @@ public class WhoisActionTest {
.asBuilder() .asBuilder()
.setBsaEnrollStartTime(Optional.of(clock.nowUtc().minusDays(1))) .setBsaEnrollStartTime(Optional.of(clock.nowUtc().minusDays(1)))
.build()); .build());
persistBsaLabel("cat", clock.nowUtc()); persistBsaLabel("cat");
newWhoisAction("domain cat.lol\r\n").run(); newWhoisAction("domain cat.lol\r\n").run();
assertThat(response.getStatus()).isEqualTo(200); assertThat(response.getStatus()).isEqualTo(200);

View file

@ -225,7 +225,7 @@ class WhoisHttpActionTest {
.asBuilder() .asBuilder()
.setBsaEnrollStartTime(Optional.of(clock.nowUtc().minusDays(1))) .setBsaEnrollStartTime(Optional.of(clock.nowUtc().minusDays(1)))
.build()); .build());
persistBsaLabel("cat", clock.nowUtc()); persistBsaLabel("cat");
Registrar registrar = persistResource(makeRegistrar("evilregistrar", "Yes Virginia", ACTIVE)); Registrar registrar = persistResource(makeRegistrar("evilregistrar", "Yes Virginia", ACTIVE));
persistResource( persistResource(
@ -256,7 +256,7 @@ class WhoisHttpActionTest {
.asBuilder() .asBuilder()
.setBsaEnrollStartTime(Optional.of(clock.nowUtc().minusDays(1))) .setBsaEnrollStartTime(Optional.of(clock.nowUtc().minusDays(1)))
.build()); .build());
persistBsaLabel("cat", clock.nowUtc()); persistBsaLabel("cat");
newWhoisHttpAction("domain cat.lol\r\n").run(); newWhoisHttpAction("domain cat.lol\r\n").run();
assertThat(response.getStatus()).isEqualTo(404); assertThat(response.getStatus()).isEqualTo(404);