Refactor Cursor to exist in one class (#988)

This allows us to get rid of the DAO as well as the sanity-checking
methods since we can be reasonably sure that the fields will be the
same. Future PRs will add conversions from ofy() to tm() calls that will
make sure that we get the same proper data in both Datastore and SQL
This commit is contained in:
gbrodman 2021-03-18 21:58:07 -04:00 committed by GitHub
parent 6bc943bb7d
commit 8b2ddf8249
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
25 changed files with 217 additions and 909 deletions

View file

@ -30,7 +30,6 @@ import google.registry.model.ofy.DatastoreTransactionManager;
import google.registry.model.ofy.Ofy;
import google.registry.model.registry.Registry;
import google.registry.persistence.transaction.TransactionManager;
import google.registry.schema.cursor.CursorDao;
import google.registry.testing.AppEngineExtension;
import google.registry.testing.FakeClock;
import google.registry.testing.InjectExtension;
@ -280,18 +279,18 @@ public class CommitLogCheckpointStrategyTest {
// Bucket checkpoint times should be clamped as expected.
assertThat(strategy.computeCheckpoint())
.isEqualTo(CommitLogCheckpoint.create(
checkpointTime,
ImmutableMap.of(1, now, 2, threshold, 3, threshold)));
.isEqualTo(
CommitLogCheckpoint.create(
checkpointTime, ImmutableMap.of(1, now, 2, threshold, 3, threshold)));
}
private void writeCommitLogToBucket(final int bucketId) {
fakeBucketIdSupplier.value = bucketId;
tm.transact(
() ->
CursorDao.saveCursor(
Cursor.create(RDE_REPORT, tm.getTransactionTime(), Registry.get("tld" + bucketId)),
"tld" + bucketId));
tm.put(
Cursor.create(
RDE_REPORT, tm.getTransactionTime(), Registry.get("tld" + bucketId))));
fakeBucketIdSupplier.value = null;
}

View file

@ -43,12 +43,11 @@ import com.google.common.collect.ImmutableSet;
import com.google.common.truth.Truth8;
import com.googlecode.objectify.Key;
import google.registry.config.RegistryConfig;
import google.registry.model.common.Cursor;
import google.registry.model.common.Cursor.CursorType;
import google.registry.model.contact.ContactResource;
import google.registry.model.domain.DomainBase;
import google.registry.model.domain.GracePeriod;
import google.registry.model.domain.secdns.DelegationSignerData;
import google.registry.model.index.ForeignKeyIndex;
import google.registry.model.ofy.CommitLogBucket;
import google.registry.model.ofy.CommitLogManifest;
import google.registry.model.ofy.CommitLogMutation;
@ -367,10 +366,11 @@ public class ReplayCommitLogsToSqlActionTest {
Key<CommitLogManifest> manifestKey =
CommitLogManifest.createKey(getBucketKey(1), now.minusMinutes(1));
createTld("tld");
// Have a commit log with a couple objects that shouldn't be replayed
ReservedList reservedList =
new ReservedList.Builder().setReservedListMap(ImmutableMap.of()).setName("name").build();
Cursor cursor = Cursor.createGlobal(CursorType.RECURRING_BILLING, now.minusHours(1));
ForeignKeyIndex<DomainBase> fki = ForeignKeyIndex.create(newDomainBase("foo.tld"), now);
tm().transact(
() -> {
try {
@ -381,8 +381,8 @@ public class ReplayCommitLogsToSqlActionTest {
getBucketKey(1), now.minusMinutes(1), ImmutableSet.of()),
// Reserved list is dually-written non-replicated
CommitLogMutation.create(manifestKey, reservedList),
// Cursors aren't replayed to SQL at all
CommitLogMutation.create(manifestKey, cursor));
// FKIs aren't replayed to SQL at all
CommitLogMutation.create(manifestKey, fki));
} catch (IOException e) {
throw new RuntimeException(e);
}

View file

@ -19,6 +19,7 @@ import static google.registry.model.common.Cursor.CursorType.RECURRING_BILLING;
import static google.registry.model.domain.Period.Unit.YEARS;
import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.model.reporting.HistoryEntry.Type.DOMAIN_AUTORENEW;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.assertBillingEvents;
import static google.registry.testing.DatabaseHelper.assertBillingEventsForResource;
import static google.registry.testing.DatabaseHelper.createTld;
@ -49,7 +50,6 @@ import google.registry.model.registry.Registry;
import google.registry.model.reporting.DomainTransactionRecord;
import google.registry.model.reporting.DomainTransactionRecord.TransactionReportField;
import google.registry.model.reporting.HistoryEntry;
import google.registry.schema.cursor.CursorDao;
import google.registry.testing.FakeClock;
import google.registry.testing.FakeResponse;
import google.registry.testing.InjectExtension;
@ -101,9 +101,7 @@ public class ExpandRecurringBillingEventsActionTest
}
private void saveCursor(final DateTime cursorTime) {
CursorDao.saveCursor(
Cursor.createGlobal(RECURRING_BILLING, cursorTime),
google.registry.schema.cursor.Cursor.GLOBAL);
tm().transact(() -> tm().put(Cursor.createGlobal(RECURRING_BILLING, cursorTime)));
}
private void runMapreduce() throws Exception {

View file

@ -18,9 +18,8 @@ import static com.google.common.truth.Truth.assertThat;
import static google.registry.model.common.Cursor.CursorType.BRDA;
import static google.registry.model.common.Cursor.CursorType.RDE_UPLOAD;
import static google.registry.model.common.Cursor.CursorType.RECURRING_BILLING;
import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.schema.cursor.Cursor.GLOBAL;
import static google.registry.schema.cursor.CursorDao.loadAndCompare;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm;
import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.persistActiveDomain;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
@ -29,56 +28,57 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
import google.registry.model.EntityTestCase;
import google.registry.model.domain.DomainBase;
import google.registry.model.registry.Registry;
import google.registry.schema.cursor.CursorDao;
import google.registry.testing.DualDatabaseTest;
import google.registry.testing.TestOfyAndSql;
import org.joda.time.DateTime;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
/** Unit tests for {@link Cursor}. */
class CursorTest extends EntityTestCase {
@DualDatabaseTest
public class CursorTest extends EntityTestCase {
public CursorTest() {
super(JpaEntityCoverageCheck.ENABLED);
}
@BeforeEach
void setUp() {
fakeClock.setTo(DateTime.parse("2010-10-17TZ"));
}
@Test
@TestOfyAndSql
void testSuccess_persistScopedCursor() {
createTld("tld");
this.fakeClock.advanceOneMilli();
final DateTime time = DateTime.parse("2012-07-12T03:30:00.000Z");
Cursor cursor = Cursor.create(RDE_UPLOAD, time, Registry.get("tld"));
CursorDao.saveCursor(cursor, "tld");
assertThat(ofy().load().key(Cursor.createKey(BRDA, Registry.get("tld"))).now()).isNull();
assertThat(
ofy()
.load()
.key(Cursor.createKey(RDE_UPLOAD, Registry.get("tld")))
.now()
.getCursorTime())
.isEqualTo(time);
loadAndCompare(cursor, "tld");
tm().transact(() -> tm().put(cursor));
transactIfJpaTm(
() -> {
assertThat(tm().loadByKeyIfPresent(Cursor.createVKey(BRDA, "tld")).isPresent()).isFalse();
assertThat(tm().loadByKey(Cursor.createVKey(RDE_UPLOAD, "tld")).getCursorTime())
.isEqualTo(time);
});
}
@Test
@TestOfyAndSql
void testSuccess_persistGlobalCursor() {
final DateTime time = DateTime.parse("2012-07-12T03:30:00.000Z");
CursorDao.saveCursor(Cursor.createGlobal(RECURRING_BILLING, time), GLOBAL);
assertThat(ofy().load().key(Cursor.createGlobalKey(RECURRING_BILLING)).now().getCursorTime())
Cursor cursor = Cursor.createGlobal(RECURRING_BILLING, time);
tm().transact(() -> tm().put(cursor));
assertThat(tm().transact(() -> tm().loadByKey(cursor.createVKey())).getCursorTime())
.isEqualTo(time);
loadAndCompare(Cursor.createGlobal(RECURRING_BILLING, time), GLOBAL);
}
@Test
@TestOfyAndSql
void testIndexing() throws Exception {
final DateTime time = DateTime.parse("2012-07-12T03:30:00.000Z");
CursorDao.saveCursor(Cursor.createGlobal(RECURRING_BILLING, time), GLOBAL);
Cursor cursor = ofy().load().key(Cursor.createGlobalKey(RECURRING_BILLING)).now();
loadAndCompare(cursor, GLOBAL);
tm().transact(() -> tm().put(Cursor.createGlobal(RECURRING_BILLING, time)));
Cursor cursor = tm().transact(() -> tm().loadByKey(Cursor.createGlobalVKey(RECURRING_BILLING)));
verifyIndexing(cursor);
}
@Test
@TestOfyAndSql
void testFailure_invalidScopeOnCreate() {
createTld("tld");
this.fakeClock.advanceOneMilli();
@ -87,13 +87,14 @@ class CursorTest extends EntityTestCase {
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() -> CursorDao.saveCursor(Cursor.create(RDE_UPLOAD, time, domain), domain.getTld()));
() -> Cursor.create(RDE_UPLOAD, time, domain),
domain.getTld());
assertThat(thrown)
.hasMessageThat()
.contains("Class required for cursor does not match scope class");
}
@Test
@TestOfyAndSql
void testFailure_invalidScopeOnKeyCreate() {
createTld("tld");
IllegalArgumentException thrown =
@ -105,14 +106,14 @@ class CursorTest extends EntityTestCase {
.contains("Class required for cursor does not match scope class");
}
@Test
@TestOfyAndSql
void testFailure_createGlobalKeyForScopedCursorType() {
IllegalArgumentException thrown =
assertThrows(IllegalArgumentException.class, () -> Cursor.createGlobalKey(RDE_UPLOAD));
assertThat(thrown).hasMessageThat().contains("Cursor type is not a global cursor");
}
@Test
@TestOfyAndSql
void testFailure_invalidScopeOnGlobalKeyCreate() {
createTld("tld");
IllegalArgumentException thrown =
@ -124,7 +125,7 @@ class CursorTest extends EntityTestCase {
.contains("Class required for cursor does not match scope class");
}
@Test
@TestOfyAndSql
void testFailure_nullScope() {
NullPointerException thrown =
assertThrows(
@ -133,7 +134,7 @@ class CursorTest extends EntityTestCase {
assertThat(thrown).hasMessageThat().contains("Cursor scope cannot be null");
}
@Test
@TestOfyAndSql
void testFailure_nullCursorType() {
createTld("tld");
NullPointerException thrown =
@ -143,7 +144,7 @@ class CursorTest extends EntityTestCase {
assertThat(thrown).hasMessageThat().contains("Cursor type cannot be null");
}
@Test
@TestOfyAndSql
void testFailure_nullTime() {
createTld("tld");
NullPointerException thrown =

View file

@ -20,6 +20,7 @@ import static google.registry.model.common.Cursor.CursorType.RDE_STAGING;
import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.model.rde.RdeMode.FULL;
import static google.registry.model.rde.RdeMode.THIN;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.persistResource;
import static org.joda.time.DateTimeConstants.TUESDAY;
@ -30,7 +31,6 @@ import google.registry.model.common.Cursor;
import google.registry.model.common.Cursor.CursorType;
import google.registry.model.ofy.Ofy;
import google.registry.model.registry.Registry;
import google.registry.schema.cursor.CursorDao;
import google.registry.testing.AppEngineExtension;
import google.registry.testing.FakeClock;
import google.registry.testing.InjectExtension;
@ -149,17 +149,24 @@ public class PendingDepositCheckerTest {
clock.advanceOneMilli();
createTldWithEscrowEnabled("fun");
clock.advanceOneMilli();
assertThat(checker.getTldsAndWatermarksPendingDepositForRdeAndBrda()).isEqualTo(
ImmutableSetMultimap.of(
"pal", PendingDeposit.create(
"pal", DateTime.parse("2000-01-01TZ"), FULL, RDE_STAGING, standardDays(1)),
"fun", PendingDeposit.create(
"fun", DateTime.parse("2000-01-01TZ"), FULL, RDE_STAGING, standardDays(1))));
assertThat(checker.getTldsAndWatermarksPendingDepositForRdeAndBrda())
.isEqualTo(
ImmutableSetMultimap.of(
"pal",
PendingDeposit.create(
"pal", DateTime.parse("2000-01-01TZ"), FULL, RDE_STAGING, standardDays(1)),
"fun",
PendingDeposit.create(
"fun",
DateTime.parse("2000-01-01TZ"),
FULL,
RDE_STAGING,
standardDays(1))));
}
private static void setCursor(
final Registry registry, final CursorType cursorType, final DateTime value) {
CursorDao.saveCursor(Cursor.create(cursorType, value, registry), registry.getTldStr());
tm().transact(() -> tm().put(Cursor.create(cursorType, value, registry)));
}
private static void createTldWithEscrowEnabled(final String tld) {

View file

@ -19,6 +19,7 @@ import static com.google.common.truth.Truth.assertThat;
import static google.registry.model.common.Cursor.CursorType.BRDA;
import static google.registry.model.common.Cursor.CursorType.RDE_STAGING;
import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.rde.RdeFixtures.makeContactResource;
import static google.registry.rde.RdeFixtures.makeDomainBase;
import static google.registry.rde.RdeFixtures.makeHostResource;
@ -54,7 +55,6 @@ import google.registry.model.ofy.Ofy;
import google.registry.model.registry.Registry;
import google.registry.request.HttpException.BadRequestException;
import google.registry.request.RequestParameters;
import google.registry.schema.cursor.CursorDao;
import google.registry.testing.FakeClock;
import google.registry.testing.FakeKeyringModule;
import google.registry.testing.FakeLockHandler;
@ -842,7 +842,7 @@ public class RdeStagingActionTest extends MapreduceTestCase<RdeStagingAction> {
private void setCursor(
final Registry registry, final CursorType cursorType, final DateTime value) {
clock.advanceOneMilli();
CursorDao.saveCursor(Cursor.create(cursorType, value, registry), registry.getTldStr());
tm().transact(() -> tm().put(Cursor.create(cursorType, value, registry)));
}
public static <T> T unmarshal(Class<T> clazz, byte[] xml) throws XmlException {

View file

@ -39,7 +39,6 @@ import google.registry.model.rde.RdeMode;
import google.registry.model.rde.RdeRevision;
import google.registry.model.registry.Registry;
import google.registry.request.RequestParameters;
import google.registry.schema.cursor.CursorDao;
import google.registry.testing.AppEngineExtension;
import google.registry.testing.FakeClock;
import google.registry.testing.FakeKeyringModule;
@ -105,10 +104,10 @@ class RdeStagingReducerTest {
@BeforeEach
void beforeEach() {
createTld("soy");
CursorDao.saveCursor(Cursor.create(CursorType.BRDA, now, Registry.get("soy")), "soy");
CursorDao.saveCursor(Cursor.create(CursorType.RDE_STAGING, now, Registry.get("soy")), "soy");
tm().transact(
() -> {
tm().put(Cursor.create(CursorType.BRDA, now, Registry.get("soy")));
tm().put(Cursor.create(CursorType.RDE_STAGING, now, Registry.get("soy")));
RdeRevision.saveRevision("soy", now, THIN, 0);
RdeRevision.saveRevision("soy", now, FULL, 0);
});

View file

@ -1,412 +0,0 @@
// Copyright 2019 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.schema.cursor;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.createTlds;
import static google.registry.testing.LogsSubject.assertAboutLogs;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.testing.TestLogHandler;
import google.registry.model.common.Cursor.CursorType;
import google.registry.model.registry.Registry;
import google.registry.testing.AppEngineExtension;
import google.registry.testing.FakeClock;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
/** Unit tests for {@link Cursor}. */
public class CursorDaoTest {
private final FakeClock fakeClock = new FakeClock();
private final TestLogHandler logHandler = new TestLogHandler();
private final Logger loggerToIntercept = Logger.getLogger(CursorDao.class.getCanonicalName());
@RegisterExtension
final AppEngineExtension appEngine =
AppEngineExtension.builder()
.withDatastoreAndCloudSql()
.enableJpaEntityCoverageCheck(true)
.withClock(fakeClock)
.build();
@Test
void save_worksSuccessfullyOnNewCursor() {
Cursor cursor = Cursor.create(CursorType.BRDA, "tld", fakeClock.nowUtc());
CursorDao.save(cursor);
Cursor returnedCursor = CursorDao.load(CursorType.BRDA, "tld");
assertThat(returnedCursor.getCursorTime()).isEqualTo(cursor.getCursorTime());
}
@Test
void save_worksSuccessfullyOnExistingCursor() {
Cursor cursor = Cursor.create(CursorType.RDE_REPORT, "tld", fakeClock.nowUtc());
CursorDao.save(cursor);
Cursor cursor2 = Cursor.create(CursorType.RDE_REPORT, "tld", fakeClock.nowUtc().plusDays(3));
CursorDao.save(cursor2);
Cursor returnedCursor = CursorDao.load(CursorType.RDE_REPORT, "tld");
assertThat(returnedCursor.getCursorTime()).isEqualTo(cursor2.getCursorTime());
}
@Test
void save_worksSuccessfullyOnNewGlobalCursor() {
Cursor cursor = Cursor.createGlobal(CursorType.RECURRING_BILLING, fakeClock.nowUtc());
CursorDao.save(cursor);
Cursor returnedCursor = CursorDao.load(CursorType.RECURRING_BILLING);
assertThat(returnedCursor.getCursorTime()).isEqualTo(cursor.getCursorTime());
}
@Test
void save_worksSuccessfullyOnExistingGlobalCursor() {
Cursor cursor = Cursor.createGlobal(CursorType.RECURRING_BILLING, fakeClock.nowUtc());
CursorDao.save(cursor);
Cursor cursor2 =
Cursor.createGlobal(CursorType.RECURRING_BILLING, fakeClock.nowUtc().plusDays(3));
CursorDao.save(cursor2);
Cursor returnedCursor = CursorDao.load(CursorType.RECURRING_BILLING);
assertThat(returnedCursor.getCursorTime()).isEqualTo(cursor2.getCursorTime());
}
@Test
void saveAll_worksSuccessfully() {
Cursor cursor = Cursor.createGlobal(CursorType.RECURRING_BILLING, fakeClock.nowUtc());
Cursor cursor2 = Cursor.create(CursorType.RDE_REPORT, "tld", fakeClock.nowUtc());
ImmutableSet<Cursor> cursors = ImmutableSet.<Cursor>builder().add(cursor, cursor2).build();
CursorDao.saveAll(cursors);
assertThat(CursorDao.loadAll()).hasSize(2);
assertThat(CursorDao.load(CursorType.RECURRING_BILLING).getCursorTime())
.isEqualTo(cursor.getCursorTime());
}
@Test
void saveAll_worksSuccessfullyEmptySet() {
CursorDao.saveAll(ImmutableSet.of());
assertThat(CursorDao.loadAll()).isEmpty();
}
@Test
void load_worksSuccessfully() {
Cursor cursor = Cursor.createGlobal(CursorType.RECURRING_BILLING, fakeClock.nowUtc());
Cursor cursor2 = Cursor.create(CursorType.RDE_REPORT, "tld", fakeClock.nowUtc());
Cursor cursor3 = Cursor.create(CursorType.RDE_REPORT, "foo", fakeClock.nowUtc());
Cursor cursor4 = Cursor.create(CursorType.BRDA, "foo", fakeClock.nowUtc());
CursorDao.saveAll(ImmutableSet.of(cursor, cursor2, cursor3, cursor4));
Cursor returnedCursor = CursorDao.load(CursorType.RDE_REPORT, "tld");
assertThat(returnedCursor.getCursorTime()).isEqualTo(cursor2.getCursorTime());
returnedCursor = CursorDao.load(CursorType.BRDA, "foo");
assertThat(returnedCursor.getCursorTime()).isEqualTo(cursor4.getCursorTime());
returnedCursor = CursorDao.load(CursorType.RECURRING_BILLING);
assertThat(returnedCursor.getCursorTime()).isEqualTo(cursor.getCursorTime());
}
@Test
void loadAll_worksSuccessfully() {
Cursor cursor = Cursor.createGlobal(CursorType.RECURRING_BILLING, fakeClock.nowUtc());
Cursor cursor2 = Cursor.create(CursorType.RDE_REPORT, "tld", fakeClock.nowUtc());
Cursor cursor3 = Cursor.create(CursorType.RDE_REPORT, "foo", fakeClock.nowUtc());
Cursor cursor4 = Cursor.create(CursorType.BRDA, "foo", fakeClock.nowUtc());
CursorDao.saveAll(ImmutableSet.of(cursor, cursor2, cursor3, cursor4));
List<Cursor> returnedCursors = CursorDao.loadAll();
assertThat(returnedCursors.size()).isEqualTo(4);
}
@Test
void loadAll_worksSuccessfullyEmptyTable() {
List<Cursor> returnedCursors = CursorDao.loadAll();
assertThat(returnedCursors.size()).isEqualTo(0);
}
@Test
void loadByType_worksSuccessfully() {
Cursor cursor = Cursor.createGlobal(CursorType.RECURRING_BILLING, fakeClock.nowUtc());
Cursor cursor2 = Cursor.create(CursorType.RDE_REPORT, "tld", fakeClock.nowUtc());
Cursor cursor3 = Cursor.create(CursorType.RDE_REPORT, "foo", fakeClock.nowUtc());
Cursor cursor4 = Cursor.create(CursorType.BRDA, "foo", fakeClock.nowUtc());
CursorDao.saveAll(ImmutableSet.of(cursor, cursor2, cursor3, cursor4));
List<Cursor> returnedCursors = CursorDao.loadByType(CursorType.RDE_REPORT);
assertThat(returnedCursors.size()).isEqualTo(2);
}
@Test
void loadByType_worksSuccessfullyNoneOfType() {
List<Cursor> returnedCursors = CursorDao.loadByType(CursorType.RDE_REPORT);
assertThat(returnedCursors.size()).isEqualTo(0);
}
@Test
void saveCursor_worksSuccessfully() {
createTld("tld");
google.registry.model.common.Cursor cursor =
google.registry.model.common.Cursor.create(
CursorType.ICANN_UPLOAD_ACTIVITY, fakeClock.nowUtc(), Registry.get("tld"));
CursorDao.saveCursor(cursor, "tld");
Cursor createdCursor = CursorDao.load(CursorType.ICANN_UPLOAD_ACTIVITY, "tld");
google.registry.model.common.Cursor dataStoreCursor =
ofy()
.load()
.key(
google.registry.model.common.Cursor.createKey(
CursorType.ICANN_UPLOAD_ACTIVITY, Registry.get("tld")))
.now();
assertThat(createdCursor.getCursorTime()).isEqualTo(cursor.getCursorTime());
assertThat(cursor).isEqualTo(dataStoreCursor);
}
@Test
void saveCursor_worksSuccessfullyOnGlobalCursor() {
google.registry.model.common.Cursor cursor =
google.registry.model.common.Cursor.createGlobal(
CursorType.RECURRING_BILLING, fakeClock.nowUtc());
CursorDao.saveCursor(cursor, Cursor.GLOBAL);
Cursor createdCursor = CursorDao.load(CursorType.RECURRING_BILLING);
google.registry.model.common.Cursor dataStoreCursor =
ofy()
.load()
.key(google.registry.model.common.Cursor.createGlobalKey(CursorType.RECURRING_BILLING))
.now();
assertThat(createdCursor.getCursorTime()).isEqualTo(cursor.getCursorTime());
assertThat(cursor).isEqualTo(dataStoreCursor);
}
@Test
void saveCursors_worksSuccessfully() {
createTlds("tld", "foo");
google.registry.model.common.Cursor cursor1 =
google.registry.model.common.Cursor.create(
CursorType.ICANN_UPLOAD_ACTIVITY, fakeClock.nowUtc(), Registry.get("tld"));
google.registry.model.common.Cursor cursor2 =
google.registry.model.common.Cursor.create(
CursorType.ICANN_UPLOAD_ACTIVITY, fakeClock.nowUtc(), Registry.get("foo"));
google.registry.model.common.Cursor cursor3 =
google.registry.model.common.Cursor.createGlobal(
CursorType.RECURRING_BILLING, fakeClock.nowUtc());
ImmutableMap<google.registry.model.common.Cursor, String> cursors =
ImmutableMap.<google.registry.model.common.Cursor, String>builder()
.put(cursor1, "tld")
.put(cursor2, "foo")
.put(cursor3, Cursor.GLOBAL)
.build();
CursorDao.saveCursors(cursors);
Cursor createdCursor1 = CursorDao.load(CursorType.ICANN_UPLOAD_ACTIVITY, "tld");
google.registry.model.common.Cursor dataStoreCursor1 =
ofy()
.load()
.key(
google.registry.model.common.Cursor.createKey(
CursorType.ICANN_UPLOAD_ACTIVITY, Registry.get("tld")))
.now();
assertThat(createdCursor1.getCursorTime()).isEqualTo(cursor1.getCursorTime());
assertThat(cursor1).isEqualTo(dataStoreCursor1);
Cursor createdCursor2 = CursorDao.load(CursorType.ICANN_UPLOAD_ACTIVITY, "foo");
google.registry.model.common.Cursor dataStoreCursor2 =
ofy()
.load()
.key(
google.registry.model.common.Cursor.createKey(
CursorType.ICANN_UPLOAD_ACTIVITY, Registry.get("foo")))
.now();
assertThat(createdCursor2.getCursorTime()).isEqualTo(cursor2.getCursorTime());
assertThat(cursor2).isEqualTo(dataStoreCursor2);
Cursor createdCursor3 = CursorDao.load(CursorType.RECURRING_BILLING);
google.registry.model.common.Cursor dataStoreCursor3 =
ofy()
.load()
.key(google.registry.model.common.Cursor.createGlobalKey(CursorType.RECURRING_BILLING))
.now();
assertThat(createdCursor3.getCursorTime()).isEqualTo(cursor3.getCursorTime());
assertThat(cursor3).isEqualTo(dataStoreCursor3);
}
@Test
void loadAndCompare_worksSuccessfully() {
loggerToIntercept.addHandler(logHandler);
createTld("tld");
google.registry.model.common.Cursor cursor =
google.registry.model.common.Cursor.create(
CursorType.ICANN_UPLOAD_ACTIVITY, fakeClock.nowUtc(), Registry.get("tld"));
CursorDao.saveCursor(cursor, "tld");
CursorDao.loadAndCompare(cursor, "tld");
assertAboutLogs().that(logHandler).hasNoLogsAtLevel(Level.WARNING);
}
@Test
void loadAndCompare_worksSuccessfullyGlobalCursor() {
loggerToIntercept.addHandler(logHandler);
google.registry.model.common.Cursor cursor =
google.registry.model.common.Cursor.createGlobal(
CursorType.RECURRING_BILLING, fakeClock.nowUtc());
CursorDao.saveCursor(cursor, Cursor.GLOBAL);
CursorDao.loadAndCompare(cursor, Cursor.GLOBAL);
assertAboutLogs().that(logHandler).hasNoLogsAtLevel(Level.WARNING);
}
@Test
void loadAndCompare_worksSuccessfullyCursorNotInCloudSql() {
loggerToIntercept.addHandler(logHandler);
createTld("tld");
google.registry.model.common.Cursor cursor =
google.registry.model.common.Cursor.create(
CursorType.ICANN_UPLOAD_ACTIVITY, fakeClock.nowUtc(), Registry.get("tld"));
CursorDao.loadAndCompare(cursor, "tld");
assertAboutLogs()
.that(logHandler)
.hasLogAtLevelWithMessage(
Level.WARNING,
"Cursor of type ICANN_UPLOAD_ACTIVITY with the scope tld was not found in Cloud SQL.");
}
@Test
void loadAndCompare_worksSuccessfullyGlobalCursorNotInCloudSql() {
loggerToIntercept.addHandler(logHandler);
google.registry.model.common.Cursor cursor =
google.registry.model.common.Cursor.createGlobal(
CursorType.RECURRING_BILLING, fakeClock.nowUtc());
CursorDao.loadAndCompare(cursor, Cursor.GLOBAL);
assertAboutLogs()
.that(logHandler)
.hasLogAtLevelWithMessage(
Level.WARNING,
"Cursor of type RECURRING_BILLING with the scope GLOBAL was not found in Cloud SQL.");
}
@Test
void loadAndCompare_worksSuccessfullyCursorsNotEqual() {
loggerToIntercept.addHandler(logHandler);
createTld("tld");
google.registry.model.common.Cursor cursor =
google.registry.model.common.Cursor.create(
CursorType.ICANN_UPLOAD_ACTIVITY, fakeClock.nowUtc(), Registry.get("tld"));
CursorDao.saveCursor(cursor, "tld");
cursor =
google.registry.model.common.Cursor.create(
CursorType.ICANN_UPLOAD_ACTIVITY, fakeClock.nowUtc().minusDays(5), Registry.get("tld"));
CursorDao.loadAndCompare(cursor, "tld");
assertAboutLogs()
.that(logHandler)
.hasLogAtLevelWithMessage(
Level.WARNING,
"This cursor of type ICANN_UPLOAD_ACTIVITY with the scope tld has a cursorTime of"
+ " 1969-12-27T00:00:00.000Z in Datastore and 1970-01-01T00:00:00.000Z in Cloud"
+ " SQL.");
}
@Test
void loadAndCompareAll_worksSuccessfully() {
loggerToIntercept.addHandler(logHandler);
// Create Datastore cursors
createTlds("tld", "foo");
google.registry.model.common.Cursor cursor1 =
google.registry.model.common.Cursor.create(
CursorType.ICANN_UPLOAD_ACTIVITY, fakeClock.nowUtc(), Registry.get("tld"));
google.registry.model.common.Cursor cursor2 =
google.registry.model.common.Cursor.create(
CursorType.ICANN_UPLOAD_ACTIVITY, fakeClock.nowUtc(), Registry.get("foo"));
// Save cursors to Cloud SQL
ImmutableMap<google.registry.model.common.Cursor, String> cursors =
ImmutableMap.<google.registry.model.common.Cursor, String>builder()
.put(cursor1, "tld")
.put(cursor2, "foo")
.build();
CursorDao.saveCursors(cursors);
CursorDao.loadAndCompareAll(cursors, CursorType.ICANN_UPLOAD_ACTIVITY);
assertAboutLogs().that(logHandler).hasNoLogsAtLevel(Level.WARNING);
}
@Test
void loadAndCompareAll_worksSuccessfullyMissingOne() {
loggerToIntercept.addHandler(logHandler);
// Create Datastore cursors
createTlds("tld", "foo", "lol");
google.registry.model.common.Cursor cursor1 =
google.registry.model.common.Cursor.create(
CursorType.ICANN_UPLOAD_ACTIVITY, fakeClock.nowUtc(), Registry.get("tld"));
google.registry.model.common.Cursor cursor2 =
google.registry.model.common.Cursor.create(
CursorType.ICANN_UPLOAD_ACTIVITY, fakeClock.nowUtc(), Registry.get("foo"));
// Save Cursors to Cloud SQL
ImmutableMap.Builder<google.registry.model.common.Cursor, String> cursors =
ImmutableMap.<google.registry.model.common.Cursor, String>builder()
.put(cursor1, "tld")
.put(cursor2, "foo");
CursorDao.saveCursors(cursors.build());
// Create a new Datastore cursor that is not saved to Cloud SQL
google.registry.model.common.Cursor cursor3 =
google.registry.model.common.Cursor.create(
CursorType.ICANN_UPLOAD_ACTIVITY, fakeClock.nowUtc().minusDays(4), Registry.get("lol"));
// Call loadAndCompareAll with all three Datastore cursors
CursorDao.loadAndCompareAll(
cursors.put(cursor3, "lol").build(), CursorType.ICANN_UPLOAD_ACTIVITY);
assertAboutLogs()
.that(logHandler)
.hasLogAtLevelWithMessage(
Level.WARNING,
"Cursor of type ICANN_UPLOAD_ACTIVITY with the scope lol was not found in Cloud SQL.");
}
@Test
void loadAndCompareAll_worksSuccessfullyOneWithWrongTime() {
loggerToIntercept.addHandler(logHandler);
// Create Datastore cursors
createTlds("tld", "foo");
google.registry.model.common.Cursor cursor1 =
google.registry.model.common.Cursor.create(
CursorType.ICANN_UPLOAD_ACTIVITY, fakeClock.nowUtc(), Registry.get("tld"));
google.registry.model.common.Cursor cursor2 =
google.registry.model.common.Cursor.create(
CursorType.ICANN_UPLOAD_ACTIVITY, fakeClock.nowUtc(), Registry.get("foo"));
// Save Cursors to Cloud SQL
CursorDao.saveCursors(ImmutableMap.of(cursor1, "tld", cursor2, "foo"));
// Change time of first Datastore cursor, but don't save new time to Cloud SQL
google.registry.model.common.Cursor cursor3 =
google.registry.model.common.Cursor.create(
CursorType.ICANN_UPLOAD_ACTIVITY, fakeClock.nowUtc().minusDays(4), Registry.get("tld"));
CursorDao.loadAndCompareAll(
ImmutableMap.of(cursor2, "foo", cursor3, "tld"), CursorType.ICANN_UPLOAD_ACTIVITY);
assertAboutLogs()
.that(logHandler)
.hasLogAtLevelWithMessage(
Level.WARNING,
"This cursor of type ICANN_UPLOAD_ACTIVITY with the scope tld has a cursorTime of"
+ " 1969-12-28T00:00:00.000Z in Datastore and 1970-01-01T00:00:00.000Z in Cloud"
+ " SQL.");
}
@Test
void loadAndCompareAll_worksSuccessfullyEmptyMap() {
loggerToIntercept.addHandler(logHandler);
CursorDao.loadAndCompareAll(ImmutableMap.of(), CursorType.ICANN_UPLOAD_ACTIVITY);
assertAboutLogs().that(logHandler).hasNoLogsAtLevel(Level.WARNING);
}
}

View file

@ -17,6 +17,7 @@ package google.registry.schema.integration;
import static com.google.common.truth.Truth.assert_;
import google.registry.model.billing.BillingEventTest;
import google.registry.model.common.CursorTest;
import google.registry.model.contact.ContactResourceTest;
import google.registry.model.domain.DomainBaseSqlTest;
import google.registry.model.domain.token.AllocationTokenTest;
@ -36,7 +37,6 @@ import google.registry.model.tmch.ClaimsListDaoTest;
import google.registry.model.tmch.TmchCrlTest;
import google.registry.persistence.transaction.JpaEntityCoverageExtension;
import google.registry.persistence.transaction.JpaTestRules.JpaIntegrationWithCoverageExtension;
import google.registry.schema.cursor.CursorDaoTest;
import google.registry.schema.integration.SqlIntegrationTestSuite.AfterSuiteTest;
import google.registry.schema.integration.SqlIntegrationTestSuite.BeforeSuiteTest;
import google.registry.schema.registrar.RegistrarDaoTest;
@ -85,7 +85,7 @@ import org.junit.runner.RunWith;
ClaimsListDaoTest.class,
ContactHistoryTest.class,
ContactResourceTest.class,
CursorDaoTest.class,
CursorTest.class,
DomainBaseSqlTest.class,
DomainHistoryTest.class,
HostHistoryTest.class,