mirror of
https://github.com/google/nomulus
synced 2026-02-10 06:50:30 +00:00
Make entities serializable for DB validation (#1401)
* Make entities serializable for DB validation Make entities that are asynchronously replicated between Datastore and Cloud SQL serializable so that they may be used in BEAM pipeline based comparison tool. Introduced an UnsafeSerializable interface (extending Serializable) and added to relevant classes. Implementing classes are allowed some shortcuts as explained in the interface's Javadoc. Post migration we will decide whether to revert this change or properly implement serialization. Verified with production data.
This commit is contained in:
@@ -25,6 +25,7 @@ import static google.registry.testing.DatabaseHelper.loadByKey;
|
||||
import static google.registry.testing.DatabaseHelper.persistActiveDomain;
|
||||
import static google.registry.testing.DatabaseHelper.persistResource;
|
||||
import static google.registry.util.DateTimeUtils.END_OF_TIME;
|
||||
import static google.registry.util.SerializeUtils.serializeDeserialize;
|
||||
import static org.joda.money.CurrencyUnit.USD;
|
||||
import static org.joda.time.DateTimeZone.UTC;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
@@ -46,6 +47,7 @@ import google.registry.persistence.VKey;
|
||||
import google.registry.testing.DualDatabaseTest;
|
||||
import google.registry.testing.TestOfyAndSql;
|
||||
import google.registry.testing.TestOfyOnly;
|
||||
import google.registry.testing.TestSqlOnly;
|
||||
import google.registry.util.DateTimeUtils;
|
||||
import org.joda.money.Money;
|
||||
import org.joda.time.DateTime;
|
||||
@@ -195,6 +197,20 @@ public class BillingEventTest extends EntityTestCase {
|
||||
ofyTmOrDoNothing(() -> assertThat(tm().loadByEntity(modification)).isEqualTo(modification));
|
||||
}
|
||||
|
||||
@TestSqlOnly
|
||||
void testSerializable() {
|
||||
BillingEvent persisted = loadByEntity(oneTime);
|
||||
assertThat(serializeDeserialize(persisted)).isEqualTo(persisted);
|
||||
persisted = loadByEntity(oneTimeSynthetic);
|
||||
assertThat(serializeDeserialize(persisted)).isEqualTo(persisted);
|
||||
persisted = loadByEntity(recurring);
|
||||
assertThat(serializeDeserialize(persisted)).isEqualTo(persisted);
|
||||
persisted = loadByEntity(cancellationOneTime);
|
||||
assertThat(serializeDeserialize(persisted)).isEqualTo(persisted);
|
||||
persisted = loadByEntity(cancellationRecurring);
|
||||
assertThat(serializeDeserialize(persisted)).isEqualTo(persisted);
|
||||
}
|
||||
|
||||
@TestOfyOnly
|
||||
void testParenting() {
|
||||
// Note that these are all tested separately because BillingEvent is an abstract base class that
|
||||
|
||||
@@ -30,6 +30,8 @@ import google.registry.model.domain.DomainBase;
|
||||
import google.registry.model.tld.Registry;
|
||||
import google.registry.testing.DualDatabaseTest;
|
||||
import google.registry.testing.TestOfyAndSql;
|
||||
import google.registry.testing.TestSqlOnly;
|
||||
import google.registry.util.SerializeUtils;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
||||
@@ -46,6 +48,15 @@ public class CursorTest extends EntityTestCase {
|
||||
fakeClock.setTo(DateTime.parse("2010-10-17TZ"));
|
||||
}
|
||||
|
||||
@TestSqlOnly
|
||||
void testSerializable() {
|
||||
final DateTime time = DateTime.parse("2012-07-12T03:30:00.000Z");
|
||||
tm().transact(() -> tm().put(Cursor.createGlobal(RECURRING_BILLING, time)));
|
||||
Cursor persisted =
|
||||
tm().transact(() -> tm().loadByKey(Cursor.createGlobalVKey(RECURRING_BILLING)));
|
||||
assertThat(SerializeUtils.serializeDeserialize(persisted)).isEqualTo(persisted);
|
||||
}
|
||||
|
||||
@TestOfyAndSql
|
||||
void testSuccess_persistScopedCursor() {
|
||||
createTld("tld");
|
||||
|
||||
@@ -48,6 +48,7 @@ import google.registry.testing.DualDatabaseTest;
|
||||
import google.registry.testing.TestOfyAndSql;
|
||||
import google.registry.testing.TestOfyOnly;
|
||||
import google.registry.testing.TestSqlOnly;
|
||||
import google.registry.util.SerializeUtils;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
||||
/** Unit tests for {@link ContactResource}. */
|
||||
@@ -174,6 +175,14 @@ public class ContactResourceTest extends EntityTestCase {
|
||||
.hasValue(contactResource);
|
||||
}
|
||||
|
||||
@TestSqlOnly
|
||||
void testSerializable() {
|
||||
ContactResource persisted =
|
||||
loadByForeignKey(ContactResource.class, contactResource.getForeignKey(), fakeClock.nowUtc())
|
||||
.get();
|
||||
assertThat(SerializeUtils.serializeDeserialize(persisted)).isEqualTo(persisted);
|
||||
}
|
||||
|
||||
@TestOfyOnly
|
||||
void testIndexing() throws Exception {
|
||||
verifyDatastoreIndexing(
|
||||
|
||||
@@ -56,6 +56,7 @@ import google.registry.testing.AppEngineExtension;
|
||||
import google.registry.testing.DualDatabaseTest;
|
||||
import google.registry.testing.FakeClock;
|
||||
import google.registry.testing.TestSqlOnly;
|
||||
import google.registry.util.SerializeUtils;
|
||||
import java.util.Arrays;
|
||||
import org.joda.money.Money;
|
||||
import org.joda.time.DateTime;
|
||||
@@ -354,6 +355,14 @@ public class DomainBaseSqlTest {
|
||||
});
|
||||
}
|
||||
|
||||
@TestSqlOnly
|
||||
void testSerializable() {
|
||||
createTld("com");
|
||||
insertInDb(contact, contact2, domain, host);
|
||||
DomainBase persisted = jpaTm().transact(() -> jpaTm().loadByEntity(domain));
|
||||
assertThat(SerializeUtils.serializeDeserialize(persisted)).isEqualTo(persisted);
|
||||
}
|
||||
|
||||
@TestSqlOnly
|
||||
void testUpdates() {
|
||||
createTld("com");
|
||||
|
||||
@@ -41,6 +41,8 @@ import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.testing.DualDatabaseTest;
|
||||
import google.registry.testing.TestOfyAndSql;
|
||||
import google.registry.testing.TestOfyOnly;
|
||||
import google.registry.testing.TestSqlOnly;
|
||||
import google.registry.util.SerializeUtils;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
||||
@@ -93,6 +95,44 @@ public class AllocationTokenTest extends EntityTestCase {
|
||||
assertThat(loadByEntity(singleUseToken)).isEqualTo(singleUseToken);
|
||||
}
|
||||
|
||||
@TestSqlOnly
|
||||
void testSerializable() {
|
||||
AllocationToken unlimitedUseToken =
|
||||
persistResource(
|
||||
new AllocationToken.Builder()
|
||||
.setToken("abc123Unlimited")
|
||||
.setTokenType(UNLIMITED_USE)
|
||||
.setCreationTimeForTest(DateTime.parse("2010-11-12T05:00:00Z"))
|
||||
.setAllowedTlds(ImmutableSet.of("dev", "app"))
|
||||
.setAllowedRegistrarIds(ImmutableSet.of("TheRegistrar, NewRegistrar"))
|
||||
.setDiscountFraction(0.5)
|
||||
.setDiscountPremiums(true)
|
||||
.setDiscountYears(3)
|
||||
.setTokenStatusTransitions(
|
||||
ImmutableSortedMap.<DateTime, TokenStatus>naturalOrder()
|
||||
.put(START_OF_TIME, NOT_STARTED)
|
||||
.put(DateTime.now(UTC), TokenStatus.VALID)
|
||||
.put(DateTime.now(UTC).plusWeeks(8), TokenStatus.ENDED)
|
||||
.build())
|
||||
.build());
|
||||
AllocationToken persisted = loadByEntity(unlimitedUseToken);
|
||||
assertThat(SerializeUtils.serializeDeserialize(persisted)).isEqualTo(persisted);
|
||||
|
||||
DomainBase domain = persistActiveDomain("example.foo");
|
||||
Key<HistoryEntry> historyEntryKey = Key.create(Key.create(domain), HistoryEntry.class, 1);
|
||||
AllocationToken singleUseToken =
|
||||
persistResource(
|
||||
new AllocationToken.Builder()
|
||||
.setToken("abc123Single")
|
||||
.setRedemptionHistoryEntry(HistoryEntry.createVKey(historyEntryKey))
|
||||
.setDomainName("example.foo")
|
||||
.setCreationTimeForTest(DateTime.parse("2010-11-12T05:00:00Z"))
|
||||
.setTokenType(SINGLE_USE)
|
||||
.build());
|
||||
persisted = loadByEntity(singleUseToken);
|
||||
assertThat(SerializeUtils.serializeDeserialize(persisted)).isEqualTo(persisted);
|
||||
}
|
||||
|
||||
@TestOfyOnly
|
||||
void testIndexing() throws Exception {
|
||||
DomainBase domain = persistActiveDomain("blahdomain.foo");
|
||||
|
||||
@@ -39,6 +39,7 @@ import google.registry.persistence.VKey;
|
||||
import google.registry.testing.DualDatabaseTest;
|
||||
import google.registry.testing.TestOfyOnly;
|
||||
import google.registry.testing.TestSqlOnly;
|
||||
import google.registry.util.SerializeUtils;
|
||||
|
||||
/** Tests for {@link ContactHistory}. */
|
||||
@DualDatabaseTest
|
||||
@@ -64,6 +65,18 @@ public class ContactHistoryTest extends EntityTestCase {
|
||||
});
|
||||
}
|
||||
|
||||
@TestSqlOnly
|
||||
void testSerializable() {
|
||||
ContactResource contact = newContactResourceWithRoid("contactId", "contact1");
|
||||
insertInDb(contact);
|
||||
ContactResource contactFromDb = loadByEntity(contact);
|
||||
ContactHistory contactHistory = createContactHistory(contactFromDb);
|
||||
insertInDb(contactHistory);
|
||||
ContactHistory fromDatabase =
|
||||
jpaTm().transact(() -> jpaTm().loadByKey(contactHistory.createVKey()));
|
||||
assertThat(SerializeUtils.serializeDeserialize(fromDatabase)).isEqualTo(fromDatabase);
|
||||
}
|
||||
|
||||
@TestSqlOnly
|
||||
void testLegacyPersistence_nullContactBase() {
|
||||
ContactResource contact = newContactResourceWithRoid("contactId", "contact1");
|
||||
|
||||
@@ -55,6 +55,7 @@ import google.registry.testing.DatabaseHelper;
|
||||
import google.registry.testing.DualDatabaseTest;
|
||||
import google.registry.testing.TestOfyOnly;
|
||||
import google.registry.testing.TestSqlOnly;
|
||||
import google.registry.util.SerializeUtils;
|
||||
import java.util.Optional;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
@@ -87,6 +88,16 @@ public class DomainHistoryTest extends EntityTestCase {
|
||||
});
|
||||
}
|
||||
|
||||
@TestSqlOnly
|
||||
void testSerializable() {
|
||||
DomainBase domain = addGracePeriodForSql(createDomainWithContactsAndHosts());
|
||||
DomainHistory domainHistory = createDomainHistory(domain);
|
||||
insertInDb(domainHistory);
|
||||
DomainHistory fromDatabase =
|
||||
jpaTm().transact(() -> jpaTm().loadByKey(domainHistory.createVKey()));
|
||||
assertThat(SerializeUtils.serializeDeserialize(fromDatabase)).isEqualTo(fromDatabase);
|
||||
}
|
||||
|
||||
@TestSqlOnly
|
||||
void testLegacyPersistence_nullResource() {
|
||||
DomainBase domain = addGracePeriodForSql(createDomainWithContactsAndHosts());
|
||||
|
||||
@@ -36,6 +36,7 @@ import google.registry.persistence.VKey;
|
||||
import google.registry.testing.DualDatabaseTest;
|
||||
import google.registry.testing.TestOfyOnly;
|
||||
import google.registry.testing.TestSqlOnly;
|
||||
import google.registry.util.SerializeUtils;
|
||||
|
||||
/** Tests for {@link HostHistory}. */
|
||||
@DualDatabaseTest
|
||||
@@ -61,6 +62,17 @@ public class HostHistoryTest extends EntityTestCase {
|
||||
});
|
||||
}
|
||||
|
||||
@TestSqlOnly
|
||||
void testSerializable() {
|
||||
HostResource host = newHostResourceWithRoid("ns1.example.com", "host1");
|
||||
insertInDb(host);
|
||||
HostResource hostFromDb = loadByEntity(host);
|
||||
HostHistory hostHistory = createHostHistory(hostFromDb);
|
||||
insertInDb(hostHistory);
|
||||
HostHistory fromDatabase = jpaTm().transact(() -> jpaTm().loadByKey(hostHistory.createVKey()));
|
||||
assertThat(SerializeUtils.serializeDeserialize(fromDatabase)).isEqualTo(fromDatabase);
|
||||
}
|
||||
|
||||
@TestSqlOnly
|
||||
void testLegacyPersistence_nullHostBase() {
|
||||
HostResource host = newHostResourceWithRoid("ns1.example.com", "host1");
|
||||
|
||||
@@ -45,6 +45,8 @@ import google.registry.model.transfer.TransferStatus;
|
||||
import google.registry.testing.DualDatabaseTest;
|
||||
import google.registry.testing.TestOfyAndSql;
|
||||
import google.registry.testing.TestOfyOnly;
|
||||
import google.registry.testing.TestSqlOnly;
|
||||
import google.registry.util.SerializeUtils;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
||||
@@ -111,6 +113,14 @@ class HostResourceTest extends EntityTestCase {
|
||||
.containsExactly(newHost);
|
||||
}
|
||||
|
||||
@TestSqlOnly
|
||||
void testSerializable() {
|
||||
HostResource newHost = host.asBuilder().setRepoId("NEWHOST").build();
|
||||
tm().transact(() -> tm().insert(newHost));
|
||||
HostResource persisted = tm().transact(() -> tm().loadByEntity(newHost));
|
||||
assertThat(SerializeUtils.serializeDeserialize(persisted)).isEqualTo(persisted);
|
||||
}
|
||||
|
||||
@TestOfyOnly
|
||||
void testLoadingByForeignKey() {
|
||||
assertThat(loadByForeignKey(HostResource.class, host.getForeignKey(), fakeClock.nowUtc()))
|
||||
|
||||
@@ -36,6 +36,7 @@ import google.registry.testing.DualDatabaseTest;
|
||||
import google.registry.testing.TestOfyAndSql;
|
||||
import google.registry.testing.TestOfyOnly;
|
||||
import google.registry.testing.TestSqlOnly;
|
||||
import google.registry.util.SerializeUtils;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
||||
/** Unit tests for {@link PollMessage}. */
|
||||
@@ -118,6 +119,20 @@ public class PollMessageTest extends EntityTestCase {
|
||||
assertThat(tm().transact(() -> tm().loadByEntity(pollMessage))).isEqualTo(pollMessage);
|
||||
}
|
||||
|
||||
@TestSqlOnly
|
||||
void testSerializableOneTime() {
|
||||
PollMessage.OneTime pollMessage =
|
||||
persistResource(
|
||||
new PollMessage.OneTime.Builder()
|
||||
.setRegistrarId("TheRegistrar")
|
||||
.setEventTime(fakeClock.nowUtc())
|
||||
.setMsg("Test poll message")
|
||||
.setParent(historyEntry)
|
||||
.build());
|
||||
PollMessage persisted = tm().transact(() -> tm().loadByEntity(pollMessage));
|
||||
assertThat(SerializeUtils.serializeDeserialize(persisted)).isEqualTo(persisted);
|
||||
}
|
||||
|
||||
@TestOfyAndSql
|
||||
void testPersistenceAutorenew() {
|
||||
PollMessage.Autorenew pollMessage =
|
||||
@@ -133,6 +148,22 @@ public class PollMessageTest extends EntityTestCase {
|
||||
assertThat(tm().transact(() -> tm().loadByEntity(pollMessage))).isEqualTo(pollMessage);
|
||||
}
|
||||
|
||||
@TestSqlOnly
|
||||
void testSerializableAutorenew() {
|
||||
PollMessage.Autorenew pollMessage =
|
||||
persistResource(
|
||||
new PollMessage.Autorenew.Builder()
|
||||
.setRegistrarId("TheRegistrar")
|
||||
.setEventTime(fakeClock.nowUtc())
|
||||
.setMsg("Test poll message")
|
||||
.setParent(historyEntry)
|
||||
.setAutorenewEndTime(fakeClock.nowUtc().plusDays(365))
|
||||
.setTargetId("foobar.foo")
|
||||
.build());
|
||||
PollMessage persisted = tm().transact(() -> tm().loadByEntity(pollMessage));
|
||||
assertThat(SerializeUtils.serializeDeserialize(persisted)).isEqualTo(persisted);
|
||||
}
|
||||
|
||||
@TestOfyOnly
|
||||
void testIndexingAutorenew() throws Exception {
|
||||
PollMessage.Autorenew pollMessage =
|
||||
|
||||
@@ -45,7 +45,9 @@ import google.registry.model.tld.Registries;
|
||||
import google.registry.testing.DualDatabaseTest;
|
||||
import google.registry.testing.TestOfyAndSql;
|
||||
import google.registry.testing.TestOfyOnly;
|
||||
import google.registry.testing.TestSqlOnly;
|
||||
import google.registry.util.CidrAddressBlock;
|
||||
import google.registry.util.SerializeUtils;
|
||||
import org.joda.money.CurrencyUnit;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
||||
@@ -135,6 +137,12 @@ class RegistrarTest extends EntityTestCase {
|
||||
assertThat(tm().transact(() -> tm().loadByKey(registrar.createVKey()))).isEqualTo(registrar);
|
||||
}
|
||||
|
||||
@TestSqlOnly
|
||||
void testSerializable() {
|
||||
Registrar persisted = tm().transact(() -> tm().loadByKey(registrar.createVKey()));
|
||||
assertThat(SerializeUtils.serializeDeserialize(persisted)).isEqualTo(persisted);
|
||||
}
|
||||
|
||||
@TestOfyOnly
|
||||
void testIndexing() throws Exception {
|
||||
verifyDatastoreIndexing(registrar, "registrarName", "ianaIdentifier");
|
||||
|
||||
@@ -47,6 +47,8 @@ import google.registry.testing.DatabaseHelper;
|
||||
import google.registry.testing.DualDatabaseTest;
|
||||
import google.registry.testing.TestOfyAndSql;
|
||||
import google.registry.testing.TestOfyOnly;
|
||||
import google.registry.testing.TestSqlOnly;
|
||||
import google.registry.util.SerializeUtils;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Optional;
|
||||
import org.joda.money.Money;
|
||||
@@ -87,6 +89,16 @@ public final class RegistryTest extends EntityTestCase {
|
||||
.isEqualTo(Registry.get("tld"));
|
||||
}
|
||||
|
||||
@TestSqlOnly
|
||||
void testSerializable() {
|
||||
ReservedList rl15 = persistReservedList("tld-reserved15", "potato,FULLY_BLOCKED");
|
||||
Registry registry = Registry.get("tld").asBuilder().setReservedLists(rl15).build();
|
||||
tm().transact(() -> tm().put(registry));
|
||||
Registry persisted =
|
||||
tm().transact(() -> tm().loadByKey(Registry.createVKey(registry.tldStrId)));
|
||||
assertThat(SerializeUtils.serializeDeserialize(persisted)).isEqualTo(persisted);
|
||||
}
|
||||
|
||||
@TestOfyAndSql
|
||||
void testFailure_registryNotFound() {
|
||||
createTld("foo");
|
||||
|
||||
@@ -16,6 +16,7 @@ package google.registry.schema.registrar;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.model.registrar.RegistrarContact.Type.WHOIS;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
|
||||
import static google.registry.testing.DatabaseHelper.insertInDb;
|
||||
import static google.registry.testing.DatabaseHelper.loadByEntity;
|
||||
import static google.registry.testing.SqlHelper.saveRegistrar;
|
||||
@@ -27,6 +28,7 @@ import google.registry.persistence.transaction.JpaTestExtensions;
|
||||
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationWithCoverageExtension;
|
||||
import google.registry.testing.DatastoreEntityExtension;
|
||||
import google.registry.testing.TmOverrideExtension;
|
||||
import google.registry.util.SerializeUtils;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Order;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -74,4 +76,11 @@ class RegistrarContactTest {
|
||||
insertInDb(testRegistrarPoc);
|
||||
assertThat(loadByEntity(testRegistrarPoc)).isEqualTo(testRegistrarPoc);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSerializable_succeeds() {
|
||||
insertInDb(testRegistrarPoc);
|
||||
RegistrarContact persisted = jpaTm().transact(() -> jpaTm().loadByEntity(testRegistrarPoc));
|
||||
assertThat(SerializeUtils.serializeDeserialize(persisted)).isEqualTo(persisted);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user