Update various tests to work with SQL as well (#1078)

* Update various tests to work with SQL as well

The main weird bit here is adding a method in DatabaseHelper to
retrieve and initialize all objects in either database. The
initialization is necessary since it's used post-command-dry-run to make
sure that no changes were actually made.
This commit is contained in:
gbrodman 2021-04-20 11:52:53 -04:00 committed by GitHub
parent 4657be21b7
commit ee31f1fd95
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 220 additions and 154 deletions

View file

@ -37,6 +37,7 @@ import google.registry.model.index.ForeignKeyIndex.ForeignKeyDomainIndex;
import google.registry.model.index.ForeignKeyIndex.ForeignKeyHostIndex; import google.registry.model.index.ForeignKeyIndex.ForeignKeyHostIndex;
import google.registry.model.ofy.DatastoreTransactionManager; import google.registry.model.ofy.DatastoreTransactionManager;
import google.registry.model.server.KmsSecret; import google.registry.model.server.KmsSecret;
import google.registry.model.tmch.ClaimsListShard.ClaimsListSingleton;
import google.registry.persistence.JpaRetries; import google.registry.persistence.JpaRetries;
import google.registry.persistence.VKey; import google.registry.persistence.VKey;
import google.registry.util.Clock; import google.registry.util.Clock;
@ -73,6 +74,7 @@ public class JpaTransactionManagerImpl implements JpaTransactionManager {
// TODO(b/176108270): Remove this property after database migration. // TODO(b/176108270): Remove this property after database migration.
private static final ImmutableSet<Class<? extends ImmutableObject>> IGNORED_ENTITY_CLASSES = private static final ImmutableSet<Class<? extends ImmutableObject>> IGNORED_ENTITY_CLASSES =
ImmutableSet.of( ImmutableSet.of(
ClaimsListSingleton.class,
EppResourceIndex.class, EppResourceIndex.class,
ForeignKeyContactIndex.class, ForeignKeyContactIndex.class,
ForeignKeyDomainIndex.class, ForeignKeyDomainIndex.class,

View file

@ -16,6 +16,7 @@ package google.registry.flows;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static google.registry.model.ofy.ObjectifyService.ofy; import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.getOnlyHistoryEntryOfType; import static google.registry.testing.DatabaseHelper.getOnlyHistoryEntryOfType;
import static google.registry.testing.DatabaseHelper.stripBillingEventId; import static google.registry.testing.DatabaseHelper.stripBillingEventId;
import static google.registry.testing.TestDataHelper.loadFile; import static google.registry.testing.TestDataHelper.loadFile;
@ -216,7 +217,7 @@ public class EppTestCase {
"Running " + inputFilename + " => " + outputFilename, "Running " + inputFilename + " => " + outputFilename,
"epp.response.resData.infData.roid", "epp.response.resData.infData.roid",
"epp.response.trID.svTRID"); "epp.response.trID.svTRID");
ofy().clearSessionCache(); // Clear the cache like OfyFilter would. tm().clearSessionCache(); // Clear the cache like OfyFilter would.
return actualOutput; return actualOutput;
} }

View file

@ -20,10 +20,11 @@ import static com.google.common.collect.Sets.difference;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage; import static com.google.common.truth.Truth.assertWithMessage;
import static google.registry.model.eppcommon.EppXmlTransformer.marshal; import static google.registry.model.eppcommon.EppXmlTransformer.marshal;
import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm; import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm;
import static google.registry.testing.DatabaseHelper.stripBillingEventId; import static google.registry.testing.DatabaseHelper.stripBillingEventId;
import static google.registry.util.DateTimeUtils.END_OF_TIME;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import static google.registry.xml.XmlTestUtils.assertXmlEquals; import static google.registry.xml.XmlTestUtils.assertXmlEquals;
import static java.nio.charset.StandardCharsets.UTF_8; import static java.nio.charset.StandardCharsets.UTF_8;
import static org.joda.time.DateTimeZone.UTC; import static org.joda.time.DateTimeZone.UTC;
@ -41,9 +42,10 @@ import google.registry.model.eppcommon.ProtocolDefinition;
import google.registry.model.eppinput.EppInput; import google.registry.model.eppinput.EppInput;
import google.registry.model.eppoutput.EppOutput; import google.registry.model.eppoutput.EppOutput;
import google.registry.model.ofy.Ofy; import google.registry.model.ofy.Ofy;
import google.registry.model.reporting.HistoryEntry; import google.registry.model.reporting.HistoryEntryDao;
import google.registry.monitoring.whitebox.EppMetric; import google.registry.monitoring.whitebox.EppMetric;
import google.registry.testing.AppEngineExtension; import google.registry.testing.AppEngineExtension;
import google.registry.testing.DatabaseHelper;
import google.registry.testing.EppLoader; import google.registry.testing.EppLoader;
import google.registry.testing.FakeClock; import google.registry.testing.FakeClock;
import google.registry.testing.FakeHttpSession; import google.registry.testing.FakeHttpSession;
@ -172,7 +174,7 @@ public abstract class FlowTestCase<F extends Flow> {
} }
protected void assertNoHistory() { protected void assertNoHistory() {
assertThat(ofy().load().type(HistoryEntry.class)).isEmpty(); assertThat(HistoryEntryDao.loadAllHistoryObjects(START_OF_TIME, END_OF_TIME)).isEmpty();
} }
/** /**
@ -301,10 +303,10 @@ public abstract class FlowTestCase<F extends Flow> {
private TmchCaMode tmchCaMode = TmchCaMode.PILOT; private TmchCaMode tmchCaMode = TmchCaMode.PILOT;
public EppOutput dryRunFlowAssertResponse(String xml, String... ignoredPaths) throws Exception { public EppOutput dryRunFlowAssertResponse(String xml, String... ignoredPaths) throws Exception {
List<Object> beforeEntities = ofy().load().list(); List<Object> beforeEntities = DatabaseHelper.loadAllEntities();
EppOutput output = EppOutput output =
runFlowAssertResponse(CommitMode.DRY_RUN, UserPrivileges.NORMAL, xml, ignoredPaths); runFlowAssertResponse(CommitMode.DRY_RUN, UserPrivileges.NORMAL, xml, ignoredPaths);
assertThat(ofy().load()).containsExactlyElementsIn(beforeEntities); assertThat(DatabaseHelper.loadAllEntities()).containsExactlyElementsIn(beforeEntities);
return output; return output;
} }

View file

@ -15,65 +15,69 @@
package google.registry.model; package google.registry.model;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm; import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.loadByEntity;
import static org.joda.time.DateTimeZone.UTC; import static org.joda.time.DateTimeZone.UTC;
import com.googlecode.objectify.annotation.Entity; import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Ignore;
import google.registry.model.common.CrossTldSingleton; import google.registry.model.common.CrossTldSingleton;
import google.registry.schema.replay.EntityTest.EntityForTesting; import google.registry.schema.replay.EntityTest.EntityForTesting;
import google.registry.testing.AppEngineExtension; import google.registry.testing.AppEngineExtension;
import google.registry.testing.DualDatabaseTest;
import google.registry.testing.TestOfyAndSql;
import org.joda.time.DateTime; import org.joda.time.DateTime;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.jupiter.api.extension.RegisterExtension;
/** Unit tests for {@link CreateAutoTimestamp}. */ /** Unit tests for {@link CreateAutoTimestamp}. */
@DualDatabaseTest
public class CreateAutoTimestampTest { public class CreateAutoTimestampTest {
@RegisterExtension @RegisterExtension
public final AppEngineExtension appEngine = public final AppEngineExtension appEngine =
AppEngineExtension.builder() AppEngineExtension.builder()
.withDatastoreAndCloudSql() .withDatastoreAndCloudSql()
.withOfyTestEntities(TestObject.class) .withOfyTestEntities(CreateAutoTimestampTestObject.class)
.withJpaUnitTestEntities(CreateAutoTimestampTestObject.class)
.build(); .build();
/** Timestamped class. */ /** Timestamped class. */
@Entity(name = "CatTestEntity") @Entity(name = "CatTestEntity")
@EntityForTesting @EntityForTesting
public static class TestObject extends CrossTldSingleton { @javax.persistence.Entity
public static class CreateAutoTimestampTestObject extends CrossTldSingleton {
@Ignore @javax.persistence.Id long id = SINGLETON_ID;
CreateAutoTimestamp createTime = CreateAutoTimestamp.create(null); CreateAutoTimestamp createTime = CreateAutoTimestamp.create(null);
} }
private TestObject reload() { private CreateAutoTimestampTestObject reload() {
return ofy().load().entity(new TestObject()).now(); return loadByEntity(new CreateAutoTimestampTestObject());
} }
@Test @TestOfyAndSql
void testSaveSetsTime() { void testSaveSetsTime() {
DateTime transactionTime = DateTime transactionTime =
tm() tm().transact(
.transact(
() -> { () -> {
TestObject object = new TestObject(); CreateAutoTimestampTestObject object = new CreateAutoTimestampTestObject();
assertThat(object.createTime.getTimestamp()).isNull(); assertThat(object.createTime.getTimestamp()).isNull();
ofy().save().entity(object); tm().put(object);
return tm().getTransactionTime(); return tm().getTransactionTime();
}); });
ofy().clearSessionCache(); tm().clearSessionCache();
assertThat(reload().createTime.timestamp).isEqualTo(transactionTime); assertThat(reload().createTime.timestamp).isEqualTo(transactionTime);
} }
@Test @TestOfyAndSql
void testResavingRespectsOriginalTime() { void testResavingRespectsOriginalTime() {
final DateTime oldCreateTime = DateTime.now(UTC).minusDays(1); final DateTime oldCreateTime = DateTime.now(UTC).minusDays(1);
tm() tm().transact(
.transact(
() -> { () -> {
TestObject object = new TestObject(); CreateAutoTimestampTestObject object = new CreateAutoTimestampTestObject();
object.createTime = CreateAutoTimestamp.create(oldCreateTime); object.createTime = CreateAutoTimestamp.create(oldCreateTime);
ofy().save().entity(object); tm().put(object);
}); });
ofy().clearSessionCache(); tm().clearSessionCache();
assertThat(reload().createTime.timestamp).isEqualTo(oldCreateTime); assertThat(reload().createTime.timestamp).isEqualTo(oldCreateTime);
} }
} }

View file

@ -116,6 +116,7 @@ import google.registry.model.transfer.TransferData;
import google.registry.model.transfer.TransferStatus; import google.registry.model.transfer.TransferStatus;
import google.registry.persistence.VKey; import google.registry.persistence.VKey;
import google.registry.tmch.LordnTaskUtils; import google.registry.tmch.LordnTaskUtils;
import java.lang.reflect.Field;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -124,6 +125,7 @@ import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.function.Function; import java.util.function.Function;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import org.hibernate.Hibernate;
import org.joda.money.CurrencyUnit; import org.joda.money.CurrencyUnit;
import org.joda.money.Money; import org.joda.money.Money;
import org.joda.time.DateTime; import org.joda.time.DateTime;
@ -339,8 +341,7 @@ public class DatabaseHelper {
/** Persists a domain and enqueues a LORDN task of the appropriate type for it. */ /** Persists a domain and enqueues a LORDN task of the appropriate type for it. */
public static DomainBase persistDomainAndEnqueueLordn(final DomainBase domain) { public static DomainBase persistDomainAndEnqueueLordn(final DomainBase domain) {
final DomainBase persistedDomain = persistResource(domain); final DomainBase persistedDomain = persistResource(domain);
// Calls {@link LordnTaskUtils#enqueueDomainBaseTask} wrapped in an ofy transaction so that // Calls {@link LordnTaskUtils#enqueueDomainBaseTask} wrapped in a transaction so that the
// the
// transaction time is set correctly. // transaction time is set correctly.
tm().transactNew(() -> LordnTaskUtils.enqueueDomainBaseTask(persistedDomain)); tm().transactNew(() -> LordnTaskUtils.enqueueDomainBaseTask(persistedDomain));
maybeAdvanceClock(); maybeAdvanceClock();
@ -995,8 +996,8 @@ public class DatabaseHelper {
* Persists a test resource to Datastore and returns it. * Persists a test resource to Datastore and returns it.
* *
* <p>Tests should always use this method (or the shortcut persist methods in this class) to * <p>Tests should always use this method (or the shortcut persist methods in this class) to
* persist test data, to avoid potentially subtle bugs related to race conditions and a stale * persist test data, to avoid potentially subtle bugs related to race conditions and a stale ofy
* ofy() session cache. Specifically, this method calls .now() on the save to force the write to * session cache. Specifically, this method calls .now() on the save to force the write to
* actually get sent to Datastore (although it does not force it to be applied) and clears the * actually get sent to Datastore (although it does not force it to be applied) and clears the
* session cache. If necessary, this method also updates the relevant {@link EppResourceIndex}, * session cache. If necessary, this method also updates the relevant {@link EppResourceIndex},
* {@link ForeignKeyIndex}. * {@link ForeignKeyIndex}.
@ -1281,6 +1282,53 @@ public class DatabaseHelper {
clientId); clientId);
} }
/**
* Loads all entities from all classes stored in the database.
*
* <p>This is not performant (it requires initializing and detaching all Hibernate entities so
* that they can be used outside of the transaction in which they're loaded) and it should only be
* used in situations where we need to verify that, for instance, a dry run flow hasn't affected
* the database at all.
*/
public static List<Object> loadAllEntities() {
if (tm().isOfy()) {
return ofy().load().list();
} else {
return jpaTm()
.transact(
() -> {
ImmutableList<? extends Class<?>> entityClasses =
jpaTm().getEntityManager().getMetamodel().getEntities().stream()
.map(javax.persistence.metamodel.Type::getJavaType)
.collect(toImmutableList());
ImmutableList.Builder<Object> result = new ImmutableList.Builder<>();
for (Class<?> entityClass : entityClasses) {
for (Object object : jpaTm().loadAllOf(entityClass)) {
// Initialize and detach the objects so they can be used for comparison later
initializeHibernateObject(object);
jpaTm().getEntityManager().detach(object);
result.add(object);
}
}
return result.build();
});
}
}
/**
* Initializes all fields in a Hibernate proxy object so it can be used outside of a transaction.
*/
private static void initializeHibernateObject(Object object) {
for (Field field : object.getClass().getDeclaredFields()) {
field.setAccessible(true);
try {
Hibernate.initialize(field.get(object));
} catch (IllegalAccessException e) {
// shouldn't happen since we set the field to be accessible
}
}
}
/** /**
* Loads (i.e. reloads) the specified entity from the DB. * Loads (i.e. reloads) the specified entity from the DB.
* *

View file

@ -15,7 +15,6 @@
package google.registry.tmch; package google.registry.tmch;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm; import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.createTld; import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.loadRegistrar; import static google.registry.testing.DatabaseHelper.loadRegistrar;
@ -29,23 +28,30 @@ import google.registry.model.domain.launch.LaunchNotice;
import google.registry.model.ofy.Ofy; import google.registry.model.ofy.Ofy;
import google.registry.model.registrar.Registrar.Type; import google.registry.model.registrar.Registrar.Type;
import google.registry.testing.AppEngineExtension; import google.registry.testing.AppEngineExtension;
import google.registry.testing.DualDatabaseTest;
import google.registry.testing.FakeClock; import google.registry.testing.FakeClock;
import google.registry.testing.InjectExtension; import google.registry.testing.InjectExtension;
import google.registry.testing.TaskQueueHelper.TaskMatcher; import google.registry.testing.TaskQueueHelper.TaskMatcher;
import google.registry.testing.TestOfyAndSql;
import google.registry.testing.TestOfyOnly;
import google.registry.util.Clock; import google.registry.util.Clock;
import org.joda.time.DateTime; import org.joda.time.DateTime;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.jupiter.api.extension.RegisterExtension;
/** Unit tests for {@link LordnTaskUtils}. */ /** Unit tests for {@link LordnTaskUtils}. */
@DualDatabaseTest
public class LordnTaskUtilsTest { public class LordnTaskUtilsTest {
private static final Clock clock = new FakeClock(DateTime.parse("2010-05-01T10:11:12Z")); private static final Clock clock = new FakeClock(DateTime.parse("2010-05-01T10:11:12Z"));
@RegisterExtension @RegisterExtension
public final AppEngineExtension appEngine = public final AppEngineExtension appEngine =
AppEngineExtension.builder().withDatastoreAndCloudSql().withTaskQueue().build(); AppEngineExtension.builder()
.withDatastoreAndCloudSql()
.withClock(clock)
.withTaskQueue()
.build();
@RegisterExtension public final InjectExtension inject = new InjectExtension(); @RegisterExtension public final InjectExtension inject = new InjectExtension();
@ -58,12 +64,14 @@ public class LordnTaskUtilsTest {
private DomainBase.Builder newDomainBuilder() { private DomainBase.Builder newDomainBuilder() {
return new DomainBase.Builder() return new DomainBase.Builder()
.setDomainName("fleece.example") .setDomainName("fleece.example")
.setPersistedCurrentSponsorClientId("TheRegistrar")
.setCreationClientId("TheRegistrar")
.setRegistrant(persistActiveContact("jd1234").createVKey()) .setRegistrant(persistActiveContact("jd1234").createVKey())
.setSmdId("smdzzzz") .setSmdId("smdzzzz")
.setCreationClientId("TheRegistrar"); .setCreationClientId("TheRegistrar");
} }
@Test @TestOfyAndSql
void test_enqueueDomainBaseTask_sunrise() { void test_enqueueDomainBaseTask_sunrise() {
persistDomainAndEnqueueLordn(newDomainBuilder().setRepoId("A-EXAMPLE").build()); persistDomainAndEnqueueLordn(newDomainBuilder().setRepoId("A-EXAMPLE").build());
String expectedPayload = String expectedPayload =
@ -72,7 +80,7 @@ public class LordnTaskUtilsTest {
"lordn-sunrise", new TaskMatcher().payload(expectedPayload).tag("example")); "lordn-sunrise", new TaskMatcher().payload(expectedPayload).tag("example"));
} }
@Test @TestOfyAndSql
void test_enqueueDomainBaseTask_claims() { void test_enqueueDomainBaseTask_claims() {
DomainBase domain = DomainBase domain =
newDomainBuilder() newDomainBuilder()
@ -84,18 +92,14 @@ public class LordnTaskUtilsTest {
persistDomainAndEnqueueLordn(domain); persistDomainAndEnqueueLordn(domain);
String expectedPayload = "11-EXAMPLE,fleece.example,landrush1tcn,1,2010-05-01T10:11:12.000Z," String expectedPayload = "11-EXAMPLE,fleece.example,landrush1tcn,1,2010-05-01T10:11:12.000Z,"
+ "2010-05-01T09:11:12.000Z"; + "2010-05-01T09:11:12.000Z";
assertTasksEnqueued( assertTasksEnqueued("lordn-claims", new TaskMatcher().payload(expectedPayload).tag("example"));
"lordn-claims", new TaskMatcher().payload(expectedPayload).tag("example"));
} }
@Test @TestOfyAndSql
void test_oteRegistrarWithNullIanaId() { void test_oteRegistrarWithNullIanaId() {
tm() tm().transact(
.transact(
() -> () ->
ofy() tm().put(
.save()
.entity(
loadRegistrar("TheRegistrar") loadRegistrar("TheRegistrar")
.asBuilder() .asBuilder()
.setType(Type.OTE) .setType(Type.OTE)
@ -107,7 +111,7 @@ public class LordnTaskUtilsTest {
"lordn-sunrise", new TaskMatcher().payload(expectedPayload).tag("example")); "lordn-sunrise", new TaskMatcher().payload(expectedPayload).tag("example"));
} }
@Test @TestOfyOnly // moot in SQL since the domain creation fails the registrar foreign key check
void test_enqueueDomainBaseTask_throwsExceptionOnInvalidRegistrar() { void test_enqueueDomainBaseTask_throwsExceptionOnInvalidRegistrar() {
DomainBase domain = DomainBase domain =
newDomainBuilder() newDomainBuilder()
@ -121,7 +125,7 @@ public class LordnTaskUtilsTest {
.contains("No registrar found for client id: nonexistentRegistrar"); .contains("No registrar found for client id: nonexistentRegistrar");
} }
@Test @TestOfyAndSql
void test_enqueueDomainBaseTask_throwsNpeOnNullDomain() { void test_enqueueDomainBaseTask_throwsNpeOnNullDomain() {
assertThrows( assertThrows(
NullPointerException.class, NullPointerException.class,

View file

@ -16,14 +16,13 @@ package google.registry.tools;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat; import static com.google.common.truth.Truth8.assertThat;
import static google.registry.model.ofy.ObjectifyService.ofy; import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.CertificateSamples.SAMPLE_CERT; import static google.registry.testing.CertificateSamples.SAMPLE_CERT;
import static google.registry.testing.CertificateSamples.SAMPLE_CERT3; import static google.registry.testing.CertificateSamples.SAMPLE_CERT3;
import static google.registry.testing.CertificateSamples.SAMPLE_CERT3_HASH; import static google.registry.testing.CertificateSamples.SAMPLE_CERT3_HASH;
import static google.registry.testing.DatabaseHelper.createTlds; import static google.registry.testing.DatabaseHelper.createTlds;
import static google.registry.testing.DatabaseHelper.persistNewRegistrar; import static google.registry.testing.DatabaseHelper.persistNewRegistrar;
import static google.registry.util.DateTimeUtils.START_OF_TIME; import static google.registry.util.DateTimeUtils.START_OF_TIME;
import static org.joda.time.DateTimeZone.UTC;
import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
@ -38,23 +37,31 @@ import com.google.common.collect.Range;
import com.google.common.net.MediaType; import com.google.common.net.MediaType;
import google.registry.flows.certs.CertificateChecker; import google.registry.flows.certs.CertificateChecker;
import google.registry.flows.certs.CertificateChecker.InsecureCertificateException; import google.registry.flows.certs.CertificateChecker.InsecureCertificateException;
import google.registry.model.ofy.Ofy;
import google.registry.model.registrar.Registrar; import google.registry.model.registrar.Registrar;
import google.registry.testing.DualDatabaseTest;
import google.registry.testing.InjectExtension;
import google.registry.testing.TestOfyAndSql;
import java.io.IOException; import java.io.IOException;
import java.util.Optional; import java.util.Optional;
import org.joda.money.CurrencyUnit; import org.joda.money.CurrencyUnit;
import org.joda.time.DateTime; import org.joda.time.DateTime;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension;
import org.mockito.ArgumentMatchers; import org.mockito.ArgumentMatchers;
import org.mockito.Mock; import org.mockito.Mock;
/** Unit tests for {@link CreateRegistrarCommand}. */ /** Unit tests for {@link CreateRegistrarCommand}. */
@DualDatabaseTest
class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand> { class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand> {
@Mock private AppEngineConnection connection; @Mock private AppEngineConnection connection;
@RegisterExtension final InjectExtension inject = new InjectExtension();
@BeforeEach @BeforeEach
void beforeEach() { void beforeEach() {
inject.setStaticField(Ofy.class, "clock", fakeClock);
command.setConnection(connection); command.setConnection(connection);
command.certificateChecker = command.certificateChecker =
new CertificateChecker( new CertificateChecker(
@ -65,9 +72,9 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
fakeClock); fakeClock);
} }
@Test @TestOfyAndSql
void testSuccess() throws Exception { void testSuccess() throws Exception {
DateTime before = DateTime.now(UTC); DateTime before = fakeClock.nowUtc();
runCommandForced( runCommandForced(
"--name=blobio", "--name=blobio",
"--password=some_password", "--password=some_password",
@ -81,10 +88,10 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
"--zip 00351", "--zip 00351",
"--cc US", "--cc US",
"clientz"); "clientz");
DateTime after = DateTime.now(UTC); DateTime after = fakeClock.nowUtc();
// Clear the cache so that the CreateAutoTimestamp field gets reloaded. // Clear the cache so that the CreateAutoTimestamp field gets reloaded.
ofy().clearSessionCache(); tm().clearSessionCache();
Optional<Registrar> registrarOptional = Registrar.loadByClientId("clientz"); Optional<Registrar> registrarOptional = Registrar.loadByClientId("clientz");
assertThat(registrarOptional).isPresent(); assertThat(registrarOptional).isPresent();
@ -112,7 +119,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
eq(new byte[0])); eq(new byte[0]));
} }
@Test @TestOfyAndSql
void testSuccess_quotedPassword() throws Exception { void testSuccess_quotedPassword() throws Exception {
runCommandForced( runCommandForced(
"--name=blobio", "--name=blobio",
@ -133,7 +140,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
assertThat(registrar.get().verifyPassword("some_password")).isTrue(); assertThat(registrar.get().verifyPassword("some_password")).isTrue();
} }
@Test @TestOfyAndSql
void testSuccess_registrarTypeFlag() throws Exception { void testSuccess_registrarTypeFlag() throws Exception {
runCommandForced( runCommandForced(
"--name=blobio", "--name=blobio",
@ -153,7 +160,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
assertThat(registrar.get().getType()).isEqualTo(Registrar.Type.TEST); assertThat(registrar.get().getType()).isEqualTo(Registrar.Type.TEST);
} }
@Test @TestOfyAndSql
void testSuccess_registrarStateFlag() throws Exception { void testSuccess_registrarStateFlag() throws Exception {
runCommandForced( runCommandForced(
"--name=blobio", "--name=blobio",
@ -175,7 +182,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
assertThat(registrar.get().getState()).isEqualTo(Registrar.State.SUSPENDED); assertThat(registrar.get().getState()).isEqualTo(Registrar.State.SUSPENDED);
} }
@Test @TestOfyAndSql
void testSuccess_allowedTldsInNonProductionEnvironment() throws Exception { void testSuccess_allowedTldsInNonProductionEnvironment() throws Exception {
createTlds("xn--q9jyb4c", "foobar"); createTlds("xn--q9jyb4c", "foobar");
@ -202,7 +209,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
assertThat(registrar.get().getAllowedTlds()).containsExactly("xn--q9jyb4c", "foobar"); assertThat(registrar.get().getAllowedTlds()).containsExactly("xn--q9jyb4c", "foobar");
} }
@Test @TestOfyAndSql
void testSuccess_allowedTldsInPDT() throws Exception { void testSuccess_allowedTldsInPDT() throws Exception {
createTlds("xn--q9jyb4c", "foobar"); createTlds("xn--q9jyb4c", "foobar");
@ -229,7 +236,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
assertThat(registrar.get().getAllowedTlds()).containsExactly("xn--q9jyb4c", "foobar"); assertThat(registrar.get().getAllowedTlds()).containsExactly("xn--q9jyb4c", "foobar");
} }
@Test @TestOfyAndSql
void testSuccess_groupCreationCanBeDisabled() throws Exception { void testSuccess_groupCreationCanBeDisabled() throws Exception {
runCommandForced( runCommandForced(
"--name=blobio", "--name=blobio",
@ -248,7 +255,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
verifyNoInteractions(connection); verifyNoInteractions(connection);
} }
@Test @TestOfyAndSql
void testFailure_groupCreationFails() throws Exception { void testFailure_groupCreationFails() throws Exception {
when(connection.sendPostRequest( when(connection.sendPostRequest(
ArgumentMatchers.anyString(), ArgumentMatchers.anyString(),
@ -275,7 +282,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
assertInStdout("BAD ROBOT NO COOKIE"); assertInStdout("BAD ROBOT NO COOKIE");
} }
@Test @TestOfyAndSql
void testSuccess_groupCreationDoesntOccurOnAlphaEnv() throws Exception { void testSuccess_groupCreationDoesntOccurOnAlphaEnv() throws Exception {
runCommandInEnvironment( runCommandInEnvironment(
RegistryToolEnvironment.ALPHA, RegistryToolEnvironment.ALPHA,
@ -295,7 +302,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
verifyNoInteractions(connection); verifyNoInteractions(connection);
} }
@Test @TestOfyAndSql
void testSuccess_ipAllowListFlag() throws Exception { void testSuccess_ipAllowListFlag() throws Exception {
runCommandForced( runCommandForced(
"--name=blobio", "--name=blobio",
@ -319,7 +326,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
.inOrder(); .inOrder();
} }
@Test @TestOfyAndSql
void testSuccess_ipAllowListFlagNull() throws Exception { void testSuccess_ipAllowListFlagNull() throws Exception {
runCommandForced( runCommandForced(
"--name=blobio", "--name=blobio",
@ -341,7 +348,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
assertThat(registrar.get().getIpAddressAllowList()).isEmpty(); assertThat(registrar.get().getIpAddressAllowList()).isEmpty();
} }
@Test @TestOfyAndSql
void testSuccess_clientCertFileFlag() throws Exception { void testSuccess_clientCertFileFlag() throws Exception {
fakeClock.setTo(DateTime.parse("2020-11-01T00:00:00Z")); fakeClock.setTo(DateTime.parse("2020-11-01T00:00:00Z"));
runCommandForced( runCommandForced(
@ -364,7 +371,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
assertThat(registrar.get().getClientCertificateHash()).hasValue(SAMPLE_CERT3_HASH); assertThat(registrar.get().getClientCertificateHash()).hasValue(SAMPLE_CERT3_HASH);
} }
@Test @TestOfyAndSql
void testFail_clientCertFileFlagWithViolation() { void testFail_clientCertFileFlagWithViolation() {
fakeClock.setTo(DateTime.parse("2020-10-01T00:00:00Z")); fakeClock.setTo(DateTime.parse("2020-10-01T00:00:00Z"));
InsecureCertificateException thrown = InsecureCertificateException thrown =
@ -394,7 +401,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
assertThat(registrar).isEmpty(); assertThat(registrar).isEmpty();
} }
@Test @TestOfyAndSql
void testFail_clientCertFileFlagWithMultipleViolations() { void testFail_clientCertFileFlagWithMultipleViolations() {
fakeClock.setTo(DateTime.parse("2055-10-01T00:00:00Z")); fakeClock.setTo(DateTime.parse("2055-10-01T00:00:00Z"));
InsecureCertificateException thrown = InsecureCertificateException thrown =
@ -424,7 +431,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
assertThat(registrar).isEmpty(); assertThat(registrar).isEmpty();
} }
@Test @TestOfyAndSql
void testSuccess_failoverClientCertFileFlag() throws Exception { void testSuccess_failoverClientCertFileFlag() throws Exception {
fakeClock.setTo(DateTime.parse("2020-11-01T00:00:00Z")); fakeClock.setTo(DateTime.parse("2020-11-01T00:00:00Z"));
runCommandForced( runCommandForced(
@ -451,7 +458,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
assertThat(registrar.getFailoverClientCertificateHash()).hasValue(SAMPLE_CERT3_HASH); assertThat(registrar.getFailoverClientCertificateHash()).hasValue(SAMPLE_CERT3_HASH);
} }
@Test @TestOfyAndSql
void testFail_failoverClientCertFileFlagWithViolations() { void testFail_failoverClientCertFileFlagWithViolations() {
fakeClock.setTo(DateTime.parse("2020-11-01T00:00:00Z")); fakeClock.setTo(DateTime.parse("2020-11-01T00:00:00Z"));
InsecureCertificateException thrown = InsecureCertificateException thrown =
@ -481,7 +488,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
assertThat(registrar).isEmpty(); assertThat(registrar).isEmpty();
} }
@Test @TestOfyAndSql
void testFail_failoverClientCertFileFlagWithMultipleViolations() { void testFail_failoverClientCertFileFlagWithMultipleViolations() {
fakeClock.setTo(DateTime.parse("2055-11-01T00:00:00Z")); fakeClock.setTo(DateTime.parse("2055-11-01T00:00:00Z"));
InsecureCertificateException thrown = InsecureCertificateException thrown =
@ -511,7 +518,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
assertThat(registrar).isEmpty(); assertThat(registrar).isEmpty();
} }
@Test @TestOfyAndSql
void testSuccess_ianaId() throws Exception { void testSuccess_ianaId() throws Exception {
runCommandForced( runCommandForced(
"--name=blobio", "--name=blobio",
@ -532,7 +539,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
assertThat(registrar.get().getIanaIdentifier()).isEqualTo(12345); assertThat(registrar.get().getIanaIdentifier()).isEqualTo(12345);
} }
@Test @TestOfyAndSql
void testSuccess_billingId() throws Exception { void testSuccess_billingId() throws Exception {
runCommandForced( runCommandForced(
"--name=blobio", "--name=blobio",
@ -554,7 +561,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
assertThat(registrar.get().getBillingIdentifier()).isEqualTo(12345); assertThat(registrar.get().getBillingIdentifier()).isEqualTo(12345);
} }
@Test @TestOfyAndSql
void testSuccess_poNumber() throws Exception { void testSuccess_poNumber() throws Exception {
runCommandForced( runCommandForced(
"--name=blobio", "--name=blobio",
@ -576,7 +583,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
assertThat(registrar.get().getPoNumber()).hasValue("AA55G"); assertThat(registrar.get().getPoNumber()).hasValue("AA55G");
} }
@Test @TestOfyAndSql
void testSuccess_billingAccountMap() throws Exception { void testSuccess_billingAccountMap() throws Exception {
runCommandForced( runCommandForced(
"--name=blobio", "--name=blobio",
@ -599,7 +606,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
.containsExactly(CurrencyUnit.USD, "abc123", CurrencyUnit.JPY, "789xyz"); .containsExactly(CurrencyUnit.USD, "abc123", CurrencyUnit.JPY, "789xyz");
} }
@Test @TestOfyAndSql
void testFailure_billingAccountMap_doesNotContainEntryForTldAllowed() { void testFailure_billingAccountMap_doesNotContainEntryForTldAllowed() {
createTlds("foo"); createTlds("foo");
@ -627,7 +634,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
assertThat(thrown).hasMessageThat().contains("USD"); assertThat(thrown).hasMessageThat().contains("USD");
} }
@Test @TestOfyAndSql
void testSuccess_billingAccountMap_onlyAppliesToRealRegistrar() throws Exception { void testSuccess_billingAccountMap_onlyAppliesToRealRegistrar() throws Exception {
createTlds("foo"); createTlds("foo");
@ -651,7 +658,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
assertThat(registrar.get().getBillingAccountMap()).containsExactly(CurrencyUnit.JPY, "789xyz"); assertThat(registrar.get().getBillingAccountMap()).containsExactly(CurrencyUnit.JPY, "789xyz");
} }
@Test @TestOfyAndSql
void testSuccess_streetAddress() throws Exception { void testSuccess_streetAddress() throws Exception {
runCommandForced( runCommandForced(
"--name=blobio", "--name=blobio",
@ -683,7 +690,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
assertThat(registrar.getLocalizedAddress().getCountryCode()).isEqualTo("US"); assertThat(registrar.getLocalizedAddress().getCountryCode()).isEqualTo("US");
} }
@Test @TestOfyAndSql
void testSuccess_email() throws Exception { void testSuccess_email() throws Exception {
runCommandForced( runCommandForced(
"--name=blobio", "--name=blobio",
@ -705,7 +712,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
assertThat(registrar.get().getEmailAddress()).isEqualTo("foo@foo.foo"); assertThat(registrar.get().getEmailAddress()).isEqualTo("foo@foo.foo");
} }
@Test @TestOfyAndSql
void testSuccess_fallBackToIcannReferralEmail() throws Exception { void testSuccess_fallBackToIcannReferralEmail() throws Exception {
runCommandForced( runCommandForced(
"--name=blobio", "--name=blobio",
@ -726,7 +733,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
assertThat(registrar.get().getEmailAddress()).isEqualTo("foo@bar.test"); assertThat(registrar.get().getEmailAddress()).isEqualTo("foo@bar.test");
} }
@Test @TestOfyAndSql
void testSuccess_url() throws Exception { void testSuccess_url() throws Exception {
runCommandForced( runCommandForced(
"--name=blobio", "--name=blobio",
@ -748,7 +755,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
assertThat(registrar.get().getUrl()).isEqualTo("http://foo.foo"); assertThat(registrar.get().getUrl()).isEqualTo("http://foo.foo");
} }
@Test @TestOfyAndSql
void testSuccess_phone() throws Exception { void testSuccess_phone() throws Exception {
runCommandForced( runCommandForced(
"--name=blobio", "--name=blobio",
@ -770,7 +777,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
assertThat(registrar.get().getPhoneNumber()).isEqualTo("+1.2125556342"); assertThat(registrar.get().getPhoneNumber()).isEqualTo("+1.2125556342");
} }
@Test @TestOfyAndSql
void testSuccess_optionalParamsAsNull() throws Exception { void testSuccess_optionalParamsAsNull() throws Exception {
runCommandForced( runCommandForced(
"--name=blobio", "--name=blobio",
@ -801,7 +808,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
assertThat(registrar.getDriveFolderId()).isNull(); assertThat(registrar.getDriveFolderId()).isNull();
} }
@Test @TestOfyAndSql
void testSuccess_optionalParamsAsEmptyString() throws Exception { void testSuccess_optionalParamsAsEmptyString() throws Exception {
runCommandForced( runCommandForced(
"--name=blobio", "--name=blobio",
@ -832,7 +839,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
assertThat(registrar.getDriveFolderId()).isNull(); assertThat(registrar.getDriveFolderId()).isNull();
} }
@Test @TestOfyAndSql
void testSuccess_blockPremiumNames() throws Exception { void testSuccess_blockPremiumNames() throws Exception {
runCommandForced( runCommandForced(
"--name=blobio", "--name=blobio",
@ -854,7 +861,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
assertThat(registrar.get().getBlockPremiumNames()).isTrue(); assertThat(registrar.get().getBlockPremiumNames()).isTrue();
} }
@Test @TestOfyAndSql
void testSuccess_noBlockPremiumNames() throws Exception { void testSuccess_noBlockPremiumNames() throws Exception {
runCommandForced( runCommandForced(
"--name=blobio", "--name=blobio",
@ -876,7 +883,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
assertThat(registrar.get().getBlockPremiumNames()).isFalse(); assertThat(registrar.get().getBlockPremiumNames()).isFalse();
} }
@Test @TestOfyAndSql
void testSuccess_registryLockAllowed() throws Exception { void testSuccess_registryLockAllowed() throws Exception {
runCommandForced( runCommandForced(
"--name=blobio", "--name=blobio",
@ -898,7 +905,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
assertThat(registrar.get().isRegistryLockAllowed()).isTrue(); assertThat(registrar.get().isRegistryLockAllowed()).isTrue();
} }
@Test @TestOfyAndSql
void testSuccess_registryLockDisallowed() throws Exception { void testSuccess_registryLockDisallowed() throws Exception {
runCommandForced( runCommandForced(
"--name=blobio", "--name=blobio",
@ -920,7 +927,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
assertThat(registrar.get().isRegistryLockAllowed()).isFalse(); assertThat(registrar.get().isRegistryLockAllowed()).isFalse();
} }
@Test @TestOfyAndSql
void testFailure_badPhoneNumber() { void testFailure_badPhoneNumber() {
ParameterException thrown = ParameterException thrown =
assertThrows( assertThrows(
@ -943,7 +950,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
assertThat(thrown).hasMessageThat().contains("phone"); assertThat(thrown).hasMessageThat().contains("phone");
} }
@Test @TestOfyAndSql
void testFailure_badPhoneNumber2() { void testFailure_badPhoneNumber2() {
ParameterException thrown = ParameterException thrown =
assertThrows( assertThrows(
@ -966,7 +973,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
assertThat(thrown).hasMessageThat().contains("phone"); assertThat(thrown).hasMessageThat().contains("phone");
} }
@Test @TestOfyAndSql
void testSuccess_fax() throws Exception { void testSuccess_fax() throws Exception {
runCommandForced( runCommandForced(
"--name=blobio", "--name=blobio",
@ -988,7 +995,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
assertThat(registrar.get().getFaxNumber()).isEqualTo("+1.2125556342"); assertThat(registrar.get().getFaxNumber()).isEqualTo("+1.2125556342");
} }
@Test @TestOfyAndSql
void testFailure_missingRegistrarType() { void testFailure_missingRegistrarType() {
IllegalArgumentException thrown = IllegalArgumentException thrown =
assertThrows( assertThrows(
@ -1008,7 +1015,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
assertThat(thrown).hasMessageThat().contains("Registrar type cannot be null"); assertThat(thrown).hasMessageThat().contains("Registrar type cannot be null");
} }
@Test @TestOfyAndSql
void testFailure_invalidRegistrarType() { void testFailure_invalidRegistrarType() {
assertThrows( assertThrows(
ParameterException.class, ParameterException.class,
@ -1026,7 +1033,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
"clientz")); "clientz"));
} }
@Test @TestOfyAndSql
void testFailure_invalidRegistrarState() { void testFailure_invalidRegistrarState() {
assertThrows( assertThrows(
ParameterException.class, ParameterException.class,
@ -1047,7 +1054,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
"clientz")); "clientz"));
} }
@Test @TestOfyAndSql
void testFailure_allowedTldDoesNotExist() { void testFailure_allowedTldDoesNotExist() {
assertThrows( assertThrows(
IllegalArgumentException.class, IllegalArgumentException.class,
@ -1068,7 +1075,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
"clientz")); "clientz"));
} }
@Test @TestOfyAndSql
void testFailure_allowedTldsInRealWithoutAbuseContact() { void testFailure_allowedTldsInRealWithoutAbuseContact() {
createTlds("xn--q9jyb4c", "foobar"); createTlds("xn--q9jyb4c", "foobar");
IllegalArgumentException thrown = IllegalArgumentException thrown =
@ -1094,7 +1101,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
assertThat(thrown).hasMessageThat().startsWith("Cannot add allowed TLDs"); assertThat(thrown).hasMessageThat().startsWith("Cannot add allowed TLDs");
} }
@Test @TestOfyAndSql
void testFailure_invalidIpAllowListFlag() { void testFailure_invalidIpAllowListFlag() {
assertThrows( assertThrows(
IllegalArgumentException.class, IllegalArgumentException.class,
@ -1115,7 +1122,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
"clientz")); "clientz"));
} }
@Test @TestOfyAndSql
void testSuccess_ipAllowListFlagWithNull() { void testSuccess_ipAllowListFlagWithNull() {
assertThrows( assertThrows(
IllegalArgumentException.class, IllegalArgumentException.class,
@ -1136,7 +1143,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
"clientz")); "clientz"));
} }
@Test @TestOfyAndSql
void testFailure_missingName() { void testFailure_missingName() {
IllegalArgumentException thrown = IllegalArgumentException thrown =
assertThrows( assertThrows(
@ -1157,7 +1164,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
assertThat(thrown).hasMessageThat().contains("--name is a required field"); assertThat(thrown).hasMessageThat().contains("--name is a required field");
} }
@Test @TestOfyAndSql
void testFailure_missingPassword() { void testFailure_missingPassword() {
IllegalArgumentException thrown = IllegalArgumentException thrown =
assertThrows( assertThrows(
@ -1178,7 +1185,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
assertThat(thrown).hasMessageThat().contains("--password is a required field"); assertThat(thrown).hasMessageThat().contains("--password is a required field");
} }
@Test @TestOfyAndSql
void testFailure_emptyPassword() { void testFailure_emptyPassword() {
IllegalArgumentException thrown = IllegalArgumentException thrown =
assertThrows( assertThrows(
@ -1200,7 +1207,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
assertThat(thrown).hasMessageThat().contains("--password is a required field"); assertThat(thrown).hasMessageThat().contains("--password is a required field");
} }
@Test @TestOfyAndSql
void testFailure_clientIdTooShort() { void testFailure_clientIdTooShort() {
assertThrows( assertThrows(
IllegalArgumentException.class, IllegalArgumentException.class,
@ -1220,7 +1227,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
"ab")); "ab"));
} }
@Test @TestOfyAndSql
void testFailure_clientIdTooLong() { void testFailure_clientIdTooLong() {
assertThrows( assertThrows(
IllegalArgumentException.class, IllegalArgumentException.class,
@ -1240,7 +1247,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
"clientabcdefghijk")); "clientabcdefghijk"));
} }
@Test @TestOfyAndSql
void testFailure_missingClientId() { void testFailure_missingClientId() {
assertThrows( assertThrows(
ParameterException.class, ParameterException.class,
@ -1260,7 +1267,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
"--force")); "--force"));
} }
@Test @TestOfyAndSql
void testFailure_missingStreetLines() { void testFailure_missingStreetLines() {
assertThrows( assertThrows(
IllegalArgumentException.class, IllegalArgumentException.class,
@ -1279,7 +1286,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
"clientz")); "clientz"));
} }
@Test @TestOfyAndSql
void testFailure_missingCity() { void testFailure_missingCity() {
assertThrows( assertThrows(
IllegalArgumentException.class, IllegalArgumentException.class,
@ -1300,7 +1307,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
"clientz")); "clientz"));
} }
@Test @TestOfyAndSql
void testFailure_missingState() { void testFailure_missingState() {
assertThrows( assertThrows(
IllegalArgumentException.class, IllegalArgumentException.class,
@ -1321,7 +1328,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
"clientz")); "clientz"));
} }
@Test @TestOfyAndSql
void testFailure_missingZip() { void testFailure_missingZip() {
assertThrows( assertThrows(
IllegalArgumentException.class, IllegalArgumentException.class,
@ -1342,7 +1349,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
"clientz")); "clientz"));
} }
@Test @TestOfyAndSql
void testFailure_missingCc() { void testFailure_missingCc() {
assertThrows( assertThrows(
IllegalArgumentException.class, IllegalArgumentException.class,
@ -1363,7 +1370,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
"clientz")); "clientz"));
} }
@Test @TestOfyAndSql
void testFailure_invalidCc() { void testFailure_invalidCc() {
assertThrows( assertThrows(
IllegalArgumentException.class, IllegalArgumentException.class,
@ -1385,7 +1392,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
"clientz")); "clientz"));
} }
@Test @TestOfyAndSql
void testFailure_tooManyStreetLines() { void testFailure_tooManyStreetLines() {
assertThrows( assertThrows(
IllegalArgumentException.class, IllegalArgumentException.class,
@ -1408,7 +1415,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
"clientz")); "clientz"));
} }
@Test @TestOfyAndSql
void testFailure_tooFewStreetLines() { void testFailure_tooFewStreetLines() {
assertThrows( assertThrows(
IllegalArgumentException.class, IllegalArgumentException.class,
@ -1428,7 +1435,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
"clientz")); "clientz"));
} }
@Test @TestOfyAndSql
void testFailure_missingIanaIdForRealRegistrar() { void testFailure_missingIanaIdForRealRegistrar() {
assertThrows( assertThrows(
IllegalArgumentException.class, IllegalArgumentException.class,
@ -1447,7 +1454,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
"clientz")); "clientz"));
} }
@Test @TestOfyAndSql
void testFailure_negativeIanaId() { void testFailure_negativeIanaId() {
assertThrows( assertThrows(
IllegalArgumentException.class, IllegalArgumentException.class,
@ -1467,7 +1474,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
"clientz")); "clientz"));
} }
@Test @TestOfyAndSql
void testFailure_nonIntegerIanaId() { void testFailure_nonIntegerIanaId() {
assertThrows( assertThrows(
ParameterException.class, ParameterException.class,
@ -1487,7 +1494,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
"clientz")); "clientz"));
} }
@Test @TestOfyAndSql
void testFailure_negativeBillingId() { void testFailure_negativeBillingId() {
assertThrows( assertThrows(
IllegalArgumentException.class, IllegalArgumentException.class,
@ -1508,7 +1515,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
"clientz")); "clientz"));
} }
@Test @TestOfyAndSql
void testFailure_nonIntegerBillingId() { void testFailure_nonIntegerBillingId() {
assertThrows( assertThrows(
ParameterException.class, ParameterException.class,
@ -1529,7 +1536,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
"clientz")); "clientz"));
} }
@Test @TestOfyAndSql
void testFailure_missingPhonePasscode() { void testFailure_missingPhonePasscode() {
assertThrows( assertThrows(
IllegalArgumentException.class, IllegalArgumentException.class,
@ -1548,7 +1555,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
"clientz")); "clientz"));
} }
@Test @TestOfyAndSql
void testFailure_missingIcannReferralEmail() { void testFailure_missingIcannReferralEmail() {
IllegalArgumentException thrown = IllegalArgumentException thrown =
assertThrows( assertThrows(
@ -1569,7 +1576,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
assertThat(thrown).hasMessageThat().contains("--icann_referral_email"); assertThat(thrown).hasMessageThat().contains("--icann_referral_email");
} }
@Test @TestOfyAndSql
void testFailure_passcodeTooShort() { void testFailure_passcodeTooShort() {
assertThrows( assertThrows(
IllegalArgumentException.class, IllegalArgumentException.class,
@ -1589,7 +1596,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
"clientz")); "clientz"));
} }
@Test @TestOfyAndSql
void testFailure_passcodeTooLong() { void testFailure_passcodeTooLong() {
assertThrows( assertThrows(
IllegalArgumentException.class, IllegalArgumentException.class,
@ -1609,7 +1616,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
"clientz")); "clientz"));
} }
@Test @TestOfyAndSql
void testFailure_invalidPasscode() { void testFailure_invalidPasscode() {
assertThrows( assertThrows(
IllegalArgumentException.class, IllegalArgumentException.class,
@ -1629,7 +1636,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
"clientz")); "clientz"));
} }
@Test @TestOfyAndSql
void testFailure_twoClientsSpecified() { void testFailure_twoClientsSpecified() {
assertThrows( assertThrows(
IllegalArgumentException.class, IllegalArgumentException.class,
@ -1650,7 +1657,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
"clientz")); "clientz"));
} }
@Test @TestOfyAndSql
void testFailure_unknownFlag() { void testFailure_unknownFlag() {
assertThrows( assertThrows(
ParameterException.class, ParameterException.class,
@ -1671,7 +1678,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
"clientz")); "clientz"));
} }
@Test @TestOfyAndSql
void testFailure_alreadyExists() { void testFailure_alreadyExists() {
persistNewRegistrar("existing", "Existing Registrar", Registrar.Type.REAL, 1L); persistNewRegistrar("existing", "Existing Registrar", Registrar.Type.REAL, 1L);
IllegalStateException thrown = IllegalStateException thrown =
@ -1694,7 +1701,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
assertThat(thrown).hasMessageThat().contains("Registrar existing already exists"); assertThat(thrown).hasMessageThat().contains("Registrar existing already exists");
} }
@Test @TestOfyAndSql
void testFailure_registrarNameSimilarToExisting() { void testFailure_registrarNameSimilarToExisting() {
// Note that "tHeRe GiStRaR" normalizes identically to "The Registrar", which is created by // Note that "tHeRe GiStRaR" normalizes identically to "The Registrar", which is created by
// AppEngineRule. // AppEngineRule.
@ -1722,7 +1729,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
+ "identically to existing registrar name The Registrar"); + "identically to existing registrar name The Registrar");
} }
@Test @TestOfyAndSql
void testFailure_clientIdNormalizesToExisting() { void testFailure_clientIdNormalizesToExisting() {
IllegalArgumentException thrown = IllegalArgumentException thrown =
assertThrows( assertThrows(
@ -1748,7 +1755,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
+ "normalizes identically to existing registrar TheRegistrar"); + "normalizes identically to existing registrar TheRegistrar");
} }
@Test @TestOfyAndSql
void testFailure_clientIdIsInvalidFormat() { void testFailure_clientIdIsInvalidFormat() {
IllegalArgumentException thrown = IllegalArgumentException thrown =
assertThrows( assertThrows(
@ -1773,7 +1780,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
"Client identifier (.L33T) can only contain lowercase letters, numbers, and hyphens"); "Client identifier (.L33T) can only contain lowercase letters, numbers, and hyphens");
} }
@Test @TestOfyAndSql
void testFailure_phone() { void testFailure_phone() {
assertThrows( assertThrows(
ParameterException.class, ParameterException.class,
@ -1794,7 +1801,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
"clientz")); "clientz"));
} }
@Test @TestOfyAndSql
void testFailure_fax() { void testFailure_fax() {
assertThrows( assertThrows(
ParameterException.class, ParameterException.class,
@ -1815,7 +1822,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
"clientz")); "clientz"));
} }
@Test @TestOfyAndSql
void testFailure_badEmail() { void testFailure_badEmail() {
IllegalArgumentException thrown = IllegalArgumentException thrown =
assertThrows( assertThrows(

View file

@ -15,8 +15,10 @@
package google.registry.tools; package google.registry.tools;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static google.registry.model.ofy.ObjectifyService.ofy; import static com.google.common.truth.Truth8.assertThat;
import static google.registry.testing.DatabaseHelper.createTld; import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.loadByKey;
import static google.registry.testing.DatabaseHelper.loadByKeyIfPresent;
import static google.registry.testing.DatabaseHelper.persistResource; import static google.registry.testing.DatabaseHelper.persistResource;
import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertThrows;
@ -25,11 +27,13 @@ import google.registry.model.common.Cursor;
import google.registry.model.common.Cursor.CursorType; import google.registry.model.common.Cursor.CursorType;
import google.registry.model.registry.Registry; import google.registry.model.registry.Registry;
import google.registry.model.registry.Registry.RegistryNotFoundException; import google.registry.model.registry.Registry.RegistryNotFoundException;
import google.registry.testing.DualDatabaseTest;
import google.registry.testing.TestOfyAndSql;
import org.joda.time.DateTime; import org.joda.time.DateTime;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
/** Unit tests for {@link UpdateCursorsCommand}. */ /** Unit tests for {@link UpdateCursorsCommand}. */
@DualDatabaseTest
class UpdateCursorsCommandTest extends CommandTestCase<UpdateCursorsCommand> { class UpdateCursorsCommandTest extends CommandTestCase<UpdateCursorsCommand> {
private Registry registry; private Registry registry;
@ -42,7 +46,7 @@ class UpdateCursorsCommandTest extends CommandTestCase<UpdateCursorsCommand> {
void doUpdateTest() throws Exception { void doUpdateTest() throws Exception {
runCommandForced("--type=brda", "--timestamp=1984-12-18T00:00:00Z", "foo"); runCommandForced("--type=brda", "--timestamp=1984-12-18T00:00:00Z", "foo");
assertThat(ofy().load().key(Cursor.createKey(CursorType.BRDA, registry)).now().getCursorTime()) assertThat(loadByKey(Cursor.createVKey(CursorType.BRDA, "foo")).getCursorTime())
.isEqualTo(DateTime.parse("1984-12-18TZ")); .isEqualTo(DateTime.parse("1984-12-18TZ"));
String changes = command.prompt(); String changes = command.prompt();
assertThat(changes) assertThat(changes)
@ -51,12 +55,7 @@ class UpdateCursorsCommandTest extends CommandTestCase<UpdateCursorsCommand> {
void doGlobalUpdateTest() throws Exception { void doGlobalUpdateTest() throws Exception {
runCommandForced("--type=recurring_billing", "--timestamp=1984-12-18T00:00:00Z"); runCommandForced("--type=recurring_billing", "--timestamp=1984-12-18T00:00:00Z");
assertThat( assertThat(loadByKey(Cursor.createGlobalVKey(CursorType.RECURRING_BILLING)).getCursorTime())
ofy()
.load()
.key(Cursor.createGlobalKey(CursorType.RECURRING_BILLING))
.now()
.getCursorTime())
.isEqualTo(DateTime.parse("1984-12-18TZ")); .isEqualTo(DateTime.parse("1984-12-18TZ"));
String changes = command.prompt(); String changes = command.prompt();
assertThat(changes) assertThat(changes)
@ -65,42 +64,42 @@ class UpdateCursorsCommandTest extends CommandTestCase<UpdateCursorsCommand> {
+ " 1984-12-18T00:00:00.000Z\n"); + " 1984-12-18T00:00:00.000Z\n");
} }
@Test @TestOfyAndSql
void testSuccess_oldValueisEmpty() throws Exception { void testSuccess_oldValueisEmpty() throws Exception {
assertThat(ofy().load().key(Cursor.createKey(CursorType.BRDA, registry)).now()).isNull(); assertThat(loadByKeyIfPresent(Cursor.createVKey(CursorType.BRDA, registry.getTldStr())))
.isEmpty();
doUpdateTest(); doUpdateTest();
} }
@Test @TestOfyAndSql
void testSuccess_hasOldValue() throws Exception { void testSuccess_hasOldValue() throws Exception {
persistResource(Cursor.create(CursorType.BRDA, DateTime.parse("1950-12-18TZ"), registry)); persistResource(Cursor.create(CursorType.BRDA, DateTime.parse("1950-12-18TZ"), registry));
doUpdateTest(); doUpdateTest();
} }
@Test @TestOfyAndSql
void testSuccess_global_hasOldValue() throws Exception { void testSuccess_global_hasOldValue() throws Exception {
persistResource( persistResource(
Cursor.createGlobal(CursorType.RECURRING_BILLING, DateTime.parse("1950-12-18TZ"))); Cursor.createGlobal(CursorType.RECURRING_BILLING, DateTime.parse("1950-12-18TZ")));
doGlobalUpdateTest(); doGlobalUpdateTest();
} }
@Test @TestOfyAndSql
void testSuccess_global_oldValueisEmpty() throws Exception { void testSuccess_global_oldValueIsEmpty() throws Exception {
assertThat(ofy().load().key(Cursor.createGlobalKey(CursorType.RECURRING_BILLING)).now()) assertThat(loadByKeyIfPresent(Cursor.createGlobalVKey(CursorType.RECURRING_BILLING))).isEmpty();
.isNull();
doGlobalUpdateTest(); doGlobalUpdateTest();
} }
@Test @TestOfyAndSql
void testSuccess_multipleTlds_hasOldValue() throws Exception { void testSuccess_multipleTlds_hasOldValue() throws Exception {
createTld("bar"); createTld("bar");
Registry registry2 = Registry.get("bar"); Registry registry2 = Registry.get("bar");
persistResource(Cursor.create(CursorType.BRDA, DateTime.parse("1950-12-18TZ"), registry)); persistResource(Cursor.create(CursorType.BRDA, DateTime.parse("1950-12-18TZ"), registry));
persistResource(Cursor.create(CursorType.BRDA, DateTime.parse("1950-12-18TZ"), registry2)); persistResource(Cursor.create(CursorType.BRDA, DateTime.parse("1950-12-18TZ"), registry2));
runCommandForced("--type=brda", "--timestamp=1984-12-18T00:00:00Z", "foo", "bar"); runCommandForced("--type=brda", "--timestamp=1984-12-18T00:00:00Z", "foo", "bar");
assertThat(ofy().load().key(Cursor.createKey(CursorType.BRDA, registry)).now().getCursorTime()) assertThat(loadByKey(Cursor.createVKey(CursorType.BRDA, "foo")).getCursorTime())
.isEqualTo(DateTime.parse("1984-12-18TZ")); .isEqualTo(DateTime.parse("1984-12-18TZ"));
assertThat(ofy().load().key(Cursor.createKey(CursorType.BRDA, registry2)).now().getCursorTime()) assertThat(loadByKey(Cursor.createVKey(CursorType.BRDA, "bar")).getCursorTime())
.isEqualTo(DateTime.parse("1984-12-18TZ")); .isEqualTo(DateTime.parse("1984-12-18TZ"));
String changes = command.prompt(); String changes = command.prompt();
assertThat(changes) assertThat(changes)
@ -109,16 +108,15 @@ class UpdateCursorsCommandTest extends CommandTestCase<UpdateCursorsCommand> {
+ "Change cursorTime of BRDA for Scope:bar to 1984-12-18T00:00:00.000Z\n"); + "Change cursorTime of BRDA for Scope:bar to 1984-12-18T00:00:00.000Z\n");
} }
@Test @TestOfyAndSql
void testSuccess_multipleTlds_oldValueisEmpty() throws Exception { void testSuccess_multipleTlds_oldValueisEmpty() throws Exception {
createTld("bar"); createTld("bar");
Registry registry2 = Registry.get("bar"); assertThat(loadByKeyIfPresent(Cursor.createVKey(CursorType.BRDA, "foo"))).isEmpty();
assertThat(ofy().load().key(Cursor.createKey(CursorType.BRDA, registry)).now()).isNull(); assertThat(loadByKeyIfPresent(Cursor.createVKey(CursorType.BRDA, "bar"))).isEmpty();
assertThat(ofy().load().key(Cursor.createKey(CursorType.BRDA, registry2)).now()).isNull();
runCommandForced("--type=brda", "--timestamp=1984-12-18T00:00:00Z", "foo", "bar"); runCommandForced("--type=brda", "--timestamp=1984-12-18T00:00:00Z", "foo", "bar");
assertThat(ofy().load().key(Cursor.createKey(CursorType.BRDA, registry)).now().getCursorTime()) assertThat(loadByKey(Cursor.createVKey(CursorType.BRDA, "foo")).getCursorTime())
.isEqualTo(DateTime.parse("1984-12-18TZ")); .isEqualTo(DateTime.parse("1984-12-18TZ"));
assertThat(ofy().load().key(Cursor.createKey(CursorType.BRDA, registry2)).now().getCursorTime()) assertThat(loadByKey(Cursor.createVKey(CursorType.BRDA, "bar")).getCursorTime())
.isEqualTo(DateTime.parse("1984-12-18TZ")); .isEqualTo(DateTime.parse("1984-12-18TZ"));
String changes = command.prompt(); String changes = command.prompt();
assertThat(changes) assertThat(changes)
@ -127,14 +125,14 @@ class UpdateCursorsCommandTest extends CommandTestCase<UpdateCursorsCommand> {
+ "Change cursorTime of BRDA for Scope:bar to 1984-12-18T00:00:00.000Z\n"); + "Change cursorTime of BRDA for Scope:bar to 1984-12-18T00:00:00.000Z\n");
} }
@Test @TestOfyAndSql
void testFailure_badTld() { void testFailure_badTld() {
assertThrows( assertThrows(
RegistryNotFoundException.class, RegistryNotFoundException.class,
() -> runCommandForced("--type=brda", "--timestamp=1984-12-18T00:00:00Z", "bar")); () -> runCommandForced("--type=brda", "--timestamp=1984-12-18T00:00:00Z", "bar"));
} }
@Test @TestOfyAndSql
void testFailure_badCursorType() { void testFailure_badCursorType() {
ParameterException thrown = ParameterException thrown =
assertThrows( assertThrows(