1
0
mirror of https://github.com/google/nomulus synced 2026-05-24 16:51:49 +00:00

Compare commits

...

9 Commits

Author SHA1 Message Date
gbrodman
18b808bd34 Fix injection with BackfillRegistryLocksCommand (#1337)
It would have been nice if this had failed at compile-time rather than
an NPE, but we need to make sure to specify that we need to inject this
command to get e.g. the random string generator

In addition, print out only the names of the failed domains (rather than
the entire domain object) for readability.
2021-09-24 14:08:30 -04:00
Lai Jiang
d7689539d7 Remove mention of bazel run (#1340)
Also provides a workaround in the error message.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/google/nomulus/1340)
<!-- Reviewable:end -->
2021-09-24 11:44:27 -04:00
Lai Jiang
c14ce6866b Remove remnants of JUnit 4 rules (#1336)
<!-- Reviewable:start -->
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/google/nomulus/1336)
<!-- Reviewable:end -->
2021-09-24 06:35:35 -04:00
Michael Muller
3b84542e46 Add a presubmit to verify no new JS dependencies (#1334)
* Add a presubmit to verify no new JS dependencies

Verify that we have a known set of javascript dependencies.  This guards
against the inadvertent introduction of a new dependency with a disallowed
license.

TESTED: Added a new package to packages.json, observed presubmit failure.

* Replaced f-strings, printed python version

For some reason, it looks like we're using a python version older than 3.6 on
our CI machines.

* Remove python version trace.
2021-09-23 14:42:47 -04:00
Lai Jiang
fc7db91d70 Consolidate the use of URL parameters to specify database override (#1331)
There are actions for which we want to provide an override for the database
to use, like when launching Spec11 and Invoicing pipelines. It make sense to
consolidate around the same parameter provided from the same module for
consistency in all cases, instead of defining an override for each action.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/google/nomulus/1331)
<!-- Reviewable:end -->
2021-09-22 20:01:19 -04:00
Weimin Yu
3d8aa85d63 Fix ReadOnlyCheckingQuery's streaming method (#1329)
* Fix ReadOnlyCheckingQuery's streaming method

Following up to PR 1314: fix one more query defaulting to List when
stream() is invoked.
2021-09-21 15:40:50 -04:00
gbrodman
e14cd8bfa2 Add locking and a response in ReplicateToDatastoreAction (#1328)
* Add locking and a response in ReplicateToDatastoreAction

The response is necessary to get nicer logs in GAE and nicer cron job
behavior.

In addition:
- fix issues where locks would be backed up and replayed to Datastore
(they shouldn't be replayed)
- do ignore-read-only writes when replaying the transactions
2021-09-21 10:12:27 -04:00
Michael Muller
82e8641816 Fix javadoc problems with SoyInfo and subprojects (#1326)
* Fix javadoc problems with SoyInfo and subprojects

The *SoyInfo.java files generated by the soy compiler contain deprecation
warnings with links to files that are not imported.  This causes a javadoc
warning.  Temporarily fix this by replacing the link tags with "LINK".  This
also allows us to remove the exclusion of these files, which is a bit nicer.

Also disable javadoc tasks from subprojects.  These just break because they
don't have access to the legacy javadoc classes in the root.
2021-09-20 10:35:07 -04:00
gbrodman
7461ada0fb Include Cursor in the initial SQL population (#1323)
The test for this also required a bit of a fix in the Cursor scope
initialization. If you persist a Key<?> in some object in Datastore, it
persists just the standard data you'd expect, basically the parent, the
kind, and the object's ID/name. Then, when you load it back in from
Datastore it uses the app ID of whatever environment you're loading in
(the Key contains this info even though it isn't included in the
toString() of Key)

If you persist the websafe string format of a Key (which is what we do
for Cursors), it includes the app ID so when you load it, it contains
the old app ID not the new one (if the app ID has changed).

In the pipelines, we use the standard default environment which has a
different app ID from the test environment that's set up by the
DatastoreEntityExtension.

As a result, we should check in Cursor to see if the key is *any*
cross-tld-key, rather than the exact one that exists within this app
environment.
2021-09-19 09:23:02 -04:00
110 changed files with 1229 additions and 943 deletions

View File

@@ -457,8 +457,6 @@ task javaIncrementalFormatApply {
task javadoc(type: Javadoc) {
source javadocSource
classpath = files(javadocClasspath)
// Exclude the misbehaving generated-by-Soy Java files
exclude "**/*SoyInfo.java"
destinationDir = file("${buildDir}/docs/javadoc")
options.encoding = "UTF-8"
// In a lot of places we don't write @return so suppress warnings about that.
@@ -483,3 +481,15 @@ task coreDev {
}
javadocDependentTasks.each { tasks.javadoc.dependsOn(it) }
// disable javadoc in subprojects, these will break because they don't have
// the correct classpath (see above).
gradle.taskGraph.whenReady { graph ->
graph.getAllTasks().each { task ->
def subprojectJavadoc = (task.path =~ /:.+:javadoc/)
if (subprojectJavadoc) {
println "Skipping ${task.path} for javadoc (only root javadoc works)"
task.enabled = false
}
}
}

View File

@@ -17,9 +17,11 @@ These aren't built in to the static code analysis tools we use (e.g. Checkstyle,
Error Prone) so we must write them manually.
"""
import json
import os
from typing import List, Tuple
import sys
import textwrap
import re
# We should never analyze any generated files
@@ -28,6 +30,13 @@ UNIVERSALLY_SKIPPED_PATTERNS = {"/build/", "cloudbuild-caches", "/out/", ".git/"
FORBIDDEN = 1
REQUIRED = 2
# The list of expected json packages and their licenses.
# These should be one of the allowed licenses in:
# config/dependency-license/allowed_licenses.json
EXPECTED_JS_PACKAGES = [
'google-closure-library', # Owned by Google, Apache 2.0
]
class PresubmitCheck:
@@ -308,6 +317,26 @@ def verify_flyway_index():
return not success
def verify_javascript_deps():
"""Verifies that we haven't introduced any new javascript dependencies."""
with open('package.json') as f:
package = json.load(f)
deps = list(package['dependencies'].keys())
if deps != EXPECTED_JS_PACKAGES:
print('Unexpected javascript dependencies. Was expecting '
'%s, got %s.' % (EXPECTED_JS_PACKAGES, deps))
print(textwrap.dedent("""
* If the new dependencies are intentional, please verify that the
* license is one of the allowed licenses (see
* config/dependency-license/allowed_licenses.json) and add an entry
* for the package (with the license in a comment) to the
* EXPECTED_JS_PACKAGES variable in config/presubmits.py.
"""))
return True
return False
def get_files():
for root, dirnames, filenames in os.walk("."):
for filename in filenames:
@@ -331,5 +360,8 @@ if __name__ == "__main__":
# when we put it here it fails fast before all of the tests are run.
failed |= verify_flyway_index()
# Make sure we haven't introduced any javascript dependencies.
failed |= verify_javascript_deps()
if failed:
sys.exit(1)

View File

@@ -457,6 +457,22 @@ task soyToJava {
"--srcs", "${soyFiles.join(',')}",
"--compileTimeGlobalsFile", "${resourcesSourceDir}/google/registry/ui/globals.txt"
}
// Replace the "@link" tags after the "@deprecated" tags in the generated
// files. The soy compiler doesn't generate imports for these, causing
// us to get warnings when we generate javadocs.
// TODO(b/200296387): To be fair, the deprecations are accurate: we're
// using the old "SoyInfo" classes instead of the new "Templates" files.
// When we convert to the new classes, this hack can go away.
def outputs = fileTree(outputDirectory) {
include '**/*.java'
}
outputs.each { file ->
exec {
commandLine 'sed', '-i', 's/@link/LINK/g', file.getCanonicalPath()
}
}
}
doLast {

View File

@@ -48,7 +48,7 @@ public class AppEngineEnvironment implements Closeable {
public AppEngineEnvironment(String appId) {
isPlaceHolderNeeded = ApiProxy.getCurrentEnvironment() == null;
// isPlaceHolderNeeded may be true when we are invoked in a test with AppEngineRule.
// isPlaceHolderNeeded may be true when we are invoked in a test with AppEngineExtension.
if (isPlaceHolderNeeded) {
ApiProxy.setEnvironmentForCurrentThread(createAppEngineEnvironment(appId));
}

View File

@@ -24,6 +24,7 @@ import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_HOST_RENAME;
import static google.registry.request.RequestParameters.extractIntParameter;
import static google.registry.request.RequestParameters.extractLongParameter;
import static google.registry.request.RequestParameters.extractOptionalBooleanParameter;
import static google.registry.request.RequestParameters.extractOptionalDatetimeParameter;
import static google.registry.request.RequestParameters.extractOptionalIntParameter;
import static google.registry.request.RequestParameters.extractOptionalParameter;
import static google.registry.request.RequestParameters.extractRequiredDatetimeParameter;
@@ -106,6 +107,13 @@ public class BatchModule {
return extractIntParameter(req, RelockDomainAction.PREVIOUS_ATTEMPTS_PARAM);
}
@Provides
@Parameter(ExpandRecurringBillingEventsAction.PARAM_CURSOR_TIME)
static Optional<DateTime> provideCursorTime(HttpServletRequest req) {
return extractOptionalDatetimeParameter(
req, ExpandRecurringBillingEventsAction.PARAM_CURSOR_TIME);
}
@Provides
@Named(QUEUE_ASYNC_ACTIONS)
static Queue provideAsyncActionsPushQueue() {

View File

@@ -25,6 +25,7 @@ import google.registry.backup.VersionedEntity;
import google.registry.beam.common.RegistryJpaIO;
import google.registry.beam.initsql.Transforms.RemoveDomainBaseForeignKeys;
import google.registry.model.billing.BillingEvent;
import google.registry.model.common.Cursor;
import google.registry.model.contact.ContactResource;
import google.registry.model.domain.DomainBase;
import google.registry.model.domain.token.AllocationToken;
@@ -62,6 +63,7 @@ import org.joda.time.DateTime;
* <ol>
* <li>{@link Registry}: Assumes that {@code PremiumList} and {@code ReservedList} have been set
* up in the SQL database.
* <li>{@link Cursor}: Logically can depend on {@code Registry}, but without foreign key.
* <li>{@link Registrar}: Logically depends on {@code Registry}, Foreign key not modeled yet.
* <li>{@link ContactResource}: references {@code Registrar}
* <li>{@link RegistrarContact}: references {@code Registrar}.
@@ -101,7 +103,11 @@ public class InitSqlPipeline implements Serializable {
*/
private static final ImmutableList<Class<?>> PHASE_ONE_ORDERED =
ImmutableList.of(
Registry.class, Registrar.class, ContactResource.class, RegistrarContact.class);
Registry.class,
Cursor.class,
Registrar.class,
ContactResource.class,
RegistrarContact.class);
/**
* Datastore kinds to be written to the SQL database after the cleansed version of {@link

View File

@@ -220,10 +220,10 @@ public class Cursor extends ImmutableObject implements DatastoreAndSqlEntity {
private static String getScopeFromId(String id) {
List<String> idSplit = Splitter.on('_').splitToList(id);
// The "parent" is always the crossTldKey; in order to find the scope (either Registry or
// cross-tld-key) we have to parse the part of the ID
// The key is always either the cross-tld-key or the key of a TLD (whose parent is the
// cross-tld-key).
Key<?> scopeKey = Key.valueOf(idSplit.get(0));
return scopeKey.equals(getCrossTldKey()) ? GLOBAL : scopeKey.getName();
return scopeKey.getParent() == null ? GLOBAL : scopeKey.getName();
}
private static CursorType getTypeFromId(String id) {

View File

@@ -18,6 +18,10 @@ import static google.registry.model.ofy.ObjectifyService.auditedOfy;
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
import static google.registry.persistence.transaction.TransactionManagerFactory.ofyTm;
import static google.registry.request.Action.Method.GET;
import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
import static javax.servlet.http.HttpServletResponse.SC_NO_CONTENT;
import static javax.servlet.http.HttpServletResponse.SC_OK;
import static org.joda.time.Duration.standardHours;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList;
@@ -26,15 +30,20 @@ import google.registry.model.UpdateAutoTimestamp;
import google.registry.model.common.DatabaseMigrationStateSchedule;
import google.registry.model.common.DatabaseMigrationStateSchedule.MigrationState;
import google.registry.model.common.DatabaseMigrationStateSchedule.ReplayDirection;
import google.registry.model.server.Lock;
import google.registry.persistence.transaction.Transaction;
import google.registry.persistence.transaction.TransactionEntity;
import google.registry.request.Action;
import google.registry.request.Response;
import google.registry.request.auth.Auth;
import google.registry.util.Clock;
import google.registry.util.RequestStatusChecker;
import java.io.IOException;
import java.util.List;
import java.util.Optional;
import javax.inject.Inject;
import javax.persistence.NoResultException;
import org.joda.time.Duration;
/** Cron task to replicate from Cloud SQL to datastore. */
@Action(
@@ -55,11 +64,18 @@ public class ReplicateToDatastoreAction implements Runnable {
*/
public static final int BATCH_SIZE = 200;
private static final Duration LEASE_LENGTH = standardHours(1);
private final Clock clock;
private final RequestStatusChecker requestStatusChecker;
private final Response response;
@Inject
public ReplicateToDatastoreAction(Clock clock) {
public ReplicateToDatastoreAction(
Clock clock, RequestStatusChecker requestStatusChecker, Response response) {
this.clock = clock;
this.requestStatusChecker = requestStatusChecker;
this.response = response;
}
@VisibleForTesting
@@ -143,24 +159,55 @@ public class ReplicateToDatastoreAction implements Runnable {
public void run() {
MigrationState state = DatabaseMigrationStateSchedule.getValueAtTime(clock.nowUtc());
if (!state.getReplayDirection().equals(ReplayDirection.SQL_TO_DATASTORE)) {
logger.atInfo().log(
"Skipping ReplicateToDatastoreAction because we are in migration phase %s.", state);
String message =
String.format(
"Skipping ReplicateToDatastoreAction because we are in migration phase %s.", state);
logger.atInfo().log(message);
// App Engine will retry on any non-2xx status code, which we don't want in this case.
response.setStatus(SC_NO_CONTENT);
response.setPayload(message);
return;
}
// TODO(b/181758163): Deal with objects that don't exist in Cloud SQL, e.g. ForeignKeyIndex,
// EppResourceIndex.
logger.atInfo().log("Processing transaction replay batch Cloud SQL -> Cloud Datastore");
int numTransactionsReplayed = 0;
for (TransactionEntity txnEntity : getTransactionBatch()) {
try {
applyTransaction(txnEntity);
} catch (Throwable t) {
logger.atSevere().withCause(t).log("Errored out replaying files");
return;
}
numTransactionsReplayed++;
Optional<Lock> lock =
Lock.acquire(
this.getClass().getSimpleName(), null, LEASE_LENGTH, requestStatusChecker, false);
if (!lock.isPresent()) {
String message = "Can't acquire ReplicateToDatastoreAction lock, aborting.";
logger.atSevere().log(message);
// App Engine will retry on any non-2xx status code, which we don't want in this case.
response.setStatus(SC_NO_CONTENT);
response.setPayload(message);
return;
}
logger.atInfo().log(
"Replayed %d transactions from Cloud SQL -> Datastore", numTransactionsReplayed);
try {
logger.atInfo().log("Processing transaction replay batch Cloud SQL -> Cloud Datastore");
int numTransactionsReplayed = replayAllTransactions();
String resultMessage =
String.format(
"Replayed %d transaction(s) from Cloud SQL -> Datastore", numTransactionsReplayed);
logger.atInfo().log(resultMessage);
response.setPayload(resultMessage);
response.setStatus(SC_OK);
} catch (Throwable t) {
String message = "Errored out replaying files";
logger.atSevere().withCause(t).log(message);
response.setStatus(SC_INTERNAL_SERVER_ERROR);
response.setPayload(message);
} finally {
lock.ifPresent(Lock::release);
}
}
private int replayAllTransactions() {
int numTransactionsReplayed = 0;
List<TransactionEntity> transactionBatch;
do {
transactionBatch = getTransactionBatch();
for (TransactionEntity transaction : transactionBatch) {
applyTransaction(transaction);
numTransactionsReplayed++;
}
} while (!transactionBatch.isEmpty());
return numTransactionsReplayed;
}
}

View File

@@ -15,6 +15,7 @@
package google.registry.model.server;
import static com.google.common.base.Preconditions.checkArgument;
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.util.DateTimeUtils.isAtOrAfter;
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
@@ -35,6 +36,7 @@ import google.registry.util.RequestStatusChecker;
import google.registry.util.RequestStatusCheckerImpl;
import java.io.Serializable;
import java.util.Optional;
import java.util.function.Supplier;
import javax.annotation.Nullable;
import javax.persistence.Column;
import javax.persistence.IdClass;
@@ -215,45 +217,45 @@ public class Lock extends ImmutableObject implements DatastoreAndSqlEntity, Seri
// It's important to use transactNew rather than transact, because a Lock can be used to control
// access to resources like GCS that can't be transactionally rolled back. Therefore, the lock
// must be definitively acquired before it is used, even when called inside another transaction.
Supplier<AcquireResult> lockAcquirer =
() -> {
DateTime now = tm().getTransactionTime();
// Checking if an unexpired lock still exists - if so, the lock can't be acquired.
Lock lock =
tm().loadByKeyIfPresent(
VKey.create(
Lock.class,
new LockId(resourceName, scope),
Key.create(Lock.class, lockId)))
.orElse(null);
if (lock != null) {
logger.atInfo().log(
"Loaded existing lock: %s for request: %s", lock.lockId, lock.requestLogId);
}
LockState lockState;
if (lock == null) {
lockState = LockState.FREE;
} else if (isAtOrAfter(now, lock.expirationTime)) {
lockState = LockState.TIMED_OUT;
} else if (checkThreadRunning && !requestStatusChecker.isRunning(lock.requestLogId)) {
lockState = LockState.OWNER_DIED;
} else {
lockState = LockState.IN_USE;
return AcquireResult.create(now, lock, null, lockState);
}
Lock newLock =
create(resourceName, scope, requestStatusChecker.getLogId(), now, leaseLength);
// Locks are not parented under an EntityGroupRoot (so as to avoid write
// contention) and don't need to be backed up.
tm().putIgnoringReadOnly(newLock);
return AcquireResult.create(now, lock, newLock, lockState);
};
// In ofy, backup is determined per-action, but in SQL it's determined per-transaction
AcquireResult acquireResult =
tm().transactNew(
() -> {
DateTime now = tm().getTransactionTime();
// Checking if an unexpired lock still exists - if so, the lock can't be acquired.
Lock lock =
tm().loadByKeyIfPresent(
VKey.create(
Lock.class,
new LockId(resourceName, scope),
Key.create(Lock.class, lockId)))
.orElse(null);
if (lock != null) {
logger.atInfo().log(
"Loaded existing lock: %s for request: %s", lock.lockId, lock.requestLogId);
}
LockState lockState;
if (lock == null) {
lockState = LockState.FREE;
} else if (isAtOrAfter(now, lock.expirationTime)) {
lockState = LockState.TIMED_OUT;
} else if (checkThreadRunning
&& !requestStatusChecker.isRunning(lock.requestLogId)) {
lockState = LockState.OWNER_DIED;
} else {
lockState = LockState.IN_USE;
return AcquireResult.create(now, lock, null, lockState);
}
Lock newLock =
create(
resourceName, scope, requestStatusChecker.getLogId(), now, leaseLength);
// Locks are not parented under an EntityGroupRoot (so as to avoid write
// contention) and don't need to be backed up.
tm().putIgnoringReadOnly(newLock);
return AcquireResult.create(now, lock, newLock, lockState);
});
tm().isOfy() ? tm().transactNew(lockAcquirer) : jpaTm().transactWithoutBackup(lockAcquirer);
logAcquireResult(acquireResult);
lockMetrics.recordAcquire(resourceName, scope, acquireResult.lockState());
@@ -263,34 +265,41 @@ public class Lock extends ImmutableObject implements DatastoreAndSqlEntity, Seri
/** Release the lock. */
public void release() {
// Just use the default clock because we aren't actually doing anything that will use the clock.
tm().transact(
() -> {
// To release a lock, check that no one else has already obtained it and if not
// delete it. If the lock in Datastore was different then this lock is gone already;
// this can happen if release() is called around the expiration time and the lock
// expires underneath us.
VKey<Lock> key =
VKey.create(
Lock.class, new LockId(resourceName, tld), Key.create(Lock.class, lockId));
Lock loadedLock = tm().loadByKeyIfPresent(key).orElse(null);
if (Lock.this.equals(loadedLock)) {
// Use deleteWithoutBackup() so that we don't create a commit log entry for deleting
// the lock.
logger.atInfo().log("Deleting lock: %s", lockId);
tm().deleteIgnoringReadOnly(key);
Supplier<Void> lockReleaser =
() -> {
// To release a lock, check that no one else has already obtained it and if not
// delete it. If the lock in Datastore was different then this lock is gone already;
// this can happen if release() is called around the expiration time and the lock
// expires underneath us.
VKey<Lock> key =
VKey.create(
Lock.class, new LockId(resourceName, tld), Key.create(Lock.class, lockId));
Lock loadedLock = tm().loadByKeyIfPresent(key).orElse(null);
if (Lock.this.equals(loadedLock)) {
// Use deleteIgnoringReadOnly() so that we don't create a commit log entry for deleting
// the lock.
logger.atInfo().log("Deleting lock: %s", lockId);
tm().deleteIgnoringReadOnly(key);
lockMetrics.recordRelease(
resourceName, tld, new Duration(acquiredTime, tm().getTransactionTime()));
} else {
logger.atSevere().log(
"The lock we acquired was transferred to someone else before we"
+ " released it! Did action take longer than lease length?"
+ " Our lock: %s, current lock: %s",
Lock.this, loadedLock);
logger.atInfo().log(
"Not deleting lock: %s - someone else has it: %s", lockId, loadedLock);
}
});
lockMetrics.recordRelease(
resourceName, tld, new Duration(acquiredTime, tm().getTransactionTime()));
} else {
logger.atSevere().log(
"The lock we acquired was transferred to someone else before we"
+ " released it! Did action take longer than lease length?"
+ " Our lock: %s, current lock: %s",
Lock.this, loadedLock);
logger.atInfo().log(
"Not deleting lock: %s - someone else has it: %s", lockId, loadedLock);
}
return null;
};
// In ofy, backup is determined per-action, but in SQL it's determined per-transaction
if (tm().isOfy()) {
tm().transact(lockReleaser);
} else {
jpaTm().transactWithoutBackup(lockReleaser);
}
}
static class LockId extends ImmutableObject implements Serializable {

View File

@@ -1,59 +0,0 @@
// Copyright 2017 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.module.backend;
import static google.registry.model.tld.Registries.assertTldExists;
import static google.registry.model.tld.Registries.assertTldsExist;
import static google.registry.request.RequestParameters.extractOptionalDatetimeParameter;
import static google.registry.request.RequestParameters.extractRequiredParameter;
import static google.registry.request.RequestParameters.extractSetOfParameters;
import com.google.common.collect.ImmutableSet;
import dagger.Module;
import dagger.Provides;
import google.registry.batch.ExpandRecurringBillingEventsAction;
import google.registry.request.Parameter;
import google.registry.request.RequestParameters;
import java.util.Optional;
import javax.servlet.http.HttpServletRequest;
import org.joda.time.DateTime;
/**
* Dagger module for injecting common settings for all Backend tasks.
*/
@Module
public class BackendModule {
@Provides
@Parameter(RequestParameters.PARAM_TLD)
static String provideTld(HttpServletRequest req) {
return assertTldExists(extractRequiredParameter(req, RequestParameters.PARAM_TLD));
}
@Provides
@Parameter(RequestParameters.PARAM_TLDS)
static ImmutableSet<String> provideTlds(HttpServletRequest req) {
ImmutableSet<String> tlds = extractSetOfParameters(req, RequestParameters.PARAM_TLDS);
assertTldsExist(tlds);
return tlds;
}
@Provides
@Parameter("cursorTime")
static Optional<DateTime> provideCursorTime(HttpServletRequest req) {
return extractOptionalDatetimeParameter(
req, ExpandRecurringBillingEventsAction.PARAM_CURSOR_TIME);
}
}

View File

@@ -94,7 +94,6 @@ import google.registry.tools.javascrap.CreateSyntheticHistoryEntriesAction;
@RequestScope
@Subcomponent(
modules = {
BackendModule.class,
BackupModule.class,
BatchModule.class,
BillingModule.class,

View File

@@ -20,11 +20,11 @@ import java.lang.reflect.Proxy;
* A dummy implementation for {@link JpaTransactionManager} which throws exception when any of its
* method is invoked.
*
* <p>This is used to initialize the {@link TransactionManagerFactory#jpaTm} when running unit
* <p>This is used to initialize the {@link TransactionManagerFactory#jpaTm()} when running unit
* tests, because obviously we cannot connect to the actual Cloud SQL backend in a unit test.
*
* <p>If a unit test needs to access the Cloud SQL database, it must add JpaTransactionManagerRule
* as a JUnit rule in the test class.
* <p>If a unit test needs to access the Cloud SQL database, it must add {@code
* JpaTransactionManagerExtension} as a JUnit extension in the test class.
*/
public class DummyJpaTransactionManager {
@@ -37,7 +37,7 @@ public class DummyJpaTransactionManager {
(proxy, method, args) -> {
throw new UnsupportedOperationException(
"JpaTransactionManager was not initialized as the runtime is detected as"
+ " Unittest. Add JpaTransactionManagerRule in the unit test for"
+ " Unittest. Add JpaTransactionManagerExtension in the unit test for"
+ " initialization.");
});
}

View File

@@ -21,6 +21,7 @@ import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Stream;
import javax.persistence.FlushModeType;
import javax.persistence.LockModeType;
import javax.persistence.Parameter;
@@ -41,6 +42,11 @@ class ReadOnlyCheckingQuery implements Query {
return delegate.getResultList();
}
@Override
public Stream getResultStream() {
return delegate.getResultStream();
}
@Override
public Object getSingleResult() {
return delegate.getSingleResult();

View File

@@ -242,7 +242,7 @@ public class Transaction extends ImmutableObject implements Buildable {
if (entity instanceof DatastoreEntity) {
((DatastoreEntity) entity).beforeDatastoreSaveOnReplay();
}
ofyTm().put(entity);
ofyTm().putIgnoringReadOnly(entity);
}
@Override
@@ -280,7 +280,7 @@ public class Transaction extends ImmutableObject implements Buildable {
@Override
public void writeToDatastore() {
ofyTm().delete(key);
ofyTm().deleteIgnoringReadOnly(key);
}
@Override

View File

@@ -14,7 +14,6 @@
package google.registry.reporting;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.request.RequestParameters.extractOptionalParameter;
import static google.registry.request.RequestParameters.extractRequiredParameter;
@@ -56,9 +55,6 @@ public class ReportingModule {
/** The request parameter specifying the jobId for a running Dataflow pipeline. */
public static final String PARAM_JOB_ID = "jobId";
/** The request parameter for specifying which database reporting actions should read from. */
public static final String DATABASE = "database";
/** Provides the Cloud Dataflow jobId for a pipeline. */
@Provides
@Parameter(PARAM_JOB_ID)
@@ -66,14 +62,6 @@ public class ReportingModule {
return extractRequiredParameter(req, PARAM_JOB_ID);
}
/** Provides the database for the pipeline to read from. */
@Provides
@Parameter(DATABASE)
static String provideDatabase(HttpServletRequest req) {
Optional<String> optionalDatabase = extractOptionalParameter(req, DATABASE);
return optionalDatabase.orElse(tm().isOfy() ? "DATASTORE" : "CLOUD_SQL");
}
/** Extracts an optional YearMonth in yyyy-MM format from the request. */
@Provides
@Parameter(PARAM_YEAR_MONTH)

View File

@@ -15,10 +15,9 @@
package google.registry.reporting.billing;
import static google.registry.beam.BeamUtils.createJobName;
import static google.registry.model.common.DatabaseMigrationStateSchedule.PrimaryDatabase.CLOUD_SQL;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.reporting.ReportingModule.DATABASE;
import static google.registry.reporting.ReportingUtils.enqueueBeamReportingTask;
import static google.registry.reporting.billing.BillingModule.PARAM_SHOULD_PUBLISH;
import static google.registry.request.Action.Method.POST;
import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
import static javax.servlet.http.HttpServletResponse.SC_OK;
@@ -31,9 +30,11 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.flogger.FluentLogger;
import com.google.common.net.MediaType;
import google.registry.config.RegistryConfig.Config;
import google.registry.model.common.DatabaseMigrationStateSchedule.PrimaryDatabase;
import google.registry.reporting.ReportingModule;
import google.registry.request.Action;
import google.registry.request.Parameter;
import google.registry.request.RequestParameters;
import google.registry.request.Response;
import google.registry.request.auth.Auth;
import google.registry.util.Clock;
@@ -72,7 +73,7 @@ public class GenerateInvoicesAction implements Runnable {
private final Clock clock;
private final Response response;
private final Dataflow dataflow;
private final String database;
private final PrimaryDatabase database;
@Inject
GenerateInvoicesAction(
@@ -81,8 +82,8 @@ public class GenerateInvoicesAction implements Runnable {
@Config("beamStagingBucketUrl") String stagingBucketUrl,
@Config("billingBucketUrl") String billingBucketUrl,
@Config("invoiceFilePrefix") String invoiceFilePrefix,
@Parameter(PARAM_SHOULD_PUBLISH) boolean shouldPublish,
@Parameter(DATABASE) String database,
@Parameter(BillingModule.PARAM_SHOULD_PUBLISH) boolean shouldPublish,
@Parameter(RequestParameters.PARAM_DATABASE) PrimaryDatabase database,
YearMonth yearMonth,
BillingEmailUtils emailUtils,
Clock clock,
@@ -93,7 +94,7 @@ public class GenerateInvoicesAction implements Runnable {
this.stagingBucketUrl = stagingBucketUrl;
// When generating the invoices using Cloud SQL before database cutover, save the reports in a
// separate bucket so that it does not overwrite the Datastore invoices.
if (tm().isOfy() && database.equals("CLOUD_SQL")) {
if (tm().isOfy() && database.equals(CLOUD_SQL)) {
billingBucketUrl = billingBucketUrl.concat("-sql");
}
this.billingBucketUrl = billingBucketUrl;
@@ -124,7 +125,7 @@ public class GenerateInvoicesAction implements Runnable {
"invoiceFilePrefix",
invoiceFilePrefix,
"database",
database,
database.name(),
"billingBucketUrl",
billingBucketUrl));
LaunchFlexTemplateResponse launchResponse =
@@ -148,14 +149,13 @@ public class GenerateInvoicesAction implements Runnable {
yearMonth.toString());
enqueueBeamReportingTask(PublishInvoicesAction.PATH, beamTaskParameters);
}
response.setStatus(SC_OK);
response.setPayload(String.format("Launched invoicing pipeline: %s", jobId));
} catch (IOException e) {
logger.atWarning().withCause(e).log("Template Launch failed");
emailUtils.sendAlertEmail(String.format("Template Launch failed due to %s", e.getMessage()));
logger.atWarning().withCause(e).log("Pipeline Launch failed");
emailUtils.sendAlertEmail(String.format("Pipeline Launch failed due to %s", e.getMessage()));
response.setStatus(SC_INTERNAL_SERVER_ERROR);
response.setPayload(String.format("Template launch failed: %s", e.getMessage()));
return;
response.setPayload(String.format("Pipeline launch failed: %s", e.getMessage()));
}
response.setStatus(SC_OK);
response.setPayload("Launched dataflow template.");
}
}

View File

@@ -16,8 +16,6 @@ package google.registry.reporting.spec11;
import static google.registry.beam.BeamUtils.createJobName;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.reporting.ReportingModule.DATABASE;
import static google.registry.reporting.ReportingModule.PARAM_DATE;
import static google.registry.reporting.ReportingUtils.enqueueBeamReportingTask;
import static google.registry.request.Action.Method.POST;
import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
@@ -33,9 +31,11 @@ import com.google.common.net.MediaType;
import google.registry.config.RegistryConfig.Config;
import google.registry.config.RegistryEnvironment;
import google.registry.keyring.api.KeyModule.Key;
import google.registry.model.common.DatabaseMigrationStateSchedule.PrimaryDatabase;
import google.registry.reporting.ReportingModule;
import google.registry.request.Action;
import google.registry.request.Parameter;
import google.registry.request.RequestParameters;
import google.registry.request.Response;
import google.registry.request.auth.Auth;
import google.registry.util.Clock;
@@ -71,7 +71,7 @@ public class GenerateSpec11ReportAction implements Runnable {
private final Clock clock;
private final Response response;
private final Dataflow dataflow;
private final String database;
private final PrimaryDatabase database;
@Inject
GenerateSpec11ReportAction(
@@ -80,15 +80,15 @@ public class GenerateSpec11ReportAction implements Runnable {
@Config("beamStagingBucketUrl") String stagingBucketUrl,
@Config("reportingBucketUrl") String reportingBucketUrl,
@Key("safeBrowsingAPIKey") String apiKey,
@Parameter(PARAM_DATE) LocalDate date,
@Parameter(DATABASE) String database,
@Parameter(ReportingModule.PARAM_DATE) LocalDate date,
@Parameter(RequestParameters.PARAM_DATABASE) PrimaryDatabase database,
Clock clock,
Response response,
Dataflow dataflow) {
this.projectId = projectId;
this.jobRegion = jobRegion;
this.stagingBucketUrl = stagingBucketUrl;
if (tm().isOfy() && database.equals("CLOUD_SQL")) {
if (tm().isOfy() && database.equals(PrimaryDatabase.CLOUD_SQL)) {
reportingBucketUrl = reportingBucketUrl.concat("-sql");
}
this.reportingBucketUrl = reportingBucketUrl;
@@ -114,7 +114,7 @@ public class GenerateSpec11ReportAction implements Runnable {
"safeBrowsingApiKey",
apiKey,
"database",
database,
database.name(),
ReportingModule.PARAM_DATE,
date.toString(),
"reportingBucketUrl",
@@ -131,21 +131,18 @@ public class GenerateSpec11ReportAction implements Runnable {
jobRegion,
new LaunchFlexTemplateRequest().setLaunchParameter(parameter))
.execute();
logger.atInfo().log("Got response: %s", launchResponse.getJob().toPrettyString());
String jobId = launchResponse.getJob().getId();
Map<String, String> beamTaskParameters =
ImmutableMap.of(
ReportingModule.PARAM_JOB_ID,
launchResponse.getJob().getId(),
ReportingModule.PARAM_DATE,
date.toString());
ReportingModule.PARAM_JOB_ID, jobId, ReportingModule.PARAM_DATE, date.toString());
enqueueBeamReportingTask(PublishSpec11ReportAction.PATH, beamTaskParameters);
logger.atInfo().log("Got response: %s", launchResponse.getJob().toPrettyString());
response.setStatus(SC_OK);
response.setPayload(String.format("Launched Spec11 pipeline: %s", jobId));
} catch (IOException e) {
logger.atWarning().withCause(e).log("Template Launch failed");
logger.atWarning().withCause(e).log("Pipeline Launch failed");
response.setStatus(SC_INTERNAL_SERVER_ERROR);
response.setPayload(String.format("Template launch failed: %s", e.getMessage()));
return;
response.setPayload(String.format("Pipeline launch failed: %s", e.getMessage()));
}
response.setStatus(SC_OK);
response.setPayload("Launched Spec11 dataflow template.");
}
}

View File

@@ -15,16 +15,24 @@
package google.registry.request;
import static com.google.common.net.MediaType.JSON_UTF_8;
import static google.registry.model.tld.Registries.assertTldExists;
import static google.registry.model.tld.Registries.assertTldsExist;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.request.RequestParameters.extractOptionalParameter;
import static google.registry.request.RequestParameters.extractRequiredParameter;
import static google.registry.request.RequestParameters.extractSetOfParameters;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.VerifyException;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.io.ByteStreams;
import com.google.common.io.CharStreams;
import com.google.common.net.MediaType;
import dagger.Module;
import dagger.Provides;
import google.registry.model.common.DatabaseMigrationStateSchedule.PrimaryDatabase;
import google.registry.request.HttpException.BadRequestException;
import google.registry.request.HttpException.UnsupportedMediaTypeException;
import google.registry.request.auth.AuthResult;
@@ -60,6 +68,29 @@ public final class RequestModule {
this.authResult = authResult;
}
@Provides
@Parameter(RequestParameters.PARAM_TLD)
static String provideTld(HttpServletRequest req) {
return assertTldExists(extractRequiredParameter(req, RequestParameters.PARAM_TLD));
}
@Provides
@Parameter(RequestParameters.PARAM_TLDS)
static ImmutableSet<String> provideTlds(HttpServletRequest req) {
ImmutableSet<String> tlds = extractSetOfParameters(req, RequestParameters.PARAM_TLDS);
assertTldsExist(tlds);
return tlds;
}
@Provides
@Parameter(RequestParameters.PARAM_DATABASE)
static PrimaryDatabase provideDatabase(HttpServletRequest req) {
return extractOptionalParameter(req, RequestParameters.PARAM_DATABASE)
.map(String::toUpperCase)
.map(PrimaryDatabase::valueOf)
.orElse(tm().isOfy() ? PrimaryDatabase.DATASTORE : PrimaryDatabase.CLOUD_SQL);
}
@Provides
static Response provideResponse(ResponseImpl response) {
return response;

View File

@@ -37,6 +37,14 @@ public final class RequestParameters {
/** The standardized request parameter name used by any action taking multiple tld parameters. */
public static final String PARAM_TLDS = "tlds";
/**
* The standardized optional request parameter name used by any action to specify which database
* to use, if the action supports such override. The supported values are (case-insensitive)
* "datastore" and "cloud_sql".
*/
// TODO (jianglai): delete this param after the database migration.
public static final String PARAM_DATABASE = "database";
/**
* Returns first GET or POST parameter associated with {@code name}.
*

View File

@@ -53,7 +53,8 @@ class CommandUtilities {
/** Prompts for yes/no input using promptText, defaulting to no. */
static boolean promptForYes(String promptText) {
checkState(
System.console() != null, "Unable to access stdin (are you running with bazel run?)");
System.console() != null,
"Unable to access stdin (are you running with `gradle registryTool`?), try using -f.");
String input = System.console().readLine(promptText + " (y/N): ");
// Null represents end-of-file (e.g. ^-D) so interpret that as a negative response.
return input != null && Ascii.toUpperCase(input).startsWith("Y");

View File

@@ -41,6 +41,7 @@ import google.registry.request.Modules.URLFetchServiceModule;
import google.registry.request.Modules.UrlFetchTransportModule;
import google.registry.request.Modules.UserServiceModule;
import google.registry.tools.AuthModule.LocalCredentialModule;
import google.registry.tools.javascrap.BackfillRegistryLocksCommand;
import google.registry.tools.javascrap.DeleteContactByRoidCommand;
import google.registry.util.UtilsModule;
import google.registry.whois.NonCachingWhoisModule;
@@ -85,6 +86,8 @@ import javax.inject.Singleton;
interface RegistryToolComponent {
void inject(AckPollMessagesCommand command);
void inject(BackfillRegistryLocksCommand command);
void inject(CheckDomainClaimsCommand command);
void inject(CheckDomainCommand command);

View File

@@ -94,7 +94,7 @@ public class BackfillRegistryLocksCommand extends ConfirmingCommand
@Override
protected String execute() {
ImmutableSet.Builder<DomainBase> failedDomainsBuilder = new ImmutableSet.Builder<>();
ImmutableSet.Builder<String> failedDomainsBuilder = new ImmutableSet.Builder<>();
jpaTm()
.transact(
() -> {
@@ -114,11 +114,11 @@ public class BackfillRegistryLocksCommand extends ConfirmingCommand
} catch (Throwable t) {
logger.atSevere().withCause(t).log(
"Error when creating lock object for domain %s.", domainBase.getDomainName());
failedDomainsBuilder.add(domainBase);
failedDomainsBuilder.add(domainBase.getDomainName());
}
}
});
ImmutableSet<DomainBase> failedDomains = failedDomainsBuilder.build();
ImmutableSet<String> failedDomains = failedDomainsBuilder.build();
if (failedDomains.isEmpty()) {
return String.format(
"Successfully created lock objects for %d domains.", lockedDomains.size());
@@ -126,7 +126,7 @@ public class BackfillRegistryLocksCommand extends ConfirmingCommand
return String.format(
"Successfully created lock objects for %d domains. We failed to create locks "
+ "for the following domains: %s",
lockedDomains.size() - failedDomains.size(), lockedDomains);
lockedDomains.size() - failedDomains.size(), failedDomains);
}
}

View File

@@ -18,13 +18,10 @@ import static com.google.common.base.Strings.emptyToNull;
import static google.registry.request.RequestParameters.extractIntParameter;
import static google.registry.request.RequestParameters.extractOptionalParameter;
import static google.registry.request.RequestParameters.extractRequiredParameter;
import static google.registry.request.RequestParameters.extractSetOfParameters;
import com.google.common.collect.ImmutableSet;
import dagger.Module;
import dagger.Provides;
import google.registry.request.Parameter;
import google.registry.request.RequestParameters;
import java.util.Optional;
import javax.servlet.http.HttpServletRequest;
@@ -60,18 +57,6 @@ public class ToolsServerModule {
return (s == null) ? Optional.empty() : Optional.of(Boolean.parseBoolean(s));
}
@Provides
@Parameter(RequestParameters.PARAM_TLD)
static String provideTld(HttpServletRequest req) {
return extractRequiredParameter(req, RequestParameters.PARAM_TLD);
}
@Provides
@Parameter(RequestParameters.PARAM_TLDS)
static ImmutableSet<String> provideTlds(HttpServletRequest req) {
return extractSetOfParameters(req, RequestParameters.PARAM_TLDS);
}
@Provides
@Parameter("limit")
static int provideLimit(HttpServletRequest req) {

View File

@@ -86,7 +86,7 @@ public class RelockDomainActionTest {
mock(AppEngineServiceUtils.class), clock, Duration.ZERO));
@RegisterExtension
public final AppEngineExtension appEngineRule =
public final AppEngineExtension appEngineExtension =
AppEngineExtension.builder()
.withDatastoreAndCloudSql()
.withTaskQueue()

View File

@@ -40,8 +40,8 @@ import google.registry.model.registrar.Registrar;
import google.registry.model.tld.Registry;
import google.registry.model.transfer.ContactTransferData;
import google.registry.persistence.transaction.CriteriaQueryBuilder;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaIntegrationTestExtension;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationTestExtension;
import google.registry.testing.AppEngineExtension;
import google.registry.testing.DatabaseHelper;
import google.registry.testing.DatastoreEntityExtension;
@@ -67,7 +67,7 @@ public class RegistryJpaReadTest {
@RegisterExtension
final transient JpaIntegrationTestExtension database =
new JpaTestRules.Builder().withClock(fakeClock).buildIntegrationTestRule();
new JpaTestExtensions.Builder().withClock(fakeClock).buildIntegrationTestExtension();
@RegisterExtension
final transient TestPipelineExtension testPipeline =

View File

@@ -29,8 +29,8 @@ import google.registry.model.ImmutableObject;
import google.registry.model.contact.ContactResource;
import google.registry.model.ofy.Ofy;
import google.registry.model.registrar.Registrar;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaIntegrationTestExtension;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationTestExtension;
import google.registry.testing.AppEngineExtension;
import google.registry.testing.DatabaseHelper;
import google.registry.testing.DatastoreEntityExtension;
@@ -56,11 +56,11 @@ class RegistryJpaWriteTest implements Serializable {
@Order(Order.DEFAULT - 1)
final transient DatastoreEntityExtension datastore = new DatastoreEntityExtension();
@RegisterExtension final transient InjectExtension injectRule = new InjectExtension();
@RegisterExtension final transient InjectExtension injectExtension = new InjectExtension();
@RegisterExtension
final transient JpaIntegrationTestExtension database =
new JpaTestRules.Builder().withClock(fakeClock).buildIntegrationTestRule();
new JpaTestExtensions.Builder().withClock(fakeClock).buildIntegrationTestExtension();
@RegisterExtension
final transient TestPipelineExtension testPipeline =
@@ -71,7 +71,7 @@ class RegistryJpaWriteTest implements Serializable {
@BeforeEach
void beforeEach() throws Exception {
try (BackupTestStore store = new BackupTestStore(fakeClock)) {
injectRule.setStaticField(Ofy.class, "clock", fakeClock);
injectExtension.setStaticField(Ofy.class, "clock", fakeClock);
// Required for contacts created below.
Registrar ofyRegistrar = AppEngineExtension.makeRegistrar2();

View File

@@ -34,8 +34,8 @@ import google.registry.model.domain.DomainBase;
import google.registry.model.ofy.Ofy;
import google.registry.model.tld.Registry;
import google.registry.persistence.VKey;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaIntegrationTestExtension;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationTestExtension;
import google.registry.testing.DatastoreEntityExtension;
import google.registry.testing.FakeClock;
import google.registry.testing.InjectExtension;
@@ -62,14 +62,14 @@ public class BackupTestStoreTest {
@RegisterExtension
final transient JpaIntegrationTestExtension jpaIntegrationTestExtension =
new JpaTestRules.Builder().buildIntegrationTestRule();
new JpaTestExtensions.Builder().buildIntegrationTestExtension();
@RegisterExtension
@Order(value = 1)
final transient DatastoreEntityExtension datastoreEntityExtension =
new DatastoreEntityExtension();
@RegisterExtension InjectExtension injectRule = new InjectExtension();
@RegisterExtension InjectExtension injectExtension = new InjectExtension();
private FakeClock fakeClock;
private BackupTestStore store;
@@ -83,7 +83,7 @@ public class BackupTestStoreTest {
void beforeEach() throws Exception {
fakeClock = new FakeClock(START_TIME);
store = new BackupTestStore(fakeClock);
injectRule.setStaticField(Ofy.class, "clock", fakeClock);
injectExtension.setStaticField(Ofy.class, "clock", fakeClock);
registry = newRegistry("tld1", "TLD1");
store.insertOrUpdate(registry);

View File

@@ -26,8 +26,8 @@ import google.registry.model.contact.ContactResource;
import google.registry.model.domain.DomainBase;
import google.registry.model.ofy.Ofy;
import google.registry.model.tld.Registry;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaIntegrationTestExtension;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationTestExtension;
import google.registry.testing.DatastoreEntityExtension;
import google.registry.testing.FakeClock;
import google.registry.testing.InjectExtension;
@@ -62,11 +62,11 @@ class CommitLogTransformsTest implements Serializable {
@TempDir
transient Path tmpDir;
@RegisterExtension final transient InjectExtension injectRule = new InjectExtension();
@RegisterExtension final transient InjectExtension injectExtension = new InjectExtension();
@RegisterExtension
final transient JpaIntegrationTestExtension jpaIntegrationTestExtension =
new JpaTestRules.Builder().withClock(fakeClock).buildIntegrationTestRule();
new JpaTestExtensions.Builder().withClock(fakeClock).buildIntegrationTestExtension();
@RegisterExtension
@Order(value = 1)
@@ -89,7 +89,7 @@ class CommitLogTransformsTest implements Serializable {
@BeforeEach
void beforeEach() throws Exception {
store = new BackupTestStore(fakeClock);
injectRule.setStaticField(Ofy.class, "clock", fakeClock);
injectExtension.setStaticField(Ofy.class, "clock", fakeClock);
registry = newRegistry("tld1", "TLD1");
store.insertOrUpdate(registry);

View File

@@ -68,14 +68,14 @@ public class DomainBaseUtilTest {
private Key<DomainBase> domainKey;
@RegisterExtension
AppEngineExtension appEngineRule =
AppEngineExtension appEngineExtension =
AppEngineExtension.builder().withDatastoreAndCloudSql().withClock(fakeClock).build();
@RegisterExtension InjectExtension injectRule = new InjectExtension();
@RegisterExtension InjectExtension injectExtension = new InjectExtension();
@BeforeEach
void beforeEach() {
injectRule.setStaticField(Ofy.class, "clock", fakeClock);
injectExtension.setStaticField(Ofy.class, "clock", fakeClock);
createTld("com");
domainKey = Key.create(null, DomainBase.class, "4-COM");
VKey<HostResource> hostKey =

View File

@@ -27,8 +27,8 @@ import google.registry.model.contact.ContactResource;
import google.registry.model.domain.DomainBase;
import google.registry.model.ofy.Ofy;
import google.registry.model.tld.Registry;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaIntegrationTestExtension;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationTestExtension;
import google.registry.testing.DatastoreEntityExtension;
import google.registry.testing.FakeClock;
import google.registry.testing.InjectExtension;
@@ -70,11 +70,11 @@ class ExportLoadingTransformsTest implements Serializable {
@TempDir
transient Path tmpDir;
@RegisterExtension final transient InjectExtension injectRule = new InjectExtension();
@RegisterExtension final transient InjectExtension injectExtension = new InjectExtension();
@RegisterExtension
final transient JpaIntegrationTestExtension jpaIntegrationTestExtension =
new JpaTestRules.Builder().buildIntegrationTestRule();
new JpaTestExtensions.Builder().buildIntegrationTestExtension();
@RegisterExtension
@Order(value = 1)
@@ -98,7 +98,7 @@ class ExportLoadingTransformsTest implements Serializable {
void beforeEach() throws Exception {
fakeClock = new FakeClock(START_TIME);
store = new BackupTestStore(fakeClock);
injectRule.setStaticField(Ofy.class, "clock", fakeClock);
injectExtension.setStaticField(Ofy.class, "clock", fakeClock);
registry = newRegistry("tld1", "TLD1");
store.insertOrUpdate(registry);

View File

@@ -17,6 +17,8 @@ package google.registry.beam.initsql;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.model.ImmutableObjectSubject.assertAboutImmutableObjects;
import static google.registry.model.ImmutableObjectSubject.immutableObjectCorrespondence;
import static google.registry.model.common.Cursor.CursorType.BRDA;
import static google.registry.model.common.Cursor.CursorType.RECURRING_BILLING;
import static google.registry.model.domain.token.AllocationToken.TokenType.SINGLE_USE;
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
import static google.registry.testing.DatabaseHelper.newRegistry;
@@ -34,6 +36,7 @@ import google.registry.flows.domain.DomainFlowUtils;
import google.registry.model.billing.BillingEvent;
import google.registry.model.billing.BillingEvent.Flag;
import google.registry.model.billing.BillingEvent.Reason;
import google.registry.model.common.Cursor;
import google.registry.model.contact.ContactResource;
import google.registry.model.domain.DesignatedContact;
import google.registry.model.domain.DomainAuthInfo;
@@ -57,8 +60,8 @@ import google.registry.model.tld.Registry;
import google.registry.model.transfer.DomainTransferData;
import google.registry.model.transfer.TransferStatus;
import google.registry.persistence.VKey;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaIntegrationTestExtension;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationTestExtension;
import google.registry.testing.AppEngineExtension;
import google.registry.testing.DatastoreEntityExtension;
import google.registry.testing.FakeClock;
@@ -86,6 +89,7 @@ class InitSqlPipelineTest {
private static final ImmutableList<Class<?>> ALL_KINDS =
ImmutableList.of(
Registry.class,
Cursor.class,
Registrar.class,
ContactResource.class,
RegistrarContact.class,
@@ -104,7 +108,7 @@ class InitSqlPipelineTest {
@Order(Order.DEFAULT - 1)
final transient DatastoreEntityExtension datastore = new DatastoreEntityExtension();
@RegisterExtension final transient InjectExtension injectRule = new InjectExtension();
@RegisterExtension final transient InjectExtension injectExtension = new InjectExtension();
@SuppressWarnings("WeakerAccess")
@TempDir
@@ -116,7 +120,7 @@ class InitSqlPipelineTest {
@RegisterExtension
final transient JpaIntegrationTestExtension database =
new JpaTestRules.Builder().withClock(fakeClock).buildIntegrationTestRule();
new JpaTestExtensions.Builder().withClock(fakeClock).buildIntegrationTestExtension();
private File exportRootDir;
private File exportDir;
@@ -131,10 +135,13 @@ class InitSqlPipelineTest {
private transient DomainHistory historyEntry;
private transient Cursor globalCursor;
private transient Cursor tldCursor;
@BeforeEach
void beforeEach() throws Exception {
try (BackupTestStore store = new BackupTestStore(fakeClock)) {
injectRule.setStaticField(Ofy.class, "clock", fakeClock);
injectExtension.setStaticField(Ofy.class, "clock", fakeClock);
exportRootDir = Files.createDirectory(tmpDir.resolve("exports")).toFile();
persistResource(newRegistry("com", "COM"));
@@ -304,6 +311,8 @@ class InitSqlPipelineTest {
.setRecurringEventKey(recurringBillEvent.createVKey())
.setParent(historyEntryKey)
.build());
globalCursor = persistResource(Cursor.createGlobal(RECURRING_BILLING, fakeClock.nowUtc()));
tldCursor = persistResource(Cursor.create(BRDA, fakeClock.nowUtc(), Registry.get("com")));
exportDir = store.export(exportRootDir.getAbsolutePath(), ALL_KINDS, ImmutableSet.of());
commitLogDir = Files.createDirectory(tmpDir.resolve("commits")).toFile();
fakeClock.advanceOneMilli();
@@ -332,6 +341,9 @@ class InitSqlPipelineTest {
.comparingElementsUsing(immutableObjectCorrespondence("revisions", "updateTimestamp"))
.containsExactly(contact1, contact2);
assertDomainEquals(jpaTm().transact(() -> jpaTm().loadByKey(domain.createVKey())), domain);
assertThat(jpaTm().transact(() -> jpaTm().loadAllOf(Cursor.class)))
.comparingElementsUsing(immutableObjectCorrespondence())
.containsExactly(globalCursor, tldCursor);
}
}

View File

@@ -29,8 +29,8 @@ import google.registry.model.domain.DomainBase;
import google.registry.model.eppcommon.AuthInfo.PasswordAuth;
import google.registry.model.ofy.Ofy;
import google.registry.model.tld.Registry;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaIntegrationTestExtension;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationTestExtension;
import google.registry.testing.DatastoreEntityExtension;
import google.registry.testing.FakeClock;
import google.registry.testing.InjectExtension;
@@ -86,11 +86,11 @@ class LoadDatastoreSnapshotTest {
@TempDir
transient Path tmpDir;
@RegisterExtension final transient InjectExtension injectRule = new InjectExtension();
@RegisterExtension final transient InjectExtension injectExtension = new InjectExtension();
@RegisterExtension
final transient JpaIntegrationTestExtension jpaIntegrationTestExtension =
new JpaTestRules.Builder().buildIntegrationTestRule();
new JpaTestExtensions.Builder().buildIntegrationTestExtension();
@RegisterExtension
@Order(value = 1)
@@ -119,7 +119,7 @@ class LoadDatastoreSnapshotTest {
void beforeEach() throws Exception {
fakeClock = new FakeClock(START_TIME);
try (BackupTestStore store = new BackupTestStore(fakeClock)) {
injectRule.setStaticField(Ofy.class, "clock", fakeClock);
injectExtension.setStaticField(Ofy.class, "clock", fakeClock);
exportRootDir = Files.createDirectory(tmpDir.resolve("export_root")).toFile();
commitLogsDir = Files.createDirectory(tmpDir.resolve("commit_logs")).toFile();

View File

@@ -43,8 +43,8 @@ import google.registry.model.domain.DomainHistory;
import google.registry.model.registrar.Registrar;
import google.registry.model.reporting.HistoryEntry;
import google.registry.model.tld.Registry;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaIntegrationTestExtension;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationTestExtension;
import google.registry.testing.DatastoreEntityExtension;
import google.registry.testing.FakeClock;
import google.registry.testing.TestDataHelper;
@@ -235,7 +235,7 @@ class InvoicingPipelineTest {
@RegisterExtension
final JpaIntegrationTestExtension database =
new JpaTestRules.Builder().withClock(new FakeClock()).buildIntegrationTestRule();
new JpaTestExtensions.Builder().withClock(new FakeClock()).buildIntegrationTestExtension();
@TempDir Path tmpDir;

View File

@@ -62,8 +62,8 @@ import google.registry.model.registrar.Registrar;
import google.registry.model.registrar.Registrar.State;
import google.registry.model.tld.Registry;
import google.registry.persistence.VKey;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaIntegrationTestExtension;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationTestExtension;
import google.registry.persistence.transaction.TransactionManagerFactory;
import google.registry.rde.DepositFragment;
import google.registry.rde.Ghostryde;
@@ -150,7 +150,7 @@ public class RdePipelineTest {
@RegisterExtension
final JpaIntegrationTestExtension database =
new JpaTestRules.Builder().withClock(clock).buildIntegrationTestRule();
new JpaTestExtensions.Builder().withClock(clock).buildIntegrationTestExtension();
@RegisterExtension
final TestPipelineExtension pipeline =

View File

@@ -47,8 +47,8 @@ import google.registry.model.registrar.Registrar;
import google.registry.model.reporting.Spec11ThreatMatch;
import google.registry.model.reporting.Spec11ThreatMatch.ThreatType;
import google.registry.model.reporting.Spec11ThreatMatchDao;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaIntegrationTestExtension;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationTestExtension;
import google.registry.testing.DatastoreEntityExtension;
import google.registry.testing.FakeClock;
import google.registry.testing.FakeSleeper;
@@ -126,7 +126,7 @@ class Spec11PipelineTest {
@RegisterExtension
final JpaIntegrationTestExtension database =
new JpaTestRules.Builder().withClock(new FakeClock()).buildIntegrationTestRule();
new JpaTestExtensions.Builder().withClock(new FakeClock()).buildIntegrationTestExtension();
private final Spec11PipelineOptions options =
PipelineOptionsFactory.create().as(Spec11PipelineOptions.class);

View File

@@ -36,7 +36,7 @@ class CommitLogFanoutActionTest {
private static final String QUEUE = "the-queue";
@RegisterExtension
final AppEngineExtension appEngineRule =
final AppEngineExtension appEngineExtension =
AppEngineExtension.builder()
.withDatastoreAndCloudSql()
.withTaskQueue(

View File

@@ -18,7 +18,6 @@ import dagger.Component;
import google.registry.config.RegistryConfig.ConfigModule;
import google.registry.cron.CronModule;
import google.registry.dns.writer.VoidDnsWriterModule;
import google.registry.module.backend.BackendModule;
import google.registry.request.RequestModule;
import google.registry.util.UtilsModule;
import javax.inject.Singleton;
@@ -26,7 +25,6 @@ import javax.inject.Singleton;
@Singleton
@Component(
modules = {
BackendModule.class,
ConfigModule.class,
CronModule.class,
DnsModule.class,

View File

@@ -81,7 +81,7 @@ public class SyncRegistrarsSheetTest {
void beforeEach() {
inject.setStaticField(Ofy.class, "clock", clock);
createTld("example");
// Remove Registrar entities created by AppEngineRule (and RegistrarContact's, for jpa).
// Remove Registrar entities created by AppEngineExtension (and RegistrarContact's, for jpa).
// We don't do this for ofy because ofy's loadAllOf() can't be called in a transaction but
// _must_ be called in a transaction in JPA.
if (!tm().isOfy()) {

View File

@@ -67,7 +67,7 @@ import org.mockito.quality.Strictness;
class EppControllerTest {
@RegisterExtension
AppEngineExtension appEngineRule =
AppEngineExtension appEngineExtension =
new AppEngineExtension.Builder().withDatastoreAndCloudSql().build();
@Mock SessionMetadata sessionMetadata;

View File

@@ -51,7 +51,7 @@ import org.mockito.Mockito;
class FlowRunnerTest {
@RegisterExtension
final AppEngineExtension appEngineRule =
final AppEngineExtension appEngineExtension =
new AppEngineExtension.Builder().withDatastoreAndCloudSql().build();
private final FlowRunner flowRunner = new FlowRunner();

View File

@@ -29,7 +29,7 @@ import org.junit.jupiter.api.extension.RegisterExtension;
public class ModelUtilsTest {
@RegisterExtension
public AppEngineExtension appEngineRule = new AppEngineExtension.Builder().build();
public AppEngineExtension appEngineExtension = new AppEngineExtension.Builder().build();
/** Test class for reflection methods. */
public static class TestClass extends ImmutableObject implements Buildable {

View File

@@ -46,7 +46,7 @@ public class CommitLogMutationTest {
@BeforeEach
void before() {
// Initialize this late to avoid dependency on NamespaceManager prior to AppEngineRule.
// Initialize this late to avoid dependency on NamespaceManager prior to AppEngineExtension.
manifestKey = CommitLogManifest.createKey(CommitLogBucket.getBucketKey(1), NOW);
createTld("tld");
someObject = Registry.get("tld");

View File

@@ -38,7 +38,7 @@ class OfyFilterTest {
private LocalServiceTestHelper helper;
private ObjectifyFactory factory;
// We can't use AppEngineRule, because it triggers the precise behavior that we are testing.
// We can't use AppEngineExtension, because it triggers the precise behavior that we are testing.
@BeforeEach
void beforeEach() {

View File

@@ -83,7 +83,7 @@ public class OfyTest {
.setTrid(Trid.create("client", "server"))
.setXmlBytes("<xml></xml>".getBytes(UTF_8))
.build();
// This can't be initialized earlier because namespaces need the AppEngineRule to work.
// This can't be initialized earlier because namespaces need the AppEngineExtension to work.
}
private void doBackupGroupRootTimestampInversionTest(Runnable runnable) {

View File

@@ -20,21 +20,30 @@ import static google.registry.persistence.transaction.TransactionManagerFactory.
import static google.registry.testing.DatabaseHelper.insertInDb;
import static google.registry.testing.LogsSubject.assertAboutLogs;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
import static javax.servlet.http.HttpServletResponse.SC_NO_CONTENT;
import static javax.servlet.http.HttpServletResponse.SC_OK;
import static org.junit.Assert.assertThrows;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableSortedMap;
import com.google.common.testing.TestLogHandler;
import com.google.common.truth.Truth8;
import google.registry.model.common.DatabaseMigrationStateSchedule;
import google.registry.model.common.DatabaseMigrationStateSchedule.MigrationState;
import google.registry.model.ofy.CommitLogBucket;
import google.registry.model.ofy.Ofy;
import google.registry.model.server.Lock;
import google.registry.persistence.transaction.TransactionEntity;
import google.registry.testing.AppEngineExtension;
import google.registry.testing.DatabaseHelper;
import google.registry.testing.FakeClock;
import google.registry.testing.FakeResponse;
import google.registry.testing.InjectExtension;
import google.registry.testing.TestObject;
import google.registry.util.RequestStatusChecker;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -54,18 +63,20 @@ public class ReplicateToDatastoreActionTest {
public final AppEngineExtension appEngine =
AppEngineExtension.builder()
.withDatastoreAndCloudSql()
.withOfyTestEntities(TestObject.class)
.withJpaUnitTestEntities(TestObject.class)
.withOfyTestEntities(Lock.class, TestObject.class)
.withJpaUnitTestEntities(Lock.class, TestObject.class)
.withClock(fakeClock)
.build();
@RegisterExtension final InjectExtension injectExtension = new InjectExtension();
private final ReplicateToDatastoreAction task = new ReplicateToDatastoreAction(fakeClock);
private final TestLogHandler logHandler = new TestLogHandler();
private ReplicateToDatastoreAction action;
private FakeResponse response;
@BeforeEach
void setUp() {
resetAction();
injectExtension.setStaticField(Ofy.class, "clock", fakeClock);
// Use a single bucket to expose timestamp inversion problems.
injectExtension.setStaticField(
@@ -95,7 +106,7 @@ public class ReplicateToDatastoreActionTest {
jpaTm().insert(foo);
jpaTm().insert(bar);
});
task.run();
runAndVerifySuccess();
assertThat(ofyTm().transact(() -> ofyTm().loadByKey(foo.key()))).isEqualTo(foo);
assertThat(ofyTm().transact(() -> ofyTm().loadByKey(bar.key()))).isEqualTo(bar);
@@ -107,7 +118,7 @@ public class ReplicateToDatastoreActionTest {
jpaTm().delete(bar.key());
jpaTm().insert(baz);
});
task.run();
runAndVerifySuccess();
assertThat(ofyTm().transact(() -> ofyTm().loadByKeyIfPresent(bar.key()).isPresent())).isFalse();
assertThat(ofyTm().transact(() -> ofyTm().loadByKey(baz.key()))).isEqualTo(baz);
@@ -120,7 +131,7 @@ public class ReplicateToDatastoreActionTest {
// Write a transaction containing "foo".
insertInDb(foo);
task.run();
runAndVerifySuccess();
// Verify that it propagated to datastore, then remove "foo" directly from datastore.
assertThat(ofyTm().transact(() -> ofyTm().loadByKey(foo.key()))).isEqualTo(foo);
@@ -128,7 +139,7 @@ public class ReplicateToDatastoreActionTest {
// Write "bar"
insertInDb(bar);
task.run();
runAndVerifySuccess();
// If we replayed only the most recent transaction, we should have "bar" but not "foo".
assertThat(ofyTm().transact(() -> ofyTm().loadByKey(bar.key()))).isEqualTo(bar);
@@ -142,23 +153,23 @@ public class ReplicateToDatastoreActionTest {
// Write a transaction and run just the batch fetch.
insertInDb(foo);
List<TransactionEntity> txns1 = task.getTransactionBatch();
List<TransactionEntity> txns1 = action.getTransactionBatch();
assertThat(txns1).hasSize(1);
// Write a second transaction and do another batch fetch.
insertInDb(bar);
List<TransactionEntity> txns2 = task.getTransactionBatch();
List<TransactionEntity> txns2 = action.getTransactionBatch();
assertThat(txns2).hasSize(2);
// Apply the first batch.
task.applyTransaction(txns1.get(0));
action.applyTransaction(txns1.get(0));
// Remove the foo record so we can ensure that this transaction doesn't get doublle-played.
ofyTm().transact(() -> ofyTm().delete(foo.key()));
// Apply the second batch.
for (TransactionEntity txn : txns2) {
task.applyTransaction(txn);
action.applyTransaction(txn);
}
// Verify that the first transaction didn't get replayed but the second one did.
@@ -179,9 +190,10 @@ public class ReplicateToDatastoreActionTest {
// Force the last transaction id back to -1 so that we look for transaction 0.
ofyTm().transact(() -> ofyTm().insert(new LastSqlTransaction(-1)));
List<TransactionEntity> txns = task.getTransactionBatch();
List<TransactionEntity> txns = action.getTransactionBatch();
assertThat(txns).hasSize(1);
assertThat(assertThrows(IllegalStateException.class, () -> task.applyTransaction(txns.get(0))))
assertThat(
assertThrows(IllegalStateException.class, () -> action.applyTransaction(txns.get(0))))
.hasMessageThat()
.isEqualTo("Missing transaction: last txn id = -1, next available txn = 1");
}
@@ -194,19 +206,21 @@ public class ReplicateToDatastoreActionTest {
// Force the last transaction id back to -1 so that we look for transaction 0.
ofyTm().transact(() -> ofyTm().insert(new LastSqlTransaction(-1)));
task.run();
action.run();
assertAboutLogs()
.that(logHandler)
.hasSevereLogWithCause(
new IllegalStateException(
"Missing transaction: last txn id = -1, next available txn = 1"));
assertThat(response.getStatus()).isEqualTo(SC_INTERNAL_SERVER_ERROR);
assertThat(response.getPayload()).isEqualTo("Errored out replaying files");
}
@Test
void testBeforeDatastoreSaveCallback() {
TestObject testObject = TestObject.create("foo");
jpaTm().transact(() -> jpaTm().put(testObject));
task.run();
action.run();
assertThat(ofyTm().loadAllOf(TestObject.class)).containsExactly(testObject);
assertThat(TestObject.beforeDatastoreSaveCallCount).isEqualTo(1);
}
@@ -231,7 +245,7 @@ public class ReplicateToDatastoreActionTest {
fakeClock.advanceBy(Duration.standardDays(1));
insertInDb(TestObject.create("foo"));
task.run();
action.run();
// Replication shouldn't have happened
assertThat(ofyTm().loadAllOf(TestObject.class)).isEmpty();
assertAboutLogs()
@@ -240,5 +254,46 @@ public class ReplicateToDatastoreActionTest {
Level.INFO,
"Skipping ReplicateToDatastoreAction because we are in migration phase "
+ "DATASTORE_PRIMARY.");
assertThat(response.getStatus()).isEqualTo(SC_NO_CONTENT);
assertThat(response.getPayload())
.isEqualTo(
"Skipping ReplicateToDatastoreAction because we are in migration phase"
+ " DATASTORE_PRIMARY.");
}
@Test
void testFailure_cannotAcquireLock() {
RequestStatusChecker requestStatusChecker = mock(RequestStatusChecker.class);
when(requestStatusChecker.getLogId()).thenReturn("logId");
Truth8.assertThat(
Lock.acquire(
ReplicateToDatastoreAction.class.getSimpleName(),
null,
Duration.standardHours(1),
requestStatusChecker,
false))
.isPresent();
fakeClock.advanceOneMilli();
resetAction();
action.run();
assertThat(response.getStatus()).isEqualTo(SC_NO_CONTENT);
assertThat(response.getPayload())
.isEqualTo("Can't acquire ReplicateToDatastoreAction lock, aborting.");
}
private void runAndVerifySuccess() {
resetAction();
action.run();
assertThat(response.getStatus()).isEqualTo(SC_OK);
assertThat(response.getPayload())
.isEqualTo("Replayed 1 transaction(s) from Cloud SQL -> Datastore");
}
private void resetAction() {
response = new FakeResponse();
RequestStatusChecker requestStatusChecker = mock(RequestStatusChecker.class);
when(requestStatusChecker.getLogId()).thenReturn("logId");
action = new ReplicateToDatastoreAction(fakeClock, requestStatusChecker, response);
}
}

View File

@@ -19,8 +19,8 @@ import static google.registry.persistence.transaction.TransactionManagerFactory.
import com.google.common.collect.ImmutableMap;
import google.registry.model.tld.label.ReservedList.ReservedListEntry;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaIntegrationWithCoverageExtension;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationWithCoverageExtension;
import google.registry.testing.DatastoreEntityExtension;
import google.registry.testing.FakeClock;
import org.junit.jupiter.api.BeforeEach;
@@ -39,7 +39,7 @@ public class ReservedListDaoTest {
@RegisterExtension
JpaIntegrationWithCoverageExtension jpa =
new JpaTestRules.Builder().withClock(fakeClock).buildIntegrationWithCoverageExtension();
new JpaTestExtensions.Builder().withClock(fakeClock).buildIntegrationWithCoverageExtension();
private ImmutableMap<String, ReservedListEntry> testReservations;

View File

@@ -18,8 +18,8 @@ import static com.google.common.truth.Truth.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
import com.google.common.collect.ImmutableMap;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaIntegrationWithCoverageExtension;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationWithCoverageExtension;
import google.registry.testing.FakeClock;
import javax.persistence.PersistenceException;
import org.junit.jupiter.api.Test;
@@ -32,7 +32,7 @@ public class ClaimsListDaoTest {
@RegisterExtension
final JpaIntegrationWithCoverageExtension jpa =
new JpaTestRules.Builder().withClock(fakeClock).buildIntegrationWithCoverageExtension();
new JpaTestExtensions.Builder().withClock(fakeClock).buildIntegrationWithCoverageExtension();
@Test
void save_insertsClaimsListSuccessfully() {

View File

@@ -22,8 +22,8 @@ import static google.registry.testing.DatabaseHelper.insertInDb;
import com.google.common.collect.ImmutableSet;
import google.registry.model.ImmutableObject;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestExtension;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaUnitTestExtension;
import java.lang.reflect.Method;
import javax.persistence.Embeddable;
import javax.persistence.Embedded;
@@ -46,7 +46,7 @@ class EntityCallbacksListenerTest {
@RegisterExtension
public final JpaUnitTestExtension jpaExtension =
new JpaTestRules.Builder().withEntityClass(TestEntity.class).buildUnitTestRule();
new JpaTestExtensions.Builder().withEntityClass(TestEntity.class).buildUnitTestExtension();
@Test
void verifyAllCallbacks_executedExpectedTimes() {

View File

@@ -33,7 +33,7 @@ import org.junit.jupiter.api.extension.RegisterExtension;
class VKeyTest {
@RegisterExtension
final AppEngineExtension appEngineRule =
final AppEngineExtension appEngineExtension =
AppEngineExtension.builder()
.withDatastoreAndCloudSql()
.withOfyTestEntities(TestObject.class)

View File

@@ -27,8 +27,8 @@ import google.registry.model.ImmutableObject;
import google.registry.model.common.TimedTransitionProperty;
import google.registry.model.domain.token.AllocationToken.TokenStatus;
import google.registry.model.domain.token.AllocationToken.TokenStatusTransition;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestExtension;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaUnitTestExtension;
import javax.persistence.Entity;
import javax.persistence.Id;
import org.joda.time.DateTime;
@@ -40,9 +40,9 @@ public class AllocationTokenStatusTransitionConverterTest {
@RegisterExtension
public final JpaUnitTestExtension jpa =
new JpaTestRules.Builder()
new JpaTestExtensions.Builder()
.withEntityClass(AllocationTokenStatusTransitionConverterTestEntity.class)
.buildUnitTestRule();
.buildUnitTestExtension();
private static final ImmutableSortedMap<DateTime, TokenStatus> values =
ImmutableSortedMap.of(

View File

@@ -24,8 +24,8 @@ import com.google.common.collect.ImmutableSortedMap;
import google.registry.model.ImmutableObject;
import google.registry.model.common.TimedTransitionProperty;
import google.registry.model.tld.Registry.BillingCostTransition;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestExtension;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaUnitTestExtension;
import javax.persistence.Entity;
import javax.persistence.Id;
import org.joda.money.Money;
@@ -38,9 +38,7 @@ public class BillingCostTransitionConverterTest {
@RegisterExtension
public final JpaUnitTestExtension jpa =
new JpaTestRules.Builder()
.withEntityClass(TestEntity.class)
.buildUnitTestRule();
new JpaTestExtensions.Builder().withEntityClass(TestEntity.class).buildUnitTestExtension();
private static final ImmutableSortedMap<DateTime, Money> values =
ImmutableSortedMap.of(

View File

@@ -23,8 +23,8 @@ import com.google.common.collect.ImmutableSet;
import com.google.common.hash.BloomFilter;
import google.registry.model.ImmutableObject;
import google.registry.model.replay.EntityTest.EntityForTesting;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestExtension;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaUnitTestExtension;
import javax.persistence.Entity;
import javax.persistence.Id;
import org.junit.jupiter.api.Test;
@@ -35,7 +35,7 @@ class BloomFilterConverterTest {
@RegisterExtension
public final JpaUnitTestExtension jpaExtension =
new JpaTestRules.Builder().withEntityClass(TestEntity.class).buildUnitTestRule();
new JpaTestExtensions.Builder().withEntityClass(TestEntity.class).buildUnitTestExtension();
@Test
void roundTripConversion_returnsSameBloomFilter() {

View File

@@ -20,8 +20,8 @@ import static google.registry.testing.DatabaseHelper.insertInDb;
import com.google.common.collect.ImmutableList;
import google.registry.model.ImmutableObject;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestExtension;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaUnitTestExtension;
import google.registry.util.CidrAddressBlock;
import java.util.List;
import javax.persistence.Entity;
@@ -34,7 +34,7 @@ public class CidrAddressBlockListConverterTest {
@RegisterExtension
public final JpaUnitTestExtension jpaExtension =
new JpaTestRules.Builder().withEntityClass(TestEntity.class).buildUnitTestRule();
new JpaTestExtensions.Builder().withEntityClass(TestEntity.class).buildUnitTestExtension();
@Test
void roundTripConversion_returnsSameCidrAddressBlock() {

View File

@@ -20,8 +20,8 @@ import static google.registry.testing.DatabaseHelper.insertInDb;
import google.registry.model.CreateAutoTimestamp;
import google.registry.model.ImmutableObject;
import google.registry.model.replay.EntityTest.EntityForTesting;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestExtension;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaUnitTestExtension;
import google.registry.testing.FakeClock;
import javax.persistence.Entity;
import javax.persistence.Id;
@@ -36,10 +36,10 @@ public class CreateAutoTimestampConverterTest {
@RegisterExtension
public final JpaUnitTestExtension jpaExtension =
new JpaTestRules.Builder()
new JpaTestExtensions.Builder()
.withClock(fakeClock)
.withEntityClass(TestEntity.class)
.buildUnitTestRule();
.buildUnitTestExtension();
@Test
void testTypeConversion() {

View File

@@ -21,8 +21,8 @@ import static google.registry.testing.DatabaseHelper.insertInDb;
import com.google.common.collect.ImmutableMap;
import google.registry.model.ImmutableObject;
import google.registry.model.registrar.Registrar.BillingAccountEntry;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestExtension;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaUnitTestExtension;
import java.util.Map;
import javax.persistence.Entity;
import javax.persistence.Id;
@@ -35,9 +35,7 @@ public class CurrencyToBillingConverterTest {
@RegisterExtension
public final JpaUnitTestExtension jpaExtension =
new JpaTestRules.Builder()
.withEntityClass(TestEntity.class)
.buildUnitTestRule();
new JpaTestExtensions.Builder().withEntityClass(TestEntity.class).buildUnitTestExtension();
@Test
void roundTripConversion_returnsSameCurrencyToBillingMap() {

View File

@@ -21,8 +21,8 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
import google.registry.model.ImmutableObject;
import google.registry.model.replay.EntityTest.EntityForTesting;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestExtension;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaUnitTestExtension;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.PersistenceException;
@@ -35,7 +35,7 @@ public class CurrencyUnitConverterTest {
@RegisterExtension
public final JpaUnitTestExtension jpaExtension =
new JpaTestRules.Builder().withEntityClass(TestEntity.class).buildUnitTestRule();
new JpaTestExtensions.Builder().withEntityClass(TestEntity.class).buildUnitTestExtension();
@Test
void roundTripConversion() {

View File

@@ -24,8 +24,8 @@ import google.registry.model.ImmutableObject;
import google.registry.model.common.DatabaseMigrationStateSchedule.MigrationState;
import google.registry.model.common.DatabaseMigrationStateSchedule.MigrationStateTransition;
import google.registry.model.common.TimedTransitionProperty;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestExtension;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaUnitTestExtension;
import javax.persistence.Entity;
import javax.persistence.Id;
import org.joda.time.DateTime;
@@ -37,9 +37,9 @@ public class DatabaseMigrationScheduleTransitionConverterTest {
@RegisterExtension
public final JpaUnitTestExtension jpa =
new JpaTestRules.Builder()
new JpaTestExtensions.Builder()
.withEntityClass(DatabaseMigrationScheduleTransitionConverterTestEntity.class)
.buildUnitTestRule();
.buildUnitTestExtension();
private static final ImmutableSortedMap<DateTime, MigrationState> values =
ImmutableSortedMap.of(

View File

@@ -19,8 +19,8 @@ import static google.registry.persistence.transaction.TransactionManagerFactory.
import static google.registry.testing.DatabaseHelper.insertInDb;
import google.registry.model.ImmutableObject;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestExtension;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaUnitTestExtension;
import java.sql.Timestamp;
import javax.persistence.Entity;
import javax.persistence.Id;
@@ -34,7 +34,7 @@ public class DateTimeConverterTest {
@RegisterExtension
public final JpaUnitTestExtension jpaExtension =
new JpaTestRules.Builder().withEntityClass(TestEntity.class).buildUnitTestRule();
new JpaTestExtensions.Builder().withEntityClass(TestEntity.class).buildUnitTestExtension();
private final DateTimeConverter converter = new DateTimeConverter();

View File

@@ -20,8 +20,8 @@ import static google.registry.testing.DatabaseHelper.insertInDb;
import google.registry.model.ImmutableObject;
import google.registry.model.replay.EntityTest.EntityForTesting;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestExtension;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaUnitTestExtension;
import javax.persistence.Entity;
import javax.persistence.Id;
import org.joda.time.Duration;
@@ -34,7 +34,9 @@ public class DurationConverterTest {
@RegisterExtension
public final JpaUnitTestExtension jpaExtension =
new JpaTestRules.Builder().withEntityClass(DurationTestEntity.class).buildUnitTestRule();
new JpaTestExtensions.Builder()
.withEntityClass(DurationTestEntity.class)
.buildUnitTestExtension();
private final DurationConverter converter = new DurationConverter();

View File

@@ -20,8 +20,8 @@ import static google.registry.testing.DatabaseHelper.insertInDb;
import com.google.common.collect.ImmutableMap;
import google.registry.model.ImmutableObject;
import google.registry.model.replay.EntityTest.EntityForTesting;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestExtension;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaUnitTestExtension;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
@@ -64,9 +64,9 @@ public class JodaMoneyConverterTest {
@RegisterExtension
public final JpaUnitTestExtension jpaExtension =
new JpaTestRules.Builder()
new JpaTestExtensions.Builder()
.withEntityClass(TestEntity.class, ComplexTestEntity.class)
.buildUnitTestRule();
.buildUnitTestExtension();
@Test
void roundTripConversion() {

View File

@@ -21,8 +21,8 @@ import static google.registry.testing.DatabaseHelper.insertInDb;
import google.registry.model.ImmutableObject;
import google.registry.model.replay.EntityTest;
import google.registry.persistence.VKey;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestExtension;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaUnitTestExtension;
import javax.persistence.Entity;
import javax.persistence.Id;
import org.joda.time.LocalDate;
@@ -35,9 +35,9 @@ public class LocalDateConverterTest {
@RegisterExtension
public final JpaUnitTestExtension jpaExtension =
new JpaTestRules.Builder()
new JpaTestExtensions.Builder()
.withEntityClass(LocalDateConverterTestEntity.class)
.buildUnitTestRule();
.buildUnitTestExtension();
private final LocalDate exampleDate = LocalDate.parse("2020-06-10", ISODateTimeFormat.date());

View File

@@ -21,8 +21,8 @@ import static google.registry.testing.DatabaseHelper.insertInDb;
import com.google.common.collect.ImmutableSet;
import google.registry.model.ImmutableObject;
import google.registry.model.eppcommon.StatusValue;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestExtension;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaUnitTestExtension;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.Id;
@@ -34,7 +34,7 @@ public class StatusValueSetConverterTest {
@RegisterExtension
public final JpaUnitTestExtension jpaExtension =
new JpaTestRules.Builder().withEntityClass(TestEntity.class).buildUnitTestRule();
new JpaTestExtensions.Builder().withEntityClass(TestEntity.class).buildUnitTestExtension();
@Test
void testRoundTrip() {

View File

@@ -21,8 +21,8 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
import com.google.common.collect.ImmutableList;
import google.registry.model.ImmutableObject;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestExtension;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaUnitTestExtension;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.Id;
@@ -35,7 +35,7 @@ public class StringListConverterTest {
@RegisterExtension
public final JpaUnitTestExtension jpaExtension =
new JpaTestRules.Builder().withEntityClass(TestEntity.class).buildUnitTestRule();
new JpaTestExtensions.Builder().withEntityClass(TestEntity.class).buildUnitTestExtension();
@Test
void roundTripConversion_returnsSameStringList() {

View File

@@ -22,8 +22,8 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import google.registry.model.ImmutableObject;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestExtension;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaUnitTestExtension;
import java.util.Map;
import javax.persistence.Converter;
import javax.persistence.Entity;
@@ -37,9 +37,9 @@ public class StringMapConverterBaseTest {
@RegisterExtension
public final JpaUnitTestExtension jpaExtension =
new JpaTestRules.Builder()
new JpaTestExtensions.Builder()
.withEntityClass(TestStringMapConverter.class, TestEntity.class)
.buildUnitTestRule();
.buildUnitTestExtension();
private static final ImmutableMap<Key, Value> MAP =
ImmutableMap.of(

View File

@@ -20,8 +20,8 @@ import static google.registry.testing.DatabaseHelper.insertInDb;
import com.google.common.collect.ImmutableSet;
import google.registry.model.ImmutableObject;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestExtension;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaUnitTestExtension;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.Id;
@@ -33,7 +33,7 @@ public class StringSetConverterTest {
@RegisterExtension
public final JpaUnitTestExtension jpaExtension =
new JpaTestRules.Builder().withEntityClass(TestEntity.class).buildUnitTestRule();
new JpaTestExtensions.Builder().withEntityClass(TestEntity.class).buildUnitTestExtension();
@Test
void roundTripConversion_returnsSameStringList() {

View File

@@ -20,8 +20,8 @@ import static google.registry.testing.DatabaseHelper.insertInDb;
import google.registry.model.ImmutableObject;
import google.registry.model.registrar.Registrar.State;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestExtension;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaUnitTestExtension;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
@@ -34,7 +34,7 @@ public class StringValueEnumeratedTest {
@RegisterExtension
public final JpaUnitTestExtension jpaExtension =
new JpaTestRules.Builder().withEntityClass(TestEntity.class).buildUnitTestRule();
new JpaTestExtensions.Builder().withEntityClass(TestEntity.class).buildUnitTestExtension();
@Test
void roundTripConversion_returnsSameEnum() {

View File

@@ -25,8 +25,8 @@ import com.google.common.collect.Maps;
import google.registry.model.ImmutableObject;
import google.registry.model.common.TimedTransitionProperty;
import google.registry.model.common.TimedTransitionProperty.TimedTransition;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestExtension;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaUnitTestExtension;
import java.util.Map;
import javax.persistence.Converter;
import javax.persistence.Entity;
@@ -41,9 +41,9 @@ class TimedTransitionPropertyConverterBaseTest {
@RegisterExtension
public final JpaUnitTestExtension jpa =
new JpaTestRules.Builder()
new JpaTestExtensions.Builder()
.withEntityClass(TestTimedTransitionPropertyConverter.class, TestEntity.class)
.buildUnitTestRule();
.buildUnitTestExtension();
private static final DateTime DATE_1 = DateTime.parse("2001-01-01T00:00:00.000Z");
private static final DateTime DATE_2 = DateTime.parse("2002-01-01T00:00:00.000Z");

View File

@@ -24,8 +24,8 @@ import google.registry.model.ImmutableObject;
import google.registry.model.common.TimedTransitionProperty;
import google.registry.model.tld.Registry.TldState;
import google.registry.model.tld.Registry.TldStateTransition;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestExtension;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaUnitTestExtension;
import javax.persistence.Entity;
import javax.persistence.Id;
import org.joda.time.DateTime;
@@ -37,9 +37,7 @@ class TldStateTransitionConverterTest {
@RegisterExtension
public final JpaUnitTestExtension jpa =
new JpaTestRules.Builder()
.withEntityClass(TestEntity.class)
.buildUnitTestRule();
new JpaTestExtensions.Builder().withEntityClass(TestEntity.class).buildUnitTestExtension();
private static final ImmutableSortedMap<DateTime, TldState> values =
ImmutableSortedMap.of(

View File

@@ -19,8 +19,8 @@ import static google.registry.persistence.transaction.TransactionManagerFactory.
import static google.registry.testing.DatabaseHelper.insertInDb;
import google.registry.model.ImmutableObject;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestExtension;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaUnitTestExtension;
import java.sql.Timestamp;
import java.time.Instant;
import java.time.ZonedDateTime;
@@ -34,7 +34,7 @@ public class ZonedDateTimeConverterTest {
@RegisterExtension
public final JpaUnitTestExtension jpaExtension =
new JpaTestRules.Builder().withEntityClass(TestEntity.class).buildUnitTestRule();
new JpaTestExtensions.Builder().withEntityClass(TestEntity.class).buildUnitTestExtension();
private final ZonedDateTimeConverter converter = new ZonedDateTimeConverter();

View File

@@ -19,7 +19,7 @@ import static google.registry.persistence.transaction.TransactionManagerFactory.
import com.google.common.collect.ImmutableList;
import google.registry.model.ImmutableObject;
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestExtension;
import google.registry.persistence.transaction.JpaTestExtensions.JpaUnitTestExtension;
import google.registry.testing.FakeClock;
import java.util.List;
import javax.persistence.Entity;
@@ -42,10 +42,10 @@ class CriteriaQueryBuilderTest {
@RegisterExtension
final JpaUnitTestExtension jpaExtension =
new JpaTestRules.Builder()
new JpaTestExtensions.Builder()
.withClock(fakeClock)
.withEntityClass(CriteriaQueryBuilderTestEntity.class)
.buildUnitTestRule();
.buildUnitTestExtension();
@BeforeEach
void beforeEach() {

View File

@@ -35,18 +35,18 @@ import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
/**
* Holds specialized JUnit rules that start a test database server and provide {@link
* Holds specialized JUnit extensions that start a test database server and provide {@link
* JpaTransactionManager} instances.
*/
public class JpaTestRules {
public class JpaTestExtensions {
private static final String GOLDEN_SCHEMA_SQL_PATH = "sql/schema/nomulus.golden.sql";
private static final String HSTORE_EXTENSION_SQL_PATH =
"sql/flyway/V14__load_extension_for_hstore.sql";
/**
* Junit rule for integration tests with JPA framework, when the underlying database is populated
* with the Nomulus Cloud SQL schema.
* JUnit extension for integration tests with JPA framework, when the underlying database is
* populated with the Nomulus Cloud SQL schema.
*/
public static class JpaIntegrationTestExtension extends JpaTransactionManagerExtension {
private JpaIntegrationTestExtension(
@@ -83,26 +83,26 @@ public class JpaTestRules {
implements BeforeEachCallback, AfterEachCallback {
private final JpaEntityCoverageExtension jpaEntityCoverage = new JpaEntityCoverageExtension();
private final JpaIntegrationTestExtension integrationTestRule;
private final JpaIntegrationTestExtension integrationTestExtension;
JpaIntegrationWithCoverageExtension(JpaIntegrationTestExtension integrationTestRule) {
this.integrationTestRule = integrationTestRule;
JpaIntegrationWithCoverageExtension(JpaIntegrationTestExtension integrationTestExtension) {
this.integrationTestExtension = integrationTestExtension;
}
@Override
public void beforeEach(ExtensionContext context) throws Exception {
integrationTestRule.beforeEach(context);
integrationTestExtension.beforeEach(context);
jpaEntityCoverage.beforeEach(context);
}
@Override
public void afterEach(ExtensionContext context) {
jpaEntityCoverage.afterEach(context);
integrationTestRule.afterEach(context);
integrationTestExtension.afterEach(context);
}
}
/** Builder of test rules that provide {@link JpaTransactionManager}. */
/** Builder of test extensions that provide {@link JpaTransactionManager}. */
public static class Builder {
private String initScript;
@@ -150,7 +150,7 @@ public class JpaTestRules {
}
/** Builds a {@link JpaIntegrationTestExtension} instance. */
public JpaIntegrationTestExtension buildIntegrationTestRule() {
public JpaIntegrationTestExtension buildIntegrationTestExtension() {
return new JpaIntegrationTestExtension(
clock == null ? new FakeClock(DateTime.now(UTC)) : clock,
ImmutableList.copyOf(extraEntityClasses),
@@ -163,14 +163,14 @@ public class JpaTestRules {
*/
public JpaIntegrationWithCoverageExtension buildIntegrationWithCoverageExtension() {
checkState(initScript == null, "Integration tests do not accept initScript");
return new JpaIntegrationWithCoverageExtension(buildIntegrationTestRule());
return new JpaIntegrationWithCoverageExtension(buildIntegrationTestExtension());
}
/**
* Builds a {@link JpaUnitTestExtension} instance that can also be used as an extension for
* JUnit5.
*/
public JpaUnitTestExtension buildUnitTestRule() {
public JpaUnitTestExtension buildUnitTestExtension() {
checkState(
!Objects.equals(GOLDEN_SCHEMA_SQL_PATH, initScript),
"Unit tests must not depend on the Nomulus schema.");

View File

@@ -18,7 +18,7 @@ import static com.google.common.truth.Truth.assertThat;
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
import static java.nio.charset.StandardCharsets.UTF_8;
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestExtension;
import google.registry.persistence.transaction.JpaTestExtensions.JpaUnitTestExtension;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
@@ -27,13 +27,13 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
/** Unit test for {@link JpaTestRules.Builder#withSqlLogging()}. */
class JpaTestRulesSqlLoggingTest {
/** Unit test for {@link JpaTestExtensions.Builder#withSqlLogging()}. */
class JpaTestExtensionsSqlLoggingTest {
// Entity under test: configured to log SQL statements to Stdout.
@RegisterExtension
JpaUnitTestExtension jpaExtension =
new JpaTestRules.Builder().withSqlLogging().buildUnitTestRule();
new JpaTestExtensions.Builder().withSqlLogging().buildUnitTestExtension();
private PrintStream orgStdout;
private ByteArrayOutputStream stdoutBuffer;

View File

@@ -32,8 +32,8 @@ import google.registry.persistence.HibernateSchemaExporter;
import google.registry.persistence.NomulusPostgreSql;
import google.registry.persistence.PersistenceModule;
import google.registry.persistence.PersistenceXmlUtility;
import google.registry.persistence.transaction.JpaTestRules.JpaIntegrationTestExtension;
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestExtension;
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationTestExtension;
import google.registry.persistence.transaction.JpaTestExtensions.JpaUnitTestExtension;
import google.registry.util.Clock;
import java.io.File;
import java.io.IOException;
@@ -71,8 +71,8 @@ import org.testcontainers.containers.PostgreSQLContainer;
* <p>This class is not for direct use. Use the specialized subclasses {@link
* JpaIntegrationTestExtension} or {@link JpaUnitTestExtension} as befits the use case.
*
* <p>This rule also replaces the {@link JpaTransactionManagerImpl} provided by {@link
* TransactionManagerFactory} with the {@link JpaTransactionManagerImpl} generated by the rule
* <p>This extension also replaces the {@link JpaTransactionManagerImpl} provided by {@link
* TransactionManagerFactory} with the {@link JpaTransactionManagerImpl} generated by the extension
* itself, so that all SQL queries will be sent to the database instance created by {@link
* PostgreSQLContainer} to achieve test purpose.
*/
@@ -102,11 +102,11 @@ abstract class JpaTransactionManagerExtension implements BeforeEachCallback, Aft
private static int emfEntityHash;
private JpaTransactionManager cachedTm;
// Hash of the ORM entity names requested by this rule instance.
// Hash of the ORM entity names requested by this extension instance.
private final int entityHash;
// Whether to create nomulus tables in the test db. Right now, only the JpaTestRules set this to
// false.
// Whether to create nomulus tables in the test db. Right now, only the JpaTestExtensions set this
// to false.
private boolean includeNomulusSchema = true;
JpaTransactionManagerExtension(

View File

@@ -20,7 +20,7 @@ import static google.registry.testing.DatabaseHelper.insertInDb;
import static org.junit.jupiter.api.Assertions.assertThrows;
import google.registry.model.ImmutableObject;
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestExtension;
import google.registry.persistence.transaction.JpaTestExtensions.JpaUnitTestExtension;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.Id;
@@ -32,14 +32,14 @@ import org.junit.jupiter.api.extension.RegisterExtension;
* JUnit test for {@link JpaTransactionManagerExtension}, with {@link JpaUnitTestExtension} as
* proxy.
*/
public class JpaTransactionManagerRuleTest {
public class JpaTransactionManagerExtensionTest {
@RegisterExtension
public final JpaUnitTestExtension jpaExtension =
new JpaTestRules.Builder().withEntityClass(TestEntity.class).buildUnitTestRule();
new JpaTestExtensions.Builder().withEntityClass(TestEntity.class).buildUnitTestExtension();
@Test
void verifiesRuleWorks() {
void verifiesExtensionWorks() {
assertThrows(
PersistenceException.class,
() ->

View File

@@ -31,7 +31,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import google.registry.model.ImmutableObject;
import google.registry.persistence.VKey;
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestExtension;
import google.registry.persistence.transaction.JpaTestExtensions.JpaUnitTestExtension;
import google.registry.testing.DatabaseHelper;
import google.registry.testing.FakeClock;
import java.io.Serializable;
@@ -73,12 +73,12 @@ class JpaTransactionManagerImplTest {
@RegisterExtension
final JpaUnitTestExtension jpaExtension =
new JpaTestRules.Builder()
new JpaTestExtensions.Builder()
.withInitScript(fileClassPath(getClass(), "test_schema.sql"))
.withClock(fakeClock)
.withEntityClass(
TestEntity.class, TestCompoundIdEntity.class, TestNamedCompoundIdEntity.class)
.buildUnitTestRule();
.buildUnitTestExtension();
@Test
void transact_succeeds() {

View File

@@ -78,7 +78,7 @@ public final class UpdateRegistrarRdapBaseUrlsActionTest {
+ "\"version\":\"1.0\"}";
@RegisterExtension
public AppEngineExtension appEngineRule =
public AppEngineExtension appEngineExtension =
new AppEngineExtension.Builder().withDatastoreAndCloudSql().build();
private static class TestHttpTransport extends MockHttpTransport {

View File

@@ -54,14 +54,14 @@ class RdeStagingMapperTest {
ArgumentCaptor.forClass(DepositFragment.class);
@RegisterExtension
AppEngineExtension appEngineRule =
AppEngineExtension appEngineExtension =
AppEngineExtension.builder().withDatastoreAndCloudSql().build();
private RdeStagingMapper rdeStagingMapper;
@BeforeEach
void beforeEach() {
// Two real registrars have been created by AppEngineRule, named "New Registrar" and "The
// Two real registrars have been created by AppEngineExtension, named "New Registrar" and "The
// Registrar". Create one included registrar (external_monitoring) and two excluded ones.
Registrar monitoringRegistrar =
persistNewRegistrar("monitoring", "monitoring", Registrar.Type.MONITORING, null);

View File

@@ -64,7 +64,7 @@ import org.junit.jupiter.api.extension.RegisterExtension;
class RdeStagingReducerTest {
@RegisterExtension
AppEngineExtension appEngineRule =
AppEngineExtension appEngineExtension =
AppEngineExtension.builder().withDatastoreAndCloudSql().withTaskQueue().build();
private static final String GCS_BUCKET = "test-rde-bucket";

View File

@@ -25,15 +25,18 @@ import static org.mockito.Mockito.when;
import com.google.common.net.MediaType;
import google.registry.beam.BeamActionTestBase;
import google.registry.model.common.DatabaseMigrationStateSchedule.PrimaryDatabase;
import google.registry.testing.AppEngineExtension;
import google.registry.testing.DualDatabaseTest;
import google.registry.testing.FakeClock;
import google.registry.testing.TaskQueueHelper.TaskMatcher;
import google.registry.testing.TestOfyAndSql;
import java.io.IOException;
import org.joda.time.YearMonth;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
/** Unit tests for {@link google.registry.reporting.billing.GenerateInvoicesAction}. */
@DualDatabaseTest
class GenerateInvoicesActionTest extends BeamActionTestBase {
@RegisterExtension
@@ -44,7 +47,7 @@ class GenerateInvoicesActionTest extends BeamActionTestBase {
private FakeClock clock = new FakeClock();
private GenerateInvoicesAction action;
@Test
@TestOfyAndSql
void testLaunchTemplateJob_withPublish() throws Exception {
action =
new GenerateInvoicesAction(
@@ -54,7 +57,7 @@ class GenerateInvoicesActionTest extends BeamActionTestBase {
"billing_bucket",
"REG-INV",
true,
"DATASTORE",
PrimaryDatabase.DATASTORE,
new YearMonth(2017, 10),
emailUtils,
clock,
@@ -63,7 +66,7 @@ class GenerateInvoicesActionTest extends BeamActionTestBase {
action.run();
assertThat(response.getContentType()).isEqualTo(MediaType.PLAIN_TEXT_UTF_8);
assertThat(response.getStatus()).isEqualTo(SC_OK);
assertThat(response.getPayload()).isEqualTo("Launched dataflow template.");
assertThat(response.getPayload()).isEqualTo("Launched invoicing pipeline: jobid");
TaskMatcher matcher =
new TaskMatcher()
@@ -74,7 +77,7 @@ class GenerateInvoicesActionTest extends BeamActionTestBase {
assertTasksEnqueued("beam-reporting", matcher);
}
@Test
@TestOfyAndSql
void testLaunchTemplateJob_withoutPublish() throws Exception {
action =
new GenerateInvoicesAction(
@@ -84,7 +87,7 @@ class GenerateInvoicesActionTest extends BeamActionTestBase {
"billing_bucket",
"REG-INV",
false,
"DATASTORE",
PrimaryDatabase.DATASTORE,
new YearMonth(2017, 10),
emailUtils,
clock,
@@ -93,11 +96,11 @@ class GenerateInvoicesActionTest extends BeamActionTestBase {
action.run();
assertThat(response.getContentType()).isEqualTo(MediaType.PLAIN_TEXT_UTF_8);
assertThat(response.getStatus()).isEqualTo(SC_OK);
assertThat(response.getPayload()).isEqualTo("Launched dataflow template.");
assertThat(response.getPayload()).isEqualTo("Launched invoicing pipeline: jobid");
assertNoTasksEnqueued("beam-reporting");
}
@Test
@TestOfyAndSql
void testCaughtIOException() throws IOException {
when(launch.execute()).thenThrow(new IOException("Pipeline error"));
action =
@@ -108,7 +111,7 @@ class GenerateInvoicesActionTest extends BeamActionTestBase {
"billing_bucket",
"REG-INV",
false,
"DATASTORE",
PrimaryDatabase.DATASTORE,
new YearMonth(2017, 10),
emailUtils,
clock,
@@ -116,8 +119,8 @@ class GenerateInvoicesActionTest extends BeamActionTestBase {
dataflow);
action.run();
assertThat(response.getStatus()).isEqualTo(SC_INTERNAL_SERVER_ERROR);
assertThat(response.getPayload()).isEqualTo("Template launch failed: Pipeline error");
verify(emailUtils).sendAlertEmail("Template Launch failed due to Pipeline error");
assertThat(response.getPayload()).isEqualTo("Pipeline launch failed: Pipeline error");
verify(emailUtils).sendAlertEmail("Pipeline Launch failed due to Pipeline error");
assertNoTasksEnqueued("beam-reporting");
}
}

View File

@@ -49,7 +49,7 @@ class IcannHttpReporterTest {
private MockLowLevelHttpRequest mockRequest;
@RegisterExtension
AppEngineExtension appEngineRule =
AppEngineExtension appEngineExtension =
new AppEngineExtension.Builder().withDatastoreAndCloudSql().build();
private MockHttpTransport createMockTransport(

View File

@@ -23,6 +23,7 @@ import static org.mockito.Mockito.when;
import com.google.common.net.MediaType;
import google.registry.beam.BeamActionTestBase;
import google.registry.model.common.DatabaseMigrationStateSchedule.PrimaryDatabase;
import google.registry.testing.AppEngineExtension;
import google.registry.testing.FakeClock;
import google.registry.testing.TaskQueueHelper.TaskMatcher;
@@ -51,7 +52,7 @@ class GenerateSpec11ReportActionTest extends BeamActionTestBase {
"gs://reporting-project/reporting-bucket/",
"api_key/a",
clock.nowUtc().toLocalDate(),
"DATASTORE",
PrimaryDatabase.DATASTORE,
clock,
response,
dataflow);
@@ -73,13 +74,14 @@ class GenerateSpec11ReportActionTest extends BeamActionTestBase {
"gs://reporting-project/reporting-bucket/",
"api_key/a",
clock.nowUtc().toLocalDate(),
"DATASTORE",
PrimaryDatabase.DATASTORE,
clock,
response,
dataflow);
action.run();
assertThat(response.getStatus()).isEqualTo(SC_OK);
assertThat(response.getContentType()).isEqualTo(MediaType.PLAIN_TEXT_UTF_8);
assertThat(response.getPayload()).isEqualTo("Launched Spec11 pipeline: jobid");
TaskMatcher matcher =
new TaskMatcher()
.url("/_dr/task/publishSpec11")

View File

@@ -38,7 +38,7 @@ import google.registry.model.tld.label.ReservedListDaoTest;
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.persistence.transaction.JpaTestExtensions.JpaIntegrationWithCoverageExtension;
import google.registry.schema.integration.SqlIntegrationTestSuite.AfterSuiteTest;
import google.registry.schema.integration.SqlIntegrationTestSuite.BeforeSuiteTest;
import google.registry.schema.registrar.RegistrarDaoTest;

View File

@@ -23,8 +23,8 @@ import static google.registry.testing.SqlHelper.saveRegistrar;
import com.google.common.collect.ImmutableSet;
import google.registry.model.registrar.Registrar;
import google.registry.model.registrar.RegistrarContact;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaIntegrationWithCoverageExtension;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationWithCoverageExtension;
import google.registry.testing.DatastoreEntityExtension;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Order;
@@ -40,7 +40,7 @@ class RegistrarContactTest {
@RegisterExtension
JpaIntegrationWithCoverageExtension jpa =
new JpaTestRules.Builder().buildIntegrationWithCoverageExtension();
new JpaTestExtensions.Builder().buildIntegrationWithCoverageExtension();
private Registrar testRegistrar;

View File

@@ -24,8 +24,8 @@ import com.google.common.collect.ImmutableList;
import google.registry.model.registrar.Registrar;
import google.registry.model.registrar.RegistrarAddress;
import google.registry.persistence.VKey;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaIntegrationWithCoverageExtension;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationWithCoverageExtension;
import google.registry.testing.DatastoreEntityExtension;
import google.registry.testing.FakeClock;
import org.joda.time.DateTime;
@@ -45,7 +45,7 @@ public class RegistrarDaoTest {
@RegisterExtension
JpaIntegrationWithCoverageExtension jpa =
new JpaTestRules.Builder().withClock(fakeClock).buildIntegrationWithCoverageExtension();
new JpaTestExtensions.Builder().withClock(fakeClock).buildIntegrationWithCoverageExtension();
private final VKey<Registrar> registrarKey = VKey.createSql(Registrar.class, "registrarId");

View File

@@ -19,7 +19,7 @@ import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
import com.google.common.collect.ImmutableList;
import com.google.common.net.HostAndPort;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.testing.AppEngineExtension;
import google.registry.testing.UserInfo;
import google.registry.tools.params.HostAndPortParameter;
@@ -134,7 +134,7 @@ public final class RegistryTestServerMain {
final RegistryTestServer server = new RegistryTestServer(address);
System.out.printf("%sLoading SQL fixtures and AppEngineRule...%s\n", BLUE, RESET);
System.out.printf("%sLoading SQL fixtures and AppEngineExtension...%s\n", BLUE, RESET);
AppEngineExtension appEngine =
AppEngineExtension.builder()
.withDatastoreAndCloudSql()
@@ -148,7 +148,7 @@ public final class RegistryTestServerMain {
.build();
appEngine.setUp();
AppEngineExtension.loadInitialData();
new JpaTestRules.Builder().buildIntegrationTestRule().beforeEach(null);
new JpaTestExtensions.Builder().buildIntegrationTestExtension().beforeEach(null);
System.out.printf("%sLoading Datastore fixtures...%s\n", BLUE, RESET);
for (Fixture fixture : fixtures) {
fixture.load();

View File

@@ -50,10 +50,10 @@ import google.registry.model.registrar.Registrar;
import google.registry.model.registrar.Registrar.State;
import google.registry.model.registrar.RegistrarAddress;
import google.registry.model.registrar.RegistrarContact;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaIntegrationTestExtension;
import google.registry.persistence.transaction.JpaTestRules.JpaIntegrationWithCoverageExtension;
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestExtension;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationTestExtension;
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationWithCoverageExtension;
import google.registry.persistence.transaction.JpaTestExtensions.JpaUnitTestExtension;
import google.registry.util.Clock;
import java.io.ByteArrayInputStream;
import java.io.File;
@@ -106,7 +106,8 @@ public final class AppEngineExtension implements BeforeEachCallback, AfterEachCa
private LocalServiceTestHelper helper;
/**
* A temporary directory for AppEngineRule's internal temp files that is different for each test.
* A temporary directory for AppEngineExtension's internal temp files that is different for each
* test.
*
* <p>Note that we can't use {@link TempDir} here because that only works in test classes, not
* extensions.
@@ -117,7 +118,7 @@ public final class AppEngineExtension implements BeforeEachCallback, AfterEachCa
* Sets up a SQL database. This is for test classes that are not a member of the {@code
* SqlIntegrationTestSuite}.
*/
private JpaIntegrationTestExtension jpaIntegrationTestRule = null;
private JpaIntegrationTestExtension jpaIntegrationTestExtension = null;
/**
* Sets up a SQL database and records the JPA entities tested by each test class. This is for
@@ -125,7 +126,7 @@ public final class AppEngineExtension implements BeforeEachCallback, AfterEachCa
*/
private JpaIntegrationWithCoverageExtension jpaIntegrationWithCoverageExtension = null;
private JpaUnitTestExtension jpaUnitTestRule;
private JpaUnitTestExtension jpaUnitTestExtension;
private boolean withDatastore;
private boolean withoutCannedData;
@@ -141,34 +142,34 @@ public final class AppEngineExtension implements BeforeEachCallback, AfterEachCa
private String taskQueueXml;
private UserInfo userInfo;
// Test Objectify entity classes to be used with this AppEngineRule instance.
// Test Objectify entity classes to be used with this AppEngineExtension instance.
private ImmutableList<Class<?>> ofyTestEntities;
private ImmutableList<Class<?>> jpaTestEntities;
/** Builder for {@link AppEngineExtension}. */
public static class Builder {
private AppEngineExtension rule = new AppEngineExtension();
private AppEngineExtension extension = new AppEngineExtension();
private ImmutableList.Builder<Class<?>> ofyTestEntities = new ImmutableList.Builder<>();
private ImmutableList.Builder<Class<?>> jpaTestEntities = new ImmutableList.Builder<>();
/** Turn on the Datastore service and the Cloud SQL service. */
public Builder withDatastoreAndCloudSql() {
rule.withDatastore = true;
rule.withCloudSql = true;
extension.withDatastore = true;
extension.withCloudSql = true;
return this;
}
/** Turns on Cloud SQL only, for use by test data generators. */
public Builder withCloudSql() {
rule.withCloudSql = true;
rule.withDatastore = false;
extension.withCloudSql = true;
extension.withDatastore = false;
return this;
}
/** Disables insertion of canned data. */
public Builder withoutCannedData() {
rule.withoutCannedData = true;
extension.withoutCannedData = true;
return this;
}
@@ -177,13 +178,13 @@ public final class AppEngineExtension implements BeforeEachCallback, AfterEachCa
* members of SqlIntegrationTestSuite.
*/
public Builder enableJpaEntityCoverageCheck(boolean enabled) {
rule.enableJpaEntityCoverageCheck = enabled;
extension.enableJpaEntityCoverageCheck = enabled;
return this;
}
/** Turn on the use of local modules. */
public Builder withLocalModules() {
rule.withLocalModules = true;
extension.withLocalModules = true;
return this;
}
@@ -194,25 +195,25 @@ public final class AppEngineExtension implements BeforeEachCallback, AfterEachCa
/** Turn on the task queue service with a specified set of queues. */
public Builder withTaskQueue(String taskQueueXml) {
rule.withTaskQueue = true;
rule.taskQueueXml = taskQueueXml;
extension.withTaskQueue = true;
extension.taskQueueXml = taskQueueXml;
return this;
}
/** Turn on the URL Fetch service. */
public Builder withUrlFetch() {
rule.withUrlFetch = true;
extension.withUrlFetch = true;
return this;
}
public Builder withClock(Clock clock) {
rule.clock = clock;
extension.clock = clock;
return this;
}
public Builder withUserService(UserInfo userInfo) {
rule.withUserService = true;
rule.userInfo = userInfo;
extension.withUserService = true;
extension.userInfo = userInfo;
return this;
}
@@ -236,23 +237,23 @@ public final class AppEngineExtension implements BeforeEachCallback, AfterEachCa
public Builder withJpaUnitTestEntities(Class<?>... entities) {
jpaTestEntities.add(entities);
rule.withJpaUnitTest = true;
extension.withJpaUnitTest = true;
return this;
}
public AppEngineExtension build() {
checkState(
!rule.enableJpaEntityCoverageCheck || rule.withCloudSql,
!extension.enableJpaEntityCoverageCheck || extension.withCloudSql,
"withJpaEntityCoverageCheck enabled without Cloud SQL");
checkState(
!rule.withJpaUnitTest || rule.withCloudSql,
!extension.withJpaUnitTest || extension.withCloudSql,
"withJpaUnitTestEntities enabled without Cloud SQL");
checkState(
!rule.withJpaUnitTest || !rule.enableJpaEntityCoverageCheck,
!extension.withJpaUnitTest || !extension.enableJpaEntityCoverageCheck,
"withJpaUnitTestEntities cannot be set when enableJpaEntityCoverageCheck");
rule.ofyTestEntities = this.ofyTestEntities.build();
rule.jpaTestEntities = this.jpaTestEntities.build();
return rule;
extension.ofyTestEntities = this.ofyTestEntities.build();
extension.jpaTestEntities = this.jpaTestEntities.build();
return extension;
}
}
@@ -366,8 +367,8 @@ public final class AppEngineExtension implements BeforeEachCallback, AfterEachCa
checkArgumentNotNull(context, "The ExtensionContext must not be null");
setUp();
if (withCloudSql) {
JpaTestRules.Builder builder =
new JpaTestRules.Builder().withEntityClass(jpaTestEntities.toArray(new Class[0]));
JpaTestExtensions.Builder builder =
new JpaTestExtensions.Builder().withEntityClass(jpaTestEntities.toArray(new Class[0]));
if (clock != null) {
builder.withClock(clock);
}
@@ -375,11 +376,11 @@ public final class AppEngineExtension implements BeforeEachCallback, AfterEachCa
jpaIntegrationWithCoverageExtension = builder.buildIntegrationWithCoverageExtension();
jpaIntegrationWithCoverageExtension.beforeEach(context);
} else if (withJpaUnitTest) {
jpaUnitTestRule = builder.buildUnitTestRule();
jpaUnitTestRule.beforeEach(context);
jpaUnitTestExtension = builder.buildUnitTestExtension();
jpaUnitTestExtension.beforeEach(context);
} else {
jpaIntegrationTestRule = builder.buildIntegrationTestRule();
jpaIntegrationTestRule.beforeEach(context);
jpaIntegrationTestExtension = builder.buildIntegrationTestExtension();
jpaIntegrationTestExtension.beforeEach(context);
}
}
if (isWithDatastoreAndCloudSql()) {
@@ -491,9 +492,9 @@ public final class AppEngineExtension implements BeforeEachCallback, AfterEachCa
if (enableJpaEntityCoverageCheck) {
jpaIntegrationWithCoverageExtension.afterEach(context);
} else if (withJpaUnitTest) {
jpaUnitTestRule.afterEach(context);
jpaUnitTestExtension.afterEach(context);
} else {
jpaIntegrationTestRule.afterEach(context);
jpaIntegrationTestExtension.afterEach(context);
}
}
tearDown();

View File

@@ -123,7 +123,7 @@ class AppEngineExtensionTest {
@Test
void testRegisterOfyEntities_duplicateEntitiesWithSameName_fails() throws Exception {
AppEngineExtension appEngineRule =
AppEngineExtension appEngineExtension =
AppEngineExtension.builder()
.withDatastoreAndCloudSql()
.withOfyTestEntities(google.registry.testing.TestObject.class, TestObject.class)
@@ -131,7 +131,7 @@ class AppEngineExtensionTest {
// Thrown before JPA is set up, therefore no need to call afterEach.
IllegalStateException thrown =
assertThrows(
IllegalStateException.class, () -> appEngineRule.beforeEach(context.getContext()));
IllegalStateException.class, () -> appEngineExtension.beforeEach(context.getContext()));
assertThat(thrown)
.hasMessageThat()
.isEqualTo(
@@ -167,7 +167,7 @@ class AppEngineExtensionTest {
.collect(entriesToImmutableMap());
assertWithMessage(
"Conflicting Ofy kinds found. Tests will break if they are registered with "
+ " AppEngineRule in the same test executor.")
+ " AppEngineExtension in the same test executor.")
.that(conflictingKinds)
.isEmpty();
}

View File

@@ -115,9 +115,9 @@ class DualDatabaseTestInvocationContextProvider implements TestTemplateInvocatio
appEngineExtensionFields.size()));
}
appEngineExtensionFields.get(0).setAccessible(true);
AppEngineExtension appEngineRule =
AppEngineExtension appEngineExtension =
(AppEngineExtension) appEngineExtensionFields.get(0).get(testInstance);
if (!appEngineRule.isWithDatastoreAndCloudSql()) {
if (!appEngineExtension.isWithDatastoreAndCloudSql()) {
throw new IllegalStateException(
"AppEngineExtension in @DualDatabaseTest test must set withDatastoreAndCloudSql()");
}

View File

@@ -23,7 +23,7 @@ import google.registry.flows.EppException;
import google.registry.model.eppinput.EppInput;
import java.util.Map;
/** Test rule that loads an Epp object from a file. */
/** Test extension that loads an Epp object from a file. */
public class EppLoader {
private String eppXml;

View File

@@ -19,7 +19,7 @@ import com.google.appengine.api.users.UserService;
import java.util.Set;
import javax.annotation.Nullable;
// TODO: Consider reconciling this with AppEngineRule.withUserService()
// TODO: Consider reconciling this with AppEngineExtension.withUserService()
/** Fake implementation of {@link UserService} for testing. */
public class FakeUserService implements UserService {

View File

@@ -37,9 +37,9 @@ import org.junit.jupiter.api.extension.ExtensionContext;
/**
* GnuPG system command JUnit extension.
*
* <p>This rule creates a isolated environment for running the {@code gpg} command inside system
* integration tests. It reduces a lot of the boilerplate of setting up the shell environment and
* importing your keyrings into a temporary config folder.
* <p>This extension creates a isolated environment for running the {@code gpg} command inside
* system integration tests. It reduces a lot of the boilerplate of setting up the shell environment
* and importing your keyrings into a temporary config folder.
*/
public final class GpgSystemCommandExtension implements BeforeEachCallback, AfterEachCallback {

View File

@@ -29,11 +29,11 @@ import org.junit.jupiter.api.extension.ExtensionContext;
/**
* JUnit extension for overriding {@code private static} fields during a test.
*
* <p>This rule uses reflection to change the value of a field while your test is running and then
* restore it to its original value after it's done (even if the test fails). The injection will
* work even if the field is marked {@code private} (but not if it's {@code final}). The downside is
* that if you rename the field in the future, IDE refactoring won't be smart enough to update the
* injection site.
* <p>This extension uses reflection to change the value of a field while your test is running and
* then restore it to its original value after it's done (even if the test fails). The injection
* will work even if the field is marked {@code private} (but not if it's {@code final}). The
* downside is that if you rename the field in the future, IDE refactoring won't be smart enough to
* update the injection site.
*
* <p>We encourage you to consider using {@link google.registry.util.NonFinalForTesting
* &#064;NonFinalForTesting} to document your injected fields.

View File

@@ -38,6 +38,7 @@ import google.registry.persistence.transaction.Transaction.Delete;
import google.registry.persistence.transaction.Transaction.Mutation;
import google.registry.persistence.transaction.Transaction.Update;
import google.registry.persistence.transaction.TransactionEntity;
import google.registry.util.RequestStatusChecker;
import java.io.IOException;
import java.util.List;
import java.util.Optional;
@@ -45,6 +46,7 @@ import javax.annotation.Nullable;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.mockito.Mockito;
/**
* A JUnit extension that replays datastore transactions against postgresql.
@@ -81,7 +83,11 @@ public class ReplayExtension implements BeforeEachCallback, AfterEachCallback {
* Create a replay extension that replays from SQL to cloud datastore when running in SQL mode.
*/
public static ReplayExtension createWithDoubleReplay(FakeClock clock) {
return new ReplayExtension(clock, true, new ReplicateToDatastoreAction(clock));
return new ReplayExtension(
clock,
true,
new ReplicateToDatastoreAction(
clock, Mockito.mock(RequestStatusChecker.class), new FakeResponse()));
}
@Override

View File

@@ -31,8 +31,8 @@ import org.junit.jupiter.api.extension.ExtensionContext;
/**
* JUnit extension for overriding the values Java system properties during tests.
*
* <p>In most scenarios this class should be the last rule/extension to apply. In JUnit 5, apply
* {@code @Order(value = Integer.MAX_VALUE)} to the extension.
* <p>In most scenarios this class should be the last extension/extension to apply. In JUnit 5,
* apply {@code @Order(value = Integer.MAX_VALUE)} to the extension.
*/
public final class SystemPropertyExtension
implements SystemPropertySetter, BeforeEachCallback, AfterEachCallback {
@@ -66,7 +66,8 @@ public final class SystemPropertyExtension
* <p>It's safe to call this method multiple times with the same {@code key} within a single test.
* Only the truly original property value will be restored at the end.
*
* <p>This method can be called fluently when declaring the Rule field, or within a Test method.
* <p>This method can be called fluently when declaring the Extension field, or within a Test
* method.
*
* @see java.lang.System#setProperty(String, String)
*/

View File

@@ -29,8 +29,8 @@ import org.junit.jupiter.api.extension.ExtensionContext;
/**
* A JUnit extension that overloads cache expiry for tests.
*
* <p>This rule is necessary because many caches in the system are singleton and referenced through
* static fields.
* <p>This extension is necessary because many caches in the system are singleton and referenced
* through static fields.
*/
public class TestCacheExtension implements BeforeEachCallback, AfterEachCallback {

View File

@@ -1705,7 +1705,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
@TestOfyAndSql
void testFailure_registrarNameSimilarToExisting() {
// Note that "tHeRe GiStRaR" normalizes identically to "The Registrar", which is created by
// AppEngineRule.
// AppEngineExtension.
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,

View File

@@ -76,7 +76,7 @@ public final class DomainLockUtilsTest {
private DomainLockUtils domainLockUtils;
@RegisterExtension
public final AppEngineExtension appEngineRule =
public final AppEngineExtension appEngineExtension =
AppEngineExtension.builder()
.withDatastoreAndCloudSql()
.withClock(clock)

View File

@@ -25,13 +25,13 @@ class GetRegistrarCommandTest extends CommandTestCase<GetRegistrarCommand> {
@Test
void testSuccess() throws Exception {
// This registrar is created by AppEngineRule.
// This registrar is created by AppEngineExtension.
runCommand("NewRegistrar");
}
@Test
void testSuccess_multipleArguments() throws Exception {
// Registrars are created by AppEngineRule.
// Registrars are created by AppEngineExtension.
runCommand("NewRegistrar", "TheRegistrar");
}

View File

@@ -67,7 +67,7 @@ class ResaveEnvironmentEntitiesCommandTest
loadRegistrar("TheRegistrar").getContacts();
assertThat(savedEntities)
.containsExactly(
// The Registrars and RegistrarContacts are created by AppEngineRule.
// The Registrars and RegistrarContacts are created by AppEngineExtension.
loadRegistrar("TheRegistrar"),
loadRegistrar("NewRegistrar"),
Registry.get("tld"),

View File

@@ -877,7 +877,7 @@ class UpdateRegistrarCommandTest extends CommandTestCase<UpdateRegistrarCommand>
@Test
void testFailure_registrarNameSimilarToExisting() {
// Note that "tHeRe GiStRaR" normalizes identically to "The Registrar", which is created by
// AppEngineRule.
// AppEngineExtension.
assertThrows(
IllegalArgumentException.class,
() -> runCommand("--name tHeRe GiStRaR", "--force", "NewRegistrar"));

Some files were not shown because too many files have changed in this diff Show More