diff --git a/core/build.gradle b/core/build.gradle index d74256477..ffd63184b 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -705,14 +705,6 @@ createToolTask( createToolTask( 'jpaDemoPipeline', 'google.registry.beam.common.JpaDemoPipeline') -// Caller must provide projectId, GCP region, runner, and the kinds to delete -// (comma-separated kind names or '*' for all). E.g.: -// nom_build :core:bulkDeleteDatastore --args="--project=domain-registry-crash \ -// --region=us-central1 --runner=DataflowRunner --kindsToDelete=*" -createToolTask( - 'bulkDeleteDatastore', - 'google.registry.beam.datastore.BulkDeleteDatastorePipeline') - project.tasks.create('generateSqlSchema', JavaExec) { classpath = sourceSets.nonprod.runtimeClasspath main = 'google.registry.tools.DevTool' @@ -757,11 +749,6 @@ createUberJar( // User should install gcloud and login to GCP before invoking this tasks. if (environment == 'alpha') { def pipelines = [ - bulkDeleteDatastore: - [ - mainClass: 'google.registry.beam.datastore.BulkDeleteDatastorePipeline', - metaData : 'google/registry/beam/bulk_delete_datastore_pipeline_metadata.json' - ], spec11 : [ mainClass: 'google.registry.beam.spec11.Spec11Pipeline', diff --git a/core/src/main/java/google/registry/batch/DeleteExpiredDomainsAction.java b/core/src/main/java/google/registry/batch/DeleteExpiredDomainsAction.java index 034fc1cb2..806a4cf1f 100644 --- a/core/src/main/java/google/registry/batch/DeleteExpiredDomainsAction.java +++ b/core/src/main/java/google/registry/batch/DeleteExpiredDomainsAction.java @@ -18,7 +18,6 @@ import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.common.net.MediaType.PLAIN_TEXT_UTF_8; import static google.registry.flows.FlowUtils.marshalWithLenientRetry; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import static google.registry.util.DateTimeUtils.END_OF_TIME; import static google.registry.util.ResourceUtils.readResourceUtf8; import static java.nio.charset.StandardCharsets.UTF_8; @@ -129,15 +128,13 @@ public class DeleteExpiredDomainsAction implements Runnable { logger.atInfo().log( "Deleting non-renewing domains with autorenew end times up through %s.", runTime); - // Note: in Datastore, this query is (and must be) non-transactional, and thus, is only - // eventually consistent. ImmutableList domainsToDelete = - transactIfJpaTm( - () -> - tm().createQueryComposer(DomainBase.class) - .where("autorenewEndTime", Comparator.LTE, runTime) - .where("deletionTime", Comparator.EQ, END_OF_TIME) - .list()); + tm().transact( + () -> + tm().createQueryComposer(DomainBase.class) + .where("autorenewEndTime", Comparator.LTE, runTime) + .where("deletionTime", Comparator.EQ, END_OF_TIME) + .list()); if (domainsToDelete.isEmpty()) { logger.atInfo().log("Found 0 domains to delete."); response.setPayload("Found 0 domains to delete."); diff --git a/core/src/main/java/google/registry/batch/DeleteProberDataAction.java b/core/src/main/java/google/registry/batch/DeleteProberDataAction.java index fa64c928a..1fb3aa457 100644 --- a/core/src/main/java/google/registry/batch/DeleteProberDataAction.java +++ b/core/src/main/java/google/registry/batch/DeleteProberDataAction.java @@ -42,7 +42,6 @@ import google.registry.model.domain.DomainHistory; import google.registry.model.tld.Registry.TldType; import google.registry.request.Action; import google.registry.request.Parameter; -import google.registry.request.Response; import google.registry.request.auth.Auth; import java.util.concurrent.atomic.AtomicInteger; import javax.inject.Inject; @@ -111,7 +110,6 @@ public class DeleteProberDataAction implements Runnable { @Config("registryAdminClientId") String registryAdminRegistrarId; - @Inject Response response; @Inject DeleteProberDataAction() {} @Override diff --git a/core/src/main/java/google/registry/batch/ExpandRecurringBillingEventsAction.java b/core/src/main/java/google/registry/batch/ExpandRecurringBillingEventsAction.java index dc92aa2f5..46a59dd9c 100644 --- a/core/src/main/java/google/registry/batch/ExpandRecurringBillingEventsAction.java +++ b/core/src/main/java/google/registry/batch/ExpandRecurringBillingEventsAction.java @@ -25,7 +25,6 @@ import static google.registry.model.reporting.HistoryEntry.Type.DOMAIN_AUTORENEW import static google.registry.persistence.transaction.QueryComposer.Comparator.EQ; import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import static google.registry.util.CollectionUtils.union; import static google.registry.util.DateTimeUtils.START_OF_TIME; import static google.registry.util.DateTimeUtils.earliestOf; @@ -96,11 +95,11 @@ public class ExpandRecurringBillingEventsAction implements Runnable { public void run() { DateTime executeTime = clock.nowUtc(); DateTime persistedCursorTime = - transactIfJpaTm( - () -> - tm().loadByKeyIfPresent(Cursor.createGlobalVKey(RECURRING_BILLING)) - .orElse(Cursor.createGlobal(RECURRING_BILLING, START_OF_TIME)) - .getCursorTime()); + tm().transact( + () -> + tm().loadByKeyIfPresent(Cursor.createGlobalVKey(RECURRING_BILLING)) + .orElse(Cursor.createGlobal(RECURRING_BILLING, START_OF_TIME)) + .getCursorTime()); DateTime cursorTime = cursorTimeParam.orElse(persistedCursorTime); checkArgument( cursorTime.isBefore(executeTime), "Cursor time must be earlier than execution time."); diff --git a/core/src/main/java/google/registry/batch/RelockDomainAction.java b/core/src/main/java/google/registry/batch/RelockDomainAction.java index 93ad413ee..e0f50b856 100644 --- a/core/src/main/java/google/registry/batch/RelockDomainAction.java +++ b/core/src/main/java/google/registry/batch/RelockDomainAction.java @@ -120,10 +120,7 @@ public class RelockDomainAction implements Runnable { * for more details on retry behavior. */ response.setStatus(SC_NO_CONTENT); response.setContentType(MediaType.PLAIN_TEXT_UTF_8); - - // nb: DomainLockUtils relies on the JPA transaction being the outermost transaction - // if we have Datastore as the primary DB (if SQL is the primary DB, it's irrelevant) - jpaTm().transact(() -> tm().transact(this::relockDomain)); + tm().transact(this::relockDomain); } private void relockDomain() { diff --git a/core/src/main/java/google/registry/batch/WipeoutDatastoreAction.java b/core/src/main/java/google/registry/batch/WipeoutDatastoreAction.java deleted file mode 100644 index b28214640..000000000 --- a/core/src/main/java/google/registry/batch/WipeoutDatastoreAction.java +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright 2021 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.batch; - -import static com.google.common.net.MediaType.PLAIN_TEXT_UTF_8; -import static google.registry.beam.BeamUtils.createJobName; -import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN; -import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR; -import static javax.servlet.http.HttpServletResponse.SC_OK; - -import com.google.api.services.dataflow.Dataflow; -import com.google.api.services.dataflow.model.LaunchFlexTemplateParameter; -import com.google.api.services.dataflow.model.LaunchFlexTemplateRequest; -import com.google.api.services.dataflow.model.LaunchFlexTemplateResponse; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import com.google.common.flogger.FluentLogger; -import google.registry.config.RegistryConfig.Config; -import google.registry.config.RegistryEnvironment; -import google.registry.model.annotations.DeleteAfterMigration; -import google.registry.request.Action; -import google.registry.request.Response; -import google.registry.request.auth.Auth; -import google.registry.util.Clock; -import javax.inject.Inject; - -/** - * Wipes out all Cloud Datastore data in a Nomulus GCP environment. - * - *

This class is created for the QA environment, where migration testing with production data - * will happen. A regularly scheduled wipeout is a prerequisite to using production data there. - */ -@Action( - service = Action.Service.BACKEND, - path = "/_dr/task/wipeOutDatastore", - auth = Auth.AUTH_INTERNAL_OR_ADMIN) -@DeleteAfterMigration -public class WipeoutDatastoreAction implements Runnable { - private static final FluentLogger logger = FluentLogger.forEnclosingClass(); - - private static final String PIPELINE_NAME = "bulk_delete_datastore_pipeline"; - - private static final ImmutableSet FORBIDDEN_ENVIRONMENTS = - ImmutableSet.of(RegistryEnvironment.PRODUCTION, RegistryEnvironment.SANDBOX); - - private final String projectId; - private final String jobRegion; - private final Response response; - private final Dataflow dataflow; - private final String stagingBucketUrl; - private final Clock clock; - - @Inject - WipeoutDatastoreAction( - @Config("projectId") String projectId, - @Config("defaultJobRegion") String jobRegion, - @Config("beamStagingBucketUrl") String stagingBucketUrl, - Clock clock, - Response response, - Dataflow dataflow) { - this.projectId = projectId; - this.jobRegion = jobRegion; - this.stagingBucketUrl = stagingBucketUrl; - this.clock = clock; - this.response = response; - this.dataflow = dataflow; - } - - @Override - public void run() { - response.setContentType(PLAIN_TEXT_UTF_8); - - if (FORBIDDEN_ENVIRONMENTS.contains(RegistryEnvironment.get())) { - response.setStatus(SC_FORBIDDEN); - response.setPayload("Wipeout is not allowed in " + RegistryEnvironment.get()); - return; - } - - try { - LaunchFlexTemplateParameter parameters = - new LaunchFlexTemplateParameter() - .setJobName(createJobName("bulk-delete-datastore-", clock)) - .setContainerSpecGcsPath( - String.format("%s/%s_metadata.json", stagingBucketUrl, PIPELINE_NAME)) - .setParameters( - ImmutableMap.of( - "kindsToDelete", - "*", - "registryEnvironment", - RegistryEnvironment.get().name())); - LaunchFlexTemplateResponse launchResponse = - dataflow - .projects() - .locations() - .flexTemplates() - .launch( - projectId, - jobRegion, - new LaunchFlexTemplateRequest().setLaunchParameter(parameters)) - .execute(); - response.setStatus(SC_OK); - response.setPayload("Launched " + launchResponse.getJob().getName()); - } catch (Exception e) { - String msg = String.format("Failed to launch %s.", PIPELINE_NAME); - logger.atSevere().withCause(e).log(msg); - response.setStatus(SC_INTERNAL_SERVER_ERROR); - response.setPayload(msg); - } - } -} diff --git a/core/src/main/java/google/registry/beam/datastore/BulkDeleteDatastorePipeline.java b/core/src/main/java/google/registry/beam/datastore/BulkDeleteDatastorePipeline.java deleted file mode 100644 index 7adecaed0..000000000 --- a/core/src/main/java/google/registry/beam/datastore/BulkDeleteDatastorePipeline.java +++ /dev/null @@ -1,336 +0,0 @@ -// Copyright 2020 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.beam.datastore; - -import static com.google.common.base.Preconditions.checkState; -import static org.apache.beam.sdk.values.TypeDescriptors.kvs; -import static org.apache.beam.sdk.values.TypeDescriptors.strings; - -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Splitter; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.ImmutableSortedSet; -import com.google.common.flogger.FluentLogger; -import com.google.datastore.v1.Entity; -import google.registry.config.RegistryEnvironment; -import google.registry.model.annotations.DeleteAfterMigration; -import java.util.Iterator; -import java.util.Map; -import org.apache.beam.sdk.Pipeline; -import org.apache.beam.sdk.extensions.gcp.options.GcpOptions; -import org.apache.beam.sdk.io.gcp.datastore.DatastoreIO; -import org.apache.beam.sdk.options.Default; -import org.apache.beam.sdk.options.Description; -import org.apache.beam.sdk.options.PipelineOptionsFactory; -import org.apache.beam.sdk.options.Validation; -import org.apache.beam.sdk.transforms.Create; -import org.apache.beam.sdk.transforms.DoFn; -import org.apache.beam.sdk.transforms.GroupByKey; -import org.apache.beam.sdk.transforms.MapElements; -import org.apache.beam.sdk.transforms.PTransform; -import org.apache.beam.sdk.transforms.ParDo; -import org.apache.beam.sdk.transforms.Reshuffle; -import org.apache.beam.sdk.transforms.View; -import org.apache.beam.sdk.values.KV; -import org.apache.beam.sdk.values.PBegin; -import org.apache.beam.sdk.values.PCollection; -import org.apache.beam.sdk.values.PCollectionTuple; -import org.apache.beam.sdk.values.PCollectionView; -import org.apache.beam.sdk.values.TupleTag; -import org.apache.beam.sdk.values.TupleTagList; - -/** - * A BEAM pipeline that deletes Datastore entities in bulk. - * - *

This pipeline provides an alternative to the GCP builtin template that performs - * the same task. It solves the following performance and usability problems in the builtin - * template: - * - *

- * - *

A user of this pipeline must specify the types of entities to delete using the {@code - * --kindsToDelete} command line argument. To delete specific entity types, give a comma-separated - * string of their kind names; to delete all data, give {@code "*"}. - * - *

When deleting all data, it is recommended for the user to specify the number of user entity - * types in the Datastore using the {@code --numOfKindsHint} argument. If the default value for this - * parameter is too low, performance will suffer. - */ -@DeleteAfterMigration -public class BulkDeleteDatastorePipeline { - private static final FluentLogger logger = FluentLogger.forEnclosingClass(); - - // This tool is not for use in our critical projects. - private static final ImmutableSet FORBIDDEN_PROJECTS = - ImmutableSet.of("domain-registry", "domain-registry-sandbox"); - - private final BulkDeletePipelineOptions options; - - BulkDeleteDatastorePipeline(BulkDeletePipelineOptions options) { - this.options = options; - } - - public void run() { - Pipeline pipeline = Pipeline.create(options); - setupPipeline(pipeline); - pipeline.run(); - } - - @SuppressWarnings("deprecation") // org.apache.beam.sdk.transforms.Reshuffle - private void setupPipeline(Pipeline pipeline) { - checkState( - !FORBIDDEN_PROJECTS.contains(options.getProject()), - "Bulk delete is forbidden in %s", - options.getProject()); - - // Pre-allocated tags to label entities by kind. In the case of delete-all, we must use a guess. - TupleTagList deletionTags; - PCollection kindsToDelete; - - if (options.getKindsToDelete().equals("*")) { - deletionTags = getDeletionTags(options.getNumOfKindsHint()); - kindsToDelete = - pipeline.apply("DiscoverEntityKinds", discoverEntityKinds(options.getProject())); - } else { - ImmutableList kindsToDeleteParam = parseKindsToDelete(options); - checkState( - !kindsToDeleteParam.contains("*"), - "The --kindsToDelete argument should not contain both '*' and other kinds."); - deletionTags = getDeletionTags(kindsToDeleteParam.size()); - kindsToDelete = pipeline.apply("UseProvidedKinds", Create.of(kindsToDeleteParam)); - } - - // Map each kind to a tag. The "SplitByKind" stage below will group entities by kind using - // this mapping. In practice, this has been effective at avoiding entity group contentions. - PCollectionView>> kindToTagMapping = - mapKindsToDeletionTags(kindsToDelete, deletionTags).apply("GetKindsToTagMap", View.asMap()); - - PCollectionTuple entities = - kindsToDelete - .apply("GenerateQueries", ParDo.of(new GenerateQueries())) - .apply("ReadEntities", DatastoreV1.read().withProjectId(options.getProject())) - .apply( - "SplitByKind", - ParDo.of(new SplitEntities(kindToTagMapping)) - .withSideInputs(kindToTagMapping) - .withOutputTags(getOneDeletionTag("placeholder"), deletionTags)); - - for (TupleTag tag : deletionTags.getAll()) { - entities - .get((TupleTag) tag) - // Reshuffle calls GroupByKey which is one way to trigger load rebalance in the pipeline. - // Using the deprecated "Reshuffle" for convenience given the short life of this tool. - .apply("RebalanceLoad", Reshuffle.viaRandomKey()) - .apply( - "DeleteEntities_" + tag.getId(), - DatastoreIO.v1().deleteEntity().withProjectId(options.getProject())); - } - } - - private static String toKeyOnlyQueryForKind(String kind) { - return "select __key__ from `" + kind + "`"; - } - - /** - * Returns a {@link TupleTag} that retains the generic type parameter and may be used in a - * multi-output {@link ParDo} (e.g. {@link SplitEntities}). - * - *

This method is NOT needed in tests when creating tags for assertions. Simply create them - * with {@code new TupleTag(String)}. - */ - @VisibleForTesting - static TupleTag getOneDeletionTag(String id) { - // The trailing {} is needed to retain generic param type. - return new TupleTag(id) {}; - } - - @VisibleForTesting - static ImmutableList parseKindsToDelete(BulkDeletePipelineOptions options) { - return ImmutableList.copyOf( - Splitter.on(",").omitEmptyStrings().trimResults().split(options.getKindsToDelete().trim())); - } - - /** - * Returns a list of {@code n} {@link TupleTag TupleTags} numbered from {@code 0} to {@code n-1}. - */ - @VisibleForTesting - static TupleTagList getDeletionTags(int n) { - ImmutableList.Builder> builder = new ImmutableList.Builder<>(); - for (int i = 0; i < n; i++) { - builder.add(getOneDeletionTag(String.valueOf(i))); - } - return TupleTagList.of(builder.build()); - } - - /** Returns a {@link PTransform} that finds all entity kinds in Datastore. */ - @VisibleForTesting - static PTransform> discoverEntityKinds(String project) { - return new PTransform>() { - @Override - public PCollection expand(PBegin input) { - // Use the __kind__ table to discover entity kinds. Data in the more informational - // __Stat_Kind__ table may be up to 48-hour stale. - return input - .apply( - "LoadEntityMetaData", - DatastoreIO.v1() - .read() - .withProjectId(project) - .withLiteralGqlQuery("select * from __kind__")) - .apply( - "GetKindNames", - ParDo.of( - new DoFn() { - @ProcessElement - public void processElement( - @Element Entity entity, OutputReceiver out) { - String kind = entity.getKey().getPath(0).getName(); - if (kind.startsWith("_")) { - return; - } - out.output(kind); - } - })); - } - }; - } - - @VisibleForTesting - static PCollection>> mapKindsToDeletionTags( - PCollection kinds, TupleTagList tags) { - // The first two stages send all strings in the 'kinds' PCollection to one worker which - // performs the mapping in the last stage. - return kinds - .apply( - "AssignSingletonKeyToKinds", - MapElements.into(kvs(strings(), strings())).via(kind -> KV.of("", kind))) - .apply("GatherKindsIntoCollection", GroupByKey.create()) - .apply("MapKindsToTag", ParDo.of(new MapKindsToTags(tags))); - } - - /** Transforms each {@code kind} string into a Datastore query for that kind. */ - @VisibleForTesting - static class GenerateQueries extends DoFn { - @ProcessElement - public void processElement(@Element String kind, OutputReceiver out) { - out.output(toKeyOnlyQueryForKind(kind)); - } - } - - private static class MapKindsToTags - extends DoFn>, KV>> { - private final TupleTagList tupleTags; - - MapKindsToTags(TupleTagList tupleTags) { - this.tupleTags = tupleTags; - } - - @ProcessElement - public void processElement( - @Element KV> kv, - OutputReceiver>> out) { - // Sort kinds so that mapping is deterministic. - ImmutableSortedSet sortedKinds = ImmutableSortedSet.copyOf(kv.getValue()); - Iterator kinds = sortedKinds.iterator(); - Iterator> tags = tupleTags.getAll().iterator(); - - while (kinds.hasNext() && tags.hasNext()) { - out.output(KV.of(kinds.next(), (TupleTag) tags.next())); - } - - if (kinds.hasNext()) { - logger.atWarning().log( - "There are more kinds to delete (%s) than our estimate (%s). " - + "Performance may suffer.", - sortedKinds.size(), tupleTags.size()); - } - // Round robin assignment so that mapping is deterministic - while (kinds.hasNext()) { - tags = tupleTags.getAll().iterator(); - while (kinds.hasNext() && tags.hasNext()) { - out.output(KV.of(kinds.next(), (TupleTag) tags.next())); - } - } - } - } - - /** - * {@link DoFn} that splits one {@link PCollection} of mixed kinds into multiple single-kind - * {@code PCollections}. - */ - @VisibleForTesting - static class SplitEntities extends DoFn { - private final PCollectionView>> kindToTagMapping; - - SplitEntities(PCollectionView>> kindToTagMapping) { - super(); - this.kindToTagMapping = kindToTagMapping; - } - - @ProcessElement - public void processElement(ProcessContext context) { - Entity entity = context.element(); - com.google.datastore.v1.Key entityKey = entity.getKey(); - String kind = entityKey.getPath(entityKey.getPathCount() - 1).getKind(); - TupleTag tag = context.sideInput(kindToTagMapping).get(kind); - context.output(tag, entity); - } - } - - public static void main(String[] args) { - BulkDeletePipelineOptions options = - PipelineOptionsFactory.fromArgs(args).withValidation().as(BulkDeletePipelineOptions.class); - BulkDeleteDatastorePipeline pipeline = new BulkDeleteDatastorePipeline(options); - pipeline.run(); - System.exit(0); - } - - public interface BulkDeletePipelineOptions extends GcpOptions { - - @Description("The Registry environment.") - RegistryEnvironment getRegistryEnvironment(); - - void setRegistryEnvironment(RegistryEnvironment environment); - - @Description( - "The Datastore KINDs to be deleted. The format may be:\n" - + "\t- The list of kinds to be deleted as a comma-separated string, or\n" - + "\t- '*', which causes all kinds to be deleted.") - @Validation.Required - String getKindsToDelete(); - - void setKindsToDelete(String kinds); - - @Description( - "An estimate of the number of KINDs to be deleted. " - + "This is recommended if --kindsToDelete is '*' and the default value is too low.") - @Default.Integer(30) - int getNumOfKindsHint(); - - void setNumOfKindsHint(int numOfKindsHint); - } -} diff --git a/core/src/main/java/google/registry/beam/datastore/DatastoreV1.java b/core/src/main/java/google/registry/beam/datastore/DatastoreV1.java deleted file mode 100644 index 49ca567b4..000000000 --- a/core/src/main/java/google/registry/beam/datastore/DatastoreV1.java +++ /dev/null @@ -1,768 +0,0 @@ -// Copyright 2020 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. - -// This class is adapted from the Apache BEAM SDK. The original license may -// be found at -// this link. - -package google.registry.beam.datastore; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Verify.verify; -import static com.google.datastore.v1.PropertyFilter.Operator.EQUAL; -import static com.google.datastore.v1.PropertyOrder.Direction.DESCENDING; -import static com.google.datastore.v1.QueryResultBatch.MoreResultsType.NOT_FINISHED; -import static com.google.datastore.v1.client.DatastoreHelper.makeAndFilter; -import static com.google.datastore.v1.client.DatastoreHelper.makeFilter; -import static com.google.datastore.v1.client.DatastoreHelper.makeOrder; -import static com.google.datastore.v1.client.DatastoreHelper.makeValue; - -import com.google.api.client.http.HttpRequestInitializer; -import com.google.auth.Credentials; -import com.google.auth.http.HttpCredentialsAdapter; -import com.google.auto.value.AutoValue; -import com.google.cloud.hadoop.util.ChainingHttpRequestInitializer; -import com.google.common.base.Strings; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; -import com.google.common.flogger.FluentLogger; -import com.google.datastore.v1.Entity; -import com.google.datastore.v1.EntityResult; -import com.google.datastore.v1.GqlQuery; -import com.google.datastore.v1.PartitionId; -import com.google.datastore.v1.Query; -import com.google.datastore.v1.QueryResultBatch; -import com.google.datastore.v1.RunQueryRequest; -import com.google.datastore.v1.RunQueryResponse; -import com.google.datastore.v1.client.Datastore; -import com.google.datastore.v1.client.DatastoreException; -import com.google.datastore.v1.client.DatastoreFactory; -import com.google.datastore.v1.client.DatastoreHelper; -import com.google.datastore.v1.client.DatastoreOptions; -import com.google.datastore.v1.client.QuerySplitter; -import com.google.protobuf.Int32Value; -import com.google.rpc.Code; -import google.registry.model.annotations.DeleteAfterMigration; -import java.io.Serializable; -import java.util.List; -import java.util.NoSuchElementException; -import javax.annotation.Nullable; -import org.apache.beam.sdk.extensions.gcp.options.GcpOptions; -import org.apache.beam.sdk.extensions.gcp.util.RetryHttpRequestInitializer; -import org.apache.beam.sdk.metrics.Counter; -import org.apache.beam.sdk.metrics.Metrics; -import org.apache.beam.sdk.options.PipelineOptions; -import org.apache.beam.sdk.transforms.DoFn; -import org.apache.beam.sdk.transforms.PTransform; -import org.apache.beam.sdk.transforms.ParDo; -import org.apache.beam.sdk.transforms.Reshuffle; -import org.apache.beam.sdk.transforms.display.DisplayData; -import org.apache.beam.sdk.transforms.display.HasDisplayData; -import org.apache.beam.sdk.util.BackOff; -import org.apache.beam.sdk.util.BackOffUtils; -import org.apache.beam.sdk.util.FluentBackoff; -import org.apache.beam.sdk.util.Sleeper; -import org.apache.beam.sdk.values.KV; -import org.apache.beam.sdk.values.PCollection; -import org.joda.time.Duration; - -/** - * Contains an adaptation of {@link org.apache.beam.sdk.io.gcp.datastore.DatastoreV1.Read}. See - * {@link MultiRead} for details. - */ -@DeleteAfterMigration -public class DatastoreV1 { - - // A package-private constructor to prevent direct instantiation from outside of this package - DatastoreV1() {} - - /** - * Non-retryable errors. See https://cloud.google.com/datastore/docs/concepts/errors#Error_Codes . - */ - private static final ImmutableSet NON_RETRYABLE_ERRORS = - ImmutableSet.of( - Code.FAILED_PRECONDITION, - Code.INVALID_ARGUMENT, - Code.PERMISSION_DENIED, - Code.UNAUTHENTICATED); - - /** - * Returns an empty {@link MultiRead} builder. Configure the source {@code projectId}, {@code - * query}, and optionally {@code namespace} and {@code numQuerySplits} using {@link - * MultiRead#withProjectId}, {@link MultiRead#withNamespace}, {@link - * MultiRead#withNumQuerySplits}. - */ - public static MultiRead read() { - return new AutoValue_DatastoreV1_MultiRead.Builder().setNumQuerySplits(0).build(); - } - - /** - * A {@link PTransform} that executes every Cloud SQL queries in a {@link PCollection } and reads - * their result rows as {@code Entity} objects. - * - *

This class is adapted from {@link org.apache.beam.sdk.io.gcp.datastore.DatastoreV1.Read}. It - * uses literal GQL queries in the input {@link PCollection} instead of a constant query provided - * to the builder. Only the {@link #expand} method is modified from the original. Everything else - * including comments have been copied verbatim. - */ - @AutoValue - public abstract static class MultiRead - extends PTransform, PCollection> { - private static final FluentLogger logger = FluentLogger.forEnclosingClass(); - - /** An upper bound on the number of splits for a query. */ - public static final int NUM_QUERY_SPLITS_MAX = 50000; - - /** A lower bound on the number of splits for a query. */ - static final int NUM_QUERY_SPLITS_MIN = 12; - - /** Default bundle size of 64MB. */ - static final long DEFAULT_BUNDLE_SIZE_BYTES = 64L * 1024L * 1024L; - - /** - * Maximum number of results to request per query. - * - *

Must be set, or it may result in an I/O error when querying Cloud Datastore. - */ - static final int QUERY_BATCH_LIMIT = 500; - - public abstract @Nullable String getProjectId(); - - public abstract @Nullable String getNamespace(); - - public abstract int getNumQuerySplits(); - - public abstract @Nullable String getLocalhost(); - - @Override - public abstract String toString(); - - abstract Builder toBuilder(); - - @AutoValue.Builder - abstract static class Builder { - abstract Builder setProjectId(String projectId); - - abstract Builder setNamespace(String namespace); - - abstract Builder setNumQuerySplits(int numQuerySplits); - - abstract Builder setLocalhost(String localhost); - - abstract MultiRead build(); - } - - /** - * Computes the number of splits to be performed on the given query by querying the estimated - * size from Cloud Datastore. - */ - static int getEstimatedNumSplits(Datastore datastore, Query query, @Nullable String namespace) { - int numSplits; - try { - long estimatedSizeBytes = getEstimatedSizeBytes(datastore, query, namespace); - logger.atInfo().log("Estimated size for the query is %d bytes.", estimatedSizeBytes); - numSplits = - (int) - Math.min( - NUM_QUERY_SPLITS_MAX, - Math.round(((double) estimatedSizeBytes) / DEFAULT_BUNDLE_SIZE_BYTES)); - } catch (Exception e) { - logger.atWarning().withCause(e).log( - "Failed the fetch estimatedSizeBytes for query: %s", query); - // Fallback in case estimated size is unavailable. - numSplits = NUM_QUERY_SPLITS_MIN; - } - return Math.max(numSplits, NUM_QUERY_SPLITS_MIN); - } - - /** - * Cloud Datastore system tables with statistics are periodically updated. This method fetches - * the latest timestamp (in microseconds) of statistics update using the {@code __Stat_Total__} - * table. - */ - private static long queryLatestStatisticsTimestamp( - Datastore datastore, @Nullable String namespace) throws DatastoreException { - Query.Builder query = Query.newBuilder(); - // Note: namespace either being null or empty represents the default namespace, in which - // case we treat it as not provided by the user. - if (Strings.isNullOrEmpty(namespace)) { - query.addKindBuilder().setName("__Stat_Total__"); - } else { - query.addKindBuilder().setName("__Stat_Ns_Total__"); - } - query.addOrder(makeOrder("timestamp", DESCENDING)); - query.setLimit(Int32Value.newBuilder().setValue(1)); - RunQueryRequest request = makeRequest(query.build(), namespace); - - RunQueryResponse response = datastore.runQuery(request); - QueryResultBatch batch = response.getBatch(); - if (batch.getEntityResultsCount() == 0) { - throw new NoSuchElementException("Datastore total statistics unavailable"); - } - Entity entity = batch.getEntityResults(0).getEntity(); - return entity.getProperties().get("timestamp").getTimestampValue().getSeconds() * 1000000; - } - - /** Retrieve latest table statistics for a given kind, namespace, and datastore. */ - private static Entity getLatestTableStats( - String ourKind, @Nullable String namespace, Datastore datastore) throws DatastoreException { - long latestTimestamp = queryLatestStatisticsTimestamp(datastore, namespace); - logger.atInfo().log("Latest stats timestamp for kind %s is %s.", ourKind, latestTimestamp); - - Query.Builder queryBuilder = Query.newBuilder(); - if (Strings.isNullOrEmpty(namespace)) { - queryBuilder.addKindBuilder().setName("__Stat_Kind__"); - } else { - queryBuilder.addKindBuilder().setName("__Stat_Ns_Kind__"); - } - - queryBuilder.setFilter( - makeAndFilter( - makeFilter("kind_name", EQUAL, makeValue(ourKind).build()).build(), - makeFilter("timestamp", EQUAL, makeValue(latestTimestamp).build()).build())); - - RunQueryRequest request = makeRequest(queryBuilder.build(), namespace); - - long now = System.currentTimeMillis(); - RunQueryResponse response = datastore.runQuery(request); - logger.atFine().log( - "Query for per-kind statistics took %d ms.", System.currentTimeMillis() - now); - - QueryResultBatch batch = response.getBatch(); - if (batch.getEntityResultsCount() == 0) { - throw new NoSuchElementException( - "Datastore statistics for kind " + ourKind + " unavailable"); - } - return batch.getEntityResults(0).getEntity(); - } - - /** - * Get the estimated size of the data returned by the given query. - * - *

Cloud Datastore provides no way to get a good estimate of how large the result of a query - * entity kind being queried, using the __Stat_Kind__ system table, assuming exactly 1 kind is - * specified in the query. - * - *

See https://cloud.google.com/datastore/docs/concepts/stats. - */ - static long getEstimatedSizeBytes(Datastore datastore, Query query, @Nullable String namespace) - throws DatastoreException { - String ourKind = query.getKind(0).getName(); - Entity entity = getLatestTableStats(ourKind, namespace, datastore); - return entity.getProperties().get("entity_bytes").getIntegerValue(); - } - - private static PartitionId.Builder forNamespace(@Nullable String namespace) { - PartitionId.Builder partitionBuilder = PartitionId.newBuilder(); - // Namespace either being null or empty represents the default namespace. - // Datastore Client libraries expect users to not set the namespace proto field in - // either of these cases. - if (!Strings.isNullOrEmpty(namespace)) { - partitionBuilder.setNamespaceId(namespace); - } - return partitionBuilder; - } - - /** Builds a {@link RunQueryRequest} from the {@code query} and {@code namespace}. */ - static RunQueryRequest makeRequest(Query query, @Nullable String namespace) { - return RunQueryRequest.newBuilder() - .setQuery(query) - .setPartitionId(forNamespace(namespace)) - .build(); - } - - /** Builds a {@link RunQueryRequest} from the {@code GqlQuery} and {@code namespace}. */ - private static RunQueryRequest makeRequest(GqlQuery gqlQuery, @Nullable String namespace) { - return RunQueryRequest.newBuilder() - .setGqlQuery(gqlQuery) - .setPartitionId(forNamespace(namespace)) - .build(); - } - - /** - * A helper function to get the split queries, taking into account the optional {@code - * namespace}. - */ - private static List splitQuery( - Query query, - @Nullable String namespace, - Datastore datastore, - QuerySplitter querySplitter, - int numSplits) - throws DatastoreException { - // If namespace is set, include it in the split request so splits are calculated accordingly. - return querySplitter.getSplits(query, forNamespace(namespace).build(), numSplits, datastore); - } - - /** - * Translates a Cloud Datastore gql query string to {@link Query}. - * - *

Currently, the only way to translate a gql query string to a Query is to run the query - * against Cloud Datastore and extract the {@code Query} from the response. To prevent reading - * any data, we set the {@code LIMIT} to 0 but if the gql query already has a limit set, we - * catch the exception with {@code INVALID_ARGUMENT} error code and retry the translation - * without the zero limit. - * - *

Note: This may result in reading actual data from Cloud Datastore but the service has a - * cap on the number of entities returned for a single rpc request, so this should not be a - * problem in practice. - */ - private static Query translateGqlQueryWithLimitCheck( - String gql, Datastore datastore, String namespace) throws DatastoreException { - String gqlQueryWithZeroLimit = gql + " LIMIT 0"; - try { - Query translatedQuery = translateGqlQuery(gqlQueryWithZeroLimit, datastore, namespace); - // Clear the limit that we set. - return translatedQuery.toBuilder().clearLimit().build(); - } catch (DatastoreException e) { - // Note: There is no specific error code or message to detect if the query already has a - // limit, so we just check for INVALID_ARGUMENT and assume that that the query might have - // a limit already set. - if (e.getCode() == Code.INVALID_ARGUMENT) { - logger.atWarning().log( - "Failed to translate Gql query '%s': %s", gqlQueryWithZeroLimit, e.getMessage()); - logger.atWarning().log( - "User query might have a limit already set, so trying without zero limit."); - // Retry without the zero limit. - return translateGqlQuery(gql, datastore, namespace); - } else { - throw e; - } - } - } - - /** Translates a gql query string to {@link Query}. */ - private static Query translateGqlQuery(String gql, Datastore datastore, String namespace) - throws DatastoreException { - logger.atInfo().log("Translating gql %s", gql); - GqlQuery gqlQuery = GqlQuery.newBuilder().setQueryString(gql).setAllowLiterals(true).build(); - RunQueryRequest req = makeRequest(gqlQuery, namespace); - return datastore.runQuery(req).getQuery(); - } - - /** - * Returns a new {@link MultiRead} that reads from the Cloud Datastore for the specified - * project. - */ - public MultiRead withProjectId(String projectId) { - checkArgument(projectId != null, "projectId can not be null"); - return toBuilder().setProjectId(projectId).build(); - } - - /** Returns a new {@link MultiRead} that reads from the given namespace. */ - public MultiRead withNamespace(String namespace) { - return toBuilder().setNamespace(namespace).build(); - } - - /** - * Returns a new {@link MultiRead} that reads by splitting the given {@code query} into {@code - * numQuerySplits}. - * - *

The semantics for the query splitting is defined below: - * - *

- */ - public MultiRead withNumQuerySplits(int numQuerySplits) { - return toBuilder() - .setNumQuerySplits(Math.min(Math.max(numQuerySplits, 0), NUM_QUERY_SPLITS_MAX)) - .build(); - } - - /** - * Returns a new {@link MultiRead} that reads from a Datastore Emulator running at the given - * localhost address. - */ - public MultiRead withLocalhost(String localhost) { - return toBuilder().setLocalhost(localhost).build(); - } - - /** Returns Number of entities available for reading. */ - public long getNumEntities( - PipelineOptions options, String ourKind, @Nullable String namespace) { - try { - V1Options v1Options = V1Options.from(getProjectId(), getNamespace(), getLocalhost()); - V1DatastoreFactory datastoreFactory = new V1DatastoreFactory(); - Datastore datastore = - datastoreFactory.getDatastore( - options, v1Options.getProjectId(), v1Options.getLocalhost()); - - Entity entity = getLatestTableStats(ourKind, namespace, datastore); - return entity.getProperties().get("count").getIntegerValue(); - } catch (Exception e) { - return -1; - } - } - - @Override - public PCollection expand(PCollection gqlQueries) { - checkArgument(getProjectId() != null, "projectId cannot be null"); - - V1Options v1Options = V1Options.from(getProjectId(), getNamespace(), getLocalhost()); - - /* - * This composite transform involves the following steps: - * 1. Apply a {@link ParDo} that translates each query in {@code gqlQueries} into a {@code - * query}. - * - * 2. A {@link ParDo} splits the resulting query into {@code numQuerySplits} and - * assign each split query a unique {@code Integer} as the key. The resulting output is - * of the type {@code PCollection>}. - * - * If the value of {@code numQuerySplits} is less than or equal to 0, then the number of - * splits will be computed dynamically based on the size of the data for the {@code query}. - * - * 3. The resulting {@code PCollection} is sharded using a {@link GroupByKey} operation. The - * queries are extracted from they {@code KV>} and flattened to - * output a {@code PCollection}. - * - * 4. In the third step, a {@code ParDo} reads entities for each query and outputs - * a {@code PCollection}. - */ - - PCollection inputQuery = - gqlQueries.apply(ParDo.of(new GqlQueryTranslateFn(v1Options))); - - return inputQuery - .apply("Split", ParDo.of(new SplitQueryFn(v1Options, getNumQuerySplits()))) - .apply("Reshuffle", Reshuffle.viaRandomKey()) - .apply("Read", ParDo.of(new ReadFn(v1Options))); - } - - @Override - public void populateDisplayData(DisplayData.Builder builder) { - super.populateDisplayData(builder); - builder - .addIfNotNull(DisplayData.item("projectId", getProjectId()).withLabel("ProjectId")) - .addIfNotNull(DisplayData.item("namespace", getNamespace()).withLabel("Namespace")); - } - - private static class V1Options implements HasDisplayData, Serializable { - private final String project; - private final @Nullable String namespace; - private final @Nullable String localhost; - - private V1Options(String project, @Nullable String namespace, @Nullable String localhost) { - this.project = project; - this.namespace = namespace; - this.localhost = localhost; - } - - public static V1Options from( - String projectId, @Nullable String namespace, @Nullable String localhost) { - return new V1Options(projectId, namespace, localhost); - } - - public String getProjectId() { - return project; - } - - public @Nullable String getNamespace() { - return namespace; - } - - public @Nullable String getLocalhost() { - return localhost; - } - - @Override - public void populateDisplayData(DisplayData.Builder builder) { - builder - .addIfNotNull(DisplayData.item("projectId", getProjectId()).withLabel("ProjectId")) - .addIfNotNull(DisplayData.item("namespace", getNamespace()).withLabel("Namespace")); - } - } - - /** A DoFn that translates a Cloud Datastore gql query string to {@code Query}. */ - static class GqlQueryTranslateFn extends DoFn { - private final V1Options v1Options; - private transient Datastore datastore; - private final V1DatastoreFactory datastoreFactory; - - GqlQueryTranslateFn(V1Options options) { - this(options, new V1DatastoreFactory()); - } - - GqlQueryTranslateFn(V1Options options, V1DatastoreFactory datastoreFactory) { - this.v1Options = options; - this.datastoreFactory = datastoreFactory; - } - - @StartBundle - public void startBundle(StartBundleContext c) { - datastore = - datastoreFactory.getDatastore( - c.getPipelineOptions(), v1Options.getProjectId(), v1Options.getLocalhost()); - } - - @ProcessElement - public void processElement(ProcessContext c) throws Exception { - String gqlQuery = c.element(); - logger.atInfo().log("User query: '%s'.", gqlQuery); - Query query = - translateGqlQueryWithLimitCheck(gqlQuery, datastore, v1Options.getNamespace()); - logger.atInfo().log("User gql query translated to Query(%s).", query); - c.output(query); - } - } - - /** - * A {@link DoFn} that splits a given query into multiple sub-queries, assigns them unique keys - * and outputs them as {@link KV}. - */ - private static class SplitQueryFn extends DoFn { - private final V1Options options; - // number of splits to make for a given query - private final int numSplits; - - private final V1DatastoreFactory datastoreFactory; - // Datastore client - private transient Datastore datastore; - // Query splitter - private transient QuerySplitter querySplitter; - - public SplitQueryFn(V1Options options, int numSplits) { - this(options, numSplits, new V1DatastoreFactory()); - } - - private SplitQueryFn(V1Options options, int numSplits, V1DatastoreFactory datastoreFactory) { - this.options = options; - this.numSplits = numSplits; - this.datastoreFactory = datastoreFactory; - } - - @StartBundle - public void startBundle(StartBundleContext c) { - datastore = - datastoreFactory.getDatastore( - c.getPipelineOptions(), options.getProjectId(), options.getLocalhost()); - querySplitter = datastoreFactory.getQuerySplitter(); - } - - @ProcessElement - public void processElement(ProcessContext c) { - Query query = c.element(); - - // If query has a user set limit, then do not split. - if (query.hasLimit()) { - c.output(query); - return; - } - - int estimatedNumSplits; - // Compute the estimated numSplits if numSplits is not specified by the user. - if (numSplits <= 0) { - estimatedNumSplits = getEstimatedNumSplits(datastore, query, options.getNamespace()); - } else { - estimatedNumSplits = numSplits; - } - - logger.atInfo().log("Splitting the query into %d splits.", estimatedNumSplits); - List querySplits; - try { - querySplits = - splitQuery( - query, options.getNamespace(), datastore, querySplitter, estimatedNumSplits); - } catch (Exception e) { - logger.atWarning().log("Unable to parallelize the given query: %s", query, e); - querySplits = ImmutableList.of(query); - } - - // assign unique keys to query splits. - for (Query subquery : querySplits) { - c.output(subquery); - } - } - - @Override - public void populateDisplayData(DisplayData.Builder builder) { - super.populateDisplayData(builder); - builder.include("options", options); - if (numSplits > 0) { - builder.add( - DisplayData.item("numQuerySplits", numSplits) - .withLabel("Requested number of Query splits")); - } - } - } - - /** A {@link DoFn} that reads entities from Cloud Datastore for each query. */ - private static class ReadFn extends DoFn { - private final V1Options options; - private final V1DatastoreFactory datastoreFactory; - // Datastore client - private transient Datastore datastore; - private final Counter rpcErrors = Metrics.counter(ReadFn.class, "datastoreRpcErrors"); - private final Counter rpcSuccesses = Metrics.counter(ReadFn.class, "datastoreRpcSuccesses"); - private static final int MAX_RETRIES = 5; - private static final FluentBackoff RUNQUERY_BACKOFF = - FluentBackoff.DEFAULT - .withMaxRetries(MAX_RETRIES) - .withInitialBackoff(Duration.standardSeconds(5)); - - public ReadFn(V1Options options) { - this(options, new V1DatastoreFactory()); - } - - private ReadFn(V1Options options, V1DatastoreFactory datastoreFactory) { - this.options = options; - this.datastoreFactory = datastoreFactory; - } - - @StartBundle - public void startBundle(StartBundleContext c) { - datastore = - datastoreFactory.getDatastore( - c.getPipelineOptions(), options.getProjectId(), options.getLocalhost()); - } - - private RunQueryResponse runQueryWithRetries(RunQueryRequest request) throws Exception { - Sleeper sleeper = Sleeper.DEFAULT; - BackOff backoff = RUNQUERY_BACKOFF.backoff(); - while (true) { - try { - RunQueryResponse response = datastore.runQuery(request); - rpcSuccesses.inc(); - return response; - } catch (DatastoreException exception) { - rpcErrors.inc(); - - if (NON_RETRYABLE_ERRORS.contains(exception.getCode())) { - throw exception; - } - if (!BackOffUtils.next(sleeper, backoff)) { - logger.atSevere().log("Aborting after %d retries.", MAX_RETRIES); - throw exception; - } - } - } - } - - /** Read and output entities for the given query. */ - @ProcessElement - public void processElement(ProcessContext context) throws Exception { - Query query = context.element(); - String namespace = options.getNamespace(); - int userLimit = query.hasLimit() ? query.getLimit().getValue() : Integer.MAX_VALUE; - - boolean moreResults = true; - QueryResultBatch currentBatch = null; - - while (moreResults) { - Query.Builder queryBuilder = query.toBuilder(); - queryBuilder.setLimit( - Int32Value.newBuilder().setValue(Math.min(userLimit, QUERY_BATCH_LIMIT))); - - if (currentBatch != null && !currentBatch.getEndCursor().isEmpty()) { - queryBuilder.setStartCursor(currentBatch.getEndCursor()); - } - - RunQueryRequest request = makeRequest(queryBuilder.build(), namespace); - RunQueryResponse response = runQueryWithRetries(request); - - currentBatch = response.getBatch(); - - // MORE_RESULTS_AFTER_LIMIT is not implemented yet: - // https://groups.google.com/forum/#!topic/gcd-discuss/iNs6M1jA2Vw, so - // use result count to determine if more results might exist. - int numFetch = currentBatch.getEntityResultsCount(); - if (query.hasLimit()) { - verify( - userLimit >= numFetch, - "Expected userLimit %s >= numFetch %s, because query limit %s must be <= userLimit", - userLimit, - numFetch, - query.getLimit()); - userLimit -= numFetch; - } - - // output all the entities from the current batch. - for (EntityResult entityResult : currentBatch.getEntityResultsList()) { - context.output(entityResult.getEntity()); - } - - // Check if we have more entities to be read. - moreResults = - // User-limit does not exist (so userLimit == MAX_VALUE) and/or has not been satisfied - (userLimit > 0) - // All indications from the API are that there are/may be more results. - && ((numFetch == QUERY_BATCH_LIMIT) - || (currentBatch.getMoreResults() == NOT_FINISHED)); - } - } - - @Override - public void populateDisplayData(DisplayData.Builder builder) { - super.populateDisplayData(builder); - builder.include("options", options); - } - } - } - - /** - * A wrapper factory class for Cloud Datastore singleton classes {@link DatastoreFactory} and - * {@link QuerySplitter} - * - *

{@link DatastoreFactory} and {@link QuerySplitter} are not java serializable, hence wrapping - * them under this class, which implements {@link Serializable}. - */ - private static class V1DatastoreFactory implements Serializable { - - /** Builds a Cloud Datastore client for the given pipeline options and project. */ - public Datastore getDatastore(PipelineOptions pipelineOptions, String projectId) { - return getDatastore(pipelineOptions, projectId, null); - } - - /** - * Builds a Cloud Datastore client for the given pipeline options, project and an optional - * locahost. - */ - public Datastore getDatastore( - PipelineOptions pipelineOptions, String projectId, @Nullable String localhost) { - Credentials credential = pipelineOptions.as(GcpOptions.class).getGcpCredential(); - HttpRequestInitializer initializer; - if (credential != null) { - initializer = - new ChainingHttpRequestInitializer( - new HttpCredentialsAdapter(credential), new RetryHttpRequestInitializer()); - } else { - initializer = new RetryHttpRequestInitializer(); - } - - DatastoreOptions.Builder builder = - new DatastoreOptions.Builder().projectId(projectId).initializer(initializer); - - if (localhost != null) { - builder.localHost(localhost); - } else { - builder.host("batch-datastore.googleapis.com"); - } - - return DatastoreFactory.get().create(builder.build()); - } - - /** Builds a Cloud Datastore {@link QuerySplitter}. */ - public QuerySplitter getQuerySplitter() { - return DatastoreHelper.getQuerySplitter(); - } - } -} diff --git a/core/src/main/java/google/registry/beam/rde/RdeIO.java b/core/src/main/java/google/registry/beam/rde/RdeIO.java index 1091ad09f..40a412704 100644 --- a/core/src/main/java/google/registry/beam/rde/RdeIO.java +++ b/core/src/main/java/google/registry/beam/rde/RdeIO.java @@ -18,7 +18,6 @@ import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Verify.verify; import static google.registry.model.common.Cursor.getCursorTimeOrStartOfTime; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import static google.registry.rde.RdeModule.BRDA_QUEUE; import static google.registry.rde.RdeModule.RDE_UPLOAD_QUEUE; import static java.nio.charset.StandardCharsets.UTF_8; @@ -270,16 +269,15 @@ public class RdeIO { @ProcessElement public void processElement( @Element KV input, PipelineOptions options) { - tm().transact( () -> { PendingDeposit key = input.getKey(); Registry registry = Registry.get(key.tld()); Optional cursor = - transactIfJpaTm( - () -> - tm().loadByKeyIfPresent( - Cursor.createScopedVKey(key.cursor(), registry))); + tm().transact( + () -> + tm().loadByKeyIfPresent( + Cursor.createScopedVKey(key.cursor(), registry))); DateTime position = getCursorTimeOrStartOfTime(cursor); checkState(key.interval() != null, "Interval must be present"); DateTime newPosition = key.watermark().plus(key.interval()); diff --git a/core/src/main/java/google/registry/config/RegistryConfig.java b/core/src/main/java/google/registry/config/RegistryConfig.java index 3fe8f8118..97fda5615 100644 --- a/core/src/main/java/google/registry/config/RegistryConfig.java +++ b/core/src/main/java/google/registry/config/RegistryConfig.java @@ -1331,19 +1331,7 @@ public final class RegistryConfig { } /** - * Returns the Google Cloud Storage bucket for storing Datastore backups. - * - * @see google.registry.export.BackupDatastoreAction - */ - public static String getDatastoreBackupsBucket() { - return "gs://" + getProjectId() + "-datastore-backups"; - } - - /** - * Returns the length of time before commit logs should be deleted from Datastore. - * - *

The only reason you'll want to retain this commit logs in Datastore is for performing - * point-in-time restoration queries for subsystems like RDE. + * Returns the length of time before commit logs should be deleted from the database. * * @see google.registry.tools.server.GenerateZoneFilesAction */ diff --git a/core/src/main/java/google/registry/env/common/backend/WEB-INF/web.xml b/core/src/main/java/google/registry/env/common/backend/WEB-INF/web.xml index 772197500..50a6443ca 100644 --- a/core/src/main/java/google/registry/env/common/backend/WEB-INF/web.xml +++ b/core/src/main/java/google/registry/env/common/backend/WEB-INF/web.xml @@ -169,36 +169,6 @@ /_dr/dnsRefresh - - - backend-servlet - /_dr/task/backupDatastore - - - - - backend-servlet - /_dr/task/checkDatastoreBackup - - - - - backend-servlet - /_dr/task/uploadDatastoreBackup - - - - - backend-servlet - /_dr/task/updateSnapshotView - - - - - backend-servlet - /_dr/task/pollBigqueryJob - - backend-servlet @@ -323,12 +293,6 @@ have been in the database for a certain period of time. --> /_dr/task/wipeOutCloudSql - - - backend-servlet - /_dr/task/wipeOutDatastore - - diff --git a/core/src/main/java/google/registry/export/AnnotatedEntities.java b/core/src/main/java/google/registry/export/AnnotatedEntities.java deleted file mode 100644 index bc06c9271..000000000 --- a/core/src/main/java/google/registry/export/AnnotatedEntities.java +++ /dev/null @@ -1,64 +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.export; - -import static com.google.common.collect.ImmutableSortedSet.toImmutableSortedSet; -import static google.registry.util.TypeUtils.hasAnnotation; - -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Ordering; -import com.googlecode.objectify.Key; -import google.registry.model.EntityClasses; -import google.registry.model.annotations.DeleteAfterMigration; -import google.registry.model.annotations.InCrossTld; -import google.registry.model.annotations.NotBackedUp; -import google.registry.model.annotations.ReportedOn; -import google.registry.model.annotations.VirtualEntity; - -/** Constants related to export code. */ -@DeleteAfterMigration -public final class AnnotatedEntities { - - /** Returns the names of kinds to include in Datastore backups. */ - public static ImmutableSet getBackupKinds() { - // Back up all entity classes that aren't annotated with @VirtualEntity (never even persisted - // to Datastore, so they can't be backed up) or @NotBackedUp (intentionally omitted). - return EntityClasses.ALL_CLASSES - .stream() - .filter(hasAnnotation(VirtualEntity.class).negate()) - .filter(hasAnnotation(NotBackedUp.class).negate()) - .map(Key::getKind) - .collect(toImmutableSortedSet(Ordering.natural())); - } - - /** Returns the names of kinds to import into reporting tools (e.g. BigQuery). */ - public static ImmutableSet getReportingKinds() { - return EntityClasses.ALL_CLASSES - .stream() - .filter(hasAnnotation(ReportedOn.class)) - .filter(hasAnnotation(VirtualEntity.class).negate()) - .map(Key::getKind) - .collect(toImmutableSortedSet(Ordering.natural())); - } - - /** Returns the names of kinds that are in the cross-TLD entity group. */ - public static ImmutableSet getCrossTldKinds() { - return EntityClasses.ALL_CLASSES.stream() - .filter(hasAnnotation(InCrossTld.class)) - .filter(hasAnnotation(VirtualEntity.class).negate()) - .map(Key::getKind) - .collect(toImmutableSortedSet(Ordering.natural())); - } -} diff --git a/core/src/main/java/google/registry/export/BackupDatastoreAction.java b/core/src/main/java/google/registry/export/BackupDatastoreAction.java deleted file mode 100644 index 8d5f52d5f..000000000 --- a/core/src/main/java/google/registry/export/BackupDatastoreAction.java +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright 2018 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.export; - -import static google.registry.request.Action.Method.POST; - -import com.google.common.base.Joiner; -import com.google.common.collect.ImmutableMultimap; -import com.google.common.flogger.FluentLogger; -import google.registry.config.RegistryConfig; -import google.registry.export.datastore.DatastoreAdmin; -import google.registry.export.datastore.Operation; -import google.registry.model.annotations.DeleteAfterMigration; -import google.registry.request.Action; -import google.registry.request.Action.Service; -import google.registry.request.HttpException.InternalServerErrorException; -import google.registry.request.Response; -import google.registry.request.auth.Auth; -import google.registry.util.Clock; -import google.registry.util.CloudTasksUtils; -import javax.inject.Inject; - -/** - * Action to trigger a Datastore backup job that writes a snapshot to Google Cloud Storage. - * - *

This is the first step of a four step workflow for exporting snapshots, with each step calling - * the next upon successful completion: - * - *

    - *
  1. The snapshot is exported to Google Cloud Storage (this action). - *
  2. The {@link CheckBackupAction} polls until the export is completed. - *
  3. The {@link UploadDatastoreBackupAction} uploads the data from GCS to BigQuery. - *
  4. The {@link UpdateSnapshotViewAction} updates the view in latest_datastore_export. - *
- */ -@Action( - service = Action.Service.BACKEND, - path = BackupDatastoreAction.PATH, - method = POST, - automaticallyPrintOk = true, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) -@DeleteAfterMigration -public class BackupDatastoreAction implements Runnable { - - private static final FluentLogger logger = FluentLogger.forEnclosingClass(); - - /** Queue to use for enqueuing the task that will actually launch the backup. */ - static final String QUEUE = "export-snapshot"; // See queue.xml. - - static final String PATH = "/_dr/task/backupDatastore"; // See web.xml. - - @Inject DatastoreAdmin datastoreAdmin; - @Inject Response response; - @Inject Clock clock; - @Inject CloudTasksUtils cloudTasksUtils; - - @Inject - BackupDatastoreAction() {} - - @Override - public void run() { - try { - Operation backup = - datastoreAdmin - .export( - RegistryConfig.getDatastoreBackupsBucket(), AnnotatedEntities.getBackupKinds()) - .execute(); - - String backupName = backup.getName(); - // Enqueue a poll task to monitor the backup for completion and load reporting-related kinds - // into bigquery. - cloudTasksUtils.enqueue( - CheckBackupAction.QUEUE, - cloudTasksUtils.createPostTaskWithDelay( - CheckBackupAction.PATH, - Service.BACKEND.toString(), - ImmutableMultimap.of( - CheckBackupAction.CHECK_BACKUP_NAME_PARAM, - backupName, - CheckBackupAction.CHECK_BACKUP_KINDS_TO_LOAD_PARAM, - Joiner.on(',').join(AnnotatedEntities.getReportingKinds())), - CheckBackupAction.POLL_COUNTDOWN)); - String message = - String.format( - "Datastore backup started with name: %s\nSaving to %s", - backupName, backup.getExportFolderUrl()); - logger.atInfo().log(message); - response.setPayload(message); - } catch (Throwable e) { - throw new InternalServerErrorException("Exception occurred while backing up Datastore", e); - } - } -} diff --git a/core/src/main/java/google/registry/export/BigqueryPollJobAction.java b/core/src/main/java/google/registry/export/BigqueryPollJobAction.java deleted file mode 100644 index e97fc43c7..000000000 --- a/core/src/main/java/google/registry/export/BigqueryPollJobAction.java +++ /dev/null @@ -1,129 +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.export; - -import static google.registry.bigquery.BigqueryUtils.toJobReferenceString; - -import com.google.api.services.bigquery.Bigquery; -import com.google.api.services.bigquery.model.Job; -import com.google.api.services.bigquery.model.JobReference; -import com.google.cloud.tasks.v2.Task; -import com.google.common.flogger.FluentLogger; -import com.google.protobuf.ByteString; -import dagger.Lazy; -import google.registry.request.Action; -import google.registry.request.Header; -import google.registry.request.HttpException.BadRequestException; -import google.registry.request.HttpException.NotModifiedException; -import google.registry.request.Payload; -import google.registry.request.auth.Auth; -import google.registry.util.CloudTasksUtils; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import javax.inject.Inject; -import org.joda.time.Duration; - -/** - * An action which polls the state of a bigquery job. If it is completed then it will log its - * completion state; otherwise it will return a failure code so that the task will be retried. - * - *

Note that this is AUTH_INTERNAL_ONLY: we don't allow "admin" for this to mitigate a - * vulnerability, see b/177308043. - */ -@Action( - service = Action.Service.BACKEND, - path = BigqueryPollJobAction.PATH, - method = {Action.Method.GET, Action.Method.POST}, - automaticallyPrintOk = true, - auth = Auth.AUTH_INTERNAL_ONLY) -public class BigqueryPollJobAction implements Runnable { - - private static final FluentLogger logger = FluentLogger.forEnclosingClass(); - - static final String QUEUE = "export-bigquery-poll"; // See queue.xml - static final String PATH = "/_dr/task/pollBigqueryJob"; // See web.xml - static final String CHAINED_TASK_QUEUE_HEADER = "X-DomainRegistry-ChainedTaskQueue"; - static final String PROJECT_ID_HEADER = "X-DomainRegistry-ProjectId"; - static final String JOB_ID_HEADER = "X-DomainRegistry-JobId"; - static final Duration POLL_COUNTDOWN = Duration.standardSeconds(20); - - @Inject Bigquery bigquery; - @Inject CloudTasksUtils cloudTasksUtils; - - @Inject @Header(CHAINED_TASK_QUEUE_HEADER) Lazy chainedQueueName; - @Inject @Header(PROJECT_ID_HEADER) String projectId; - @Inject @Header(JOB_ID_HEADER) String jobId; - - @Inject @Payload ByteString payload; - - @Inject BigqueryPollJobAction() {} - - @Override - public void run() { - boolean jobOutcome = - checkJobOutcome(); // Throws a NotModifiedException if the job hasn't completed. - // If the job failed, do not enqueue the next step. - if (!jobOutcome || payload == null || payload.size() == 0) { - return; - } - // If there is a payload, it's a chained task, so enqueue it. - Task task; - try { - task = - (Task) - new ObjectInputStream(new ByteArrayInputStream(payload.toByteArray())).readObject(); - } catch (ClassNotFoundException | IOException e) { - throw new BadRequestException("Cannot deserialize task from payload", e); - } - Task enqueuedTask = cloudTasksUtils.enqueue(chainedQueueName.get(), task); - logger.atInfo().log( - "Added chained task %s for %s to queue %s: %s", - enqueuedTask.getName(), - enqueuedTask.getAppEngineHttpRequest().getRelativeUri(), - chainedQueueName.get(), - enqueuedTask); - } - - /** - * Returns true if the provided job succeeded, false if it failed, and throws an exception if it - * is still pending. - */ - private boolean checkJobOutcome() { - Job job = null; - String jobRefString = - toJobReferenceString(new JobReference().setProjectId(projectId).setJobId(jobId)); - - try { - job = bigquery.jobs().get(projectId, jobId).execute(); - } catch (IOException e) { - // We will throw a new exception because done==false, but first log this exception. - logger.atWarning().withCause(e).log("Error checking outcome of BigQuery job %s.", jobId); - } - // If job is not yet done, then throw an exception so that we'll return a failing HTTP status - // code and the task will be retried. - if (job == null || !job.getStatus().getState().equals("DONE")) { - throw new NotModifiedException(jobRefString); - } - - // Check if the job ended with an error. - if (job.getStatus().getErrorResult() != null) { - logger.atSevere().log("Bigquery job failed - %s - %s.", jobRefString, job); - return false; - } - logger.atInfo().log("Bigquery job succeeded - %s.", jobRefString); - return true; - } -} diff --git a/core/src/main/java/google/registry/export/CheckBackupAction.java b/core/src/main/java/google/registry/export/CheckBackupAction.java deleted file mode 100644 index 4b94873a0..000000000 --- a/core/src/main/java/google/registry/export/CheckBackupAction.java +++ /dev/null @@ -1,195 +0,0 @@ -// Copyright 2018 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.export; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.collect.Sets.intersection; -import static google.registry.request.Action.Method.GET; -import static google.registry.request.Action.Method.POST; -import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND; - -import com.google.api.client.googleapis.json.GoogleJsonResponseException; -import com.google.common.base.Joiner; -import com.google.common.base.Splitter; -import com.google.common.collect.ImmutableMultimap; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Sets; -import com.google.common.flogger.FluentLogger; -import google.registry.export.datastore.DatastoreAdmin; -import google.registry.export.datastore.Operation; -import google.registry.model.annotations.DeleteAfterMigration; -import google.registry.request.Action; -import google.registry.request.Action.Service; -import google.registry.request.HttpException; -import google.registry.request.HttpException.BadRequestException; -import google.registry.request.HttpException.InternalServerErrorException; -import google.registry.request.HttpException.NoContentException; -import google.registry.request.HttpException.NotModifiedException; -import google.registry.request.Parameter; -import google.registry.request.RequestMethod; -import google.registry.request.Response; -import google.registry.request.auth.Auth; -import google.registry.util.Clock; -import google.registry.util.CloudTasksUtils; -import java.io.IOException; -import java.util.Set; -import javax.inject.Inject; -import org.joda.time.Duration; -import org.joda.time.PeriodType; -import org.joda.time.format.PeriodFormat; - -/** - * Action that checks the status of a snapshot, and if complete, trigger loading it into BigQuery. - */ -@Action( - service = Action.Service.BACKEND, - path = CheckBackupAction.PATH, - method = {POST, GET}, - automaticallyPrintOk = true, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) -@DeleteAfterMigration -public class CheckBackupAction implements Runnable { - - /** Parameter names for passing parameters into this action. */ - static final String CHECK_BACKUP_NAME_PARAM = "name"; - - static final String CHECK_BACKUP_KINDS_TO_LOAD_PARAM = "kindsToLoad"; - - /** Action-specific details needed for enqueuing tasks against itself. */ - static final String QUEUE = "export-snapshot-poll"; // See queue.xml. - - static final String PATH = "/_dr/task/checkDatastoreBackup"; // See web.xml. - static final Duration POLL_COUNTDOWN = Duration.standardMinutes(2); - - /** The maximum amount of time we allow a backup to run before abandoning it. */ - static final Duration MAXIMUM_BACKUP_RUNNING_TIME = Duration.standardHours(20); - - private static final FluentLogger logger = FluentLogger.forEnclosingClass(); - - @Inject DatastoreAdmin datastoreAdmin; - @Inject Clock clock; - @Inject Response response; - @Inject CloudTasksUtils cloudTasksUtils; - @Inject @RequestMethod Action.Method requestMethod; - - @Inject - @Parameter(CHECK_BACKUP_NAME_PARAM) - String backupName; - - @Inject - @Parameter(CHECK_BACKUP_KINDS_TO_LOAD_PARAM) - String kindsToLoadParam; - - @Inject - CheckBackupAction() {} - - @Override - public void run() { - try { - if (requestMethod == POST) { - checkAndLoadBackupIfComplete(); - } else { - // This is a GET request. - // TODO(weiminyu): consider moving this functionality to Registry tool. - response.setPayload(getExportStatus().toPrettyString()); - } - } catch (HttpException e) { - // Rethrow and let caller propagate status code and error message to the response. - // See google.registry.request.RequestHandler#handleRequest. - throw e; - } catch (Throwable e) { - throw new InternalServerErrorException( - "Exception occurred while checking datastore exports.", e); - } - } - - private Operation getExportStatus() throws IOException { - try { - return datastoreAdmin.get(backupName).execute(); - } catch (GoogleJsonResponseException e) { - if (e.getStatusCode() == SC_NOT_FOUND) { - String message = String.format("Bad backup name %s: %s", backupName, e.getMessage()); - // TODO(b/19081569): Ideally this would return a 2XX error so the task would not be - // retried but we might abandon backups that start late and haven't yet written to - // Datastore. We could fix that by replacing this with a two-phase polling strategy. - throw new BadRequestException(message, e); - } - throw e; - } - } - - private void checkAndLoadBackupIfComplete() throws IOException { - Set kindsToLoad = ImmutableSet.copyOf(Splitter.on(',').split(kindsToLoadParam)); - Operation backup = getExportStatus(); - - checkArgument(backup.isExport(), "Expecting an export operation: [%s].", backupName); - - if (backup.isProcessing() - && backup.getRunningTime(clock).isShorterThan(MAXIMUM_BACKUP_RUNNING_TIME)) { - // Backup might still be running, so send a 304 to have the task retry. - throw new NotModifiedException( - String.format( - "Datastore backup %s still in progress: %s", backupName, backup.getProgress())); - } - if (!backup.isSuccessful()) { - // Declare the backup a lost cause, and send 204 No Content so the task will - // not be retried. - String message = - String.format( - "Datastore backup %s abandoned - not complete after %s. Progress: %s", - backupName, - PeriodFormat.getDefault() - .print( - backup - .getRunningTime(clock) - .toPeriod() - .normalizedStandard(PeriodType.dayTime().withMillisRemoved())), - backup.getProgress()); - throw new NoContentException(message); - } - - String backupId = backup.getExportId(); - // Log a warning if kindsToLoad is not a subset of the exported kinds. - if (!backup.getKinds().containsAll(kindsToLoad)) { - logger.atWarning().log( - "Kinds to load included non-exported kinds: %s", - Sets.difference(kindsToLoad, backup.getKinds())); - } - // Load kinds from the backup, limited to those also in kindsToLoad (if it's present). - ImmutableSet exportedKindsToLoad = - ImmutableSet.copyOf(intersection(backup.getKinds(), kindsToLoad)); - String message = String.format("Datastore backup %s complete - ", backupName); - if (exportedKindsToLoad.isEmpty()) { - message += "no kinds to load into BigQuery."; - } else { - /** Enqueue a task for starting a backup load. */ - cloudTasksUtils.enqueue( - UploadDatastoreBackupAction.QUEUE, - cloudTasksUtils.createPostTask( - UploadDatastoreBackupAction.PATH, - Service.BACKEND.toString(), - ImmutableMultimap.of( - UploadDatastoreBackupAction.UPLOAD_BACKUP_ID_PARAM, - backupId, - UploadDatastoreBackupAction.UPLOAD_BACKUP_FOLDER_PARAM, - backup.getExportFolderUrl(), - UploadDatastoreBackupAction.UPLOAD_BACKUP_KINDS_PARAM, - Joiner.on(',').join(exportedKindsToLoad)))); - message += "BigQuery load task enqueued."; - } - logger.atInfo().log(message); - response.setPayload(message); - } -} diff --git a/core/src/main/java/google/registry/export/ExportRequestModule.java b/core/src/main/java/google/registry/export/ExportRequestModule.java deleted file mode 100644 index 1c47cac4d..000000000 --- a/core/src/main/java/google/registry/export/ExportRequestModule.java +++ /dev/null @@ -1,113 +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.export; - -import static google.registry.export.BigqueryPollJobAction.CHAINED_TASK_QUEUE_HEADER; -import static google.registry.export.BigqueryPollJobAction.JOB_ID_HEADER; -import static google.registry.export.BigqueryPollJobAction.PROJECT_ID_HEADER; -import static google.registry.export.CheckBackupAction.CHECK_BACKUP_KINDS_TO_LOAD_PARAM; -import static google.registry.export.CheckBackupAction.CHECK_BACKUP_NAME_PARAM; -import static google.registry.export.UpdateSnapshotViewAction.UPDATE_SNAPSHOT_DATASET_ID_PARAM; -import static google.registry.export.UpdateSnapshotViewAction.UPDATE_SNAPSHOT_KIND_PARAM; -import static google.registry.export.UpdateSnapshotViewAction.UPDATE_SNAPSHOT_TABLE_ID_PARAM; -import static google.registry.export.UpdateSnapshotViewAction.UPDATE_SNAPSHOT_VIEWNAME_PARAM; -import static google.registry.export.UploadDatastoreBackupAction.UPLOAD_BACKUP_FOLDER_PARAM; -import static google.registry.export.UploadDatastoreBackupAction.UPLOAD_BACKUP_ID_PARAM; -import static google.registry.export.UploadDatastoreBackupAction.UPLOAD_BACKUP_KINDS_PARAM; -import static google.registry.request.RequestParameters.extractRequiredHeader; -import static google.registry.request.RequestParameters.extractRequiredParameter; - -import dagger.Module; -import dagger.Provides; -import google.registry.request.Header; -import google.registry.request.Parameter; -import javax.servlet.http.HttpServletRequest; - -/** Dagger module for data export tasks. */ -@Module -public final class ExportRequestModule { - - @Provides - @Parameter(UPDATE_SNAPSHOT_DATASET_ID_PARAM) - static String provideUpdateSnapshotDatasetId(HttpServletRequest req) { - return extractRequiredParameter(req, UPDATE_SNAPSHOT_DATASET_ID_PARAM); - } - - @Provides - @Parameter(UPDATE_SNAPSHOT_TABLE_ID_PARAM) - static String provideUpdateSnapshotTableId(HttpServletRequest req) { - return extractRequiredParameter(req, UPDATE_SNAPSHOT_TABLE_ID_PARAM); - } - - @Provides - @Parameter(UPDATE_SNAPSHOT_KIND_PARAM) - static String provideUpdateSnapshotKind(HttpServletRequest req) { - return extractRequiredParameter(req, UPDATE_SNAPSHOT_KIND_PARAM); - } - - @Provides - @Parameter(UPDATE_SNAPSHOT_VIEWNAME_PARAM) - static String provideUpdateSnapshotViewName(HttpServletRequest req) { - return extractRequiredParameter(req, UPDATE_SNAPSHOT_VIEWNAME_PARAM); - } - - @Provides - @Parameter(UPLOAD_BACKUP_FOLDER_PARAM) - static String provideSnapshotUrlPrefix(HttpServletRequest req) { - return extractRequiredParameter(req, UPLOAD_BACKUP_FOLDER_PARAM); - } - - @Provides - @Parameter(UPLOAD_BACKUP_ID_PARAM) - static String provideLoadSnapshotId(HttpServletRequest req) { - return extractRequiredParameter(req, UPLOAD_BACKUP_ID_PARAM); - } - - @Provides - @Parameter(UPLOAD_BACKUP_KINDS_PARAM) - static String provideLoadSnapshotKinds(HttpServletRequest req) { - return extractRequiredParameter(req, UPLOAD_BACKUP_KINDS_PARAM); - } - - @Provides - @Parameter(CHECK_BACKUP_NAME_PARAM) - static String provideCheckSnapshotName(HttpServletRequest req) { - return extractRequiredParameter(req, CHECK_BACKUP_NAME_PARAM); - } - - @Provides - @Parameter(CHECK_BACKUP_KINDS_TO_LOAD_PARAM) - static String provideCheckSnapshotKindsToLoad(HttpServletRequest req) { - return extractRequiredParameter(req, CHECK_BACKUP_KINDS_TO_LOAD_PARAM); - } - - @Provides - @Header(CHAINED_TASK_QUEUE_HEADER) - static String provideChainedTaskQueue(HttpServletRequest req) { - return extractRequiredHeader(req, CHAINED_TASK_QUEUE_HEADER); - } - - @Provides - @Header(JOB_ID_HEADER) - static String provideJobId(HttpServletRequest req) { - return extractRequiredHeader(req, JOB_ID_HEADER); - } - - @Provides - @Header(PROJECT_ID_HEADER) - static String provideProjectId(HttpServletRequest req) { - return extractRequiredHeader(req, PROJECT_ID_HEADER); - } -} diff --git a/core/src/main/java/google/registry/export/UpdateSnapshotViewAction.java b/core/src/main/java/google/registry/export/UpdateSnapshotViewAction.java deleted file mode 100644 index 333d52764..000000000 --- a/core/src/main/java/google/registry/export/UpdateSnapshotViewAction.java +++ /dev/null @@ -1,146 +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.export; - -import static google.registry.request.Action.Method.POST; - -import com.google.api.client.googleapis.json.GoogleJsonResponseException; -import com.google.api.services.bigquery.Bigquery; -import com.google.api.services.bigquery.model.Table; -import com.google.api.services.bigquery.model.TableReference; -import com.google.api.services.bigquery.model.ViewDefinition; -import com.google.common.flogger.FluentLogger; -import google.registry.bigquery.CheckedBigquery; -import google.registry.config.RegistryConfig.Config; -import google.registry.model.annotations.DeleteAfterMigration; -import google.registry.request.Action; -import google.registry.request.HttpException.InternalServerErrorException; -import google.registry.request.Parameter; -import google.registry.request.auth.Auth; -import google.registry.util.SqlTemplate; -import java.io.IOException; -import javax.inject.Inject; - -/** Update a well-known view to point at a certain Datastore snapshot table in BigQuery. */ -@Action( - service = Action.Service.BACKEND, - path = UpdateSnapshotViewAction.PATH, - method = POST, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) -@DeleteAfterMigration -public class UpdateSnapshotViewAction implements Runnable { - - /** Headers for passing parameters into the servlet. */ - static final String UPDATE_SNAPSHOT_DATASET_ID_PARAM = "dataset"; - - static final String UPDATE_SNAPSHOT_TABLE_ID_PARAM = "table"; - static final String UPDATE_SNAPSHOT_KIND_PARAM = "kind"; - static final String UPDATE_SNAPSHOT_VIEWNAME_PARAM = "viewname"; - - /** Servlet-specific details needed for enqueuing tasks against itself. */ - // For now this queue is shared by the backup workflows started by BackupDatastoreAction. - // TODO(weiminyu): update queue name (snapshot->backup) after ExportSnapshot flow is removed. - static final String QUEUE = "export-snapshot-update-view"; // See queue.xml. - - static final String PATH = "/_dr/task/updateSnapshotView"; // See web.xml. - - private static final FluentLogger logger = FluentLogger.forEnclosingClass(); - - @Inject - @Parameter(UPDATE_SNAPSHOT_DATASET_ID_PARAM) - String datasetId; - - @Inject - @Parameter(UPDATE_SNAPSHOT_TABLE_ID_PARAM) - String tableId; - - @Inject - @Parameter(UPDATE_SNAPSHOT_KIND_PARAM) - String kindName; - - @Inject - @Parameter(UPDATE_SNAPSHOT_VIEWNAME_PARAM) - String viewName; - - @Inject - @Config("projectId") - String projectId; - - @Inject CheckedBigquery checkedBigquery; - - @Inject - UpdateSnapshotViewAction() {} - - @Override - public void run() { - try { - SqlTemplate sqlTemplate = - SqlTemplate.create( - "#standardSQL\nSELECT * FROM `%PROJECT%.%SOURCE_DATASET%.%SOURCE_TABLE%`"); - updateSnapshotView(datasetId, tableId, kindName, viewName, sqlTemplate); - } catch (Throwable e) { - throw new InternalServerErrorException( - String.format("Could not update snapshot view %s for table %s", viewName, tableId), e); - } - } - - private void updateSnapshotView( - String sourceDatasetId, - String sourceTableId, - String kindName, - String viewDataset, - SqlTemplate viewQueryTemplate) - throws IOException { - - Bigquery bigquery = checkedBigquery.ensureDataSetExists(projectId, viewDataset); - updateTable( - bigquery, - new Table() - .setTableReference( - new TableReference() - .setProjectId(projectId) - .setDatasetId(viewDataset) - .setTableId(kindName)) - .setView( - new ViewDefinition() - .setUseLegacySql(false) - .setQuery( - viewQueryTemplate - .put("PROJECT", projectId) - .put("SOURCE_DATASET", sourceDatasetId) - .put("SOURCE_TABLE", sourceTableId) - .build()))); - - logger.atInfo().log( - "Updated view [%s:%s.%s] to point at snapshot table [%s:%s.%s].", - projectId, viewDataset, kindName, projectId, sourceDatasetId, sourceTableId); - } - - private static void updateTable(Bigquery bigquery, Table table) throws IOException { - TableReference ref = table.getTableReference(); - try { - bigquery - .tables() - .update(ref.getProjectId(), ref.getDatasetId(), ref.getTableId(), table) - .execute(); - } catch (GoogleJsonResponseException e) { - if (e.getDetails() != null && e.getDetails().getCode() == 404) { - bigquery.tables().insert(ref.getProjectId(), ref.getDatasetId(), table).execute(); - } else { - logger.atWarning().withCause(e).log("UpdateSnapshotViewAction errored out."); - } - } - } -} diff --git a/core/src/main/java/google/registry/export/UploadDatastoreBackupAction.java b/core/src/main/java/google/registry/export/UploadDatastoreBackupAction.java deleted file mode 100644 index c42ef3756..000000000 --- a/core/src/main/java/google/registry/export/UploadDatastoreBackupAction.java +++ /dev/null @@ -1,215 +0,0 @@ -// Copyright 2018 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.export; - -import static com.google.common.base.MoreObjects.firstNonNull; -import static google.registry.request.Action.Method.POST; - -import com.google.api.services.bigquery.Bigquery; -import com.google.api.services.bigquery.model.Job; -import com.google.api.services.bigquery.model.JobConfiguration; -import com.google.api.services.bigquery.model.JobConfigurationLoad; -import com.google.api.services.bigquery.model.JobReference; -import com.google.api.services.bigquery.model.TableReference; -import com.google.cloud.tasks.v2.Task; -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Joiner; -import com.google.common.base.Splitter; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMultimap; -import com.google.common.flogger.FluentLogger; -import com.google.common.net.HttpHeaders; -import com.google.common.net.MediaType; -import com.google.protobuf.ByteString; -import com.google.protobuf.util.Timestamps; -import google.registry.bigquery.BigqueryUtils.SourceFormat; -import google.registry.bigquery.BigqueryUtils.WriteDisposition; -import google.registry.bigquery.CheckedBigquery; -import google.registry.config.RegistryConfig.Config; -import google.registry.model.annotations.DeleteAfterMigration; -import google.registry.request.Action; -import google.registry.request.Action.Service; -import google.registry.request.HttpException.BadRequestException; -import google.registry.request.HttpException.InternalServerErrorException; -import google.registry.request.Parameter; -import google.registry.request.auth.Auth; -import google.registry.util.Clock; -import google.registry.util.CloudTasksUtils; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.ObjectOutputStream; -import javax.inject.Inject; - -/** Action to load a Datastore backup from Google Cloud Storage into BigQuery. */ -@Action( - service = Action.Service.BACKEND, - path = UploadDatastoreBackupAction.PATH, - method = POST, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) -@DeleteAfterMigration -public class UploadDatastoreBackupAction implements Runnable { - - /** Parameter names for passing parameters into the servlet. */ - static final String UPLOAD_BACKUP_ID_PARAM = "id"; - - static final String UPLOAD_BACKUP_FOLDER_PARAM = "folder"; - static final String UPLOAD_BACKUP_KINDS_PARAM = "kinds"; - - static final String BACKUP_DATASET = "datastore_backups"; - - /** Servlet-specific details needed for enqueuing tasks against itself. */ - static final String QUEUE = "export-snapshot"; // See queue.xml. - - static final String LATEST_BACKUP_VIEW_NAME = "latest_datastore_export"; - - static final String PATH = "/_dr/task/uploadDatastoreBackup"; // See web.xml. - - private static final FluentLogger logger = FluentLogger.forEnclosingClass(); - - @Inject CheckedBigquery checkedBigquery; - @Inject CloudTasksUtils cloudTasksUtils; - @Inject Clock clock; - - @Inject @Config("projectId") String projectId; - - @Inject - @Parameter(UPLOAD_BACKUP_FOLDER_PARAM) - String backupFolderUrl; - - @Inject - @Parameter(UPLOAD_BACKUP_ID_PARAM) - String backupId; - - @Inject - @Parameter(UPLOAD_BACKUP_KINDS_PARAM) - String backupKinds; - - @Inject - UploadDatastoreBackupAction() {} - - @Override - public void run() { - try { - String message = uploadBackup(backupId, backupFolderUrl, Splitter.on(',').split(backupKinds)); - logger.atInfo().log("Loaded backup successfully: %s", message); - } catch (Throwable e) { - logger.atSevere().withCause(e).log("Error loading backup."); - if (e instanceof IllegalArgumentException) { - throw new BadRequestException("Error calling load backup: " + e.getMessage(), e); - } else { - throw new InternalServerErrorException( - "Error loading backup: " + firstNonNull(e.getMessage(), e.toString())); - } - } - } - - private String uploadBackup(String backupId, String backupFolderUrl, Iterable kinds) - throws IOException { - Bigquery bigquery = checkedBigquery.ensureDataSetExists(projectId, BACKUP_DATASET); - String loadMessage = - String.format("Loading Datastore backup %s from %s...", backupId, backupFolderUrl); - logger.atInfo().log(loadMessage); - - String sanitizedBackupId = sanitizeForBigquery(backupId); - StringBuilder builder = new StringBuilder(loadMessage + "\n"); - builder.append("Load jobs:\n"); - - for (String kindName : kinds) { - String jobId = String.format("load-backup-%s-%s", sanitizedBackupId, kindName); - JobReference jobRef = new JobReference().setProjectId(projectId).setJobId(jobId); - String sourceUri = getBackupInfoFileForKind(backupFolderUrl, kindName); - String tableId = String.format("%s_%s", sanitizedBackupId, kindName); - - // Launch the load job. - Job job = makeLoadJob(jobRef, sourceUri, tableId); - bigquery.jobs().insert(projectId, job).execute(); - - // Serialize the chainedTask into a byte array to put in the task payload. - ByteArrayOutputStream taskBytes = new ByteArrayOutputStream(); - new ObjectOutputStream(taskBytes) - .writeObject( - cloudTasksUtils.createPostTask( - UpdateSnapshotViewAction.PATH, - Service.BACKEND.toString(), - ImmutableMultimap.of( - UpdateSnapshotViewAction.UPDATE_SNAPSHOT_DATASET_ID_PARAM, - BACKUP_DATASET, - UpdateSnapshotViewAction.UPDATE_SNAPSHOT_TABLE_ID_PARAM, - tableId, - UpdateSnapshotViewAction.UPDATE_SNAPSHOT_KIND_PARAM, - kindName, - UpdateSnapshotViewAction.UPDATE_SNAPSHOT_VIEWNAME_PARAM, - LATEST_BACKUP_VIEW_NAME))); - - // Enqueues a task to poll for the success or failure of the referenced BigQuery job and to - // launch the provided task in the specified queue if the job succeeds. - cloudTasksUtils.enqueue( - BigqueryPollJobAction.QUEUE, - Task.newBuilder() - .setAppEngineHttpRequest( - cloudTasksUtils - .createPostTask(BigqueryPollJobAction.PATH, Service.BACKEND.toString(), null) - .getAppEngineHttpRequest() - .toBuilder() - .putHeaders(BigqueryPollJobAction.PROJECT_ID_HEADER, jobRef.getProjectId()) - .putHeaders(BigqueryPollJobAction.JOB_ID_HEADER, jobRef.getJobId()) - .putHeaders( - BigqueryPollJobAction.CHAINED_TASK_QUEUE_HEADER, - UpdateSnapshotViewAction.QUEUE) - // need to include CONTENT_TYPE in header when body is not empty - .putHeaders(HttpHeaders.CONTENT_TYPE, MediaType.FORM_DATA.toString()) - .setBody(ByteString.copyFrom(taskBytes.toByteArray())) - .build()) - .setScheduleTime( - Timestamps.fromMillis( - clock.nowUtc().plus(BigqueryPollJobAction.POLL_COUNTDOWN).getMillis())) - .build()); - - builder.append(String.format(" - %s:%s\n", projectId, jobId)); - logger.atInfo().log("Submitted load job %s:%s.", projectId, jobId); - } - return builder.toString(); - } - - private static String sanitizeForBigquery(String backupId) { - return backupId.replaceAll("[^a-zA-Z0-9_]", "_"); - } - - @VisibleForTesting - static String getBackupInfoFileForKind(String backupFolderUrl, String kindName) { - return Joiner.on('/') - .join( - backupFolderUrl, - "all_namespaces", - String.format("kind_%s", kindName), - String.format("all_namespaces_kind_%s.%s", kindName, "export_metadata")); - } - - private Job makeLoadJob(JobReference jobRef, String sourceUri, String tableId) { - TableReference tableReference = - new TableReference() - .setProjectId(jobRef.getProjectId()) - .setDatasetId(BACKUP_DATASET) - .setTableId(tableId); - return new Job() - .setJobReference(jobRef) - .setConfiguration(new JobConfiguration() - .setLoad(new JobConfigurationLoad() - .setWriteDisposition(WriteDisposition.WRITE_EMPTY.toString()) - .setSourceFormat(SourceFormat.DATASTORE_BACKUP.toString()) - .setSourceUris(ImmutableList.of(sourceUri)) - .setDestinationTable(tableReference))); - } -} diff --git a/core/src/main/java/google/registry/export/datastore/DatastoreAdmin.java b/core/src/main/java/google/registry/export/datastore/DatastoreAdmin.java deleted file mode 100644 index 1fcdfac36..000000000 --- a/core/src/main/java/google/registry/export/datastore/DatastoreAdmin.java +++ /dev/null @@ -1,279 +0,0 @@ -// Copyright 2018 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.export.datastore; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.api.client.googleapis.services.json.AbstractGoogleJsonClient; -import com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest; -import com.google.api.client.http.HttpRequestInitializer; -import com.google.api.client.http.HttpTransport; -import com.google.api.client.json.GenericJson; -import com.google.api.client.json.JsonFactory; -import com.google.api.client.util.Key; -import com.google.common.base.Strings; -import com.google.common.collect.ImmutableList; -import google.registry.model.annotations.DeleteAfterMigration; -import java.util.Collection; -import java.util.Optional; - -/** - * Java client to Cloud - * Datastore Admin REST API. - */ -@DeleteAfterMigration -public class DatastoreAdmin extends AbstractGoogleJsonClient { - - private static final String ROOT_URL = "https://datastore.googleapis.com/v1/"; - private static final String SERVICE_PATH = ""; - - // GCP project that this instance is associated with. - private final String projectId; - - protected DatastoreAdmin(Builder builder) { - super(builder); - this.projectId = checkNotNull(builder.projectId, "GCP projectId missing."); - } - - /** - * Returns an {@link Export} request that starts exporting all Cloud Datastore databases owned by - * the GCP project identified by {@link #projectId}. - * - *

Typical usage is: - * - *

-   *     {@code Export export = datastoreAdmin.export(parameters ...);}
-   *     {@code Operation operation = export.execute();}
-   *     {@code while (!operation.isSuccessful()) { ...}}
-   * 
- * - *

Please see the API - * specification of the export method for details. - * - *

The following undocumented behaviors with regard to {@code outputUrlPrefix} have been - * observed: - * - *

    - *
  • If outputUrlPrefix refers to a GCS bucket, exported data will be nested deeper in the - * bucket with a timestamped path. This is useful when periodical backups are desired - *
  • If outputUrlPrefix is a already a nested path in a GCS bucket, exported data will be put - * under this path. This means that a nested path is not reusable, since the export process - * by default would not overwrite existing files. - *
- * - * @param outputUrlPrefix the full resource URL of the external storage location - * @param kinds the datastore 'kinds' to be exported. If empty, all kinds will be exported - */ - public Export export(String outputUrlPrefix, Collection kinds) { - return new Export(new ExportRequest(outputUrlPrefix, kinds)); - } - - /** - * Imports the entire backup specified by {@code backupUrl} back to Cloud Datastore. - * - *

A successful backup restores deleted entities and reverts updates to existing entities since - * the backup time. However, it does not affect newly added entities. - */ - public Import importBackup(String backupUrl) { - return new Import(new ImportRequest(backupUrl, ImmutableList.of())); - } - - /** - * Imports the backup specified by {@code backupUrl} back to Cloud Datastore. Only entities whose - * types are included in {@code kinds} are imported. - * - * @see #importBackup(String) - */ - public Import importBackup(String backupUrl, Collection kinds) { - return new Import(new ImportRequest(backupUrl, kinds)); - } - - /** - * Returns a {@link Get} request that retrieves the details of an export or import {@link - * Operation}. - * - * @param operationName name of the {@code Operation} as returned by an export or import request - */ - public Get get(String operationName) { - return new Get(operationName); - } - - /** - * Returns a {@link ListOperations} request that retrieves all export or import {@link Operation - * operations} matching {@code filter}. - * - *

Sample usage: find all operations started after 2018-10-31 00:00:00 UTC and has stopped: - * - *

-   *     {@code String filter = "metadata.common.startTime>\"2018-10-31T0:0:0Z\" AND done=true";}
-   *     {@code List operations = datastoreAdmin.list(filter);}
-   * 
- * - *

Please refer to {@link Operation} for how to reference operation properties. - */ - public ListOperations list(String filter) { - checkArgument(!Strings.isNullOrEmpty(filter), "Filter must not be null or empty."); - return new ListOperations(Optional.of(filter)); - } - - /** - * Returns a {@link ListOperations} request that retrieves all export or import {@link Operation * - * operations}. - */ - public ListOperations listAll() { - return new ListOperations(Optional.empty()); - } - - /** Builder for {@link DatastoreAdmin}. */ - public static class Builder extends AbstractGoogleJsonClient.Builder { - - private String projectId; - - public Builder( - HttpTransport httpTransport, - JsonFactory jsonFactory, - HttpRequestInitializer httpRequestInitializer) { - super(httpTransport, jsonFactory, ROOT_URL, SERVICE_PATH, httpRequestInitializer, false); - } - - @Override - public Builder setApplicationName(String applicationName) { - return (Builder) super.setApplicationName(applicationName); - } - - /** Sets the GCP project ID of the Cloud Datastore databases being managed. */ - public Builder setProjectId(String projectId) { - this.projectId = projectId; - return this; - } - - @Override - public DatastoreAdmin build() { - return new DatastoreAdmin(this); - } - } - - /** A request to export Cloud Datastore databases. */ - public class Export extends DatastoreAdminRequest { - - Export(ExportRequest exportRequest) { - super( - DatastoreAdmin.this, - "POST", - "projects/{projectId}:export", - exportRequest, - Operation.class); - set("projectId", projectId); - } - } - - /** A request to restore an backup to a Cloud Datastore database. */ - public class Import extends DatastoreAdminRequest { - - Import(ImportRequest importRequest) { - super( - DatastoreAdmin.this, - "POST", - "projects/{projectId}:import", - importRequest, - Operation.class); - set("projectId", projectId); - } - } - - /** A request to retrieve details of an export or import operation. */ - public class Get extends DatastoreAdminRequest { - - Get(String operationName) { - super(DatastoreAdmin.this, "GET", operationName, null, Operation.class); - } - } - - /** A request to retrieve all export or import operations matching a given filter. */ - public class ListOperations extends DatastoreAdminRequest { - - ListOperations(Optional filter) { - super( - DatastoreAdmin.this, - "GET", - "projects/{projectId}/operations", - null, - Operation.OperationList.class); - set("projectId", projectId); - filter.ifPresent(f -> set("filter", f)); - } - } - - /** Base class of all DatastoreAdmin requests. */ - abstract static class DatastoreAdminRequest extends AbstractGoogleJsonClientRequest { - /** - * @param client Google JSON client - * @param requestMethod HTTP Method - * @param uriTemplate URI template for the path relative to the base URL. If it starts with a - * "/" the base path from the base URL will be stripped out. The URI template can also be a - * full URL. URI template expansion is done using {@link - * com.google.api.client.http.UriTemplate#expand(String, String, Object, boolean)} - * @param jsonContent POJO that can be serialized into JSON content or {@code null} for none - * @param responseClass response class to parse into - */ - protected DatastoreAdminRequest( - DatastoreAdmin client, - String requestMethod, - String uriTemplate, - Object jsonContent, - Class responseClass) { - super(client, requestMethod, uriTemplate, jsonContent, responseClass); - } - } - - /** - * Model object that describes the JSON content in an export request. - * - *

Please note that some properties defined in the API are excluded, e.g., {@code databaseId} - * (not supported by Cloud Datastore) and labels (not used by Domain Registry). - */ - @SuppressWarnings("unused") - static class ExportRequest extends GenericJson { - @Key private final String outputUrlPrefix; - @Key private final EntityFilter entityFilter; - - ExportRequest(String outputUrlPrefix, Collection kinds) { - checkNotNull(outputUrlPrefix, "outputUrlPrefix"); - checkArgument(!kinds.isEmpty(), "kinds must not be empty"); - this.outputUrlPrefix = outputUrlPrefix; - this.entityFilter = new EntityFilter(kinds); - } - } - - /** - * Model object that describes the JSON content in an export request. - * - *

Please note that some properties defined in the API are excluded, e.g., {@code databaseId} - * (not supported by Cloud Datastore) and labels (not used by Domain Registry). - */ - @SuppressWarnings("unused") - static class ImportRequest extends GenericJson { - @Key private final String inputUrl; - @Key private final EntityFilter entityFilter; - - ImportRequest(String inputUrl, Collection kinds) { - checkNotNull(inputUrl, "outputUrlPrefix"); - this.inputUrl = inputUrl; - this.entityFilter = new EntityFilter(kinds); - } - } -} diff --git a/core/src/main/java/google/registry/export/datastore/DatastoreAdminModule.java b/core/src/main/java/google/registry/export/datastore/DatastoreAdminModule.java deleted file mode 100644 index 070c24c81..000000000 --- a/core/src/main/java/google/registry/export/datastore/DatastoreAdminModule.java +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2018 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.export.datastore; - -import dagger.Module; -import dagger.Provides; -import google.registry.config.CredentialModule; -import google.registry.config.RegistryConfig; -import google.registry.model.annotations.DeleteAfterMigration; -import google.registry.util.GoogleCredentialsBundle; -import javax.inject.Singleton; - -/** Dagger module that configures provision of {@link DatastoreAdmin}. */ -@Module -@DeleteAfterMigration -public abstract class DatastoreAdminModule { - - @Singleton - @Provides - static DatastoreAdmin provideDatastoreAdmin( - @CredentialModule.DefaultCredential GoogleCredentialsBundle credentialsBundle, - @RegistryConfig.Config("projectId") String projectId) { - return new DatastoreAdmin.Builder( - credentialsBundle.getHttpTransport(), - credentialsBundle.getJsonFactory(), - credentialsBundle.getHttpRequestInitializer()) - .setApplicationName(projectId) - .setProjectId(projectId) - .build(); - } -} diff --git a/core/src/main/java/google/registry/export/datastore/EntityFilter.java b/core/src/main/java/google/registry/export/datastore/EntityFilter.java deleted file mode 100644 index ce7ce4e9d..000000000 --- a/core/src/main/java/google/registry/export/datastore/EntityFilter.java +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2018 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.export.datastore; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.api.client.json.GenericJson; -import com.google.api.client.util.Key; -import com.google.common.collect.ImmutableList; -import google.registry.model.annotations.DeleteAfterMigration; -import java.util.Collection; -import java.util.List; - -/** - * Model object that describes the Cloud Datastore 'kinds' to be exported or imported. The JSON form - * of this type is found in export/import requests and responses. - * - *

Please note that properties not used by Domain Registry are not included, e.g., {@code - * namespaceIds}. - */ -@DeleteAfterMigration -public class EntityFilter extends GenericJson { - - @Key private List kinds = ImmutableList.of(); - - /** For JSON deserialization. */ - public EntityFilter() {} - - EntityFilter(Collection kinds) { - checkNotNull(kinds, "kinds"); - this.kinds = ImmutableList.copyOf(kinds); - } - - List getKinds() { - return ImmutableList.copyOf(kinds); - } -} diff --git a/core/src/main/java/google/registry/export/datastore/Operation.java b/core/src/main/java/google/registry/export/datastore/Operation.java deleted file mode 100644 index cdf61e1a3..000000000 --- a/core/src/main/java/google/registry/export/datastore/Operation.java +++ /dev/null @@ -1,250 +0,0 @@ -// Copyright 2018 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.export.datastore; - -import static com.google.common.base.Preconditions.checkState; -import static com.google.common.base.Strings.isNullOrEmpty; - -import com.google.api.client.json.GenericJson; -import com.google.api.client.util.Key; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; -import google.registry.export.datastore.DatastoreAdmin.Get; -import google.registry.model.annotations.DeleteAfterMigration; -import google.registry.util.Clock; -import java.util.List; -import java.util.Optional; -import javax.annotation.Nullable; -import org.joda.time.DateTime; -import org.joda.time.Duration; - -/** - * Model object that describes the details of an export or import operation in Cloud Datastore. - * - *

{@link Operation} instances are parsed from the JSON payload in Datastore response messages. - */ -@DeleteAfterMigration -public class Operation extends GenericJson { - - private static final String STATE_SUCCESS = "SUCCESSFUL"; - private static final String STATE_PROCESSING = "PROCESSING"; - - @Key private String name; - @Key private Metadata metadata; - @Key private boolean done; - - /** For JSON deserialization. */ - public Operation() {} - - /** Returns the name of this operation, which may be used in a {@link Get} request. */ - public String getName() { - checkState(name != null, "Name must not be null."); - return name; - } - - public boolean isExport() { - return !isNullOrEmpty(getExportFolderUrl()); - } - - public boolean isImport() { - return !isNullOrEmpty(getMetadata().getInputUrl()); - } - - public boolean isDone() { - return done; - } - - private String getState() { - return getMetadata().getCommonMetadata().getState(); - } - - public boolean isSuccessful() { - return getState().equals(STATE_SUCCESS); - } - - public boolean isProcessing() { - return getState().equals(STATE_PROCESSING); - } - - /** - * Returns the elapsed time since starting if this operation is still running, or the total - * running time if this operation has completed. - */ - public Duration getRunningTime(Clock clock) { - return new Duration( - getStartTime(), getMetadata().getCommonMetadata().getEndTime().orElse(clock.nowUtc())); - } - - public DateTime getStartTime() { - return getMetadata().getCommonMetadata().getStartTime(); - } - - public ImmutableSet getKinds() { - return ImmutableSet.copyOf(getMetadata().getEntityFilter().getKinds()); - } - - /** - * Returns the URL to the GCS folder that holds the exported data. This folder is created by - * Datastore and is under the {@code outputUrlPrefix} set to {@linkplain - * DatastoreAdmin#export(String, java.util.Collection) the export request}. - * - * @throws IllegalStateException if this is not an export operation - */ - public String getExportFolderUrl() { - return getMetadata().getOutputUrlPrefix(); - } - - /** - * Returns the last segment of the {@linkplain #getExportFolderUrl() export folder URL} which can - * be used as unique identifier of this export operation. This is a better ID than the {@linkplain - * #getName() operation name}, which is opaque. - * - * @throws IllegalStateException if this is not an export operation - */ - public String getExportId() { - String exportFolderUrl = getExportFolderUrl(); - return exportFolderUrl.substring(exportFolderUrl.lastIndexOf('/') + 1); - } - - public String getProgress() { - StringBuilder result = new StringBuilder(); - Progress progress = getMetadata().getProgressBytes(); - if (progress != null) { - result.append( - String.format(" [%s/%s bytes]", progress.workCompleted, progress.workEstimated)); - } - progress = getMetadata().getProgressEntities(); - if (progress != null) { - result.append( - String.format(" [%s/%s entities]", progress.workCompleted, progress.workEstimated)); - } - if (result.length() == 0) { - return "Progress: N/A"; - } - return "Progress:" + result; - } - - private Metadata getMetadata() { - checkState(metadata != null, "Response metadata missing."); - return metadata; - } - - /** Models the common metadata properties of all operations. */ - public static class CommonMetadata extends GenericJson { - - @Key private String startTime; - @Key @Nullable private String endTime; - @Key private String operationType; - @Key private String state; - - public CommonMetadata() {} - - String getOperationType() { - checkState(!isNullOrEmpty(operationType), "operationType may not be null or empty"); - return operationType; - } - - String getState() { - checkState(!isNullOrEmpty(state), "state may not be null or empty"); - return state; - } - - DateTime getStartTime() { - checkState(startTime != null, "StartTime missing."); - return DateTime.parse(startTime); - } - - Optional getEndTime() { - return Optional.ofNullable(endTime).map(DateTime::parse); - } - } - - /** Models the metadata of a Cloud Datatore export or import operation. */ - public static class Metadata extends GenericJson { - @Key("common") - private CommonMetadata commonMetadata; - - @Key private Progress progressEntities; - @Key private Progress progressBytes; - @Key private EntityFilter entityFilter; - @Key private String inputUrl; - @Key private String outputUrlPrefix; - - public Metadata() {} - - CommonMetadata getCommonMetadata() { - checkState(commonMetadata != null, "CommonMetadata field is null."); - return commonMetadata; - } - - public Progress getProgressEntities() { - return progressEntities; - } - - public Progress getProgressBytes() { - return progressBytes; - } - - public EntityFilter getEntityFilter() { - return entityFilter; - } - - public String getInputUrl() { - return checkUrls().inputUrl; - } - - public String getOutputUrlPrefix() { - return checkUrls().outputUrlPrefix; - } - - Metadata checkUrls() { - checkState( - isNullOrEmpty(inputUrl) || isNullOrEmpty(outputUrlPrefix), - "inputUrl and outputUrlPrefix must not be both present"); - checkState( - !isNullOrEmpty(inputUrl) || !isNullOrEmpty(outputUrlPrefix), - "inputUrl and outputUrlPrefix must not be both missing"); - return this; - } - } - - /** Progress of an export or import operation. */ - public static class Progress extends GenericJson { - @Key private long workCompleted; - @Key private long workEstimated; - - public Progress() {} - - long getWorkCompleted() { - return workCompleted; - } - - public long getWorkEstimated() { - return workEstimated; - } - } - - /** List of {@link Operation Operations}. */ - public static class OperationList extends GenericJson { - @Key private List operations; - - /** For JSON deserialization. */ - public OperationList() {} - - ImmutableList toList() { - return ImmutableList.copyOf(operations); - } - } -} diff --git a/core/src/main/java/google/registry/export/sheet/SyncRegistrarsSheet.java b/core/src/main/java/google/registry/export/sheet/SyncRegistrarsSheet.java index 41ab32944..7c4aaf712 100644 --- a/core/src/main/java/google/registry/export/sheet/SyncRegistrarsSheet.java +++ b/core/src/main/java/google/registry/export/sheet/SyncRegistrarsSheet.java @@ -25,7 +25,6 @@ import static google.registry.model.registrar.RegistrarPoc.Type.MARKETING; import static google.registry.model.registrar.RegistrarPoc.Type.TECH; import static google.registry.model.registrar.RegistrarPoc.Type.WHOIS; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import static google.registry.util.DateTimeUtils.START_OF_TIME; import com.google.common.base.Joiner; @@ -63,8 +62,7 @@ class SyncRegistrarsSheet { */ boolean wereRegistrarsModified() { Optional cursor = - transactIfJpaTm( - () -> tm().loadByKeyIfPresent(Cursor.createGlobalVKey(SYNC_REGISTRAR_SHEET))); + tm().transact(() -> tm().loadByKeyIfPresent(Cursor.createGlobalVKey(SYNC_REGISTRAR_SHEET))); DateTime lastUpdateTime = !cursor.isPresent() ? START_OF_TIME : cursor.get().getCursorTime(); for (Registrar registrar : Registrar.loadAllCached()) { if (DateTimeUtils.isAtOrAfter(registrar.getLastUpdateTime(), lastUpdateTime)) { diff --git a/core/src/main/java/google/registry/flows/FlowUtils.java b/core/src/main/java/google/registry/flows/FlowUtils.java index 89c5bf7af..49aa308eb 100644 --- a/core/src/main/java/google/registry/flows/FlowUtils.java +++ b/core/src/main/java/google/registry/flows/FlowUtils.java @@ -53,7 +53,7 @@ public final class FlowUtils { } } - /** Persists the saves and deletes in an {@link EntityChanges} to Datastore. */ + /** Persists the saves and deletes in an {@link EntityChanges} to the DB. */ public static void persistEntityChanges(EntityChanges entityChanges) { tm().putAll(entityChanges.getSaves()); tm().delete(entityChanges.getDeletes()); diff --git a/core/src/main/java/google/registry/flows/ResourceFlowUtils.java b/core/src/main/java/google/registry/flows/ResourceFlowUtils.java index 4d24d21b3..5f8a5be60 100644 --- a/core/src/main/java/google/registry/flows/ResourceFlowUtils.java +++ b/core/src/main/java/google/registry/flows/ResourceFlowUtils.java @@ -19,7 +19,6 @@ import static google.registry.model.EppResourceUtils.isLinked; import static google.registry.model.EppResourceUtils.loadByForeignKey; import static google.registry.model.index.ForeignKeyIndex.loadAndGetKey; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Sets; @@ -176,7 +175,7 @@ public final class ResourceFlowUtils { throw new BadAuthInfoForResourceException(); } // Check the authInfo against the contact. - verifyAuthInfo(authInfo, transactIfJpaTm(() -> tm().loadByKey(foundContact.get()))); + verifyAuthInfo(authInfo, tm().transact(() -> tm().loadByKey(foundContact.get()))); } /** Check that the given {@link AuthInfo} is valid for the given contact. */ diff --git a/core/src/main/java/google/registry/flows/TransactionalFlow.java b/core/src/main/java/google/registry/flows/TransactionalFlow.java index f64f6a770..55be99f1a 100644 --- a/core/src/main/java/google/registry/flows/TransactionalFlow.java +++ b/core/src/main/java/google/registry/flows/TransactionalFlow.java @@ -17,7 +17,7 @@ package google.registry.flows; /** * Interface for a {@link Flow} that needs to be run transactionally. * - *

Any flow that mutates Datastore should implement this so that {@link FlowRunner} will know how - * to run it. + *

Any flow that mutates the DB should implement this so that {@link FlowRunner} will know how to + * run it. */ public interface TransactionalFlow extends Flow {} diff --git a/core/src/main/java/google/registry/flows/domain/DomainInfoFlow.java b/core/src/main/java/google/registry/flows/domain/DomainInfoFlow.java index 0ff20743c..7c2ca8c0c 100644 --- a/core/src/main/java/google/registry/flows/domain/DomainInfoFlow.java +++ b/core/src/main/java/google/registry/flows/domain/DomainInfoFlow.java @@ -22,7 +22,6 @@ import static google.registry.flows.domain.DomainFlowUtils.handleFeeRequest; import static google.registry.flows.domain.DomainFlowUtils.loadForeignKeyedDesignatedContacts; import static google.registry.model.EppResourceUtils.loadByForeignKey; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; @@ -110,7 +109,7 @@ public final class DomainInfoFlow implements Flow { .setRepoId(domain.getRepoId()) .setCurrentSponsorClientId(domain.getCurrentSponsorRegistrarId()) .setRegistrant( - transactIfJpaTm(() -> tm().loadByKey(domain.getRegistrant())).getContactId()); + tm().transact(() -> tm().loadByKey(domain.getRegistrant())).getContactId()); // If authInfo is non-null, then the caller is authorized to see the full information since we // will have already verified the authInfo is valid. if (registrarId.equals(domain.getCurrentSponsorRegistrarId()) || authInfo.isPresent()) { @@ -118,7 +117,7 @@ public final class DomainInfoFlow implements Flow { infoBuilder .setStatusValues(domain.getStatusValues()) .setContacts( - transactIfJpaTm(() -> loadForeignKeyedDesignatedContacts(domain.getContacts()))) + tm().transact(() -> loadForeignKeyedDesignatedContacts(domain.getContacts()))) .setNameservers(hostsRequest.requestDelegated() ? domain.loadNameserverHostNames() : null) .setSubordinateHosts( hostsRequest.requestSubordinate() ? domain.getSubordinateHosts() : null) diff --git a/core/src/main/java/google/registry/flows/domain/DomainTransferRejectFlow.java b/core/src/main/java/google/registry/flows/domain/DomainTransferRejectFlow.java index 9055bbdc2..43ecfa263 100644 --- a/core/src/main/java/google/registry/flows/domain/DomainTransferRejectFlow.java +++ b/core/src/main/java/google/registry/flows/domain/DomainTransferRejectFlow.java @@ -63,7 +63,7 @@ import org.joda.time.DateTime; * transfer is automatically approved. Within that window, this flow allows the losing client to * reject the transfer request. * - *

When the transfer was requested, poll messages and billing events were saved to Datastore with + *

When the transfer was requested, poll messages and billing events were saved to SQL with * timestamps such that they only would become active when the transfer period passed. In this flow, * those speculative objects are deleted. * diff --git a/core/src/main/java/google/registry/flows/domain/token/AllocationTokenFlowUtils.java b/core/src/main/java/google/registry/flows/domain/token/AllocationTokenFlowUtils.java index 31bd072a1..0da6c5378 100644 --- a/core/src/main/java/google/registry/flows/domain/token/AllocationTokenFlowUtils.java +++ b/core/src/main/java/google/registry/flows/domain/token/AllocationTokenFlowUtils.java @@ -16,7 +16,6 @@ package google.registry.flows.domain.token; import static com.google.common.base.Preconditions.checkArgument; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; @@ -161,7 +160,7 @@ public class AllocationTokenFlowUtils { throw new InvalidAllocationTokenException(); } Optional maybeTokenEntity = - transactIfJpaTm(() -> tm().loadByKeyIfPresent(VKey.create(AllocationToken.class, token))); + tm().transact(() -> tm().loadByKeyIfPresent(VKey.create(AllocationToken.class, token))); if (!maybeTokenEntity.isPresent()) { throw new InvalidAllocationTokenException(); } diff --git a/core/src/main/java/google/registry/flows/host/HostInfoFlow.java b/core/src/main/java/google/registry/flows/host/HostInfoFlow.java index ad0a962ea..95bc870b7 100644 --- a/core/src/main/java/google/registry/flows/host/HostInfoFlow.java +++ b/core/src/main/java/google/registry/flows/host/HostInfoFlow.java @@ -19,7 +19,6 @@ import static google.registry.flows.ResourceFlowUtils.loadAndVerifyExistence; import static google.registry.flows.host.HostFlowUtils.validateHostName; import static google.registry.model.EppResourceUtils.isLinked; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import com.google.common.collect.ImmutableSet; import google.registry.flows.EppException; @@ -78,8 +77,8 @@ public final class HostInfoFlow implements Flow { // there is no superordinate domain, the host's own values for these fields will be correct. if (host.isSubordinate()) { DomainBase superordinateDomain = - transactIfJpaTm( - () -> tm().loadByKey(host.getSuperordinateDomain()).cloneProjectedAtTime(now)); + tm().transact( + () -> tm().loadByKey(host.getSuperordinateDomain()).cloneProjectedAtTime(now)); hostInfoDataBuilder .setCurrentSponsorClientId(superordinateDomain.getCurrentSponsorRegistrarId()) .setLastTransferTime(host.computeLastTransferTime(superordinateDomain)); diff --git a/core/src/main/java/google/registry/flows/poll/PollFlowUtils.java b/core/src/main/java/google/registry/flows/poll/PollFlowUtils.java index 6ba489966..5f7064234 100644 --- a/core/src/main/java/google/registry/flows/poll/PollFlowUtils.java +++ b/core/src/main/java/google/registry/flows/poll/PollFlowUtils.java @@ -18,7 +18,6 @@ import static com.google.common.base.Preconditions.checkArgument; import static google.registry.persistence.transaction.QueryComposer.Comparator.EQ; import static google.registry.persistence.transaction.QueryComposer.Comparator.LTE; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import static google.registry.util.DateTimeUtils.isBeforeOrAt; import google.registry.model.poll.PollMessage; @@ -31,13 +30,13 @@ public final class PollFlowUtils { /** Returns the number of poll messages for the given registrar that are not in the future. */ public static int getPollMessageCount(String registrarId, DateTime now) { - return transactIfJpaTm(() -> createPollMessageQuery(registrarId, now).count()).intValue(); + return tm().transact(() -> createPollMessageQuery(registrarId, now).count()).intValue(); } /** Returns the first (by event time) poll message not in the future for this registrar. */ public static Optional getFirstPollMessage(String registrarId, DateTime now) { - return transactIfJpaTm( - () -> createPollMessageQuery(registrarId, now).orderBy("eventTime").first()); + return tm().transact( + () -> createPollMessageQuery(registrarId, now).orderBy("eventTime").first()); } /** diff --git a/core/src/main/java/google/registry/model/EppResourceUtils.java b/core/src/main/java/google/registry/model/EppResourceUtils.java index 9c040f68d..ca83b3b95 100644 --- a/core/src/main/java/google/registry/model/EppResourceUtils.java +++ b/core/src/main/java/google/registry/model/EppResourceUtils.java @@ -19,7 +19,6 @@ import static com.google.common.collect.ImmutableSet.toImmutableSet; import static google.registry.model.ofy.ObjectifyService.auditedOfy; import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import static google.registry.util.DateTimeUtils.START_OF_TIME; import static google.registry.util.DateTimeUtils.isAtOrAfter; import static google.registry.util.DateTimeUtils.isBeforeOrAt; @@ -163,7 +162,7 @@ public final class EppResourceUtils { T resource = useCache ? EppResource.loadCached(fki.getResourceKey()) - : transactIfJpaTm(() -> tm().loadByKeyIfPresent(fki.getResourceKey()).orElse(null)); + : tm().transact(() -> tm().loadByKeyIfPresent(fki.getResourceKey()).orElse(null)); if (resource == null || isAtOrAfter(now, resource.getDeletionTime())) { return Optional.empty(); } diff --git a/core/src/main/java/google/registry/model/UnsafeSerializable.java b/core/src/main/java/google/registry/model/UnsafeSerializable.java index e7d9f797d..978e0336d 100644 --- a/core/src/main/java/google/registry/model/UnsafeSerializable.java +++ b/core/src/main/java/google/registry/model/UnsafeSerializable.java @@ -21,7 +21,6 @@ import java.io.Serializable; * entities are made {@link Serializable} so that they can be passed between JVMs. The intended use * case is BEAM pipeline-based cross-database data validation between Datastore and Cloud SQL during * the migration. Note that only objects loaded from the SQL database need serialization support. - * Objects exported from Datastore can already be serialized as protocol buffers. * *

All entities implementing this interface take advantage of the fact that all Java collection * classes we use, either directly or indirectly, including those in Java libraries, Guava, diff --git a/core/src/main/java/google/registry/model/UpdateAutoTimestamp.java b/core/src/main/java/google/registry/model/UpdateAutoTimestamp.java index 5781409ad..73114d1f3 100644 --- a/core/src/main/java/google/registry/model/UpdateAutoTimestamp.java +++ b/core/src/main/java/google/registry/model/UpdateAutoTimestamp.java @@ -19,7 +19,6 @@ import static google.registry.util.DateTimeUtils.START_OF_TIME; import com.googlecode.objectify.annotation.Ignore; import com.googlecode.objectify.annotation.OnLoad; -import google.registry.model.translators.UpdateAutoTimestampTranslatorFactory; import google.registry.util.DateTimeUtils; import java.time.ZonedDateTime; import java.util.Optional; @@ -34,8 +33,6 @@ import org.joda.time.DateTime; /** * A timestamp that auto-updates on each save to Datastore/Cloud SQL. - * - * @see UpdateAutoTimestampTranslatorFactory */ @Embeddable public class UpdateAutoTimestamp extends ImmutableObject implements UnsafeSerializable { diff --git a/core/src/main/java/google/registry/model/billing/BillingEvent.java b/core/src/main/java/google/registry/model/billing/BillingEvent.java index e634d1359..cf08faaef 100644 --- a/core/src/main/java/google/registry/model/billing/BillingEvent.java +++ b/core/src/main/java/google/registry/model/billing/BillingEvent.java @@ -19,7 +19,6 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import static google.registry.util.CollectionUtils.forceEmptyToNull; import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy; import static google.registry.util.DateTimeUtils.END_OF_TIME; @@ -909,7 +908,7 @@ public abstract class BillingEvent extends ImmutableObject checkNotNull(instance.reason); checkNotNull(instance.eventRef); BillingEvent.OneTime billingEvent = - transactIfJpaTm(() -> tm().loadByKey(VKey.from(instance.eventRef))); + tm().transact(() -> tm().loadByKey(VKey.from(instance.eventRef))); checkArgument( Objects.equals(instance.cost.getCurrencyUnit(), billingEvent.cost.getCurrencyUnit()), "Referenced billing event is in a different currency"); diff --git a/core/src/main/java/google/registry/model/domain/DomainContent.java b/core/src/main/java/google/registry/model/domain/DomainContent.java index bb83fa171..8366c164c 100644 --- a/core/src/main/java/google/registry/model/domain/DomainContent.java +++ b/core/src/main/java/google/registry/model/domain/DomainContent.java @@ -24,7 +24,6 @@ import static com.google.common.collect.Sets.intersection; import static google.registry.model.EppResourceUtils.projectResourceOntoBuilderAtTime; import static google.registry.model.EppResourceUtils.setAutomaticTransferSuccessProperties; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import static google.registry.util.CollectionUtils.forceEmptyToNull; import static google.registry.util.CollectionUtils.nullToEmpty; import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy; @@ -604,11 +603,11 @@ public class DomainContent extends EppResource /** Loads and returns the fully qualified host names of all linked nameservers. */ public ImmutableSortedSet loadNameserverHostNames() { - return transactIfJpaTm( - () -> - tm().loadByKeys(getNameservers()).values().stream() - .map(HostResource::getHostName) - .collect(toImmutableSortedSet(Ordering.natural()))); + return tm().transact( + () -> + tm().loadByKeys(getNameservers()).values().stream() + .map(HostResource::getHostName) + .collect(toImmutableSortedSet(Ordering.natural()))); } /** A key to the registrant who registered this domain. */ diff --git a/core/src/main/java/google/registry/model/ofy/DatastoreTransactionManager.java b/core/src/main/java/google/registry/model/ofy/DatastoreTransactionManager.java deleted file mode 100644 index 94ab71043..000000000 --- a/core/src/main/java/google/registry/model/ofy/DatastoreTransactionManager.java +++ /dev/null @@ -1,509 +0,0 @@ -// Copyright 2019 The Nomulus Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package google.registry.model.ofy; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.collect.ImmutableList.toImmutableList; -import static com.google.common.collect.ImmutableMap.toImmutableMap; -import static com.google.common.collect.ImmutableSet.toImmutableSet; -import static google.registry.model.common.EntityGroupRoot.getCrossTldKey; -import static google.registry.model.ofy.ObjectifyService.auditedOfy; -import static google.registry.util.PreconditionsUtils.checkArgumentNotNull; - -import com.google.common.base.Functions; -import com.google.common.collect.ImmutableCollection; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; -import com.google.common.collect.Streams; -import com.googlecode.objectify.Key; -import com.googlecode.objectify.Result; -import com.googlecode.objectify.cmd.Query; -import google.registry.model.ImmutableObject; -import google.registry.model.annotations.DeleteAfterMigration; -import google.registry.model.annotations.InCrossTld; -import google.registry.model.contact.ContactHistory; -import google.registry.model.domain.DomainHistory; -import google.registry.model.host.HostHistory; -import google.registry.model.reporting.HistoryEntry; -import google.registry.persistence.VKey; -import google.registry.persistence.transaction.QueryComposer; -import google.registry.persistence.transaction.TransactionManager; -import java.util.List; -import java.util.NoSuchElementException; -import java.util.Optional; -import java.util.function.Supplier; -import java.util.stream.Stream; -import java.util.stream.StreamSupport; -import javax.annotation.Nullable; -import javax.persistence.NoResultException; -import javax.persistence.NonUniqueResultException; -import org.joda.time.DateTime; - -/** Datastore implementation of {@link TransactionManager}. */ -@DeleteAfterMigration -public class DatastoreTransactionManager implements TransactionManager { - - private Ofy injectedOfy; - - /** Constructs an instance. */ - public DatastoreTransactionManager(Ofy injectedOfy) { - this.injectedOfy = injectedOfy; - } - - private Ofy getOfy() { - return injectedOfy == null ? auditedOfy() : injectedOfy; - } - - @Override - public boolean inTransaction() { - return getOfy().inTransaction(); - } - - @Override - public void assertInTransaction() { - getOfy().assertInTransaction(); - } - - @Override - public T transact(Supplier work) { - return getOfy().transact(work); - } - - @Override - public void transact(Runnable work) { - getOfy().transact(work); - } - - @Override - public T transactNew(Supplier work) { - return getOfy().transactNew(work); - } - - @Override - public void transactNew(Runnable work) { - getOfy().transactNew(work); - } - - @Override - public R transactNewReadOnly(Supplier work) { - return getOfy().transactNewReadOnly(work); - } - - @Override - public void transactNewReadOnly(Runnable work) { - getOfy().transactNewReadOnly(work); - } - - @Override - public R doTransactionless(Supplier work) { - return getOfy().doTransactionless(work); - } - - @Override - public DateTime getTransactionTime() { - return getOfy().getTransactionTime(); - } - - @Override - public void insert(Object entity) { - put(entity); - } - - @Override - public void insertAll(ImmutableCollection entities) { - putAll(entities); - } - - @Override - public void insertAll(ImmutableObject... entities) { - putAll(entities); - } - - @Override - public void insertWithoutBackup(ImmutableObject entity) { - putWithoutBackup(entity); - } - - @Override - public void insertAllWithoutBackup(ImmutableCollection entities) { - putAllWithoutBackup(entities); - } - - @Override - public void put(Object entity) { - saveEntity(entity); - } - - @Override - public void putAll(ImmutableObject... entities) { - syncIfTransactionless( - getOfy().save().entities(toDatastoreEntities(ImmutableList.copyOf(entities)))); - } - - @Override - public void putAll(ImmutableCollection entities) { - syncIfTransactionless(getOfy().save().entities(toDatastoreEntities(entities))); - } - - @Override - public void putWithoutBackup(ImmutableObject entity) { - syncIfTransactionless(getOfy().saveWithoutBackup().entities(toDatastoreEntity(entity))); - } - - @Override - public void putAllWithoutBackup(ImmutableCollection entities) { - syncIfTransactionless(getOfy().saveWithoutBackup().entities(toDatastoreEntities(entities))); - } - - @Override - public void update(Object entity) { - put(entity); - } - - @Override - public void updateAll(ImmutableCollection entities) { - putAll(entities); - } - - @Override - public void updateAll(ImmutableObject... entities) { - updateAll(ImmutableList.copyOf(entities)); - } - - @Override - public void updateWithoutBackup(ImmutableObject entity) { - putWithoutBackup(entity); - } - - @Override - public void updateAllWithoutBackup(ImmutableCollection entities) { - putAllWithoutBackup(entities); - } - - @Override - public boolean exists(Object entity) { - return getOfy().load().key(Key.create(toDatastoreEntity(entity))).now() != null; - } - - @Override - public boolean exists(VKey key) { - return loadNullable(key) != null; - } - - // TODO: add tests for these methods. They currently have some degree of test coverage because - // they are used when retrieving the nameservers which require these, as they are now loaded by - // VKey instead of by ofy Key. But ideally, there should be one set of TransactionManager - // interface tests that are applied to both the datastore and SQL implementations. - @Override - public Optional loadByKeyIfPresent(VKey key) { - return Optional.ofNullable(loadNullable(key)); - } - - @Override - public ImmutableMap, T> loadByKeysIfPresent( - Iterable> keys) { - // Keep track of the Key -> VKey mapping so we can translate them back. - ImmutableMap, VKey> keyMap = - StreamSupport.stream(keys.spliterator(), false) - .distinct() - .collect(toImmutableMap(key -> (Key) key.getOfyKey(), Functions.identity())); - - return getOfy().load().keys(keyMap.keySet()).entrySet().stream() - .collect( - toImmutableMap( - entry -> keyMap.get(entry.getKey()), entry -> toSqlEntity(entry.getValue()))); - } - - @SuppressWarnings("unchecked") - @Override - public ImmutableList loadByEntitiesIfPresent(Iterable entities) { - return getOfy() - .load() - .entities(toDatastoreEntities(ImmutableList.copyOf(entities))) - .values() - .stream() - .map(DatastoreTransactionManager::toSqlEntity) - .map(entity -> (T) entity) - .collect(toImmutableList()); - } - - @Override - public T loadByKey(VKey key) { - T result = loadNullable(key); - if (result == null) { - throw new NoSuchElementException(key.toString()); - } - return result; - } - - @Override - public ImmutableMap, T> loadByKeys( - Iterable> keys) { - ImmutableMap, T> result = loadByKeysIfPresent(keys); - ImmutableSet> missingKeys = - Streams.stream(keys).filter(k -> !result.containsKey(k)).collect(toImmutableSet()); - if (!missingKeys.isEmpty()) { - // Ofy ignores nonexistent keys but the method contract specifies to throw if nonexistent - throw new NoSuchElementException( - String.format("Failed to load nonexistent entities for keys: %s", missingKeys)); - } - return result; - } - - @SuppressWarnings("unchecked") - @Override - public T loadByEntity(T entity) { - return (T) toSqlEntity(auditedOfy().load().entity(toDatastoreEntity(entity)).now()); - } - - @Override - public ImmutableList loadByEntities(Iterable entities) { - ImmutableList result = loadByEntitiesIfPresent(entities); - if (result.size() != Iterables.size(entities)) { - throw new NoSuchElementException( - String.format("Attempted to load entities, some of which are missing: %s", entities)); - } - return result; - } - - @Override - public ImmutableList loadAllOf(Class clazz) { - return ImmutableList.copyOf(getPossibleAncestorQuery(clazz)); - } - - @Override - public Stream loadAllOfStream(Class clazz) { - return Streams.stream(getPossibleAncestorQuery(clazz)); - } - - @Override - public Optional loadSingleton(Class clazz) { - List elements = getPossibleAncestorQuery(clazz).limit(2).list(); - checkArgument( - elements.size() <= 1, - "Expected at most one entity of type %s, found at least two", - clazz.getSimpleName()); - return elements.stream().findFirst(); - } - - @Override - public void delete(VKey key) { - syncIfTransactionless(getOfy().delete().key(key.getOfyKey())); - } - - @Override - public void delete(Iterable> vKeys) { - // We have to create a list to work around the wildcard capture issue here. - // See https://docs.oracle.com/javase/tutorial/java/generics/capture.html - ImmutableList> list = - StreamSupport.stream(vKeys.spliterator(), false) - .map(VKey::getOfyKey) - .collect(toImmutableList()); - syncIfTransactionless(getOfy().delete().keys(list)); - } - - @Override - public T delete(T entity) { - syncIfTransactionless(getOfy().delete().entity(toDatastoreEntity(entity))); - return entity; - } - - @Override - public void deleteWithoutBackup(VKey key) { - syncIfTransactionless(getOfy().deleteWithoutBackup().key(key.getOfyKey())); - } - - @Override - public void deleteWithoutBackup(Iterable> keys) { - syncIfTransactionless( - getOfy() - .deleteWithoutBackup() - .keys(Streams.stream(keys).map(VKey::getOfyKey).collect(toImmutableList()))); - } - - @Override - public void deleteWithoutBackup(Object entity) { - syncIfTransactionless(getOfy().deleteWithoutBackup().entity(toDatastoreEntity(entity))); - } - - @Override - public QueryComposer createQueryComposer(Class entity) { - return new DatastoreQueryComposerImpl<>(entity); - } - - @Override - public void clearSessionCache() { - getOfy().clearSessionCache(); - } - - @Override - public boolean isOfy() { - return true; - } - - /** - * Executes the given {@link Result} instance synchronously if not in a transaction. - * - *

The {@link Result} instance contains a task that will be executed by Objectify - * asynchronously. If it is in a transaction, we don't need to execute the task immediately - * because it is guaranteed to be done by the end of the transaction. However, if it is not in a - * transaction, we need to execute it in case the following code expects that happens before - * themselves. - */ - private void syncIfTransactionless(Result result) { - if (!inTransaction()) { - result.now(); - } - } - - /** - * The following three methods exist due to the migration to Cloud SQL. - * - *

In Cloud SQL, {@link HistoryEntry} objects are represented instead as {@link DomainHistory}, - * {@link ContactHistory}, and {@link HostHistory} objects. During the migration, we do not wish - * to change the Datastore schema so all of these objects are stored in Datastore as HistoryEntry - * objects. They are converted to/from the appropriate classes upon retrieval, and converted to - * HistoryEntry on save. See go/r3.0-history-objects for more details. - */ - private void saveEntity(Object entity) { - checkArgumentNotNull(entity, "entity must be specified"); - syncIfTransactionless(getOfy().save().entity(toDatastoreEntity(entity))); - } - - @Nullable - private T loadNullable(VKey key) { - return toSqlEntity(getOfy().load().key(key.getOfyKey()).now()); - } - - /** Converts a possible {@link HistoryEntry} child to a {@link HistoryEntry}. */ - private static Object toDatastoreEntity(@Nullable Object obj) { - if (obj instanceof HistoryEntry) { - return ((HistoryEntry) obj).asHistoryEntry(); - } - return obj; - } - - private static ImmutableList toDatastoreEntities(ImmutableCollection collection) { - return collection.stream() - .map(DatastoreTransactionManager::toDatastoreEntity) - .collect(toImmutableList()); - } - - /** - * Converts an object to the corresponding child {@link HistoryEntry} if necessary and possible. - * - *

This should be used when returning objects from Datastore to make sure they reflect the most - * recent type of the object in question. - */ - @SuppressWarnings("unchecked") - public static T toSqlEntity(@Nullable T obj) { - if (obj instanceof HistoryEntry) { - return (T) ((HistoryEntry) obj).toChildHistoryEntity(); - } - return obj; - } - - /** A query for returning any/all results of an object, with an ancestor if possible. */ - private Query getPossibleAncestorQuery(Class clazz) { - Query query = getOfy().load().type(clazz); - // If the entity is in the cross-TLD entity group, then we can take advantage of an ancestor - // query to give us strong transactional consistency. - if (clazz.isAnnotationPresent(InCrossTld.class)) { - query = query.ancestor(getCrossTldKey()); - } - return query; - } - - private static class DatastoreQueryComposerImpl extends QueryComposer { - - DatastoreQueryComposerImpl(Class entityClass) { - super(entityClass); - } - - Query buildQuery() { - checkOnlyOneInequalityField(); - Query result = auditedOfy().load().type(entityClass); - for (WhereClause pred : predicates) { - String comparatorString = pred.comparator.getDatastoreString(); - if (comparatorString == null) { - throw new UnsupportedOperationException( - String.format("The %s operation is not supported on Datastore.", pred.comparator)); - } - result = result.filter(pred.fieldName + comparatorString, pred.value); - } - - if (orderBy != null) { - result = result.order(orderBy); - } - - return result; - } - - @Override - public Optional first() { - return Optional.ofNullable(buildQuery().limit(1).first().now()); - } - - @Override - public T getSingleResult() { - List results = buildQuery().limit(2).list(); - if (results.size() == 0) { - // The exception text here is the same as what we get for JPA queries. - throw new NoResultException("No entity found for query"); - } else if (results.size() > 1) { - throw new NonUniqueResultException("More than one result found for getSingleResult query"); - } - return results.get(0); - } - - @Override - public Stream stream() { - return Streams.stream(buildQuery()); - } - - @Override - public long count() { - // Objectify provides a count() function, but unfortunately that doesn't work if there are - // more than 1000 (the default response page size?) entries in the result set. We also use - // chunkAll() here as it provides a nice performance boost. - // - // There is some information on this issue on SO, see: - // https://stackoverflow.com/questions/751124/how-does-one-get-a-count-of-rows-in-a-datastore-model-in-google-app-engine - return Iterables.size(buildQuery().chunkAll().keys()); - } - - @Override - public ImmutableList list() { - return ImmutableList.copyOf(buildQuery().list()); - } - - private void checkOnlyOneInequalityField() { - // Datastore inequality queries are limited to one property, see - // https://cloud.google.com/appengine/docs/standard/go111/datastore/query-restrictions#inequality_filters_are_limited_to_at_most_one_property - long numInequalityFields = - predicates.stream() - .filter(pred -> !pred.comparator.equals(Comparator.EQ)) - .map(pred -> pred.fieldName) - .distinct() - .count(); - checkArgument( - numInequalityFields <= 1, - "Datastore cannot handle inequality queries on multiple fields, we found %s fields.", - numInequalityFields); - } - } -} diff --git a/core/src/main/java/google/registry/model/ofy/ObjectifyService.java b/core/src/main/java/google/registry/model/ofy/ObjectifyService.java index 2958a3b60..62938f9f7 100644 --- a/core/src/main/java/google/registry/model/ofy/ObjectifyService.java +++ b/core/src/main/java/google/registry/model/ofy/ObjectifyService.java @@ -44,7 +44,6 @@ import google.registry.model.translators.DurationTranslatorFactory; import google.registry.model.translators.EppHistoryVKeyTranslatorFactory; import google.registry.model.translators.InetAddressTranslatorFactory; import google.registry.model.translators.ReadableInstantUtcTranslatorFactory; -import google.registry.model.translators.UpdateAutoTimestampTranslatorFactory; import google.registry.model.translators.VKeyTranslatorFactory; /** @@ -130,8 +129,7 @@ public class ObjectifyService { new InetAddressTranslatorFactory(), new MoneyStringTranslatorFactory(), new ReadableInstantUtcTranslatorFactory(), - new VKeyTranslatorFactory(), - new UpdateAutoTimestampTranslatorFactory())) { + new VKeyTranslatorFactory())) { factory().getTranslators().add(translatorFactory); } } diff --git a/core/src/main/java/google/registry/model/rde/RdeRevision.java b/core/src/main/java/google/registry/model/rde/RdeRevision.java index 0a2d06bd8..b9e417dc5 100644 --- a/core/src/main/java/google/registry/model/rde/RdeRevision.java +++ b/core/src/main/java/google/registry/model/rde/RdeRevision.java @@ -17,7 +17,6 @@ package google.registry.model.rde; import static com.google.common.base.Preconditions.checkArgument; import static google.registry.model.rde.RdeNamingUtils.makePartialName; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import com.google.common.base.VerifyException; import com.googlecode.objectify.Key; @@ -97,8 +96,8 @@ public final class RdeRevision extends BackupGroupRoot { RdeRevisionId sqlKey = RdeRevisionId.create(tld, date.toLocalDate(), mode); Key ofyKey = Key.create(RdeRevision.class, id); Optional revisionOptional = - transactIfJpaTm( - () -> tm().loadByKeyIfPresent(VKey.create(RdeRevision.class, sqlKey, ofyKey))); + tm().transact( + () -> tm().loadByKeyIfPresent(VKey.create(RdeRevision.class, sqlKey, ofyKey))); return revisionOptional.map(rdeRevision -> rdeRevision.revision + 1).orElse(0); } diff --git a/core/src/main/java/google/registry/model/registrar/Registrar.java b/core/src/main/java/google/registry/model/registrar/Registrar.java index 58bad4722..7a0680660 100644 --- a/core/src/main/java/google/registry/model/registrar/Registrar.java +++ b/core/src/main/java/google/registry/model/registrar/Registrar.java @@ -34,7 +34,6 @@ import static google.registry.model.ofy.ObjectifyService.auditedOfy; import static google.registry.model.tld.Registries.assertTldsExist; import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy; import static google.registry.util.CollectionUtils.nullToEmptyImmutableSortedCopy; import static google.registry.util.DateTimeUtils.START_OF_TIME; @@ -820,7 +819,7 @@ public class Registrar extends ImmutableObject .collect(toImmutableSet()); Set> missingTldKeys = Sets.difference( - newTldKeys, transactIfJpaTm(() -> tm().loadByKeysIfPresent(newTldKeys)).keySet()); + newTldKeys, tm().transact(() -> tm().loadByKeysIfPresent(newTldKeys)).keySet()); checkArgument(missingTldKeys.isEmpty(), "Trying to set nonexisting TLDs: %s", missingTldKeys); getInstance().allowedTlds = ImmutableSortedSet.copyOf(allowedTlds); return this; @@ -1023,7 +1022,7 @@ public class Registrar extends ImmutableObject /** Loads all registrar entities directly from Datastore. */ public static Iterable loadAll() { - return transactIfJpaTm(() -> tm().loadAllOf(Registrar.class)); + return tm().transact(() -> tm().loadAllOf(Registrar.class)); } /** Loads all registrar entities using an in-memory cache. */ @@ -1041,7 +1040,7 @@ public class Registrar extends ImmutableObject /** Loads and returns a registrar entity by its id directly from Datastore. */ public static Optional loadByRegistrarId(String registrarId) { checkArgument(!Strings.isNullOrEmpty(registrarId), "registrarId must be specified"); - return transactIfJpaTm(() -> tm().loadByKeyIfPresent(createVKey(registrarId))); + return tm().transact(() -> tm().loadByKeyIfPresent(createVKey(registrarId))); } /** diff --git a/core/src/main/java/google/registry/model/translators/UpdateAutoTimestampTranslatorFactory.java b/core/src/main/java/google/registry/model/translators/UpdateAutoTimestampTranslatorFactory.java deleted file mode 100644 index 6bd1636af..000000000 --- a/core/src/main/java/google/registry/model/translators/UpdateAutoTimestampTranslatorFactory.java +++ /dev/null @@ -1,55 +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.model.translators; - -import static google.registry.persistence.transaction.TransactionManagerFactory.ofyTm; -import static org.joda.time.DateTimeZone.UTC; - -import google.registry.model.UpdateAutoTimestamp; -import java.util.Date; -import org.joda.time.DateTime; - -/** Saves {@link UpdateAutoTimestamp} as the current time. */ -public class UpdateAutoTimestampTranslatorFactory - extends AbstractSimpleTranslatorFactory { - - public UpdateAutoTimestampTranslatorFactory() { - super(UpdateAutoTimestamp.class); - } - - @Override - SimpleTranslator createTranslator() { - return new SimpleTranslator() { - - /** - * Load an existing timestamp. It can be assumed to be non-null since if the field is null in - * Datastore then Objectify will skip this translator and directly load a null. - */ - @Override - public UpdateAutoTimestamp loadValue(Date datastoreValue) { - // Load an existing timestamp, or treat it as START_OF_TIME if none exists. - return UpdateAutoTimestamp.create(new DateTime(datastoreValue, UTC)); - } - - /** Save a timestamp, setting it to the current time. */ - @Override - public Date saveValue(UpdateAutoTimestamp pojoValue) { - return UpdateAutoTimestamp.autoUpdateEnabled() - ? ofyTm().getTransactionTime().toDate() - : pojoValue.getTimestamp().toDate(); - } - }; - } -} diff --git a/core/src/main/java/google/registry/module/backend/BackendComponent.java b/core/src/main/java/google/registry/module/backend/BackendComponent.java index 9bb3ce2d1..97319d770 100644 --- a/core/src/main/java/google/registry/module/backend/BackendComponent.java +++ b/core/src/main/java/google/registry/module/backend/BackendComponent.java @@ -24,7 +24,6 @@ import google.registry.config.CredentialModule; import google.registry.config.RegistryConfig.ConfigModule; import google.registry.dns.writer.VoidDnsWriterModule; import google.registry.export.DriveModule; -import google.registry.export.datastore.DatastoreAdminModule; import google.registry.export.sheet.SheetsServiceModule; import google.registry.flows.ServerTridProviderModule; import google.registry.flows.custom.CustomLogicFactoryModule; @@ -40,7 +39,6 @@ import google.registry.monitoring.whitebox.StackdriverModule; import google.registry.persistence.PersistenceModule; import google.registry.privileges.secretmanager.SecretManagerModule; import google.registry.rde.JSchModule; -import google.registry.request.Modules.DatastoreServiceModule; import google.registry.request.Modules.Jackson2Module; import google.registry.request.Modules.NetHttpTransportModule; import google.registry.request.Modules.UrlConnectionServiceModule; @@ -63,8 +61,6 @@ import javax.inject.Singleton; CloudTasksUtilsModule.class, CredentialModule.class, CustomLogicFactoryModule.class, - DatastoreAdminModule.class, - DatastoreServiceModule.class, DirectoryModule.class, DummyKeyringModule.class, DriveModule.class, diff --git a/core/src/main/java/google/registry/module/backend/BackendRequestComponent.java b/core/src/main/java/google/registry/module/backend/BackendRequestComponent.java index d8f103f72..6e544ea01 100644 --- a/core/src/main/java/google/registry/module/backend/BackendRequestComponent.java +++ b/core/src/main/java/google/registry/module/backend/BackendRequestComponent.java @@ -27,7 +27,6 @@ import google.registry.batch.ResaveEntityAction; import google.registry.batch.SendExpiringCertificateNotificationEmailAction; import google.registry.batch.WipeOutCloudSqlAction; import google.registry.batch.WipeOutContactHistoryPiiAction; -import google.registry.batch.WipeoutDatastoreAction; import google.registry.cron.CronModule; import google.registry.cron.TldFanoutAction; import google.registry.dns.DnsModule; @@ -38,16 +37,10 @@ import google.registry.dns.writer.VoidDnsWriterModule; import google.registry.dns.writer.clouddns.CloudDnsWriterModule; import google.registry.dns.writer.dnsupdate.DnsUpdateConfigModule; import google.registry.dns.writer.dnsupdate.DnsUpdateWriterModule; -import google.registry.export.BackupDatastoreAction; -import google.registry.export.BigqueryPollJobAction; -import google.registry.export.CheckBackupAction; import google.registry.export.ExportDomainListsAction; import google.registry.export.ExportPremiumTermsAction; -import google.registry.export.ExportRequestModule; import google.registry.export.ExportReservedTermsAction; import google.registry.export.SyncGroupMembersAction; -import google.registry.export.UpdateSnapshotViewAction; -import google.registry.export.UploadDatastoreBackupAction; import google.registry.export.sheet.SheetModule; import google.registry.export.sheet.SyncRegistrarsSheetAction; import google.registry.flows.FlowComponent; @@ -95,7 +88,6 @@ import google.registry.tmch.TmchSmdrlAction; DnsModule.class, DnsUpdateConfigModule.class, DnsUpdateWriterModule.class, - ExportRequestModule.class, IcannReportingModule.class, RdeModule.class, ReportingModule.class, @@ -108,14 +100,8 @@ import google.registry.tmch.TmchSmdrlAction; }) interface BackendRequestComponent { - BackupDatastoreAction backupDatastoreAction(); - - BigqueryPollJobAction bigqueryPollJobAction(); - BrdaCopyAction brdaCopyAction(); - CheckBackupAction checkBackupAction(); - CopyDetailReportsAction copyDetailReportAction(); DeleteExpiredDomainsAction deleteExpiredDomainsAction(); @@ -148,6 +134,8 @@ interface BackendRequestComponent { PublishDnsUpdatesAction publishDnsUpdatesAction(); + PublishInvoicesAction uploadInvoicesAction(); + PublishSpec11ReportAction publishSpec11ReportAction(); ReadDnsQueueAction readDnsQueueAction(); @@ -182,18 +170,10 @@ interface BackendRequestComponent { TmchSmdrlAction tmchSmdrlAction(); - UploadDatastoreBackupAction uploadDatastoreBackupAction(); - UpdateRegistrarRdapBaseUrlsAction updateRegistrarRdapBaseUrlsAction(); - UpdateSnapshotViewAction updateSnapshotViewAction(); - - PublishInvoicesAction uploadInvoicesAction(); - WipeOutCloudSqlAction wipeOutCloudSqlAction(); - WipeoutDatastoreAction wipeoutDatastoreAction(); - WipeOutContactHistoryPiiAction wipeOutContactHistoryPiiAction(); @Subcomponent.Builder diff --git a/core/src/main/java/google/registry/module/tools/ToolsComponent.java b/core/src/main/java/google/registry/module/tools/ToolsComponent.java index 0a5243787..11c58ad0d 100644 --- a/core/src/main/java/google/registry/module/tools/ToolsComponent.java +++ b/core/src/main/java/google/registry/module/tools/ToolsComponent.java @@ -33,7 +33,6 @@ import google.registry.keyring.kms.KmsModule; import google.registry.module.tools.ToolsRequestComponent.ToolsRequestComponentModule; import google.registry.monitoring.whitebox.StackdriverModule; import google.registry.privileges.secretmanager.SecretManagerModule; -import google.registry.request.Modules.DatastoreServiceModule; import google.registry.request.Modules.Jackson2Module; import google.registry.request.Modules.NetHttpTransportModule; import google.registry.request.Modules.UserServiceModule; @@ -50,7 +49,6 @@ import javax.inject.Singleton; CredentialModule.class, CustomLogicFactoryModule.class, CloudTasksUtilsModule.class, - DatastoreServiceModule.class, DirectoryModule.class, DummyKeyringModule.class, DriveModule.class, diff --git a/core/src/main/java/google/registry/persistence/transaction/TransactionManagerFactory.java b/core/src/main/java/google/registry/persistence/transaction/TransactionManagerFactory.java index 5f643ecc2..de0825e32 100644 --- a/core/src/main/java/google/registry/persistence/transaction/TransactionManagerFactory.java +++ b/core/src/main/java/google/registry/persistence/transaction/TransactionManagerFactory.java @@ -22,7 +22,6 @@ import com.google.appengine.api.utils.SystemProperty.Environment.Value; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Suppliers; import google.registry.config.RegistryEnvironment; -import google.registry.model.ofy.DatastoreTransactionManager; import google.registry.persistence.DaggerPersistenceComponent; import google.registry.tools.RegistryToolEnvironment; import google.registry.util.NonFinalForTesting; @@ -33,8 +32,6 @@ import java.util.function.Supplier; // TODO: Rename this to PersistenceFactory and move to persistence package. public final class TransactionManagerFactory { - private static final DatastoreTransactionManager ofyTm = createTransactionManager(); - /** Optional override to manually set the transaction manager per-test. */ private static Optional tmForTest = Optional.empty(); @@ -67,10 +64,6 @@ public final class TransactionManagerFactory { } } - private static DatastoreTransactionManager createTransactionManager() { - return new DatastoreTransactionManager(null); - } - /** * This function uses App Engine API to determine if the current runtime environment is App * Engine. @@ -87,8 +80,8 @@ public final class TransactionManagerFactory { /** * Returns the {@link TransactionManager} instance. * - *

Returns the {@link JpaTransactionManager} or {@link DatastoreTransactionManager} based on - * the migration schedule or the manually specified per-test transaction manager. + *

Returns the {@link JpaTransactionManager} or replica based on the possible manually + * specified per-test transaction manager. */ public static TransactionManager tm() { return tmForTest.orElseGet(TransactionManagerFactory::jpaTm); @@ -119,12 +112,6 @@ public final class TransactionManagerFactory { return tm().isOfy() ? tm() : replicaJpaTm(); } - /** Returns {@link DatastoreTransactionManager} instance. */ - @VisibleForTesting - public static DatastoreTransactionManager ofyTm() { - return ofyTm; - } - /** Sets the return of {@link #jpaTm()} to the given instance of {@link JpaTransactionManager}. */ public static void setJpaTm(Supplier jpaTmSupplier) { checkArgumentNotNull(jpaTmSupplier, "jpaTmSupplier"); diff --git a/core/src/main/java/google/registry/persistence/transaction/TransactionManagerUtil.java b/core/src/main/java/google/registry/persistence/transaction/TransactionManagerUtil.java deleted file mode 100644 index fc36a688c..000000000 --- a/core/src/main/java/google/registry/persistence/transaction/TransactionManagerUtil.java +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2020 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.persistence.transaction; - -import static google.registry.persistence.transaction.TransactionManagerFactory.tm; - -import google.registry.model.ofy.DatastoreTransactionManager; -import java.util.function.Supplier; - -/** Utility class that provides supplementary methods for {@link TransactionManager}. */ -public class TransactionManagerUtil { - - /** - * Returns the result of the given {@link Supplier}. - * - *

If {@link TransactionManagerFactory#tm()} returns a {@link JpaTransactionManager} instance, - * the {@link Supplier} is executed in a transaction. - */ - public static T transactIfJpaTm(Supplier supplier) { - if (tm() instanceof JpaTransactionManager) { - return tm().transact(supplier); - } else { - return supplier.get(); - } - } - - /** - * Executes the given {@link Runnable}. - * - *

If {@link TransactionManagerFactory#tm()} returns a {@link JpaTransactionManager} instance, - * the {@link Runnable} is executed in a transaction. - */ - public static void transactIfJpaTm(Runnable runnable) { - transactIfJpaTm( - () -> { - runnable.run(); - return null; - }); - } - - /** - * Executes the given {@link Runnable} if {@link TransactionManagerFactory#tm()} returns a {@link - * DatastoreTransactionManager} instance, otherwise does nothing. - */ - public static void ofyTmOrDoNothing(Runnable ofyRunnable) { - if (tm() instanceof DatastoreTransactionManager) { - ofyRunnable.run(); - } - } - - /** - * Returns the result from the given {@link Supplier} if {@link TransactionManagerFactory#tm()} - * returns a {@link DatastoreTransactionManager} instance, otherwise returns null. - */ - public static T ofyTmOrDoNothing(Supplier ofySupplier) { - if (tm() instanceof DatastoreTransactionManager) { - return ofySupplier.get(); - } else { - return null; - } - } - - private TransactionManagerUtil() {} -} diff --git a/core/src/main/java/google/registry/rdap/RdapEntityAction.java b/core/src/main/java/google/registry/rdap/RdapEntityAction.java index 94d753d64..bbb99faf0 100644 --- a/core/src/main/java/google/registry/rdap/RdapEntityAction.java +++ b/core/src/main/java/google/registry/rdap/RdapEntityAction.java @@ -15,7 +15,6 @@ package google.registry.rdap; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import static google.registry.rdap.RdapUtils.getRegistrarByIanaIdentifier; import static google.registry.rdap.RdapUtils.getRegistrarByName; import static google.registry.request.Action.Method.GET; @@ -72,7 +71,7 @@ public class RdapEntityAction extends RdapActionBase { if (ROID_PATTERN.matcher(pathSearchString).matches()) { VKey contactVKey = VKey.create(ContactResource.class, pathSearchString); Optional contactResource = - transactIfJpaTm(() -> tm().loadByKeyIfPresent(contactVKey)); + tm().transact(() -> tm().loadByKeyIfPresent(contactVKey)); // As per Andy Newton on the regext mailing list, contacts by themselves have no role, since // they are global, and might have different roles for different domains. if (contactResource.isPresent() && isAuthorized(contactResource.get())) { diff --git a/core/src/main/java/google/registry/rdap/RdapEntitySearchAction.java b/core/src/main/java/google/registry/rdap/RdapEntitySearchAction.java index a062375d2..521ec2c3d 100644 --- a/core/src/main/java/google/registry/rdap/RdapEntitySearchAction.java +++ b/core/src/main/java/google/registry/rdap/RdapEntitySearchAction.java @@ -17,7 +17,6 @@ package google.registry.rdap; import static com.google.common.collect.ImmutableList.toImmutableList; import static google.registry.persistence.transaction.TransactionManagerFactory.replicaJpaTm; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import static google.registry.rdap.RdapUtils.getRegistrarByIanaIdentifier; import static google.registry.request.Action.Method.GET; import static google.registry.request.Action.Method.HEAD; @@ -325,11 +324,11 @@ public class RdapEntitySearchAction extends RdapSearchActionBase { contactResourceList = ImmutableList.of(); } else { Optional contactResource = - transactIfJpaTm( - () -> - tm().loadByKeyIfPresent( - VKey.create( - ContactResource.class, partialStringQuery.getInitialString()))); + tm().transact( + () -> + tm().loadByKeyIfPresent( + VKey.create( + ContactResource.class, partialStringQuery.getInitialString()))); contactResourceList = (contactResource.isPresent() && shouldBeVisible(contactResource.get())) ? ImmutableList.of(contactResource.get()) diff --git a/core/src/main/java/google/registry/rdap/RdapJsonFormatter.java b/core/src/main/java/google/registry/rdap/RdapJsonFormatter.java index 12964eb2d..98c0d83d6 100644 --- a/core/src/main/java/google/registry/rdap/RdapJsonFormatter.java +++ b/core/src/main/java/google/registry/rdap/RdapJsonFormatter.java @@ -22,7 +22,6 @@ import static com.google.common.collect.ImmutableSetMultimap.toImmutableSetMulti import static google.registry.model.EppResourceUtils.isLinked; import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import static google.registry.rdap.RdapIcannStandardInformation.CONTACT_REDACTED_VALUE; import static google.registry.util.CollectionUtils.union; @@ -358,11 +357,11 @@ public class RdapJsonFormatter { // Kick off the database loads of the nameservers that we will need, so it can load // asynchronously while we load and process the contacts. ImmutableSet loadedHosts = - transactIfJpaTm( - () -> ImmutableSet.copyOf(tm().loadByKeys(domainBase.getNameservers()).values())); + tm().transact( + () -> ImmutableSet.copyOf(tm().loadByKeys(domainBase.getNameservers()).values())); // Load the registrant and other contacts and add them to the data. ImmutableMap, ContactResource> loadedContacts = - transactIfJpaTm(() -> tm().loadByKeysIfPresent(domainBase.getReferencedContacts())); + tm().transact(() -> tm().loadByKeysIfPresent(domainBase.getReferencedContacts())); // RDAP Response Profile 2.7.3, A domain MUST have the REGISTRANT, ADMIN, TECH roles and MAY // have others. We also add the BILLING. // @@ -441,12 +440,12 @@ public class RdapJsonFormatter { statuses.add(StatusValue.LINKED); } if (hostResource.isSubordinate() - && transactIfJpaTm( - () -> - tm().loadByKey(hostResource.getSuperordinateDomain()) - .cloneProjectedAtTime(getRequestTime()) - .getStatusValues() - .contains(StatusValue.PENDING_TRANSFER))) { + && tm().transact( + () -> + tm().loadByKey(hostResource.getSuperordinateDomain()) + .cloneProjectedAtTime(getRequestTime()) + .getStatusValues() + .contains(StatusValue.PENDING_TRANSFER))) { statuses.add(StatusValue.PENDING_TRANSFER); } builder diff --git a/core/src/main/java/google/registry/rde/DepositFragment.java b/core/src/main/java/google/registry/rde/DepositFragment.java index b9f6d9f56..4f5d78fdd 100644 --- a/core/src/main/java/google/registry/rde/DepositFragment.java +++ b/core/src/main/java/google/registry/rde/DepositFragment.java @@ -17,7 +17,7 @@ package google.registry.rde; import com.google.auto.value.AutoValue; import java.io.Serializable; -/** Container of Datastore resource marshalled by {@link RdeMarshaller}. */ +/** Container of RDE resource marshalled by {@link RdeMarshaller}. */ @AutoValue public abstract class DepositFragment implements Serializable { diff --git a/core/src/main/java/google/registry/rde/DomainBaseToXjcConverter.java b/core/src/main/java/google/registry/rde/DomainBaseToXjcConverter.java index 59f0ea6ab..b6f095d1c 100644 --- a/core/src/main/java/google/registry/rde/DomainBaseToXjcConverter.java +++ b/core/src/main/java/google/registry/rde/DomainBaseToXjcConverter.java @@ -16,7 +16,6 @@ package google.registry.rde; import static com.google.common.base.Preconditions.checkState; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import com.google.common.base.Ascii; import com.google.common.base.Strings; @@ -173,7 +172,7 @@ final class DomainBaseToXjcConverter { if (registrant == null) { logger.atWarning().log("Domain %s has no registrant contact.", domainName); } else { - ContactResource registrantContact = transactIfJpaTm(() -> tm().loadByKey(registrant)); + ContactResource registrantContact = tm().transact(() -> tm().loadByKey(registrant)); checkState( registrantContact != null, "Registrant contact %s on domain %s does not exist", @@ -305,7 +304,7 @@ final class DomainBaseToXjcConverter { "Contact key for type %s is null on domain %s", model.getType(), domainName); - ContactResource contact = transactIfJpaTm(() -> tm().loadByKey(model.getContactKey())); + ContactResource contact = tm().transact(() -> tm().loadByKey(model.getContactKey())); checkState( contact != null, "Contact %s on domain %s does not exist", diff --git a/core/src/main/java/google/registry/rde/EscrowTaskRunner.java b/core/src/main/java/google/registry/rde/EscrowTaskRunner.java index ad3ff4a93..a5dde92b0 100644 --- a/core/src/main/java/google/registry/rde/EscrowTaskRunner.java +++ b/core/src/main/java/google/registry/rde/EscrowTaskRunner.java @@ -15,7 +15,6 @@ package google.registry.rde; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import com.google.common.flogger.FluentLogger; import google.registry.model.common.Cursor; @@ -91,7 +90,7 @@ class EscrowTaskRunner { logger.atInfo().log("Performing escrow for TLD '%s'.", registry.getTld()); DateTime startOfToday = clock.nowUtc().withTimeAtStartOfDay(); DateTime nextRequiredRun = - transactIfJpaTm( + tm().transact( () -> tm().loadByKeyIfPresent(Cursor.createScopedVKey(cursorType, registry))) .map(Cursor::getCursorTime) .orElse(startOfToday); diff --git a/core/src/main/java/google/registry/rde/PendingDepositChecker.java b/core/src/main/java/google/registry/rde/PendingDepositChecker.java index 8fb0a4efe..9d0e710c7 100644 --- a/core/src/main/java/google/registry/rde/PendingDepositChecker.java +++ b/core/src/main/java/google/registry/rde/PendingDepositChecker.java @@ -16,7 +16,6 @@ package google.registry.rde; import static com.google.common.base.Preconditions.checkArgument; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import static google.registry.util.DateTimeUtils.isBeforeOrAt; import com.google.common.collect.ImmutableSetMultimap; @@ -91,8 +90,8 @@ public final class PendingDepositChecker { } // Avoid creating a transaction unless absolutely necessary. Optional maybeCursor = - transactIfJpaTm( - () -> tm().loadByKeyIfPresent(Cursor.createScopedVKey(cursorType, registry))); + tm().transact( + () -> tm().loadByKeyIfPresent(Cursor.createScopedVKey(cursorType, registry))); DateTime cursorValue = maybeCursor.map(Cursor::getCursorTime).orElse(startingPoint); if (isBeforeOrAt(cursorValue, now)) { DateTime watermark = diff --git a/core/src/main/java/google/registry/reporting/spec11/Spec11EmailUtils.java b/core/src/main/java/google/registry/reporting/spec11/Spec11EmailUtils.java index 4467b83da..3e3249556 100644 --- a/core/src/main/java/google/registry/reporting/spec11/Spec11EmailUtils.java +++ b/core/src/main/java/google/registry/reporting/spec11/Spec11EmailUtils.java @@ -19,7 +19,6 @@ import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.common.io.Resources.getResource; import static google.registry.persistence.transaction.QueryComposer.Comparator; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; @@ -131,21 +130,21 @@ public class Spec11EmailUtils { private RegistrarThreatMatches filterOutNonPublishedMatches( RegistrarThreatMatches registrarThreatMatches) { ImmutableList filteredMatches = - transactIfJpaTm( - () -> { - return registrarThreatMatches.threatMatches().stream() - .filter( - threatMatch -> - tm() - .createQueryComposer(DomainBase.class) - .where( - "fullyQualifiedDomainName", - Comparator.EQ, - threatMatch.fullyQualifiedDomainName()) - .stream() - .anyMatch(DomainBase::shouldPublishToDns)) - .collect(toImmutableList()); - }); + tm().transact( + () -> { + return registrarThreatMatches.threatMatches().stream() + .filter( + threatMatch -> + tm() + .createQueryComposer(DomainBase.class) + .where( + "fullyQualifiedDomainName", + Comparator.EQ, + threatMatch.fullyQualifiedDomainName()) + .stream() + .anyMatch(DomainBase::shouldPublishToDns)) + .collect(toImmutableList()); + }); return RegistrarThreatMatches.create(registrarThreatMatches.clientId(), filteredMatches); } diff --git a/core/src/main/java/google/registry/request/Modules.java b/core/src/main/java/google/registry/request/Modules.java index 5c84e8b22..ce959b94d 100644 --- a/core/src/main/java/google/registry/request/Modules.java +++ b/core/src/main/java/google/registry/request/Modules.java @@ -14,15 +14,12 @@ package google.registry.request; -import static com.google.appengine.api.datastore.DatastoreServiceFactory.getDatastoreService; - import com.google.api.client.extensions.appengine.http.UrlFetchTransport; import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport; import com.google.api.client.http.HttpTransport; import com.google.api.client.http.javanet.NetHttpTransport; import com.google.api.client.json.JsonFactory; import com.google.api.client.json.jackson2.JacksonFactory; -import com.google.appengine.api.datastore.DatastoreService; import com.google.appengine.api.urlfetch.URLFetchService; import com.google.appengine.api.urlfetch.URLFetchServiceFactory; import com.google.appengine.api.users.UserService; @@ -35,17 +32,6 @@ import javax.inject.Singleton; /** Dagger modules for App Engine services and other vendor classes. */ public final class Modules { - /** Dagger module for {@link DatastoreService}. */ - @Module - public static final class DatastoreServiceModule { - private static final DatastoreService datastoreService = getDatastoreService(); - - @Provides - static DatastoreService provideDatastoreService() { - return datastoreService; - } - } - /** Dagger module for {@link UrlConnectionService}. */ @Module public static final class UrlConnectionServiceModule { diff --git a/core/src/main/java/google/registry/request/auth/AuthenticatedRegistrarAccessor.java b/core/src/main/java/google/registry/request/auth/AuthenticatedRegistrarAccessor.java index 782889b34..882204b26 100644 --- a/core/src/main/java/google/registry/request/auth/AuthenticatedRegistrarAccessor.java +++ b/core/src/main/java/google/registry/request/auth/AuthenticatedRegistrarAccessor.java @@ -18,7 +18,6 @@ import static com.google.common.base.MoreObjects.toStringHelper; import static com.google.common.base.Preconditions.checkNotNull; import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import com.google.appengine.api.users.User; import com.google.common.annotations.VisibleForTesting; @@ -331,18 +330,18 @@ public class AuthenticatedRegistrarAccessor { // Admins have ADMIN access to all registrars, and also OWNER access to the registry registrar // and all non-REAL or non-live registrars. if (isAdmin) { - transactIfJpaTm( - () -> - tm().loadAllOf(Registrar.class) - .forEach( - registrar -> { - if (registrar.getType() != Registrar.Type.REAL - || !registrar.isLive() - || registrar.getRegistrarId().equals(registryAdminClientId)) { - builder.put(registrar.getRegistrarId(), Role.OWNER); - } - builder.put(registrar.getRegistrarId(), Role.ADMIN); - })); + tm().transact( + () -> + tm().loadAllOf(Registrar.class) + .forEach( + registrar -> { + if (registrar.getType() != Registrar.Type.REAL + || !registrar.isLive() + || registrar.getRegistrarId().equals(registryAdminClientId)) { + builder.put(registrar.getRegistrarId(), Role.OWNER); + } + builder.put(registrar.getRegistrarId(), Role.ADMIN); + })); } return builder.build(); diff --git a/core/src/main/java/google/registry/tmch/ClaimsListParser.java b/core/src/main/java/google/registry/tmch/ClaimsListParser.java index 72c036f91..0f71b585b 100644 --- a/core/src/main/java/google/registry/tmch/ClaimsListParser.java +++ b/core/src/main/java/google/registry/tmch/ClaimsListParser.java @@ -36,7 +36,7 @@ public class ClaimsListParser { /** * Converts the lines from the DNL CSV file into a {@link ClaimsList} object. * - *

Please note that this does not insert the object into Datastore. + *

Please note that this does not insert the object into the DB. */ public static ClaimsList parse(List lines) { ImmutableMap.Builder builder = new ImmutableMap.Builder<>(); diff --git a/core/src/main/java/google/registry/tmch/TmchData.java b/core/src/main/java/google/registry/tmch/TmchData.java index 7858ef1db..d4a5c96b3 100644 --- a/core/src/main/java/google/registry/tmch/TmchData.java +++ b/core/src/main/java/google/registry/tmch/TmchData.java @@ -24,7 +24,7 @@ import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.openpgp.bc.BcPGPPublicKeyRing; -/** Helper class for common data loaded from the jar and Datastore at runtime. */ +/** Helper class for common data loaded from the jar and SQL at runtime. */ public final class TmchData { private static final String BEGIN_ENCODED_SMD = "-----BEGIN ENCODED SMD-----"; diff --git a/core/src/main/java/google/registry/tools/CountDomainsCommand.java b/core/src/main/java/google/registry/tools/CountDomainsCommand.java index 45f50db33..560c9b2a6 100644 --- a/core/src/main/java/google/registry/tools/CountDomainsCommand.java +++ b/core/src/main/java/google/registry/tools/CountDomainsCommand.java @@ -17,7 +17,6 @@ package google.registry.tools; import static google.registry.model.tld.Registries.assertTldsExist; import static google.registry.persistence.transaction.QueryComposer.Comparator; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import com.beust.jcommander.Parameter; import com.beust.jcommander.Parameters; @@ -47,11 +46,11 @@ final class CountDomainsCommand implements CommandWithRemoteApi { } private long getCountForTld(String tld, DateTime now) { - return transactIfJpaTm( - () -> - tm().createQueryComposer(DomainBase.class) - .where("tld", Comparator.EQ, tld) - .where("deletionTime", Comparator.GT, now) - .count()); + return tm().transact( + () -> + tm().createQueryComposer(DomainBase.class) + .where("tld", Comparator.EQ, tld) + .where("deletionTime", Comparator.GT, now) + .count()); } } diff --git a/core/src/main/java/google/registry/tools/DeleteTldCommand.java b/core/src/main/java/google/registry/tools/DeleteTldCommand.java index a6c9ca96e..5d180b957 100644 --- a/core/src/main/java/google/registry/tools/DeleteTldCommand.java +++ b/core/src/main/java/google/registry/tools/DeleteTldCommand.java @@ -16,7 +16,6 @@ package google.registry.tools; import static com.google.common.base.Preconditions.checkState; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import com.beust.jcommander.Parameter; import com.beust.jcommander.Parameters; @@ -78,11 +77,11 @@ final class DeleteTldCommand extends ConfirmingCommand implements CommandWithRem } private boolean tldContainsDomains(String tld) { - return transactIfJpaTm( - () -> - tm().createQueryComposer(DomainBase.class) - .where("tld", Comparator.EQ, tld) - .first() - .isPresent()); + return tm().transact( + () -> + tm().createQueryComposer(DomainBase.class) + .where("tld", Comparator.EQ, tld) + .first() + .isPresent()); } } diff --git a/core/src/main/java/google/registry/tools/GenerateAllocationTokensCommand.java b/core/src/main/java/google/registry/tools/GenerateAllocationTokensCommand.java index d1d9cc909..fee463c9e 100644 --- a/core/src/main/java/google/registry/tools/GenerateAllocationTokensCommand.java +++ b/core/src/main/java/google/registry/tools/GenerateAllocationTokensCommand.java @@ -21,7 +21,6 @@ import static google.registry.model.billing.BillingEvent.RenewalPriceBehavior.DE import static google.registry.model.domain.token.AllocationToken.TokenType.SINGLE_USE; import static google.registry.model.domain.token.AllocationToken.TokenType.UNLIMITED_USE; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import static google.registry.util.CollectionUtils.nullToEmpty; import static google.registry.util.StringGenerator.DEFAULT_PASSWORD_LENGTH; import static java.nio.charset.StandardCharsets.UTF_8; @@ -278,7 +277,7 @@ class GenerateAllocationTokensCommand implements CommandWithRemoteApi { if (dryRun) { savedTokens = tokens; } else { - transactIfJpaTm(() -> tm().transact(() -> tm().putAll(tokens))); + tm().transact(() -> tm().transact(() -> tm().putAll(tokens))); savedTokens = tm().transact(() -> tm().loadByEntities(tokens)); } savedTokens.forEach( @@ -307,10 +306,10 @@ class GenerateAllocationTokensCommand implements CommandWithRemoteApi { candidates.stream() .map(input -> VKey.create(AllocationToken.class, input)) .collect(toImmutableSet()); - return transactIfJpaTm( - () -> - tm().loadByKeysIfPresent(existingTokenKeys).values().stream() - .map(AllocationToken::getToken) - .collect(toImmutableSet())); + return tm().transact( + () -> + tm().loadByKeysIfPresent(existingTokenKeys).values().stream() + .map(AllocationToken::getToken) + .collect(toImmutableSet())); } } diff --git a/core/src/main/java/google/registry/tools/GenerateDnsReportCommand.java b/core/src/main/java/google/registry/tools/GenerateDnsReportCommand.java index ace2497bb..63cfe4c97 100644 --- a/core/src/main/java/google/registry/tools/GenerateDnsReportCommand.java +++ b/core/src/main/java/google/registry/tools/GenerateDnsReportCommand.java @@ -18,7 +18,6 @@ import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.common.io.BaseEncoding.base16; import static google.registry.model.tld.Registries.assertTldExists; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import static google.registry.util.DateTimeUtils.isBeforeOrAt; import static java.nio.charset.StandardCharsets.US_ASCII; @@ -75,11 +74,11 @@ final class GenerateDnsReportCommand implements CommandWithRemoteApi { result.append("[\n"); List domains = - transactIfJpaTm( - () -> - tm().createQueryComposer(DomainBase.class) - .where("tld", Comparator.EQ, tld) - .list()); + tm().transact( + () -> + tm().createQueryComposer(DomainBase.class) + .where("tld", Comparator.EQ, tld) + .list()); for (DomainBase domain : domains) { // Skip deleted domains and domains that don't get published to DNS. if (isBeforeOrAt(domain.getDeletionTime(), now) || !domain.shouldPublishToDns()) { @@ -88,8 +87,7 @@ final class GenerateDnsReportCommand implements CommandWithRemoteApi { write(domain); } - Iterable nameservers = - transactIfJpaTm(() -> tm().loadAllOf(HostResource.class)); + Iterable nameservers = tm().transact(() -> tm().loadAllOf(HostResource.class)); for (HostResource nameserver : nameservers) { // Skip deleted hosts and external hosts. if (isBeforeOrAt(nameserver.getDeletionTime(), now) diff --git a/core/src/main/java/google/registry/tools/GenerateLordnCommand.java b/core/src/main/java/google/registry/tools/GenerateLordnCommand.java index 9522c4e39..200c9739d 100644 --- a/core/src/main/java/google/registry/tools/GenerateLordnCommand.java +++ b/core/src/main/java/google/registry/tools/GenerateLordnCommand.java @@ -16,7 +16,6 @@ package google.registry.tools; import static google.registry.persistence.transaction.QueryComposer.Comparator; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import static java.nio.charset.StandardCharsets.UTF_8; import com.beust.jcommander.Parameter; @@ -63,14 +62,14 @@ final class GenerateLordnCommand implements CommandWithRemoteApi { DateTime now = clock.nowUtc(); ImmutableList.Builder claimsCsv = new ImmutableList.Builder<>(); ImmutableList.Builder sunriseCsv = new ImmutableList.Builder<>(); - transactIfJpaTm( - () -> - tm() - .createQueryComposer(DomainBase.class) - .where("tld", Comparator.EQ, tld) - .orderBy("repoId") - .stream() - .forEach(domain -> processDomain(claimsCsv, sunriseCsv, domain))); + tm().transact( + () -> + tm() + .createQueryComposer(DomainBase.class) + .where("tld", Comparator.EQ, tld) + .orderBy("repoId") + .stream() + .forEach(domain -> processDomain(claimsCsv, sunriseCsv, domain))); ImmutableList claimsRows = claimsCsv.build(); ImmutableList claimsAll = new ImmutableList.Builder() diff --git a/core/src/main/java/google/registry/tools/GetOperationStatusCommand.java b/core/src/main/java/google/registry/tools/GetOperationStatusCommand.java deleted file mode 100644 index 9a7c9ee91..000000000 --- a/core/src/main/java/google/registry/tools/GetOperationStatusCommand.java +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2019 The Nomulus Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package google.registry.tools; - -import static com.google.common.base.Preconditions.checkArgument; - -import com.beust.jcommander.Parameter; -import com.beust.jcommander.Parameters; -import com.google.api.client.json.JsonFactory; -import com.google.api.client.json.jackson2.JacksonFactory; -import com.google.common.base.Strings; -import google.registry.export.datastore.DatastoreAdmin; -import java.util.List; -import javax.inject.Inject; - -/** Command to get the status of a Datastore operation, e.g., an import or export. */ -@Parameters(separators = " =", commandDescription = "Get status of a Datastore operation.") -public class GetOperationStatusCommand implements Command { - - private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance(); - - @Parameter(description = "Name of the Datastore import or export operation.") - private List mainParameters; - - @Inject DatastoreAdmin datastoreAdmin; - - @Override - public void run() throws Exception { - checkArgument( - mainParameters.size() == 1, "Requires exactly one argument: the name of the operation."); - String operationName = mainParameters.get(0); - checkArgument(!Strings.isNullOrEmpty(operationName), "Missing operation name."); - System.out.println(JSON_FACTORY.toPrettyString(datastoreAdmin.get(operationName).execute())); - } -} diff --git a/core/src/main/java/google/registry/tools/ImportDatastoreCommand.java b/core/src/main/java/google/registry/tools/ImportDatastoreCommand.java deleted file mode 100644 index 7e2e3d31f..000000000 --- a/core/src/main/java/google/registry/tools/ImportDatastoreCommand.java +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright 2019 The Nomulus Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package google.registry.tools; - -import static com.google.common.base.Preconditions.checkArgument; - -import com.beust.jcommander.Parameter; -import com.beust.jcommander.Parameters; -import com.google.common.base.Ascii; -import com.google.common.collect.ImmutableList; -import google.registry.export.datastore.DatastoreAdmin; -import google.registry.export.datastore.Operation; -import google.registry.model.annotations.DeleteAfterMigration; -import java.util.List; -import java.util.concurrent.TimeUnit; -import javax.annotation.Nullable; -import javax.inject.Inject; -import org.joda.time.Duration; - -/** - * Command that imports an earlier backup into Datastore. - * - *

This command is part of the Datastore restore process. Please refer to the playbook for - * the entire process. - */ -@DeleteAfterMigration -@Parameters(separators = " =", commandDescription = "Imports a backup of the Datastore.") -public class ImportDatastoreCommand extends ConfirmingCommand { - - @Parameter(names = "--backup_url", description = "URL to the backup on GCS to be imported.") - private String backupUrl; - - @Nullable - @Parameter( - names = "--kinds", - description = "List of entity kinds to be imported. Default is to import all.") - private List kinds = ImmutableList.of(); - - @Parameter( - names = "--async", - description = "If true, command will launch import operation and quit.") - private boolean async; - - @Parameter( - names = "--poll_interval", - description = - "Polling interval while waiting for completion synchronously. " - + "Value is in ISO-8601 format, e.g., PT10S for 10 seconds.") - private Duration pollingInterval = Duration.standardSeconds(30); - - @Parameter( - names = "--confirm_production_import", - description = "Set this option to 'PRODUCTION' to confirm import in production environment.") - private String confirmProductionImport = ""; - - @Inject DatastoreAdmin datastoreAdmin; - - @Override - protected String execute() throws Exception { - RegistryToolEnvironment currentEnvironment = RegistryToolEnvironment.get(); - - // Extra confirmation for running in production - checkArgument( - !currentEnvironment.equals(RegistryToolEnvironment.PRODUCTION) - || confirmProductionImport.equals("PRODUCTION"), - "The confirm_production_import option must be set when restoring production environment."); - - Operation importOperation = datastoreAdmin.importBackup(backupUrl, kinds).execute(); - - String statusCommand = - String.format( - "nomulus -e %s get_operation_status %s", - Ascii.toLowerCase(currentEnvironment.name()), importOperation.getName()); - - if (async) { - return String.format( - "Datastore import started. Run this command to check its progress:\n%s", - statusCommand); - } - - System.out.println( - "Waiting for import to complete.\n" - + "You may press Ctrl-C at any time, and use this command to check progress:\n" - + statusCommand); - while (importOperation.isProcessing()) { - waitInteractively(pollingInterval); - - importOperation = datastoreAdmin.get(importOperation.getName()).execute(); - - System.out.printf("\n%s\n", importOperation.getProgress()); - } - return String.format( - "\nDatastore import %s %s.", - importOperation.getName(), importOperation.isSuccessful() ? "succeeded" : "failed"); - } - - @Override - protected String prompt() { - return "\nThis command is an intermediate step in the Datastore restore process.\n\n" - + "Please read and understand the playbook entry at\n" - + " http://playbooks/domain_registry/procedures/backup-restore-testing.md\n" - + "before proceeding.\n"; - } - - /** Prints dots to console at regular interval while waiting. */ - private static void waitInteractively(Duration pollingInterval) throws InterruptedException { - int sleepSeconds = 2; - long iterations = (pollingInterval.getStandardSeconds() + sleepSeconds - 1) / sleepSeconds; - - for (int i = 0; i < iterations; i++) { - TimeUnit.SECONDS.sleep(sleepSeconds); - System.out.print('.'); - System.out.flush(); - } - } -} diff --git a/core/src/main/java/google/registry/tools/LevelDbLogReader.java b/core/src/main/java/google/registry/tools/LevelDbLogReader.java deleted file mode 100644 index 0244420d3..000000000 --- a/core/src/main/java/google/registry/tools/LevelDbLogReader.java +++ /dev/null @@ -1,221 +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.tools; - -import static com.google.common.base.Preconditions.checkState; - -import com.google.common.annotations.VisibleForTesting; -import com.google.common.collect.Lists; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.nio.ByteBuffer; -import java.nio.channels.Channels; -import java.nio.channels.ReadableByteChannel; -import java.nio.file.FileSystems; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.Optional; - -/** - * Iterator that incrementally parses binary data in LevelDb format into records. - * - *

The input source is automatically closed when all data have been read. - * - *

There are several other implementations of this, none of which appeared suitable for our use - * case: The original C++ implementation. - * com.google.appengine.api.files.RecordReadChannel - Exactly what we need but deprecated. The - * referenced replacement: The App Engine GCS - * Client - Does not appear to have any support for working with LevelDB. * - * - *

See log_format.md - */ -public final class LevelDbLogReader implements Iterator { - - @VisibleForTesting static final int BLOCK_SIZE = 32 * 1024; - @VisibleForTesting static final int HEADER_SIZE = 7; - - private final ByteArrayOutputStream recordContents = new ByteArrayOutputStream(); - private final LinkedList recordList = Lists.newLinkedList(); - - private final ByteBuffer byteBuffer = ByteBuffer.allocate(BLOCK_SIZE); - private final ReadableByteChannel channel; - - LevelDbLogReader(ReadableByteChannel channel) { - this.channel = channel; - } - - @Override - public boolean hasNext() { - while (recordList.isEmpty()) { - try { - Optional block = readFromChannel(); - if (!block.isPresent()) { - return false; - } - if (block.get().length != BLOCK_SIZE) { - throw new IllegalStateException("Data size is not multiple of " + BLOCK_SIZE); - } - processBlock(block.get()); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - return true; - } - - @Override - public byte[] next() { - checkState(hasNext(), "The next() method called on empty iterator."); - return recordList.removeFirst(); - } - - /** - * Returns the next {@link #BLOCK_SIZE} bytes from the input channel, or {@link Optional#empty()} - * if there is no more data. - */ - // TODO(weiminyu): use ByteBuffer directly. - private Optional readFromChannel() throws IOException { - while (channel.isOpen()) { - int bytesRead = channel.read(byteBuffer); - if (!byteBuffer.hasRemaining() || bytesRead < 0) { - byteBuffer.flip(); - if (!byteBuffer.hasRemaining()) { - channel.close(); - return Optional.empty(); - } - byte[] result = new byte[byteBuffer.remaining()]; - byteBuffer.get(result); - byteBuffer.clear(); - return Optional.of(result); - } - } - return Optional.empty(); - } - - /** Read a complete block, which must be exactly 32 KB. */ - private void processBlock(byte[] block) { - // Read records from the block until there is no longer enough space for a record (i.e. until - // we're at HEADER_SIZE - 1 bytes from the end of the block). - int i = 0; - while (i < BLOCK_SIZE - (HEADER_SIZE - 1)) { - RecordHeader recordHeader = readRecordHeader(block, i); - if (recordHeader.type == ChunkType.END) { - // A type of zero indicates that we've reached the padding zeroes at the end of the block. - break; - } - - // Copy the contents of the record into recordContents. - recordContents.write(block, i + HEADER_SIZE, recordHeader.size); - - // If this is the last (or only) chunk in the record, store the full contents into the List. - if (recordHeader.type == ChunkType.FULL || recordHeader.type == ChunkType.LAST) { - recordList.add(recordContents.toByteArray()); - recordContents.reset(); - } - - i += recordHeader.size + HEADER_SIZE; - } - } - - /** - * Gets a byte from "block" as an unsigned value. - * - *

Java bytes are signed, which doesn't work very well for our bit-shifting operations. - */ - private int getUnsignedByte(byte[] block, int pos) { - return block[pos] & 0xFF; - } - - /** Reads the 7 byte record header. */ - private RecordHeader readRecordHeader(byte[] block, int pos) { - // Read checksum (4 bytes, LE). - int checksum = - getUnsignedByte(block, pos) - | (getUnsignedByte(block, pos + 1) << 8) - | (getUnsignedByte(block, pos + 2) << 16) - | (getUnsignedByte(block, pos + 3) << 24); - // Read size (2 bytes, LE). - int size = getUnsignedByte(block, pos + 4) | (getUnsignedByte(block, pos + 5) << 8); - // Read type (1 byte). - int type = getUnsignedByte(block, pos + 6); - - return new RecordHeader(checksum, size, ChunkType.fromCode(type)); - } - - /** Returns a {@link LevelDbLogReader} over a {@link ReadableByteChannel}. */ - public static LevelDbLogReader from(ReadableByteChannel channel) { - return new LevelDbLogReader(channel); - } - - /** Returns a {@link LevelDbLogReader} over an {@link InputStream}. */ - public static LevelDbLogReader from(InputStream source) { - return new LevelDbLogReader(Channels.newChannel(source)); - } - - /** Returns a {@link LevelDbLogReader} over a file specified by {@link Path}. */ - public static LevelDbLogReader from(Path path) throws IOException { - return from(Files.newInputStream(path)); - } - - /** Returns a {@link LevelDbLogReader} over a file specified by {@code filename}. */ - public static LevelDbLogReader from(String filename) throws IOException { - return from(FileSystems.getDefault().getPath(filename)); - } - - /** Aggregates the fields in a record header. */ - private static final class RecordHeader { - final int checksum; - final int size; - final ChunkType type; - - public RecordHeader(int checksum, int size, ChunkType type) { - this.checksum = checksum; - this.size = size; - this.type = type; - } - } - - @VisibleForTesting - enum ChunkType { - // Warning: these values must map to their array indices. If this relationship is broken, - // you'll need to change fromCode() to not simply index into values(). - END(0), - FULL(1), - FIRST(2), - MIDDLE(3), - LAST(4); - - private final int code; - - ChunkType(int code) { - this.code = code; - } - - int getCode() { - return code; - } - - /** Construct a record type from the numeric record type code. */ - static ChunkType fromCode(int code) { - return values()[code]; - } - } -} diff --git a/core/src/main/java/google/registry/tools/ListCursorsCommand.java b/core/src/main/java/google/registry/tools/ListCursorsCommand.java index 0528771db..1b0ea6154 100644 --- a/core/src/main/java/google/registry/tools/ListCursorsCommand.java +++ b/core/src/main/java/google/registry/tools/ListCursorsCommand.java @@ -16,7 +16,6 @@ package google.registry.tools; import static com.google.common.collect.ImmutableMap.toImmutableMap; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import com.beust.jcommander.Parameter; import com.beust.jcommander.Parameters; @@ -59,7 +58,7 @@ final class ListCursorsCommand implements CommandWithRemoteApi { .filter(r -> !filterEscrowEnabled || r.getEscrowEnabled()) .collect(toImmutableMap(r -> r, r -> Cursor.createScopedVKey(cursorType, r))); ImmutableMap, Cursor> cursors = - transactIfJpaTm(() -> tm().loadByKeysIfPresent(registries.values())); + tm().transact(() -> tm().loadByKeysIfPresent(registries.values())); if (!registries.isEmpty()) { String header = String.format(OUTPUT_FMT, "TLD", "Cursor Time", "Last Update Time"); System.out.printf("%s\n%s\n", header, Strings.repeat("-", header.length())); diff --git a/core/src/main/java/google/registry/tools/ListDatastoreOperationsCommand.java b/core/src/main/java/google/registry/tools/ListDatastoreOperationsCommand.java deleted file mode 100644 index dca5fef9c..000000000 --- a/core/src/main/java/google/registry/tools/ListDatastoreOperationsCommand.java +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright 2019 The Nomulus Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package google.registry.tools; - -import com.beust.jcommander.Parameter; -import com.beust.jcommander.Parameters; -import com.google.api.client.json.JsonFactory; -import com.google.api.client.json.jackson2.JacksonFactory; -import google.registry.export.datastore.DatastoreAdmin; -import google.registry.export.datastore.DatastoreAdmin.ListOperations; -import google.registry.model.annotations.DeleteAfterMigration; -import google.registry.util.Clock; -import java.util.Optional; -import javax.annotation.Nullable; -import javax.inject.Inject; -import org.joda.time.DateTime; -import org.joda.time.Duration; - -/** Command that lists Datastore operations. */ -@DeleteAfterMigration -@Parameters(separators = " =", commandDescription = "List Datastore operations.") -public class ListDatastoreOperationsCommand implements Command { - - private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance(); - - @Nullable - @Parameter( - names = "--start_time_filter", - description = - "Duration relative to current time, used to filter operations by start time. " - + "Value is in ISO-8601 format, e.g., PT10S for 10 seconds.") - private Duration startTimeFilter; - - @Inject DatastoreAdmin datastoreAdmin; - @Inject Clock clock; - - @Override - public void run() throws Exception { - ListOperations listOperations = - getQueryFilter().map(datastoreAdmin::list).orElseGet(() -> datastoreAdmin.listAll()); - System.out.println(JSON_FACTORY.toPrettyString(listOperations.execute())); - } - - private Optional getQueryFilter() { - if (startTimeFilter == null) { - return Optional.empty(); - } - - DateTime earliestStartingTime = clock.nowUtc().minus(startTimeFilter); - return Optional.of( - String.format("metadata.common.startTime>\"%s\"", earliestStartingTime)); - } -} diff --git a/core/src/main/java/google/registry/tools/LoadSnapshotCommand.java b/core/src/main/java/google/registry/tools/LoadSnapshotCommand.java deleted file mode 100644 index a5d09d088..000000000 --- a/core/src/main/java/google/registry/tools/LoadSnapshotCommand.java +++ /dev/null @@ -1,131 +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.tools; - -import static com.google.common.util.concurrent.Futures.addCallback; -import static com.google.common.util.concurrent.MoreExecutors.directExecutor; - -import com.beust.jcommander.Parameter; -import com.beust.jcommander.Parameters; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.util.concurrent.FutureCallback; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; -import google.registry.bigquery.BigqueryUtils.SourceFormat; -import google.registry.export.AnnotatedEntities; -import google.registry.model.annotations.DeleteAfterMigration; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Objects; - -/** Command to load Datastore snapshots into Bigquery. */ -@DeleteAfterMigration -@Parameters(separators = " =", commandDescription = "Load Datastore snapshot into Bigquery") -final class LoadSnapshotCommand extends BigqueryCommand { - - @Parameter( - names = "--snapshot", - description = "Common filename prefix of the specific snapshot series to import.") - private String snapshotPrefix = null; - - @Parameter( - names = "--gcs_bucket", - description = "Name of the GCS bucket from which to import Datastore snapshots.") - private String snapshotGcsBucket = "domain-registry/snapshots/testing"; - - @Parameter( - names = "--kinds", - description = "List of Datastore kinds for which to import snapshot data.") - private List kindNames = new ArrayList<>(AnnotatedEntities.getReportingKinds()); - - /** Runs the main snapshot import logic. */ - @Override - public void runWithBigquery() throws Exception { - kindNames.removeAll(ImmutableList.of("")); // Filter out any empty kind names. - if (snapshotPrefix == null || kindNames.isEmpty()) { - System.err.println("Nothing to import; specify --snapshot and at least one kind."); - return; - } - Map> loadJobs = loadSnapshotKinds(kindNames); - waitForLoadJobs(loadJobs); - } - - /** - * Starts load jobs for the given snapshot kinds, and returns a map of kind name to - * ListenableFuture representing the result of the load job for that kind. - */ - private Map> loadSnapshotKinds(List kindNames) { - ImmutableMap.Builder> builder = new ImmutableMap.Builder<>(); - for (String kind : kindNames) { - String filename = String.format( - "gs://%s/%s.%s.backup_info", snapshotGcsBucket, snapshotPrefix, kind); - builder.put(kind, loadSnapshotFile(filename, kind)); - System.err.println("Started load job for kind: " + kind); - } - return builder.build(); - } - - /** Starts a load job for the specified kind name, sourcing data from the given GCS file. */ - private ListenableFuture loadSnapshotFile(String filename, String kindName) { - return bigquery() - .startLoad( - bigquery() - .buildDestinationTable(kindName) - .description("Datastore snapshot import for " + kindName + ".") - .build(), - SourceFormat.DATASTORE_BACKUP, - ImmutableList.of(filename)); - } - - /** - * Block on the completion of the load jobs in the provided map, printing out information on - * each job's success or failure. - */ - private void waitForLoadJobs(Map> loadJobs) throws Exception { - final long startTime = System.currentTimeMillis(); - System.err.println("Waiting for load jobs..."); - // Add callbacks to each load job that print information on successful completion or failure. - for (final String jobId : loadJobs.keySet()) { - final String jobName = "load-" + jobId; - addCallback( - loadJobs.get(jobId), - new FutureCallback() { - private double elapsedSeconds() { - return (System.currentTimeMillis() - startTime) / 1000.0; - } - - @Override - public void onSuccess(Object unused) { - System.err.printf("Job %s succeeded (%.3fs)\n", jobName, elapsedSeconds()); - } - - @Override - public void onFailure(Throwable error) { - System.err.printf( - "Job %s failed (%.3fs): %s\n", jobName, elapsedSeconds(), error.getMessage()); - } - }, - directExecutor()); - } - // Block on the completion of all the load jobs. - List results = Futures.successfulAsList(loadJobs.values()).get(); - int numSucceeded = (int) results.stream().filter(Objects::nonNull).count(); - System.err.printf( - "All load jobs have terminated: %d/%d successful.\n", - numSucceeded, loadJobs.size()); - } -} diff --git a/core/src/main/java/google/registry/tools/RegistryCli.java b/core/src/main/java/google/registry/tools/RegistryCli.java index 00668026a..127a77a84 100644 --- a/core/src/main/java/google/registry/tools/RegistryCli.java +++ b/core/src/main/java/google/registry/tools/RegistryCli.java @@ -15,7 +15,6 @@ package google.registry.tools; import static com.google.common.base.Preconditions.checkState; -import static google.registry.persistence.transaction.TransactionManagerFactory.ofyTm; import static google.registry.tools.Injector.injectReflectively; import static java.nio.charset.StandardCharsets.UTF_8; @@ -264,7 +263,7 @@ final class RegistryCli implements AutoCloseable, CommandRunner { ObjectifyService.initOfy(); // Make sure we start the command with a clean cache, so that any previous command won't // interfere with this one. - ofyTm().clearSessionCache(); + ObjectifyService.ofy().clearSessionCache(); // Enable Cloud SQL for command that needs remote API as they will very likely use // Cloud SQL after the database migration. Note that the DB password is stored in Datastore diff --git a/core/src/main/java/google/registry/tools/RegistryTool.java b/core/src/main/java/google/registry/tools/RegistryTool.java index 3d3bba0d3..068b5fc08 100644 --- a/core/src/main/java/google/registry/tools/RegistryTool.java +++ b/core/src/main/java/google/registry/tools/RegistryTool.java @@ -17,7 +17,6 @@ package google.registry.tools; import com.google.common.collect.ImmutableMap; import google.registry.tools.javascrap.BackfillRegistrarBillingAccountsCommand; import google.registry.tools.javascrap.CompareEscrowDepositsCommand; -import google.registry.tools.javascrap.HardDeleteHostCommand; /** Container class to create and run remote commands against a Datastore instance. */ public final class RegistryTool { @@ -70,7 +69,6 @@ public final class RegistryTool { .put("get_history_entries", GetHistoryEntriesCommand.class) .put("get_host", GetHostCommand.class) .put("get_keyring_secret", GetKeyringSecretCommand.class) - .put("get_operation_status", GetOperationStatusCommand.class) .put("get_premium_list", GetPremiumListCommand.class) .put("get_registrar", GetRegistrarCommand.class) .put("get_reserved_list", GetReservedListCommand.class) @@ -80,18 +78,14 @@ public final class RegistryTool { .put("get_sql_credential", GetSqlCredentialCommand.class) .put("get_tld", GetTldCommand.class) .put("ghostryde", GhostrydeCommand.class) - .put("hard_delete_host", HardDeleteHostCommand.class) .put("hash_certificate", HashCertificateCommand.class) - .put("import_datastore", ImportDatastoreCommand.class) .put("list_cursors", ListCursorsCommand.class) - .put("list_datastore_operations", ListDatastoreOperationsCommand.class) .put("list_domains", ListDomainsCommand.class) .put("list_hosts", ListHostsCommand.class) .put("list_premium_lists", ListPremiumListsCommand.class) .put("list_registrars", ListRegistrarsCommand.class) .put("list_reserved_lists", ListReservedListsCommand.class) .put("list_tlds", ListTldsCommand.class) - .put("load_snapshot", LoadSnapshotCommand.class) .put("load_test", LoadTestCommand.class) .put("lock_domain", LockDomainCommand.class) .put("login", LoginCommand.class) diff --git a/core/src/main/java/google/registry/tools/RegistryToolComponent.java b/core/src/main/java/google/registry/tools/RegistryToolComponent.java index d392327bc..3c69fdfd6 100644 --- a/core/src/main/java/google/registry/tools/RegistryToolComponent.java +++ b/core/src/main/java/google/registry/tools/RegistryToolComponent.java @@ -26,7 +26,6 @@ import google.registry.config.RegistryConfig.ConfigModule; import google.registry.dns.writer.VoidDnsWriterModule; import google.registry.dns.writer.clouddns.CloudDnsWriterModule; import google.registry.dns.writer.dnsupdate.DnsUpdateWriterModule; -import google.registry.export.datastore.DatastoreAdminModule; import google.registry.keyring.KeyringModule; import google.registry.keyring.api.DummyKeyringModule; import google.registry.keyring.api.KeyModule; @@ -37,7 +36,6 @@ import google.registry.persistence.PersistenceModule.ReadOnlyReplicaJpaTm; import google.registry.persistence.transaction.JpaTransactionManager; import google.registry.privileges.secretmanager.SecretManagerModule; import google.registry.rde.RdeModule; -import google.registry.request.Modules.DatastoreServiceModule; import google.registry.request.Modules.Jackson2Module; import google.registry.request.Modules.UrlConnectionServiceModule; import google.registry.request.Modules.UrlFetchServiceModule; @@ -45,7 +43,6 @@ import google.registry.request.Modules.UserServiceModule; import google.registry.tools.AuthModule.LocalCredentialModule; import google.registry.tools.javascrap.BackfillRegistrarBillingAccountsCommand; import google.registry.tools.javascrap.CompareEscrowDepositsCommand; -import google.registry.tools.javascrap.HardDeleteHostCommand; import google.registry.util.UtilsModule; import google.registry.whois.NonCachingWhoisModule; import javax.annotation.Nullable; @@ -67,8 +64,6 @@ import javax.inject.Singleton; ConfigModule.class, CloudDnsWriterModule.class, CloudTasksUtilsModule.class, - DatastoreAdminModule.class, - DatastoreServiceModule.class, DummyKeyringModule.class, DnsUpdateWriterModule.class, Jackson2Module.class, @@ -125,22 +120,12 @@ interface RegistryToolComponent { void inject(GetKeyringSecretCommand command); - void inject(GetOperationStatusCommand command); - void inject(GetSqlCredentialCommand command); void inject(GhostrydeCommand command); - void inject(HardDeleteHostCommand command); - - void inject(ImportDatastoreCommand command); - void inject(ListCursorsCommand command); - void inject(ListDatastoreOperationsCommand command); - - void inject(LoadSnapshotCommand command); - void inject(LockDomainCommand command); void inject(LoginCommand command); diff --git a/core/src/main/java/google/registry/tools/UpdateAllocationTokensCommand.java b/core/src/main/java/google/registry/tools/UpdateAllocationTokensCommand.java index 3e0e820dd..90519f435 100644 --- a/core/src/main/java/google/registry/tools/UpdateAllocationTokensCommand.java +++ b/core/src/main/java/google/registry/tools/UpdateAllocationTokensCommand.java @@ -19,7 +19,6 @@ import static com.google.common.collect.ImmutableSet.toImmutableSet; import static com.google.common.collect.Iterables.partition; import static com.google.common.collect.Streams.stream; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import com.beust.jcommander.Parameter; import com.beust.jcommander.Parameters; @@ -118,17 +117,19 @@ final class UpdateAllocationTokensCommand extends UpdateOrDeleteAllocationTokens } tokensToSave = - transactIfJpaTm( - () -> - tm().loadByKeys(getTokenKeys()).values().stream() - .collect(toImmutableMap(Function.identity(), this::updateToken)) - .entrySet() - .stream() - .filter( - entry -> - !entry.getKey().equals(entry.getValue())) // only update changed tokens - .map(Map.Entry::getValue) - .collect(toImmutableSet())); + tm().transact( + () -> + tm().loadByKeys(getTokenKeys()).values().stream() + .collect(toImmutableMap(Function.identity(), this::updateToken)) + .entrySet() + .stream() + .filter( + entry -> + !entry + .getKey() + .equals(entry.getValue())) // only update changed tokens + .map(Map.Entry::getValue) + .collect(toImmutableSet())); } @Override diff --git a/core/src/main/java/google/registry/tools/UpdateDomainCommand.java b/core/src/main/java/google/registry/tools/UpdateDomainCommand.java index 8dd3d3cf7..662fc7adf 100644 --- a/core/src/main/java/google/registry/tools/UpdateDomainCommand.java +++ b/core/src/main/java/google/registry/tools/UpdateDomainCommand.java @@ -21,7 +21,6 @@ import static google.registry.model.domain.rgp.GracePeriodStatus.AUTO_RENEW; import static google.registry.model.eppcommon.StatusValue.PENDING_DELETE; import static google.registry.model.eppcommon.StatusValue.SERVER_UPDATE_PROHIBITED; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import static google.registry.util.PreconditionsUtils.checkArgumentPresent; import static java.util.function.Predicate.isEqual; @@ -344,11 +343,11 @@ final class UpdateDomainCommand extends CreateOrUpdateDomainCommand { ImmutableSet getContactsOfType( DomainBase domainBase, final DesignatedContact.Type contactType) { - return transactIfJpaTm( - () -> - domainBase.getContacts().stream() - .filter(contact -> contact.getType().equals(contactType)) - .map(contact -> tm().loadByKey(contact.getContactKey()).getContactId()) - .collect(toImmutableSet())); + return tm().transact( + () -> + domainBase.getContacts().stream() + .filter(contact -> contact.getType().equals(contactType)) + .map(contact -> tm().loadByKey(contact.getContactKey()).getContactId()) + .collect(toImmutableSet())); } } diff --git a/core/src/main/java/google/registry/tools/UpdateOrDeleteAllocationTokensCommand.java b/core/src/main/java/google/registry/tools/UpdateOrDeleteAllocationTokensCommand.java index 7cc1f5afb..acb9310fc 100644 --- a/core/src/main/java/google/registry/tools/UpdateOrDeleteAllocationTokensCommand.java +++ b/core/src/main/java/google/registry/tools/UpdateOrDeleteAllocationTokensCommand.java @@ -18,7 +18,6 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkState; import static com.google.common.collect.ImmutableSet.toImmutableSet; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import com.beust.jcommander.Parameter; import com.google.common.collect.ImmutableSet; @@ -59,18 +58,18 @@ abstract class UpdateOrDeleteAllocationTokensCommand extends ConfirmingCommand .map(token -> VKey.create(AllocationToken.class, token)) .collect(toImmutableSet()); ImmutableSet> nonexistentKeys = - transactIfJpaTm( - () -> keys.stream().filter(key -> !tm().exists(key)).collect(toImmutableSet())); + tm().transact( + () -> keys.stream().filter(key -> !tm().exists(key)).collect(toImmutableSet())); checkState(nonexistentKeys.isEmpty(), "Tokens with keys %s did not exist.", nonexistentKeys); return keys; } else { checkArgument(!prefix.isEmpty(), "Provided prefix should not be blank"); - return transactIfJpaTm( - () -> - tm().loadAllOf(AllocationToken.class).stream() - .filter(token -> token.getToken().startsWith(prefix)) - .map(AllocationToken::createVKey) - .collect(toImmutableSet())); + return tm().transact( + () -> + tm().loadAllOf(AllocationToken.class).stream() + .filter(token -> token.getToken().startsWith(prefix)) + .map(AllocationToken::createVKey) + .collect(toImmutableSet())); } } } diff --git a/core/src/main/java/google/registry/tools/javascrap/HardDeleteHostCommand.java b/core/src/main/java/google/registry/tools/javascrap/HardDeleteHostCommand.java deleted file mode 100644 index f7fc784ed..000000000 --- a/core/src/main/java/google/registry/tools/javascrap/HardDeleteHostCommand.java +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright 2021 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.tools.javascrap; - -import static com.google.common.base.Verify.verify; -import static google.registry.model.ofy.ObjectifyService.auditedOfy; -import static google.registry.persistence.transaction.TransactionManagerFactory.ofyTm; -import static google.registry.persistence.transaction.TransactionManagerFactory.tm; - -import com.beust.jcommander.Parameter; -import com.beust.jcommander.Parameters; -import com.google.common.collect.ImmutableList; -import com.googlecode.objectify.Key; -import google.registry.model.host.HostResource; -import google.registry.model.index.EppResourceIndex; -import google.registry.model.index.ForeignKeyIndex; -import google.registry.tools.CommandWithRemoteApi; -import google.registry.tools.ConfirmingCommand; -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -/** - * Deletes a {@link HostResource} by its ROID. - * - *

This deletes the host itself, everything in the same entity group including all {@link - * google.registry.model.reporting.HistoryEntry}s and {@link - * google.registry.model.poll.PollMessage}s, the {@link EppResourceIndex}, and the {@link - * ForeignKeyIndex} (if it exists). - * - *

DO NOT use this to hard-delete a host that is still in use on a domain. Bad things will - * happen. - */ -@Parameters(separators = " =", commandDescription = "Delete a host by its ROID.") -public class HardDeleteHostCommand extends ConfirmingCommand implements CommandWithRemoteApi { - - @Parameter(names = "--roid", description = "The ROID of the host to be deleted.") - String roid; - - @Parameter(names = "--hostname", description = "The hostname, for verification.") - String hostname; - - private ImmutableList> toDelete; - - @Override - protected void init() { - ofyTm() - .transact( - () -> { - Key targetKey = Key.create(HostResource.class, roid); - HostResource host = auditedOfy().load().key(targetKey).now(); - verify(Objects.equals(host.getHostName(), hostname), "Hostname does not match"); - - List> objectsInEntityGroup = - auditedOfy().load().ancestor(host).keys().list(); - - Optional> fki = - Optional.ofNullable( - auditedOfy().load().key(ForeignKeyIndex.createKey(host)).now()); - if (!fki.isPresent()) { - System.out.println( - "No ForeignKeyIndex exists, likely because resource is soft-deleted." - + " Continuing."); - } - - EppResourceIndex eppResourceIndex = - auditedOfy().load().entity(EppResourceIndex.create(targetKey)).now(); - verify(eppResourceIndex.getKey().equals(targetKey), "Wrong EppResource Index loaded"); - - ImmutableList.Builder> toDeleteBuilder = - new ImmutableList.Builder>() - .addAll(objectsInEntityGroup) - .add(Key.create(eppResourceIndex)); - fki.ifPresent(f -> toDeleteBuilder.add(Key.create(f))); - toDelete = toDeleteBuilder.build(); - - System.out.printf("\n\nAbout to delete %d entities with keys:\n", toDelete.size()); - toDelete.forEach(System.out::println); - }); - } - - @Override - protected String execute() { - tm().transact(() -> auditedOfy().delete().keys(toDelete).now()); - return "Done."; - } -} diff --git a/core/src/main/java/google/registry/tools/server/ListHostsAction.java b/core/src/main/java/google/registry/tools/server/ListHostsAction.java index 27451be2b..38f49e97b 100644 --- a/core/src/main/java/google/registry/tools/server/ListHostsAction.java +++ b/core/src/main/java/google/registry/tools/server/ListHostsAction.java @@ -16,7 +16,6 @@ package google.registry.tools.server; import static com.google.common.collect.ImmutableSortedSet.toImmutableSortedSet; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import static google.registry.request.Action.Method.GET; import static google.registry.request.Action.Method.POST; import static java.util.Comparator.comparing; @@ -51,7 +50,7 @@ public final class ListHostsAction extends ListObjectsAction { @Override public ImmutableSet loadObjects() { final DateTime now = clock.nowUtc(); - return transactIfJpaTm(() -> tm().loadAllOf(HostResource.class)).stream() + return tm().transact(() -> tm().loadAllOf(HostResource.class)).stream() .filter(host -> EppResourceUtils.isActive(host, now)) .collect(toImmutableSortedSet(comparing(HostResource::getHostName))); } diff --git a/core/src/main/resources/google/registry/beam/bulk_delete_datastore_pipeline_metadata.json b/core/src/main/resources/google/registry/beam/bulk_delete_datastore_pipeline_metadata.json deleted file mode 100644 index 2f2cfb38e..000000000 --- a/core/src/main/resources/google/registry/beam/bulk_delete_datastore_pipeline_metadata.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "Bulk Delete Cloud Datastore", - "description": "An Apache Beam batch pipeline that deletes Cloud Datastore in bulk. This is easier to use than the GCP-provided template.", - "parameters": [ - { - "name": "registryEnvironment", - "label": "The Registry environment.", - "helpText": "The Registry environment, required only because the worker initializer demands it.", - "is_optional": false, - "regexes": [ - "^PRODUCTION|SANDBOX|CRASH|QA|ALPHA$" - ] - }, - { - "name": "kindsToDelete", - "label": "The data KINDs to delete.", - "helpText": "The Datastore KINDs to be deleted. The format may be: the list of kinds to be deleted as a comma-separated string; or '*', which causes all kinds to be deleted." - }, - { - "name": "getNumOfKindsHint", - "label": "An estimate of the number of KINDs to be deleted.", - "helpText": "An estimate of the number of KINDs to be deleted. This is recommended if --kindsToDelete is '*' and the default value is too low.", - "is_optional": true, - "regexes": [ - "^[1-9][0-9]*$" - ] - } - ] -} diff --git a/core/src/test/java/google/registry/batch/AsyncTaskEnqueuerTest.java b/core/src/test/java/google/registry/batch/AsyncTaskEnqueuerTest.java index bf2d641e1..f9441388e 100644 --- a/core/src/test/java/google/registry/batch/AsyncTaskEnqueuerTest.java +++ b/core/src/test/java/google/registry/batch/AsyncTaskEnqueuerTest.java @@ -55,7 +55,7 @@ public class AsyncTaskEnqueuerTest { @RegisterExtension public final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().withTaskQueue().build(); + AppEngineExtension.builder().withCloudSql().withTaskQueue().build(); @RegisterExtension public final InjectExtension inject = new InjectExtension(); diff --git a/core/src/test/java/google/registry/batch/DeleteExpiredDomainsActionTest.java b/core/src/test/java/google/registry/batch/DeleteExpiredDomainsActionTest.java index 24cacf862..354e14ca5 100644 --- a/core/src/test/java/google/registry/batch/DeleteExpiredDomainsActionTest.java +++ b/core/src/test/java/google/registry/batch/DeleteExpiredDomainsActionTest.java @@ -19,7 +19,6 @@ import static com.google.common.truth.Truth.assertThat; import static google.registry.model.eppcommon.StatusValue.PENDING_DELETE; import static google.registry.model.reporting.HistoryEntry.Type.DOMAIN_CREATE; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import static google.registry.testing.DatabaseHelper.createTld; import static google.registry.testing.DatabaseHelper.loadByEntity; import static google.registry.testing.DatabaseHelper.newDomainBase; @@ -41,30 +40,24 @@ import google.registry.model.poll.PollMessage; import google.registry.model.reporting.HistoryEntry; import google.registry.persistence.transaction.QueryComposer.Comparator; import google.registry.testing.AppEngineExtension; -import google.registry.testing.DualDatabaseTest; import google.registry.testing.FakeClock; import google.registry.testing.FakeLockHandler; import google.registry.testing.FakeResponse; import google.registry.testing.InjectExtension; -import google.registry.testing.TestOfyAndSql; import java.util.Optional; import org.joda.time.DateTime; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; /** Unit tests for {@link DeleteExpiredDomainsAction}. */ -@DualDatabaseTest class DeleteExpiredDomainsActionTest { private final FakeClock clock = new FakeClock(DateTime.parse("2016-06-13T20:21:22Z")); @RegisterExtension public final AppEngineExtension appEngine = - AppEngineExtension.builder() - .withDatastoreAndCloudSql() - .withClock(clock) - .withTaskQueue() - .build(); + AppEngineExtension.builder().withCloudSql().withClock(clock).withTaskQueue().build(); @RegisterExtension public final InjectExtension inject = new InjectExtension(); @@ -86,7 +79,7 @@ class DeleteExpiredDomainsActionTest { eppController, "NewRegistrar", clock, new FakeLockHandler(true), response); } - @TestOfyAndSql + @Test void test_deletesOnlyExpiredDomain() { // A normal, active autorenewing domain that shouldn't be touched. DomainBase activeDomain = persistActiveDomain("foo.tld"); @@ -131,7 +124,7 @@ class DeleteExpiredDomainsActionTest { assertThat(reloadedExpiredDomain.getDeletionTime()).isEqualTo(clock.nowUtc().plusDays(35)); } - @TestOfyAndSql + @Test void test_deletesThreeDomainsInOneRun() throws Exception { DomainBase domain1 = persistNonAutorenewingDomain("ecck1.tld"); DomainBase domain2 = persistNonAutorenewingDomain("veee2.tld"); @@ -143,14 +136,14 @@ class DeleteExpiredDomainsActionTest { int maxRetries = 5; while (true) { ImmutableSet matchingDomains = - transactIfJpaTm( - () -> - tm() - .createQueryComposer(DomainBase.class) - .where("autorenewEndTime", Comparator.LTE, clock.nowUtc()) - .stream() - .map(DomainBase::getDomainName) - .collect(toImmutableSet())); + tm().transact( + () -> + tm() + .createQueryComposer(DomainBase.class) + .where("autorenewEndTime", Comparator.LTE, clock.nowUtc()) + .stream() + .map(DomainBase::getDomainName) + .collect(toImmutableSet())); if (matchingDomains.containsAll(ImmutableSet.of("ecck1.tld", "veee2.tld", "tarm3.tld"))) { break; } diff --git a/core/src/test/java/google/registry/batch/DeleteProberDataActionTest.java b/core/src/test/java/google/registry/batch/DeleteProberDataActionTest.java index e3ccfdfdf..4e53151e6 100644 --- a/core/src/test/java/google/registry/batch/DeleteProberDataActionTest.java +++ b/core/src/test/java/google/registry/batch/DeleteProberDataActionTest.java @@ -51,32 +51,25 @@ import google.registry.model.reporting.HistoryEntry; import google.registry.model.tld.Registry; import google.registry.model.tld.Registry.TldType; import google.registry.testing.AppEngineExtension; -import google.registry.testing.DualDatabaseTest; import google.registry.testing.FakeClock; -import google.registry.testing.FakeResponse; import google.registry.testing.SystemPropertyExtension; -import google.registry.testing.TestOfyAndSql; import java.util.Optional; import java.util.Set; import org.joda.money.Money; import org.joda.time.DateTime; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; /** Unit tests for {@link DeleteProberDataAction}. */ -@DualDatabaseTest class DeleteProberDataActionTest { private static final DateTime DELETION_TIME = DateTime.parse("2010-01-01T00:00:00.000Z"); @RegisterExtension public final AppEngineExtension appEngine = - AppEngineExtension.builder() - .withDatastoreAndCloudSql() - .withLocalModules() - .withTaskQueue() - .build(); + AppEngineExtension.builder().withCloudSql().withLocalModules().withTaskQueue().build(); @RegisterExtension final SystemPropertyExtension systemPropertyExtension = new SystemPropertyExtension(); @@ -108,7 +101,6 @@ class DeleteProberDataActionTest { private void resetAction() { action = new DeleteProberDataAction(); action.dnsQueue = DnsQueue.createForTesting(new FakeClock()); - action.response = new FakeResponse(); action.isDryRun = false; action.tlds = ImmutableSet.of(); action.registryAdminRegistrarId = "TheRegistrar"; @@ -120,7 +112,7 @@ class DeleteProberDataActionTest { RegistryEnvironment.UNITTEST.setup(systemPropertyExtension); } - @TestOfyAndSql + @Test void test_deletesAllAndOnlyProberData() throws Exception { Set tldEntities = persistLotsOfDomains("tld"); Set exampleEntities = persistLotsOfDomains("example"); @@ -135,7 +127,7 @@ class DeleteProberDataActionTest { assertAllAbsent(oaEntities); } - @TestOfyAndSql + @Test void testSuccess_deletesAllAndOnlyGivenTlds() throws Exception { Set tldEntities = persistLotsOfDomains("tld"); Set exampleEntities = persistLotsOfDomains("example"); @@ -151,7 +143,7 @@ class DeleteProberDataActionTest { assertAllAbsent(ibEntities); } - @TestOfyAndSql + @Test void testFail_givenNonTestTld() { action.tlds = ImmutableSet.of("not-test.test"); IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, action::run); @@ -160,7 +152,7 @@ class DeleteProberDataActionTest { .contains("If tlds are given, they must all exist and be TEST tlds"); } - @TestOfyAndSql + @Test void testFail_givenNonExistentTld() { action.tlds = ImmutableSet.of("non-existent.test"); IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, action::run); @@ -169,7 +161,7 @@ class DeleteProberDataActionTest { .contains("If tlds are given, they must all exist and be TEST tlds"); } - @TestOfyAndSql + @Test void testFail_givenNonDotTestTldOnProd() { action.tlds = ImmutableSet.of("example"); RegistryEnvironment.PRODUCTION.setup(systemPropertyExtension); @@ -179,7 +171,7 @@ class DeleteProberDataActionTest { .contains("On production, can only work on TLDs that end with .test"); } - @TestOfyAndSql + @Test void testSuccess_doesntDeleteNicDomainForProbers() throws Exception { DomainBase nic = persistActiveDomain("nic.ib-any.test"); Set ibEntities = persistLotsOfDomains("ib-any.test"); @@ -188,7 +180,7 @@ class DeleteProberDataActionTest { assertAllExist(ImmutableSet.of(nic)); } - @TestOfyAndSql + @Test void testDryRun_doesntDeleteData() throws Exception { Set tldEntities = persistLotsOfDomains("tld"); Set oaEntities = persistLotsOfDomains("oa-canary.test"); @@ -198,7 +190,7 @@ class DeleteProberDataActionTest { assertAllExist(oaEntities); } - @TestOfyAndSql + @Test void testSuccess_activeDomain_isSoftDeleted() throws Exception { DomainBase domain = persistResource( @@ -213,7 +205,7 @@ class DeleteProberDataActionTest { assertDnsTasksEnqueued("blah.ib-any.test"); } - @TestOfyAndSql + @Test void testSuccess_activeDomain_doubleMapSoftDeletes() throws Exception { DomainBase domain = persistResource( newDomainBase("blah.ib-any.test") @@ -230,7 +222,7 @@ class DeleteProberDataActionTest { assertDnsTasksEnqueued("blah.ib-any.test"); } - @TestOfyAndSql + @Test void test_recentlyCreatedDomain_isntDeletedYet() throws Exception { persistResource( newDomainBase("blah.ib-any.test") @@ -244,7 +236,7 @@ class DeleteProberDataActionTest { assertThat(domain.get().getDeletionTime()).isEqualTo(END_OF_TIME); } - @TestOfyAndSql + @Test void testDryRun_doesntSoftDeleteData() throws Exception { DomainBase domain = persistResource( @@ -257,7 +249,7 @@ class DeleteProberDataActionTest { assertThat(loadByEntity(domain).getDeletionTime()).isEqualTo(END_OF_TIME); } - @TestOfyAndSql + @Test void test_domainWithSubordinateHosts_isSkipped() throws Exception { persistActiveHost("ns1.blah.ib-any.test"); DomainBase nakedDomain = @@ -275,7 +267,7 @@ class DeleteProberDataActionTest { assertAllAbsent(ImmutableSet.of(nakedDomain)); } - @TestOfyAndSql + @Test void testFailure_registryAdminClientId_isRequiredForSoftDeletion() { persistResource( newDomainBase("blah.ib-any.test") diff --git a/core/src/test/java/google/registry/batch/ExpandRecurringBillingEventsActionTest.java b/core/src/test/java/google/registry/batch/ExpandRecurringBillingEventsActionTest.java index d44ce097c..b9b018441 100644 --- a/core/src/test/java/google/registry/batch/ExpandRecurringBillingEventsActionTest.java +++ b/core/src/test/java/google/registry/batch/ExpandRecurringBillingEventsActionTest.java @@ -22,7 +22,6 @@ import static google.registry.model.domain.Period.Unit.YEARS; import static google.registry.model.reporting.HistoryEntry.Type.DOMAIN_AUTORENEW; import static google.registry.model.reporting.HistoryEntry.Type.DOMAIN_CREATE; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import static google.registry.testing.DatabaseHelper.assertBillingEventsForResource; import static google.registry.testing.DatabaseHelper.createTld; import static google.registry.testing.DatabaseHelper.getHistoryEntriesOfType; @@ -55,29 +54,23 @@ import google.registry.model.reporting.DomainTransactionRecord.TransactionReport import google.registry.model.reporting.HistoryEntry; import google.registry.model.tld.Registry; import google.registry.testing.AppEngineExtension; -import google.registry.testing.DualDatabaseTest; import google.registry.testing.FakeClock; import google.registry.testing.FakeResponse; -import google.registry.testing.TestOfyAndSql; import java.util.ArrayList; import java.util.List; import java.util.Optional; import org.joda.money.Money; import org.joda.time.DateTime; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; /** Unit tests for {@link ExpandRecurringBillingEventsAction}. */ -@DualDatabaseTest public class ExpandRecurringBillingEventsActionTest { @RegisterExtension public final AppEngineExtension appEngine = - AppEngineExtension.builder() - .withDatastoreAndCloudSql() - .withLocalModules() - .withTaskQueue() - .build(); + AppEngineExtension.builder().withCloudSql().withLocalModules().withTaskQueue().build(); private DateTime currentTestTime = DateTime.parse("1999-01-05T00:00:00Z"); private final FakeClock clock = new FakeClock(currentTestTime); @@ -139,8 +132,7 @@ public class ExpandRecurringBillingEventsActionTest { } private void assertCursorAt(DateTime expectedCursorTime) { - Cursor cursor = - transactIfJpaTm(() -> tm().loadByKey(Cursor.createGlobalVKey(RECURRING_BILLING))); + Cursor cursor = tm().transact(() -> tm().loadByKey(Cursor.createGlobalVKey(RECURRING_BILLING))); assertThat(cursor).isNotNull(); assertThat(cursor.getCursorTime()).isEqualTo(expectedCursorTime); } @@ -183,7 +175,7 @@ public class ExpandRecurringBillingEventsActionTest { .setTargetId(domain.getDomainName()); } - @TestOfyAndSql + @Test void testSuccess_expandSingleEvent() throws Exception { persistResource(recurring); action.cursorTimeParam = Optional.of(START_OF_TIME); @@ -197,7 +189,7 @@ public class ExpandRecurringBillingEventsActionTest { assertCursorAt(currentTestTime); } - @TestOfyAndSql + @Test void testSuccess_expandSingleEvent_deletedDomain() throws Exception { DateTime deletionTime = DateTime.parse("2000-08-01T00:00:00Z"); DomainBase deletedDomain = persistDeletedDomain("deleted.tld", deletionTime); @@ -240,7 +232,7 @@ public class ExpandRecurringBillingEventsActionTest { assertCursorAt(currentTestTime); } - @TestOfyAndSql + @Test void testSuccess_expandSingleEvent_idempotentForDuplicateRuns() throws Exception { persistResource(recurring); action.cursorTimeParam = Optional.of(START_OF_TIME); @@ -258,7 +250,7 @@ public class ExpandRecurringBillingEventsActionTest { assertBillingEventsForResource(domain, expected, recurring); } - @TestOfyAndSql + @Test void testSuccess_expandSingleEvent_idempotentForExistingOneTime() throws Exception { persistResource(recurring); BillingEvent.OneTime persisted = @@ -272,7 +264,7 @@ public class ExpandRecurringBillingEventsActionTest { assertBillingEventsForResource(domain, persisted, recurring); } - @TestOfyAndSql + @Test void testSuccess_expandSingleEvent_notIdempotentForDifferentBillingTime() throws Exception { persistResource(recurring); action.cursorTimeParam = Optional.of(START_OF_TIME); @@ -295,7 +287,7 @@ public class ExpandRecurringBillingEventsActionTest { assertBillingEventsForResource(domain, persisted, expected, recurring); } - @TestOfyAndSql + @Test void testSuccess_expandSingleEvent_notIdempotentForDifferentRecurring() throws Exception { persistResource(recurring); BillingEvent.Recurring recurring2 = persistResource(recurring.asBuilder().setId(3L).build()); @@ -321,7 +313,7 @@ public class ExpandRecurringBillingEventsActionTest { assertBillingEventsForResource(domain, persisted, expected, recurring, recurring2); } - @TestOfyAndSql + @Test void testSuccess_ignoreRecurringBeforeWindow() throws Exception { recurring = persistResource( @@ -338,7 +330,7 @@ public class ExpandRecurringBillingEventsActionTest { assertCursorAt(currentTestTime); } - @TestOfyAndSql + @Test void testSuccess_ignoreRecurringAfterWindow() throws Exception { recurring = persistResource(recurring.asBuilder().setEventTime(clock.nowUtc().plusYears(2)).build()); @@ -349,7 +341,7 @@ public class ExpandRecurringBillingEventsActionTest { assertBillingEventsForResource(domain, recurring); } - @TestOfyAndSql + @Test void testSuccess_expandSingleEvent_billingTimeAtCursorTime() throws Exception { persistResource(recurring); action.cursorTimeParam = Optional.of(DateTime.parse("2000-02-19T00:00:00Z")); @@ -363,7 +355,7 @@ public class ExpandRecurringBillingEventsActionTest { assertCursorAt(currentTestTime); } - @TestOfyAndSql + @Test void testSuccess_expandSingleEvent_cursorTimeBetweenEventAndBillingTime() throws Exception { persistResource(recurring); action.cursorTimeParam = Optional.of(DateTime.parse("2000-01-12T00:00:00Z")); @@ -377,7 +369,7 @@ public class ExpandRecurringBillingEventsActionTest { assertCursorAt(currentTestTime); } - @TestOfyAndSql + @Test void testSuccess_expandSingleEvent_billingTimeAtExecutionTime() throws Exception { clock.setTo(currentTestTime); persistResource(recurring); @@ -393,7 +385,7 @@ public class ExpandRecurringBillingEventsActionTest { assertCursorAt(currentTestTime); } - @TestOfyAndSql + @Test void testSuccess_expandSingleEvent_multipleYearCreate() throws Exception { action.cursorTimeParam = Optional.of(recurring.getEventTime()); recurring = @@ -415,7 +407,7 @@ public class ExpandRecurringBillingEventsActionTest { assertCursorAt(currentTestTime); } - @TestOfyAndSql + @Test void testSuccess_expandSingleEvent_withCursor() throws Exception { persistResource(recurring); saveCursor(START_OF_TIME); @@ -429,7 +421,7 @@ public class ExpandRecurringBillingEventsActionTest { assertCursorAt(currentTestTime); } - @TestOfyAndSql + @Test void testSuccess_expandSingleEvent_withCursorPastExpected() throws Exception { persistResource(recurring); // Simulate a quick second run of the action (this should be a no-op). @@ -441,7 +433,7 @@ public class ExpandRecurringBillingEventsActionTest { assertCursorAt(currentTestTime); } - @TestOfyAndSql + @Test void testSuccess_expandSingleEvent_recurrenceEndBeforeEvent() throws Exception { // This can occur when a domain is transferred or deleted before a domain comes up for renewal. recurring = @@ -458,7 +450,7 @@ public class ExpandRecurringBillingEventsActionTest { assertCursorAt(currentTestTime); } - @TestOfyAndSql + @Test void testSuccess_expandSingleEvent_dryRun() throws Exception { persistResource(recurring); action.isDryRun = true; @@ -470,7 +462,7 @@ public class ExpandRecurringBillingEventsActionTest { assertCursorAt(START_OF_TIME); // Cursor doesn't move on a dry run. } - @TestOfyAndSql + @Test void testSuccess_expandSingleEvent_multipleYears() throws Exception { clock.setTo(clock.nowUtc().plusYears(5)); List expectedEvents = new ArrayList<>(); @@ -497,7 +489,7 @@ public class ExpandRecurringBillingEventsActionTest { assertCursorAt(currentTestTime); } - @TestOfyAndSql + @Test void testSuccess_expandSingleEvent_multipleYears_cursorInBetweenYears() throws Exception { clock.setTo(clock.nowUtc().plusYears(5)); List expectedEvents = new ArrayList<>(); @@ -524,7 +516,7 @@ public class ExpandRecurringBillingEventsActionTest { assertCursorAt(currentTestTime); } - @TestOfyAndSql + @Test void testSuccess_singleEvent_beforeRenewal() throws Exception { // Need to restore to the time before the clock was advanced so that the commit log's timestamp // is not inverted when the clock is later reverted. @@ -539,7 +531,7 @@ public class ExpandRecurringBillingEventsActionTest { assertCursorAt(currentTestTime); } - @TestOfyAndSql + @Test void testSuccess_singleEvent_afterRecurrenceEnd_inAutorenewGracePeriod() throws Exception { // The domain creation date is 1999-01-05, and the first renewal date is thus 2000-01-05. clock.setTo(DateTime.parse("2001-02-06T00:00:00Z")); @@ -568,7 +560,7 @@ public class ExpandRecurringBillingEventsActionTest { assertCursorAt(currentTestTime); } - @TestOfyAndSql + @Test void testSuccess_singleEvent_afterRecurrenceEnd_outsideAutorenewGracePeriod() throws Exception { // The domain creation date is 1999-01-05, and the first renewal date is thus 2000-01-05. clock.setTo(DateTime.parse("2001-02-06T00:00:00Z")); @@ -597,7 +589,7 @@ public class ExpandRecurringBillingEventsActionTest { assertCursorAt(currentTestTime); } - @TestOfyAndSql + @Test void testSuccess_expandSingleEvent_billingTimeOnLeapYear() throws Exception { recurring = persistResource( @@ -618,7 +610,7 @@ public class ExpandRecurringBillingEventsActionTest { assertCursorAt(currentTestTime); } - @TestOfyAndSql + @Test void testSuccess_expandSingleEvent_billingTimeNotOnLeapYear() throws Exception { recurring = persistResource( @@ -640,7 +632,7 @@ public class ExpandRecurringBillingEventsActionTest { assertCursorAt(currentTestTime); } - @TestOfyAndSql + @Test void testSuccess_expandMultipleEvents() throws Exception { persistResource(recurring); DomainBase domain2 = @@ -735,7 +727,7 @@ public class ExpandRecurringBillingEventsActionTest { assertCursorAt(currentTestTime); } - @TestOfyAndSql + @Test void testSuccess_expandMultipleEvents_anchorTenant() throws Exception { persistResource( Registry.get("tld") @@ -783,7 +775,7 @@ public class ExpandRecurringBillingEventsActionTest { assertCursorAt(currentTestTime); } - @TestOfyAndSql + @Test void testSuccess_expandMultipleEvents_premiumDomain_internalRegistration() throws Exception { persistResource( Registry.get("tld") @@ -841,7 +833,7 @@ public class ExpandRecurringBillingEventsActionTest { assertCursorAt(currentTestTime); } - @TestOfyAndSql + @Test void testSuccess_premiumDomain() throws Exception { persistResource( Registry.get("tld") @@ -861,7 +853,7 @@ public class ExpandRecurringBillingEventsActionTest { assertCursorAt(currentTestTime); } - @TestOfyAndSql + @Test void testSuccess_premiumDomain_forAnchorTenant() throws Exception { persistResource( Registry.get("tld") @@ -881,7 +873,7 @@ public class ExpandRecurringBillingEventsActionTest { assertCursorAt(currentTestTime); } - @TestOfyAndSql + @Test void testSuccess_standardDomain_forAnchorTenant() throws Exception { recurring = persistResource(recurring.asBuilder().setRenewalPriceBehavior(NONPREMIUM).build()); action.cursorTimeParam = Optional.of(START_OF_TIME); @@ -895,7 +887,7 @@ public class ExpandRecurringBillingEventsActionTest { assertCursorAt(currentTestTime); } - @TestOfyAndSql + @Test void testSuccess_premiumDomain_forInternalRegistration() throws Exception { persistResource( Registry.get("tld") @@ -921,7 +913,7 @@ public class ExpandRecurringBillingEventsActionTest { assertCursorAt(currentTestTime); } - @TestOfyAndSql + @Test void testSuccess_standardDomain_forInternalRegistration() throws Exception { recurring = persistResource( @@ -942,7 +934,7 @@ public class ExpandRecurringBillingEventsActionTest { assertCursorAt(currentTestTime); } - @TestOfyAndSql + @Test void testSuccess_varyingRenewPrices() throws Exception { clock.setTo(currentTestTime); persistResource( @@ -986,7 +978,7 @@ public class ExpandRecurringBillingEventsActionTest { assertCursorAt(currentTestTime); } - @TestOfyAndSql + @Test void testSuccess_varyingRenewPrices_anchorTenant() throws Exception { clock.setTo(currentTestTime); persistResource( @@ -1031,7 +1023,7 @@ public class ExpandRecurringBillingEventsActionTest { assertCursorAt(currentTestTime); } - @TestOfyAndSql + @Test void testSuccess_varyingRenewPrices_internalRegistration() throws Exception { clock.setTo(currentTestTime); persistResource( @@ -1082,7 +1074,7 @@ public class ExpandRecurringBillingEventsActionTest { assertCursorAt(currentTestTime); } - @TestOfyAndSql + @Test void testFailure_cursorAfterExecutionTime() { action.cursorTimeParam = Optional.of(clock.nowUtc().plusYears(1)); IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, this::runAction); @@ -1091,7 +1083,7 @@ public class ExpandRecurringBillingEventsActionTest { .contains("Cursor time must be earlier than execution time."); } - @TestOfyAndSql + @Test void testFailure_cursorAtExecutionTime() { // The clock advances one milli on run. action.cursorTimeParam = Optional.of(clock.nowUtc().plusMillis(1)); diff --git a/core/src/test/java/google/registry/batch/RelockDomainActionTest.java b/core/src/test/java/google/registry/batch/RelockDomainActionTest.java index f8b84203a..1aaf7f35d 100644 --- a/core/src/test/java/google/registry/batch/RelockDomainActionTest.java +++ b/core/src/test/java/google/registry/batch/RelockDomainActionTest.java @@ -43,10 +43,8 @@ import google.registry.testing.AppEngineExtension; import google.registry.testing.CloudTasksHelper; import google.registry.testing.CloudTasksHelper.TaskMatcher; import google.registry.testing.DeterministicStringGenerator; -import google.registry.testing.DualDatabaseTest; import google.registry.testing.FakeClock; import google.registry.testing.FakeResponse; -import google.registry.testing.TestOfyAndSql; import google.registry.testing.UserInfo; import google.registry.tools.DomainLockUtils; import google.registry.util.EmailMessage; @@ -58,6 +56,7 @@ import org.joda.time.DateTime; import org.joda.time.Duration; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.RegisterExtension; import org.mockito.Mock; @@ -65,7 +64,6 @@ import org.mockito.junit.jupiter.MockitoExtension; /** Unit tests for {@link RelockDomainAction}. */ @ExtendWith(MockitoExtension.class) -@DualDatabaseTest public class RelockDomainActionTest { private static final String DOMAIN_NAME = "example.tld"; @@ -84,7 +82,7 @@ public class RelockDomainActionTest { @RegisterExtension public final AppEngineExtension appEngineExtension = AppEngineExtension.builder() - .withDatastoreAndCloudSql() + .withCloudSql() .withTaskQueue() .withUserService(UserInfo.create(POC_ID, "12345")) .build(); @@ -116,7 +114,7 @@ public class RelockDomainActionTest { verifyNoMoreInteractions(sendEmailService); } - @TestOfyAndSql + @Test void testLock() { action.run(); assertThat(loadByEntity(domain).getStatusValues()) @@ -128,7 +126,7 @@ public class RelockDomainActionTest { .isEqualTo(newLock); } - @TestOfyAndSql + @Test void testFailure_unknownCode() throws Exception { action = createAction(12128675309L); action.run(); @@ -137,7 +135,7 @@ public class RelockDomainActionTest { assertTaskEnqueued(1, 12128675309L, Duration.standardMinutes(10)); // should retry, transient } - @TestOfyAndSql + @Test void testFailure_pendingDelete() throws Exception { persistResource(domain.asBuilder().setStatusValues(ImmutableSet.of(PENDING_DELETE)).build()); action.run(); @@ -149,7 +147,7 @@ public class RelockDomainActionTest { cloudTasksHelper.assertNoTasksEnqueued(QUEUE_ASYNC_ACTIONS); } - @TestOfyAndSql + @Test void testFailure_pendingTransfer() throws Exception { persistResource(domain.asBuilder().setStatusValues(ImmutableSet.of(PENDING_TRANSFER)).build()); action.run(); @@ -161,7 +159,7 @@ public class RelockDomainActionTest { cloudTasksHelper.assertNoTasksEnqueued(QUEUE_ASYNC_ACTIONS); } - @TestOfyAndSql + @Test void testFailure_domainAlreadyLocked() { domainLockUtils.administrativelyApplyLock(DOMAIN_NAME, CLIENT_ID, null, true); action.run(); @@ -171,7 +169,7 @@ public class RelockDomainActionTest { cloudTasksHelper.assertNoTasksEnqueued(QUEUE_ASYNC_ACTIONS); } - @TestOfyAndSql + @Test void testFailure_domainDeleted() throws Exception { persistDomainAsDeleted(domain, clock.nowUtc()); action.run(); @@ -183,7 +181,7 @@ public class RelockDomainActionTest { cloudTasksHelper.assertNoTasksEnqueued(QUEUE_ASYNC_ACTIONS); } - @TestOfyAndSql + @Test void testFailure_domainTransferred() throws Exception { persistResource( domain.asBuilder().setPersistedCurrentSponsorRegistrarId("NewRegistrar").build()); @@ -198,7 +196,7 @@ public class RelockDomainActionTest { cloudTasksHelper.assertNoTasksEnqueued(QUEUE_ASYNC_ACTIONS); } - @TestOfyAndSql + @Test public void testFailure_transientFailure_enqueuesTask() { // Hard-delete the domain to simulate a DB failure deleteTestDomain(domain, clock.nowUtc()); @@ -209,7 +207,7 @@ public class RelockDomainActionTest { assertTaskEnqueued(1); } - @TestOfyAndSql + @Test void testFailure_sufficientTransientFailures_sendsEmail() throws Exception { // Hard-delete the domain to simulate a DB failure deleteTestDomain(domain, clock.nowUtc()); @@ -222,7 +220,7 @@ public class RelockDomainActionTest { assertThat(response.getPayload()).startsWith("Re-lock failed: VKey"); } - @TestOfyAndSql + @Test void testSuccess_afterSufficientFailures_sendsEmail() throws Exception { action = createAction(oldLock.getRevisionId(), RelockDomainAction.FAILURES_BEFORE_EMAIL + 1); action.run(); @@ -230,7 +228,7 @@ public class RelockDomainActionTest { assertSuccessEmailSent(); } - @TestOfyAndSql + @Test void testFailure_relockAlreadySet() { RegistryLock newLock = domainLockUtils.administrativelyApplyLock(DOMAIN_NAME, CLIENT_ID, null, true); @@ -244,7 +242,7 @@ public class RelockDomainActionTest { cloudTasksHelper.assertNoTasksEnqueued(QUEUE_ASYNC_ACTIONS); } - @TestOfyAndSql + @Test void testFailure_slowsDown() throws Exception { deleteTestDomain(domain, clock.nowUtc()); action = createAction(oldLock.getRevisionId(), RelockDomainAction.ATTEMPTS_BEFORE_SLOWDOWN); diff --git a/core/src/test/java/google/registry/batch/ResaveAllEppResourcesPipelineActionTest.java b/core/src/test/java/google/registry/batch/ResaveAllEppResourcesPipelineActionTest.java index 5745adc7b..95e7b43b3 100644 --- a/core/src/test/java/google/registry/batch/ResaveAllEppResourcesPipelineActionTest.java +++ b/core/src/test/java/google/registry/batch/ResaveAllEppResourcesPipelineActionTest.java @@ -35,8 +35,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; public class ResaveAllEppResourcesPipelineActionTest extends BeamActionTestBase { @RegisterExtension - final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().build(); + final AppEngineExtension appEngine = AppEngineExtension.builder().withCloudSql().build(); private final FakeClock fakeClock = new FakeClock(); diff --git a/core/src/test/java/google/registry/batch/ResaveEntityActionTest.java b/core/src/test/java/google/registry/batch/ResaveEntityActionTest.java index 5c553a594..e313e7c7b 100644 --- a/core/src/test/java/google/registry/batch/ResaveEntityActionTest.java +++ b/core/src/test/java/google/registry/batch/ResaveEntityActionTest.java @@ -40,13 +40,12 @@ import google.registry.request.Response; import google.registry.testing.AppEngineExtension; import google.registry.testing.CloudTasksHelper; import google.registry.testing.CloudTasksHelper.TaskMatcher; -import google.registry.testing.DualDatabaseTest; import google.registry.testing.FakeClock; import google.registry.testing.InjectExtension; -import google.registry.testing.TestOfyAndSql; import org.joda.time.DateTime; import org.joda.time.Duration; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.RegisterExtension; import org.mockito.Mock; @@ -56,12 +55,11 @@ import org.mockito.quality.Strictness; /** Unit tests for {@link ResaveEntityAction}. */ @ExtendWith(MockitoExtension.class) -@DualDatabaseTest public class ResaveEntityActionTest { @RegisterExtension public final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().withTaskQueue().build(); + AppEngineExtension.builder().withCloudSql().withTaskQueue().build(); @RegisterExtension public final InjectExtension inject = new InjectExtension(); @@ -88,7 +86,7 @@ public class ResaveEntityActionTest { } @MockitoSettings(strictness = Strictness.LENIENT) - @TestOfyAndSql + @Test void test_domainPendingTransfer_isResavedAndTransferCompleted() { DomainBase domain = persistDomainWithPendingTransfer( @@ -113,7 +111,7 @@ public class ResaveEntityActionTest { verify(response).setPayload("Entity re-saved."); } - @TestOfyAndSql + @Test void test_domainPendingDeletion_isResavedAndReenqueued() { DomainBase newDomain = newDomainBase("domain.tld"); DomainBase domain = diff --git a/core/src/test/java/google/registry/batch/SendExpiringCertificateNotificationEmailActionTest.java b/core/src/test/java/google/registry/batch/SendExpiringCertificateNotificationEmailActionTest.java index 427737b48..c4e0ba1f9 100644 --- a/core/src/test/java/google/registry/batch/SendExpiringCertificateNotificationEmailActionTest.java +++ b/core/src/test/java/google/registry/batch/SendExpiringCertificateNotificationEmailActionTest.java @@ -38,11 +38,9 @@ import google.registry.model.registrar.RegistrarAddress; import google.registry.model.registrar.RegistrarPoc; import google.registry.model.registrar.RegistrarPoc.Type; import google.registry.testing.AppEngineExtension; -import google.registry.testing.DualDatabaseTest; import google.registry.testing.FakeClock; import google.registry.testing.FakeResponse; import google.registry.testing.InjectExtension; -import google.registry.testing.TestOfyAndSql; import google.registry.util.SelfSignedCaCertificate; import google.registry.util.SendEmailService; import java.security.cert.X509Certificate; @@ -51,10 +49,10 @@ import javax.annotation.Nullable; import javax.mail.internet.InternetAddress; import org.joda.time.DateTime; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; /** Unit tests for {@link SendExpiringCertificateNotificationEmailAction}. */ -@DualDatabaseTest class SendExpiringCertificateNotificationEmailActionTest { private static final String EXPIRATION_WARNING_EMAIL_BODY_TEXT = @@ -75,7 +73,7 @@ class SendExpiringCertificateNotificationEmailActionTest { @RegisterExtension public final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().withTaskQueue().build(); + AppEngineExtension.builder().withCloudSql().withTaskQueue().build(); @RegisterExtension public final InjectExtension inject = new InjectExtension(); private final FakeClock clock = new FakeClock(DateTime.parse("2021-05-24T20:21:22Z")); @@ -111,7 +109,7 @@ class SendExpiringCertificateNotificationEmailActionTest { persistResource(createRegistrar("clientId", "sampleRegistrar", null, null).build()); } - @TestOfyAndSql + @Test void sendNotificationEmail_techEMailAsRecipient_returnsTrue() throws Exception { X509Certificate expiringCertificate = SelfSignedCaCertificate.create( @@ -133,7 +131,7 @@ class SendExpiringCertificateNotificationEmailActionTest { .isEqualTo(true); } - @TestOfyAndSql + @Test void sendNotificationEmail_adminEMailAsRecipient_returnsTrue() throws Exception { X509Certificate expiringCertificate = SelfSignedCaCertificate.create( @@ -155,7 +153,7 @@ class SendExpiringCertificateNotificationEmailActionTest { .isEqualTo(true); } - @TestOfyAndSql + @Test void sendNotificationEmail_returnsFalse_unsupportedEmailType() throws Exception { Registrar registrar = persistResource( @@ -185,7 +183,7 @@ class SendExpiringCertificateNotificationEmailActionTest { .isEqualTo(false); } - @TestOfyAndSql + @Test void sendNotificationEmail_returnsFalse_noEmailRecipients() throws Exception { X509Certificate expiringCertificate = SelfSignedCaCertificate.create( @@ -201,7 +199,7 @@ class SendExpiringCertificateNotificationEmailActionTest { .isEqualTo(false); } - @TestOfyAndSql + @Test void sendNotificationEmail_throwsRunTimeException() throws Exception { doThrow(new RuntimeException("this is a runtime exception")) .when(sendEmailService) @@ -247,7 +245,7 @@ class SendExpiringCertificateNotificationEmailActionTest { registrar.getRegistrarName())); } - @TestOfyAndSql + @Test void sendNotificationEmail_returnsFalse_noCertificate() { assertThat( action.sendNotificationEmail( @@ -255,7 +253,7 @@ class SendExpiringCertificateNotificationEmailActionTest { .isEqualTo(false); } - @TestOfyAndSql + @Test void sendNotificationEmails_allEmailsBeingSent_onlyMainCertificates() throws Exception { for (int i = 1; i <= 10; i++) { Registrar registrar = @@ -275,7 +273,7 @@ class SendExpiringCertificateNotificationEmailActionTest { assertThat(action.sendNotificationEmails()).isEqualTo(10); } - @TestOfyAndSql + @Test void sendNotificationEmails_allEmailsBeingSent_onlyFailOverCertificates() throws Exception { for (int i = 1; i <= 10; i++) { Registrar registrar = @@ -295,7 +293,7 @@ class SendExpiringCertificateNotificationEmailActionTest { assertThat(action.sendNotificationEmails()).isEqualTo(10); } - @TestOfyAndSql + @Test void sendNotificationEmails_allEmailsBeingSent_mixedOfCertificates() throws Exception { X509Certificate expiringCertificate = SelfSignedCaCertificate.create( @@ -334,7 +332,7 @@ class SendExpiringCertificateNotificationEmailActionTest { assertThat(action.sendNotificationEmails()).isEqualTo(16); } - @TestOfyAndSql + @Test void updateLastNotificationSentDate_updatedSuccessfully_primaryCertificate() throws Exception { X509Certificate expiringCertificate = SelfSignedCaCertificate.create( @@ -350,7 +348,7 @@ class SendExpiringCertificateNotificationEmailActionTest { .isEqualTo(clock.nowUtc()); } - @TestOfyAndSql + @Test void updateLastNotificationSentDate_updatedSuccessfully_failOverCertificate() throws Exception { X509Certificate expiringCertificate = SelfSignedCaCertificate.create( @@ -366,7 +364,7 @@ class SendExpiringCertificateNotificationEmailActionTest { .isEqualTo(clock.nowUtc()); } - @TestOfyAndSql + @Test void updateLastNotificationSentDate_noUpdates_noLastNotificationSentDate() throws Exception { X509Certificate expiringCertificate = SelfSignedCaCertificate.create( @@ -386,7 +384,7 @@ class SendExpiringCertificateNotificationEmailActionTest { .contains("Failed to update the last notification sent date to Registrar"); } - @TestOfyAndSql + @Test void updateLastNotificationSentDate_noUpdates_invalidCertificateType() throws Exception { X509Certificate expiringCertificate = SelfSignedCaCertificate.create( @@ -406,7 +404,7 @@ class SendExpiringCertificateNotificationEmailActionTest { assertThat(thrown).hasMessageThat().contains("No enum constant"); } - @TestOfyAndSql + @Test void getRegistrarsWithExpiringCertificates_returnsPartOfRegistrars() throws Exception { X509Certificate expiringCertificate = SelfSignedCaCertificate.create( @@ -434,7 +432,7 @@ class SendExpiringCertificateNotificationEmailActionTest { assertThat(results).hasSize(numOfRegistrarsWithExpiringCertificates); } - @TestOfyAndSql + @Test void getRegistrarsWithExpiringCertificates_returnsPartOfRegistrars_failOverCertificateBranch() throws Exception { X509Certificate expiringCertificate = @@ -463,7 +461,7 @@ class SendExpiringCertificateNotificationEmailActionTest { .isEqualTo(numOfRegistrarsWithExpiringCertificates); } - @TestOfyAndSql + @Test void getRegistrarsWithExpiringCertificates_returnsAllRegistrars() throws Exception { X509Certificate expiringCertificate = SelfSignedCaCertificate.create( @@ -481,7 +479,7 @@ class SendExpiringCertificateNotificationEmailActionTest { .isEqualTo(numOfRegistrarsWithExpiringCertificates); } - @TestOfyAndSql + @Test void getRegistrarsWithExpiringCertificates_returnsNoRegistrars() throws Exception { X509Certificate certificate = SelfSignedCaCertificate.create( @@ -496,18 +494,18 @@ class SendExpiringCertificateNotificationEmailActionTest { assertThat(action.getRegistrarsWithExpiringCertificates()).isEmpty(); } - @TestOfyAndSql + @Test void getRegistrarsWithExpiringCertificates_noRegistrarsInDatabase() { assertThat(action.getRegistrarsWithExpiringCertificates()).isEmpty(); } - @TestOfyAndSql + @Test void getEmailAddresses_success_returnsAnEmptyList() { assertThat(action.getEmailAddresses(sampleRegistrar, Type.TECH)).isEmpty(); assertThat(action.getEmailAddresses(sampleRegistrar, Type.ADMIN)).isEmpty(); } - @TestOfyAndSql + @Test void getEmailAddresses_success_returnsAListOfEmails() throws Exception { Registrar registrar = persistResource(makeRegistrar1()); ImmutableList contacts = @@ -570,7 +568,7 @@ class SendExpiringCertificateNotificationEmailActionTest { new InternetAddress("john@example-registrar.tld")); } - @TestOfyAndSql + @Test void getEmailAddresses_failure_returnsPartialListOfEmails_skipInvalidEmails() { // when building a new RegistrarContact object, there's already an email validation process. // if the registrarContact is created successful, the email address of the contact object @@ -578,7 +576,7 @@ class SendExpiringCertificateNotificationEmailActionTest { // a new InternetAddress using the email address string of the contact object. } - @TestOfyAndSql + @Test void getEmailBody_returnsEmailBodyText() { String registrarName = "good registrar"; String certExpirationDateStr = "2021-06-15"; @@ -600,7 +598,7 @@ class SendExpiringCertificateNotificationEmailActionTest { assertThat(emailBody).doesNotContain("%4$s"); } - @TestOfyAndSql + @Test void getEmailBody_throwsIllegalArgumentException_noExpirationDate() { IllegalArgumentException thrown = assertThrows( @@ -611,7 +609,7 @@ class SendExpiringCertificateNotificationEmailActionTest { assertThat(thrown).hasMessageThat().contains("Expiration date cannot be null"); } - @TestOfyAndSql + @Test void getEmailBody_throwsIllegalArgumentException_noCertificateType() { IllegalArgumentException thrown = assertThrows( @@ -622,7 +620,7 @@ class SendExpiringCertificateNotificationEmailActionTest { assertThat(thrown).hasMessageThat().contains("Certificate type cannot be null"); } - @TestOfyAndSql + @Test void getEmailBody_throwsIllegalArgumentException_noRegistrarId() { IllegalArgumentException thrown = assertThrows( @@ -636,7 +634,7 @@ class SendExpiringCertificateNotificationEmailActionTest { assertThat(thrown).hasMessageThat().contains("Registrar Id cannot be null"); } - @TestOfyAndSql + @Test void run_sentZeroEmail_responseStatusIs200() { action.run(); assertThat(response.getStatus()).isEqualTo(SC_OK); @@ -644,7 +642,7 @@ class SendExpiringCertificateNotificationEmailActionTest { .isEqualTo("Done. Sent 0 expiring certificate notification emails in total."); } - @TestOfyAndSql + @Test void run_sentEmails_responseStatusIs200() throws Exception { for (int i = 1; i <= 5; i++) { Registrar registrar = diff --git a/core/src/test/java/google/registry/batch/WipeOutContactHistoryPiiActionTest.java b/core/src/test/java/google/registry/batch/WipeOutContactHistoryPiiActionTest.java index 6181d70af..0096ec8a2 100644 --- a/core/src/test/java/google/registry/batch/WipeOutContactHistoryPiiActionTest.java +++ b/core/src/test/java/google/registry/batch/WipeOutContactHistoryPiiActionTest.java @@ -36,17 +36,15 @@ import google.registry.model.eppcommon.PresenceMarker; import google.registry.model.eppcommon.StatusValue; import google.registry.testing.AppEngineExtension; import google.registry.testing.DatabaseHelper; -import google.registry.testing.DualDatabaseTest; import google.registry.testing.FakeClock; import google.registry.testing.FakeResponse; import google.registry.testing.InjectExtension; -import google.registry.testing.TestSqlOnly; import org.joda.time.DateTime; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; /** Unit tests for {@link WipeOutContactHistoryPiiAction}. */ -@DualDatabaseTest class WipeOutContactHistoryPiiActionTest { private static final int TEST_BATCH_SIZE = 20; @@ -102,7 +100,7 @@ class WipeOutContactHistoryPiiActionTest { @RegisterExtension public final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().withTaskQueue().build(); + AppEngineExtension.builder().withCloudSql().withTaskQueue().build(); @RegisterExtension public final InjectExtension inject = new InjectExtension(); private final FakeClock clock = new FakeClock(DateTime.parse("2021-08-26T20:21:22Z")); @@ -118,7 +116,7 @@ class WipeOutContactHistoryPiiActionTest { clock, MIN_MONTHS_BEFORE_WIPE_OUT, TEST_BATCH_SIZE, response); } - @TestSqlOnly + @Test void getAllHistoryEntitiesOlderThan_returnsAllPersistedEntities() { ImmutableList expectedToBeWipedOut = persistLotsOfContactHistoryEntities( @@ -132,7 +130,7 @@ class WipeOutContactHistoryPiiActionTest { .containsExactlyElementsIn(expectedToBeWipedOut)); } - @TestSqlOnly + @Test void getAllHistoryEntitiesOlderThan_returnsOnlyOldEnoughPersistedEntities() { ImmutableList expectedToBeWipedOut = persistLotsOfContactHistoryEntities( @@ -151,7 +149,7 @@ class WipeOutContactHistoryPiiActionTest { .containsExactlyElementsIn(expectedToBeWipedOut)); } - @TestSqlOnly + @Test void run_withNoEntitiesToWipeOut_success() { assertThat( jpaTm() @@ -179,7 +177,7 @@ class WipeOutContactHistoryPiiActionTest { .isEqualTo("Done. Wiped out PII of 0 ContactHistory entities in total."); } - @TestSqlOnly + @Test void run_withOneBatchOfEntities_success() { int numOfMonthsFromNow = MIN_MONTHS_BEFORE_WIPE_OUT + 2; ImmutableList expectedToBeWipedOut = @@ -216,7 +214,7 @@ class WipeOutContactHistoryPiiActionTest { assertAllPiiFieldsAreWipedOut(DatabaseHelper.loadByEntitiesIfPresent(expectedToBeWipedOut)); } - @TestSqlOnly + @Test void run_withMultipleBatches_numOfEntitiesAsNonMultipleOfBatchSize_success() { int numOfMonthsFromNow = MIN_MONTHS_BEFORE_WIPE_OUT + 2; ImmutableList expectedToBeWipedOut = @@ -252,7 +250,7 @@ class WipeOutContactHistoryPiiActionTest { assertAllPiiFieldsAreWipedOut(DatabaseHelper.loadByEntitiesIfPresent(expectedToBeWipedOut)); } - @TestSqlOnly + @Test void run_withMultipleBatches_numOfEntitiesAsMultiplesOfBatchSize_success() { int numOfMonthsFromNow = MIN_MONTHS_BEFORE_WIPE_OUT + 2; ImmutableList expectedToBeWipedOut = @@ -289,7 +287,7 @@ class WipeOutContactHistoryPiiActionTest { assertAllPiiFieldsAreWipedOut(DatabaseHelper.loadByEntitiesIfPresent(expectedToBeWipedOut)); } - @TestSqlOnly + @Test void wipeOutContactHistoryData_wipesOutNoEntity() { jpaTm() .transact( @@ -302,7 +300,7 @@ class WipeOutContactHistoryPiiActionTest { }); } - @TestSqlOnly + @Test void wipeOutContactHistoryData_wipesOutMultipleEntities() { int numOfMonthsFromNow = MIN_MONTHS_BEFORE_WIPE_OUT + 3; ImmutableList expectedToBeWipedOut = diff --git a/core/src/test/java/google/registry/batch/WipeOutDatastoreActionTest.java b/core/src/test/java/google/registry/batch/WipeOutDatastoreActionTest.java deleted file mode 100644 index 2fcd94ec6..000000000 --- a/core/src/test/java/google/registry/batch/WipeOutDatastoreActionTest.java +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright 2021 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.batch; - -import static com.google.common.truth.Truth.assertThat; -import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN; -import static org.apache.http.HttpStatus.SC_INTERNAL_SERVER_ERROR; -import static org.apache.http.HttpStatus.SC_OK; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoInteractions; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import google.registry.beam.BeamActionTestBase; -import google.registry.config.RegistryEnvironment; -import google.registry.testing.FakeClock; -import org.junit.jupiter.api.Test; - -/** Unit tests for {@link WipeoutDatastoreAction}. */ -class WipeOutDatastoreActionTest extends BeamActionTestBase { - - private final FakeClock clock = new FakeClock(); - - @Test - void run_projectNotAllowed() { - try { - RegistryEnvironment.SANDBOX.setup(); - WipeoutDatastoreAction action = - new WipeoutDatastoreAction( - "domain-registry-sandbox", - "us-central1", - "gs://some-bucket", - clock, - response, - dataflow); - action.run(); - assertThat(response.getStatus()).isEqualTo(SC_FORBIDDEN); - verifyNoInteractions(dataflow); - } finally { - RegistryEnvironment.UNITTEST.setup(); - } - } - - @Test - void run_projectAllowed() throws Exception { - WipeoutDatastoreAction action = - new WipeoutDatastoreAction( - "domain-registry-qa", "us-central1", "gs://some-bucket", clock, response, dataflow); - action.run(); - assertThat(response.getStatus()).isEqualTo(SC_OK); - verify(launch, times(1)).execute(); - verifyNoMoreInteractions(launch); - } - - @Test - void run_failure() throws Exception { - when(launch.execute()).thenThrow(new RuntimeException()); - WipeoutDatastoreAction action = - new WipeoutDatastoreAction( - "domain-registry-qa", "us-central1", "gs://some-bucket", clock, response, dataflow); - action.run(); - assertThat(response.getStatus()).isEqualTo(SC_INTERNAL_SERVER_ERROR); - verify(launch, times(1)).execute(); - verifyNoMoreInteractions(launch); - } -} diff --git a/core/src/test/java/google/registry/beam/datastore/BulkDeleteDatastorePipelineTest.java b/core/src/test/java/google/registry/beam/datastore/BulkDeleteDatastorePipelineTest.java deleted file mode 100644 index da7e7214c..000000000 --- a/core/src/test/java/google/registry/beam/datastore/BulkDeleteDatastorePipelineTest.java +++ /dev/null @@ -1,152 +0,0 @@ -// Copyright 2020 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.beam.datastore; - -import static google.registry.beam.datastore.BulkDeleteDatastorePipeline.discoverEntityKinds; -import static google.registry.beam.datastore.BulkDeleteDatastorePipeline.getDeletionTags; -import static google.registry.beam.datastore.BulkDeleteDatastorePipeline.getOneDeletionTag; - -import com.google.common.base.Verify; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Iterables; -import com.google.datastore.v1.Entity; -import com.google.datastore.v1.Key; -import com.google.datastore.v1.Key.PathElement; -import google.registry.beam.TestPipelineExtension; -import google.registry.beam.datastore.BulkDeleteDatastorePipeline.GenerateQueries; -import google.registry.beam.datastore.BulkDeleteDatastorePipeline.SplitEntities; -import java.io.Serializable; -import java.util.Map; -import org.apache.beam.sdk.testing.PAssert; -import org.apache.beam.sdk.transforms.Count; -import org.apache.beam.sdk.transforms.Create; -import org.apache.beam.sdk.transforms.ParDo; -import org.apache.beam.sdk.transforms.View; -import org.apache.beam.sdk.values.KV; -import org.apache.beam.sdk.values.PCollection; -import org.apache.beam.sdk.values.PCollectionTuple; -import org.apache.beam.sdk.values.PCollectionView; -import org.apache.beam.sdk.values.TupleTag; -import org.apache.beam.sdk.values.TupleTagList; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.condition.EnabledIfSystemProperty; -import org.junit.jupiter.api.extension.RegisterExtension; - -/** Unit tests for {@link BulkDeleteDatastorePipeline}. */ -class BulkDeleteDatastorePipelineTest implements Serializable { - - @RegisterExtension - final transient TestPipelineExtension testPipeline = - TestPipelineExtension.create().enableAbandonedNodeEnforcement(true); - - @Test - void generateQueries() { - PCollection queries = - testPipeline - .apply("InjectKinds", Create.of("A", "B")) - .apply("GenerateQueries", ParDo.of(new GenerateQueries())); - - PAssert.that(queries).containsInAnyOrder("select __key__ from `A`", "select __key__ from `B`"); - testPipeline.run(); - } - - @Test - void mapKindsToTags() { - TupleTagList tags = getDeletionTags(2); - PCollection kinds = testPipeline.apply("InjectKinds", Create.of("A", "B")); - PCollection>> kindToTagMapping = - BulkDeleteDatastorePipeline.mapKindsToDeletionTags(kinds, tags); - PAssert.thatMap(kindToTagMapping) - .isEqualTo( - ImmutableMap.of( - "A", new TupleTag("0"), - "B", new TupleTag("1"))); - testPipeline.run(); - } - - @Test - void mapKindsToTags_fewerKindsThanTags() { - TupleTagList tags = getDeletionTags(3); - PCollection kinds = testPipeline.apply("InjectKinds", Create.of("A", "B")); - PCollection>> kindToTagMapping = - BulkDeleteDatastorePipeline.mapKindsToDeletionTags(kinds, tags); - PAssert.thatMap(kindToTagMapping) - .isEqualTo( - ImmutableMap.of( - "A", new TupleTag("0"), - "B", new TupleTag("1"))); - testPipeline.run(); - } - - @Test - void mapKindsToTags_moreKindsThanTags() { - TupleTagList tags = getDeletionTags(2); - PCollection kinds = testPipeline.apply("InjectKinds", Create.of("A", "B", "C")); - PCollection>> kindToTagMapping = - BulkDeleteDatastorePipeline.mapKindsToDeletionTags(kinds, tags); - PAssert.thatMap(kindToTagMapping) - .isEqualTo( - ImmutableMap.of( - "A", new TupleTag("0"), - "B", new TupleTag("1"), - "C", new TupleTag("0"))); - testPipeline.run(); - } - - @Test - void splitEntitiesByKind() { - TupleTagList tags = getDeletionTags(2); - PCollection kinds = testPipeline.apply("InjectKinds", Create.of("A", "B")); - PCollectionView>> kindToTagMapping = - BulkDeleteDatastorePipeline.mapKindsToDeletionTags(kinds, tags).apply(View.asMap()); - Entity entityA = createTestEntity("A", 1); - Entity entityB = createTestEntity("B", 2); - PCollection entities = - testPipeline.apply("InjectEntities", Create.of(entityA, entityB)); - PCollectionTuple allCollections = - entities.apply( - "SplitByKind", - ParDo.of(new SplitEntities(kindToTagMapping)) - .withSideInputs(kindToTagMapping) - .withOutputTags(getOneDeletionTag("placeholder"), tags)); - PAssert.that(allCollections.get((TupleTag) tags.get(0))).containsInAnyOrder(entityA); - PAssert.that(allCollections.get((TupleTag) tags.get(1))).containsInAnyOrder(entityB); - testPipeline.run(); - } - - private static Entity createTestEntity(String kind, long id) { - return Entity.newBuilder() - .setKey(Key.newBuilder().addPath(PathElement.newBuilder().setId(id).setKind(kind))) - .build(); - } - - @Test - @EnabledIfSystemProperty(named = "test.gcp_integration.env", matches = "\\S+") - void discoverKindsFromDatastore() { - String environmentName = System.getProperty("test.gcp_integration.env"); - String project = "domain-registry-" + environmentName; - - PCollection kinds = - testPipeline.apply("DiscoverEntityKinds", discoverEntityKinds(project)); - - PAssert.that(kinds.apply(Count.globally())) - .satisfies( - longs -> { - Verify.verify(Iterables.size(longs) == 1 && Iterables.getFirst(longs, -1L) > 0); - return null; - }); - testPipeline.run(); - } -} diff --git a/core/src/test/java/google/registry/cron/TldFanoutActionTest.java b/core/src/test/java/google/registry/cron/TldFanoutActionTest.java index 6e850e569..174731b6a 100644 --- a/core/src/test/java/google/registry/cron/TldFanoutActionTest.java +++ b/core/src/test/java/google/registry/cron/TldFanoutActionTest.java @@ -48,8 +48,7 @@ class TldFanoutActionTest { private final CloudTasksHelper cloudTasksHelper = new CloudTasksHelper(new FakeClock()); @RegisterExtension - final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().build(); + final AppEngineExtension appEngine = AppEngineExtension.builder().withCloudSql().build(); private static ImmutableListMultimap getParamsMap(String... keysAndValues) { ImmutableListMultimap.Builder params = new ImmutableListMultimap.Builder<>(); diff --git a/core/src/test/java/google/registry/dns/DnsInjectionTest.java b/core/src/test/java/google/registry/dns/DnsInjectionTest.java index acfd62cb6..6b297feb4 100644 --- a/core/src/test/java/google/registry/dns/DnsInjectionTest.java +++ b/core/src/test/java/google/registry/dns/DnsInjectionTest.java @@ -45,7 +45,7 @@ public final class DnsInjectionTest { @RegisterExtension public final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().withTaskQueue().build(); + AppEngineExtension.builder().withCloudSql().withTaskQueue().build(); @RegisterExtension public final InjectExtension inject = new InjectExtension(); diff --git a/core/src/test/java/google/registry/dns/DnsQueueTest.java b/core/src/test/java/google/registry/dns/DnsQueueTest.java index 613ee9825..338a60ffa 100644 --- a/core/src/test/java/google/registry/dns/DnsQueueTest.java +++ b/core/src/test/java/google/registry/dns/DnsQueueTest.java @@ -33,7 +33,7 @@ public class DnsQueueTest { @RegisterExtension public final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().withTaskQueue().build(); + AppEngineExtension.builder().withCloudSql().withTaskQueue().build(); private DnsQueue dnsQueue; private final FakeClock clock = new FakeClock(DateTime.parse("2010-01-01T10:00:00Z")); diff --git a/core/src/test/java/google/registry/dns/PublishDnsUpdatesActionTest.java b/core/src/test/java/google/registry/dns/PublishDnsUpdatesActionTest.java index 1a21fbbad..2b4e32751 100644 --- a/core/src/test/java/google/registry/dns/PublishDnsUpdatesActionTest.java +++ b/core/src/test/java/google/registry/dns/PublishDnsUpdatesActionTest.java @@ -53,7 +53,7 @@ public class PublishDnsUpdatesActionTest { @RegisterExtension public final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().withTaskQueue().build(); + AppEngineExtension.builder().withCloudSql().withTaskQueue().build(); @RegisterExtension public final InjectExtension inject = new InjectExtension(); private final FakeClock clock = new FakeClock(DateTime.parse("1971-01-01TZ")); diff --git a/core/src/test/java/google/registry/dns/ReadDnsQueueActionTest.java b/core/src/test/java/google/registry/dns/ReadDnsQueueActionTest.java index e2eb026c8..449758eb9 100644 --- a/core/src/test/java/google/registry/dns/ReadDnsQueueActionTest.java +++ b/core/src/test/java/google/registry/dns/ReadDnsQueueActionTest.java @@ -72,7 +72,7 @@ public class ReadDnsQueueActionTest { @RegisterExtension public final AppEngineExtension appEngine = AppEngineExtension.builder() - .withDatastoreAndCloudSql() + .withCloudSql() .withTaskQueue( Joiner.on('\n') .join( diff --git a/core/src/test/java/google/registry/dns/RefreshDnsActionTest.java b/core/src/test/java/google/registry/dns/RefreshDnsActionTest.java index 4bd003881..622711e64 100644 --- a/core/src/test/java/google/registry/dns/RefreshDnsActionTest.java +++ b/core/src/test/java/google/registry/dns/RefreshDnsActionTest.java @@ -39,7 +39,7 @@ public class RefreshDnsActionTest { @RegisterExtension public final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().withTaskQueue().build(); + AppEngineExtension.builder().withCloudSql().withTaskQueue().build(); private final DnsQueue dnsQueue = mock(DnsQueue.class); private final FakeClock clock = new FakeClock(); diff --git a/core/src/test/java/google/registry/dns/writer/clouddns/CloudDnsWriterTest.java b/core/src/test/java/google/registry/dns/writer/clouddns/CloudDnsWriterTest.java index 6a924641c..e1eb565e7 100644 --- a/core/src/test/java/google/registry/dns/writer/clouddns/CloudDnsWriterTest.java +++ b/core/src/test/java/google/registry/dns/writer/clouddns/CloudDnsWriterTest.java @@ -45,8 +45,6 @@ import google.registry.model.eppcommon.StatusValue; import google.registry.model.host.HostResource; import google.registry.persistence.VKey; import google.registry.testing.AppEngineExtension; -import google.registry.testing.DualDatabaseTest; -import google.registry.testing.TestOfyAndSql; import google.registry.util.Retrier; import google.registry.util.SystemClock; import google.registry.util.SystemSleeper; @@ -56,6 +54,7 @@ import java.net.Inet6Address; import java.net.InetAddress; import org.joda.time.Duration; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.RegisterExtension; import org.mockito.ArgumentCaptor; @@ -68,12 +67,10 @@ import org.mockito.quality.Strictness; /** Test case for {@link CloudDnsWriter}. */ @ExtendWith(MockitoExtension.class) -@DualDatabaseTest public class CloudDnsWriterTest { @RegisterExtension - public final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().build(); + public final AppEngineExtension appEngine = AppEngineExtension.builder().withCloudSql().build(); private static final Inet4Address IPv4 = (Inet4Address) InetAddresses.forString("127.0.0.1"); private static final Inet6Address IPv6 = (Inet6Address) InetAddresses.forString("::1"); @@ -314,7 +311,7 @@ public class CloudDnsWriterTest { } @MockitoSettings(strictness = Strictness.LENIENT) - @TestOfyAndSql + @Test void testLoadDomain_nonExistentDomain() { writer.publishDomain("example.tld"); @@ -322,7 +319,7 @@ public class CloudDnsWriterTest { } @MockitoSettings(strictness = Strictness.LENIENT) - @TestOfyAndSql + @Test void testLoadDomain_noDsDataOrNameservers() { persistResource(fakeDomain("example.tld", ImmutableSet.of(), 0)); writer.publishDomain("example.tld"); @@ -330,7 +327,7 @@ public class CloudDnsWriterTest { verifyZone(fakeDomainRecords("example.tld", 0, 0, 0, 0)); } - @TestOfyAndSql + @Test void testLoadDomain_deleteOldData() { stubZone = fakeDomainRecords("example.tld", 2, 2, 2, 2); persistResource(fakeDomain("example.tld", ImmutableSet.of(), 0)); @@ -339,7 +336,7 @@ public class CloudDnsWriterTest { verifyZone(fakeDomainRecords("example.tld", 0, 0, 0, 0)); } - @TestOfyAndSql + @Test void testLoadDomain_withExternalNs() { persistResource( fakeDomain("example.tld", ImmutableSet.of(persistResource(fakeHost("0.external"))), 0)); @@ -348,7 +345,7 @@ public class CloudDnsWriterTest { verifyZone(fakeDomainRecords("example.tld", 0, 0, 1, 0)); } - @TestOfyAndSql + @Test void testLoadDomain_withDsData() { persistResource( fakeDomain("example.tld", ImmutableSet.of(persistResource(fakeHost("0.external"))), 1)); @@ -357,7 +354,7 @@ public class CloudDnsWriterTest { verifyZone(fakeDomainRecords("example.tld", 0, 0, 1, 1)); } - @TestOfyAndSql + @Test void testLoadDomain_withInBailiwickNs_IPv4() { persistResource( fakeDomain( @@ -372,7 +369,7 @@ public class CloudDnsWriterTest { verifyZone(fakeDomainRecords("example.tld", 1, 0, 0, 0)); } - @TestOfyAndSql + @Test void testLoadDomain_withInBailiwickNs_IPv6() { persistResource( fakeDomain( @@ -387,7 +384,7 @@ public class CloudDnsWriterTest { verifyZone(fakeDomainRecords("example.tld", 0, 1, 0, 0)); } - @TestOfyAndSql + @Test void testLoadDomain_withNameserveThatEndsWithDomainName() { persistResource( fakeDomain( @@ -400,7 +397,7 @@ public class CloudDnsWriterTest { } @MockitoSettings(strictness = Strictness.LENIENT) - @TestOfyAndSql + @Test void testLoadHost_externalHost() { writer.publishHost("ns1.example.com"); @@ -408,7 +405,7 @@ public class CloudDnsWriterTest { verifyZone(ImmutableSet.of()); } - @TestOfyAndSql + @Test void testLoadHost_removeStaleNsRecords() { // Initialize the zone with both NS records stubZone = fakeDomainRecords("example.tld", 2, 0, 0, 0); @@ -431,7 +428,7 @@ public class CloudDnsWriterTest { } @MockitoSettings(strictness = Strictness.LENIENT) - @TestOfyAndSql + @Test void retryMutateZoneOnError() { CloudDnsWriter spyWriter = spy(writer); // First call - throw. Second call - do nothing. @@ -445,7 +442,7 @@ public class CloudDnsWriterTest { } @MockitoSettings(strictness = Strictness.LENIENT) - @TestOfyAndSql + @Test void testLoadDomain_withClientHold() { persistResource( fakeDomain( @@ -461,7 +458,7 @@ public class CloudDnsWriterTest { } @MockitoSettings(strictness = Strictness.LENIENT) - @TestOfyAndSql + @Test void testLoadDomain_withServerHold() { persistResource( fakeDomain( @@ -478,7 +475,7 @@ public class CloudDnsWriterTest { } @MockitoSettings(strictness = Strictness.LENIENT) - @TestOfyAndSql + @Test void testLoadDomain_withPendingDelete() { persistResource( fakeDomain( @@ -493,7 +490,7 @@ public class CloudDnsWriterTest { verifyZone(ImmutableSet.of()); } - @TestOfyAndSql + @Test void testDuplicateRecords() { // In publishing DNS records, we can end up publishing information on the same host twice // (through a domain change and a host change), so this scenario needs to work. @@ -511,7 +508,7 @@ public class CloudDnsWriterTest { verifyZone(fakeDomainRecords("example.tld", 1, 0, 0, 0)); } - @TestOfyAndSql + @Test void testInvalidZoneNames() { createTld("triple.secret.tld"); persistResource( @@ -527,7 +524,7 @@ public class CloudDnsWriterTest { } @MockitoSettings(strictness = Strictness.LENIENT) - @TestOfyAndSql + @Test void testEmptyCommit() { writer.commit(); verify(dnsConnection, times(0)).changes(); diff --git a/core/src/test/java/google/registry/dns/writer/dnsupdate/DnsUpdateWriterTest.java b/core/src/test/java/google/registry/dns/writer/dnsupdate/DnsUpdateWriterTest.java index 59ddc9f4f..2962d3879 100644 --- a/core/src/test/java/google/registry/dns/writer/dnsupdate/DnsUpdateWriterTest.java +++ b/core/src/test/java/google/registry/dns/writer/dnsupdate/DnsUpdateWriterTest.java @@ -42,15 +42,14 @@ import google.registry.model.eppcommon.StatusValue; import google.registry.model.host.HostResource; import google.registry.model.ofy.Ofy; import google.registry.testing.AppEngineExtension; -import google.registry.testing.DualDatabaseTest; import google.registry.testing.FakeClock; import google.registry.testing.InjectExtension; -import google.registry.testing.TestOfyAndSql; import java.util.ArrayList; import java.util.Collections; import org.joda.time.DateTime; import org.joda.time.Duration; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.RegisterExtension; import org.mockito.ArgumentCaptor; @@ -71,12 +70,11 @@ import org.xbill.DNS.Update; /** Unit tests for {@link DnsUpdateWriter}. */ @ExtendWith(MockitoExtension.class) -@DualDatabaseTest public class DnsUpdateWriterTest { @RegisterExtension public final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().withTaskQueue().build(); + AppEngineExtension.builder().withCloudSql().withTaskQueue().build(); @RegisterExtension public final InjectExtension inject = new InjectExtension(); @@ -98,7 +96,7 @@ public class DnsUpdateWriterTest { "tld", Duration.ZERO, Duration.ZERO, Duration.ZERO, mockResolver, clock); } - @TestOfyAndSql + @Test void testPublishDomainCreate_publishesNameServers() throws Exception { HostResource host1 = persistActiveHost("ns1.example.tld"); HostResource host2 = persistActiveHost("ns2.example.tld"); @@ -121,7 +119,7 @@ public class DnsUpdateWriterTest { } @MockitoSettings(strictness = Strictness.LENIENT) - @TestOfyAndSql + @Test void testPublishAtomic_noCommit() { HostResource host1 = persistActiveHost("ns.example1.tld"); DomainBase domain1 = @@ -145,7 +143,7 @@ public class DnsUpdateWriterTest { verifyNoInteractions(mockResolver); } - @TestOfyAndSql + @Test void testPublishAtomic_oneUpdate() throws Exception { HostResource host1 = persistActiveHost("ns.example1.tld"); DomainBase domain1 = @@ -177,7 +175,7 @@ public class DnsUpdateWriterTest { assertThatTotalUpdateSetsIs(update, 4); // The delete and NS sets for each TLD } - @TestOfyAndSql + @Test void testPublishDomainCreate_publishesDelegationSigner() throws Exception { DomainBase domain = persistActiveDomain("example.tld") @@ -201,7 +199,7 @@ public class DnsUpdateWriterTest { assertThatTotalUpdateSetsIs(update, 3); // The delete, the NS, and DS sets } - @TestOfyAndSql + @Test void testPublishDomainWhenNotActive_removesDnsRecords() throws Exception { DomainBase domain = persistActiveDomain("example.tld") @@ -221,7 +219,7 @@ public class DnsUpdateWriterTest { assertThatTotalUpdateSetsIs(update, 1); // Just the delete set } - @TestOfyAndSql + @Test void testPublishDomainDelete_removesDnsRecords() throws Exception { persistDeletedDomain("example.tld", clock.nowUtc().minusDays(1)); @@ -235,7 +233,7 @@ public class DnsUpdateWriterTest { assertThatTotalUpdateSetsIs(update, 1); // Just the delete set } - @TestOfyAndSql + @Test void testPublishHostCreate_publishesAddressRecords() throws Exception { HostResource host = persistResource( @@ -268,7 +266,7 @@ public class DnsUpdateWriterTest { assertThatTotalUpdateSetsIs(update, 5); } - @TestOfyAndSql + @Test void testPublishHostDelete_removesDnsRecords() throws Exception { persistDeletedHost("ns1.example.tld", clock.nowUtc().minusDays(1)); persistActiveDomain("example.tld"); @@ -284,7 +282,7 @@ public class DnsUpdateWriterTest { assertThatTotalUpdateSetsIs(update, 2); // Just the delete set } - @TestOfyAndSql + @Test void testPublishHostDelete_removesGlueRecords() throws Exception { persistDeletedHost("ns1.example.tld", clock.nowUtc().minusDays(1)); persistResource( @@ -305,7 +303,7 @@ public class DnsUpdateWriterTest { assertThatTotalUpdateSetsIs(update, 3); } - @TestOfyAndSql + @Test void testPublishDomainExternalAndInBailiwickNameServer() throws Exception { HostResource externalNameserver = persistResource(newHostResource("ns1.example.com")); HostResource inBailiwickNameserver = @@ -342,7 +340,7 @@ public class DnsUpdateWriterTest { assertThatTotalUpdateSetsIs(update, 5); } - @TestOfyAndSql + @Test void testPublishDomainDeleteOrphanGlues() throws Exception { HostResource inBailiwickNameserver = persistResource( @@ -380,7 +378,7 @@ public class DnsUpdateWriterTest { @MockitoSettings(strictness = Strictness.LENIENT) @SuppressWarnings("AssertThrowsMultipleStatements") - @TestOfyAndSql + @Test void testPublishDomainFails_whenDnsUpdateReturnsError() throws Exception { DomainBase domain = persistActiveDomain("example.tld") @@ -401,7 +399,7 @@ public class DnsUpdateWriterTest { @MockitoSettings(strictness = Strictness.LENIENT) @SuppressWarnings("AssertThrowsMultipleStatements") - @TestOfyAndSql + @Test void testPublishHostFails_whenDnsUpdateReturnsError() throws Exception { HostResource host = persistActiveSubordinateHost("ns1.example.tld", persistActiveDomain("example.tld")) diff --git a/core/src/test/java/google/registry/export/AnnotatedEntitiesTest.java b/core/src/test/java/google/registry/export/AnnotatedEntitiesTest.java deleted file mode 100644 index c115f37c9..000000000 --- a/core/src/test/java/google/registry/export/AnnotatedEntitiesTest.java +++ /dev/null @@ -1,102 +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.export; - -import static com.google.common.base.Strings.repeat; -import static com.google.common.collect.ImmutableList.toImmutableList; -import static com.google.common.io.Resources.getResource; -import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.Truth.assertWithMessage; -import static google.registry.export.AnnotatedEntities.getBackupKinds; -import static google.registry.export.AnnotatedEntities.getCrossTldKinds; -import static google.registry.export.AnnotatedEntities.getReportingKinds; -import static google.registry.util.ResourceUtils.readResourceUtf8; - -import com.google.common.base.Joiner; -import com.google.common.base.Splitter; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Streams; -import com.google.re2j.Pattern; -import org.junit.jupiter.api.Test; - -/** Unit tests for {@link AnnotatedEntities}. */ -class AnnotatedEntitiesTest { - - private static final String GOLDEN_BACKUP_KINDS_FILENAME = "backup_kinds.txt"; - - private static final String GOLDEN_REPORTING_KINDS_FILENAME = "reporting_kinds.txt"; - - private static final String GOLDEN_CROSSTLD_KINDS_FILENAME = "crosstld_kinds.txt"; - - private static final String UPDATE_INSTRUCTIONS_TEMPLATE = Joiner.on('\n').join( - "", - repeat("-", 80), - "Your changes affect the list of %s kinds in the golden file:", - " %s", - "If these changes are desired, update the golden file with the following contents:", - repeat("=", 80), - "%s", - repeat("=", 80), - ""); - - @Test - void testBackupKinds_matchGoldenFile() { - checkKindsMatchGoldenFile("backed-up", GOLDEN_BACKUP_KINDS_FILENAME, getBackupKinds()); - } - - @Test - void testReportingKinds_matchGoldenFile() { - checkKindsMatchGoldenFile("reporting", GOLDEN_REPORTING_KINDS_FILENAME, getReportingKinds()); - } - - @Test - void testCrossTldKinds_matchGoldenFile() { - checkKindsMatchGoldenFile("crosstld", GOLDEN_CROSSTLD_KINDS_FILENAME, getCrossTldKinds()); - } - - @Test - void testReportingKinds_areSubsetOfBackupKinds() { - assertThat(getBackupKinds()).containsAtLeastElementsIn(getReportingKinds()); - } - - private static void checkKindsMatchGoldenFile( - String kindsName, String goldenFilename, ImmutableSet actualKinds) { - String updateInstructions = - String.format( - UPDATE_INSTRUCTIONS_TEMPLATE, - kindsName, - getResource(AnnotatedEntitiesTest.class, goldenFilename).toString(), - Joiner.on('\n').join(actualKinds)); - assertWithMessage(updateInstructions) - .that(actualKinds) - .containsExactlyElementsIn(extractListFromFile(goldenFilename)) - .inOrder(); - } - - /** - * Helper method to extract list from file - * - * @param filename - * @return ImmutableList - */ - private static ImmutableList extractListFromFile(String filename) { - String fileContents = readResourceUtf8(AnnotatedEntitiesTest.class, filename); - final Pattern stripComments = Pattern.compile("\\s*#.*$"); - return Streams.stream(Splitter.on('\n').split(fileContents.trim())) - .map(line -> stripComments.matcher(line).replaceFirst("")) - .collect(toImmutableList()); - } -} diff --git a/core/src/test/java/google/registry/export/BackupDatastoreActionTest.java b/core/src/test/java/google/registry/export/BackupDatastoreActionTest.java deleted file mode 100644 index cc4ffce08..000000000 --- a/core/src/test/java/google/registry/export/BackupDatastoreActionTest.java +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright 2018 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.export; - -import static com.google.common.truth.Truth.assertThat; -import static google.registry.export.CheckBackupAction.CHECK_BACKUP_KINDS_TO_LOAD_PARAM; -import static google.registry.export.CheckBackupAction.CHECK_BACKUP_NAME_PARAM; -import static org.mockito.Mockito.when; - -import com.google.cloud.tasks.v2.HttpMethod; -import com.google.common.base.Joiner; -import com.google.protobuf.util.Timestamps; -import google.registry.export.datastore.DatastoreAdmin; -import google.registry.export.datastore.DatastoreAdmin.Export; -import google.registry.export.datastore.Operation; -import google.registry.testing.AppEngineExtension; -import google.registry.testing.CloudTasksHelper; -import google.registry.testing.CloudTasksHelper.TaskMatcher; -import google.registry.testing.FakeClock; -import google.registry.testing.FakeResponse; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -/** Unit tests for {@link BackupDatastoreAction}. */ -@ExtendWith(MockitoExtension.class) -public class BackupDatastoreActionTest { - - @RegisterExtension - public final AppEngineExtension appEngine = AppEngineExtension.builder().withTaskQueue().build(); - - @Mock private DatastoreAdmin datastoreAdmin; - @Mock private Export exportRequest; - @Mock private Operation backupOperation; - - private final FakeResponse response = new FakeResponse(); - private CloudTasksHelper cloudTasksHelper = new CloudTasksHelper(); - private final BackupDatastoreAction action = new BackupDatastoreAction(); - - @BeforeEach - void beforeEach() throws Exception { - action.datastoreAdmin = datastoreAdmin; - action.response = response; - action.cloudTasksUtils = cloudTasksHelper.getTestCloudTasksUtils(); - action.clock = new FakeClock(); - when(datastoreAdmin.export( - "gs://registry-project-id-datastore-backups", AnnotatedEntities.getBackupKinds())) - .thenReturn(exportRequest); - when(exportRequest.execute()).thenReturn(backupOperation); - when(backupOperation.getName()) - .thenReturn("projects/registry-project-id/operations/ASA1ODYwNjc"); - when(backupOperation.getExportFolderUrl()) - .thenReturn("gs://registry-project-id-datastore-backups/some-id"); - } - - @Test - void testBackup_enqueuesPollTask() { - action.run(); - cloudTasksHelper.assertTasksEnqueued( - CheckBackupAction.QUEUE, - new TaskMatcher() - .url(CheckBackupAction.PATH) - .param(CHECK_BACKUP_NAME_PARAM, "projects/registry-project-id/operations/ASA1ODYwNjc") - .param( - CHECK_BACKUP_KINDS_TO_LOAD_PARAM, - Joiner.on(",").join(AnnotatedEntities.getReportingKinds())) - .method(HttpMethod.POST) - .scheduleTime( - Timestamps.fromMillis( - action.clock.nowUtc().plus(CheckBackupAction.POLL_COUNTDOWN).getMillis()))); - assertThat(response.getPayload()) - .isEqualTo( - "Datastore backup started with name: " - + "projects/registry-project-id/operations/ASA1ODYwNjc\n" - + "Saving to gs://registry-project-id-datastore-backups/some-id"); - } -} diff --git a/core/src/test/java/google/registry/export/BigqueryPollJobActionTest.java b/core/src/test/java/google/registry/export/BigqueryPollJobActionTest.java deleted file mode 100644 index 20a738438..000000000 --- a/core/src/test/java/google/registry/export/BigqueryPollJobActionTest.java +++ /dev/null @@ -1,161 +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.export; - -import static com.google.common.truth.Truth.assertThat; -import static google.registry.testing.TestLogHandlerUtils.assertLogMessage; -import static java.nio.charset.StandardCharsets.UTF_8; -import static java.util.logging.Level.INFO; -import static java.util.logging.Level.SEVERE; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import com.google.api.services.bigquery.Bigquery; -import com.google.api.services.bigquery.model.ErrorProto; -import com.google.api.services.bigquery.model.Job; -import com.google.api.services.bigquery.model.JobStatus; -import com.google.cloud.tasks.v2.AppEngineHttpRequest; -import com.google.cloud.tasks.v2.HttpMethod; -import com.google.cloud.tasks.v2.Task; -import com.google.common.net.HttpHeaders; -import com.google.common.net.MediaType; -import com.google.protobuf.ByteString; -import google.registry.request.HttpException.BadRequestException; -import google.registry.request.HttpException.NotModifiedException; -import google.registry.testing.AppEngineExtension; -import google.registry.testing.CloudTasksHelper; -import google.registry.testing.CloudTasksHelper.TaskMatcher; -import google.registry.util.CapturingLogHandler; -import google.registry.util.JdkLoggerConfig; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.ObjectOutputStream; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; - -/** Unit tests for {@link BigqueryPollJobAction}. */ -public class BigqueryPollJobActionTest { - - @RegisterExtension - public final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().withTaskQueue().build(); - - private static final String PROJECT_ID = "project_id"; - private static final String JOB_ID = "job_id"; - private static final String CHAINED_QUEUE_NAME = UpdateSnapshotViewAction.QUEUE; - - private final Bigquery bigquery = mock(Bigquery.class); - private final Bigquery.Jobs bigqueryJobs = mock(Bigquery.Jobs.class); - private final Bigquery.Jobs.Get bigqueryJobsGet = mock(Bigquery.Jobs.Get.class); - - private final CapturingLogHandler logHandler = new CapturingLogHandler(); - private BigqueryPollJobAction action = new BigqueryPollJobAction(); - private CloudTasksHelper cloudTasksHelper = new CloudTasksHelper(); - - @BeforeEach - void beforeEach() throws Exception { - action.bigquery = bigquery; - when(bigquery.jobs()).thenReturn(bigqueryJobs); - when(bigqueryJobs.get(PROJECT_ID, JOB_ID)).thenReturn(bigqueryJobsGet); - action.cloudTasksUtils = cloudTasksHelper.getTestCloudTasksUtils(); - action.projectId = PROJECT_ID; - action.jobId = JOB_ID; - action.chainedQueueName = () -> CHAINED_QUEUE_NAME; - JdkLoggerConfig.getConfig(BigqueryPollJobAction.class).addHandler(logHandler); - } - - @Test - void testSuccess_jobCompletedSuccessfully() throws Exception { - when(bigqueryJobsGet.execute()).thenReturn( - new Job().setStatus(new JobStatus().setState("DONE"))); - action.run(); - assertLogMessage( - logHandler, INFO, String.format("Bigquery job succeeded - %s:%s", PROJECT_ID, JOB_ID)); - } - - @Test - void testSuccess_chainedPayloadAndJobSucceeded_enqueuesChainedTask() throws Exception { - when(bigqueryJobsGet.execute()).thenReturn( - new Job().setStatus(new JobStatus().setState("DONE"))); - - Task chainedTask = - Task.newBuilder() - .setName("my_task_name") - .setAppEngineHttpRequest( - AppEngineHttpRequest.newBuilder() - .setHttpMethod(HttpMethod.POST) - .setRelativeUri("/_dr/something") - .putHeaders("X-Test", "foo") - .putHeaders(HttpHeaders.CONTENT_TYPE, MediaType.FORM_DATA.toString()) - .setBody(ByteString.copyFromUtf8("testing=bar"))) - .build(); - ByteArrayOutputStream bytes = new ByteArrayOutputStream(); - new ObjectOutputStream(bytes).writeObject(chainedTask); - action.payload = ByteString.copyFrom(bytes.toByteArray()); - - action.run(); - assertLogMessage( - logHandler, INFO, String.format("Bigquery job succeeded - %s:%s", PROJECT_ID, JOB_ID)); - assertLogMessage( - logHandler, - INFO, - "Added chained task my_task_name for /_dr/something to queue " + CHAINED_QUEUE_NAME); - cloudTasksHelper.assertTasksEnqueued( - CHAINED_QUEUE_NAME, - new TaskMatcher() - .url("/_dr/something") - .header("X-Test", "foo") - .header(HttpHeaders.CONTENT_TYPE, MediaType.FORM_DATA.toString()) - .param("testing", "bar") - .taskName("my_task_name") - .method(HttpMethod.POST)); - } - - @Test - void testJobFailed() throws Exception { - when(bigqueryJobsGet.execute()).thenReturn(new Job().setStatus( - new JobStatus() - .setState("DONE") - .setErrorResult(new ErrorProto().setMessage("Job failed")))); - action.run(); - assertLogMessage( - logHandler, SEVERE, String.format("Bigquery job failed - %s:%s", PROJECT_ID, JOB_ID)); - cloudTasksHelper.assertNoTasksEnqueued(CHAINED_QUEUE_NAME); - } - - @Test - void testJobPending() throws Exception { - when(bigqueryJobsGet.execute()).thenReturn( - new Job().setStatus(new JobStatus().setState("PENDING"))); - assertThrows(NotModifiedException.class, action::run); - } - - @Test - void testJobStatusUnreadable() throws Exception { - when(bigqueryJobsGet.execute()).thenThrow(IOException.class); - assertThrows(NotModifiedException.class, action::run); - } - - @Test - void testFailure_badChainedTaskPayload() throws Exception { - when(bigqueryJobsGet.execute()).thenReturn( - new Job().setStatus(new JobStatus().setState("DONE"))); - action.payload = ByteString.copyFrom("payload".getBytes(UTF_8)); - BadRequestException thrown = assertThrows(BadRequestException.class, action::run); - assertThat(thrown).hasMessageThat().contains("Cannot deserialize task from payload"); - } -} diff --git a/core/src/test/java/google/registry/export/CheckBackupActionTest.java b/core/src/test/java/google/registry/export/CheckBackupActionTest.java deleted file mode 100644 index 0c133fc75..000000000 --- a/core/src/test/java/google/registry/export/CheckBackupActionTest.java +++ /dev/null @@ -1,211 +0,0 @@ -// Copyright 2018 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.export; - -import static com.google.common.truth.Truth.assertThat; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.when; - -import com.google.api.client.googleapis.json.GoogleJsonResponseException; -import com.google.api.client.http.HttpHeaders; -import com.google.api.client.json.JsonFactory; -import com.google.api.client.json.jackson2.JacksonFactory; -import com.google.cloud.tasks.v2.HttpMethod; -import google.registry.export.datastore.DatastoreAdmin; -import google.registry.export.datastore.DatastoreAdmin.Get; -import google.registry.export.datastore.Operation; -import google.registry.request.Action.Method; -import google.registry.request.HttpException.BadRequestException; -import google.registry.request.HttpException.NoContentException; -import google.registry.request.HttpException.NotModifiedException; -import google.registry.testing.AppEngineExtension; -import google.registry.testing.CloudTasksHelper; -import google.registry.testing.CloudTasksHelper.TaskMatcher; -import google.registry.testing.FakeClock; -import google.registry.testing.FakeResponse; -import google.registry.testing.TestDataHelper; -import org.joda.time.DateTime; -import org.joda.time.Duration; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.mockito.junit.jupiter.MockitoSettings; -import org.mockito.quality.Strictness; - -/** Unit tests for {@link CheckBackupAction}. */ -@ExtendWith(MockitoExtension.class) -public class CheckBackupActionTest { - - private static final DateTime START_TIME = DateTime.parse("2014-08-01T01:02:03Z"); - private static final DateTime COMPLETE_TIME = START_TIME.plus(Duration.standardMinutes(30)); - private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance(); - - @RegisterExtension - public final AppEngineExtension appEngine = AppEngineExtension.builder().withTaskQueue().build(); - - @Mock private DatastoreAdmin datastoreAdmin; - @Mock private Get getNotFoundBackupProgressRequest; - @Mock private Get getBackupProgressRequest; - private Operation backupOperation; - - private final FakeResponse response = new FakeResponse(); - private final FakeClock clock = new FakeClock(COMPLETE_TIME.plusMillis(1000)); - private final CheckBackupAction action = new CheckBackupAction(); - private final CloudTasksHelper cloudTasksHelper = new CloudTasksHelper(); - - @BeforeEach - void beforeEach() throws Exception { - action.requestMethod = Method.POST; - action.datastoreAdmin = datastoreAdmin; - action.clock = clock; - action.backupName = "some_backup"; - action.kindsToLoadParam = "one,two"; - action.response = response; - action.cloudTasksUtils = cloudTasksHelper.getTestCloudTasksUtils(); - - when(datastoreAdmin.get(anyString())).thenReturn(getBackupProgressRequest); - when(getBackupProgressRequest.execute()).thenAnswer(arg -> backupOperation); - } - - private void setPendingBackup() throws Exception { - backupOperation = - JSON_FACTORY.fromString( - TestDataHelper.loadFile( - CheckBackupActionTest.class, "backup_operation_in_progress.json"), - Operation.class); - } - - private void setCompleteBackup() throws Exception { - backupOperation = - JSON_FACTORY.fromString( - TestDataHelper.loadFile(CheckBackupActionTest.class, "backup_operation_success.json"), - Operation.class); - } - - private void setBackupNotFound() throws Exception { - when(datastoreAdmin.get(anyString())).thenReturn(getNotFoundBackupProgressRequest); - when(getNotFoundBackupProgressRequest.execute()) - .thenThrow( - new GoogleJsonResponseException( - new GoogleJsonResponseException.Builder(404, "NOT_FOUND", new HttpHeaders()) - .setMessage("No backup found"), - null)); - } - - private void assertLoadTaskEnqueued(String id, String folder, String kinds) { - cloudTasksHelper.assertTasksEnqueued( - "export-snapshot", - new TaskMatcher() - .url("/_dr/task/uploadDatastoreBackup") - .method(HttpMethod.POST) - .param("id", id) - .param("folder", folder) - .param("kinds", kinds)); - } - - @Test - void testPost_forPendingBackup_returnsNotModified() throws Exception { - setPendingBackup(); - - NotModifiedException thrown = assertThrows(NotModifiedException.class, action::run); - assertThat(thrown) - .hasMessageThat() - .contains("Datastore backup some_backup still in progress: Progress: N/A"); - } - - @Test - void testPost_forStalePendingBackupBackup_returnsNoContent() throws Exception { - setPendingBackup(); - clock.setTo( - START_TIME - .plus(Duration.standardHours(20)) - .plus(Duration.standardMinutes(3)) - .plus(Duration.millis(1234))); - - NoContentException thrown = assertThrows(NoContentException.class, action::run); - assertThat(thrown) - .hasMessageThat() - .contains( - "Datastore backup some_backup abandoned - " - + "not complete after 20 hours, 3 minutes and 1 second. Progress: Progress: N/A"); - } - - @Test - void testPost_forCompleteBackup_enqueuesLoadTask() throws Exception { - setCompleteBackup(); - action.run(); - assertLoadTaskEnqueued( - "2014-08-01T01:02:03_99364", - "gs://registry-project-id-datastore-export-test/2014-08-01T01:02:03_99364", - "one,two"); - } - - @Test - void testPost_forCompleteBackup_withExtraKindsToLoad_enqueuesLoadTask() throws Exception { - setCompleteBackup(); - action.kindsToLoadParam = "one,foo"; - - action.run(); - assertLoadTaskEnqueued( - "2014-08-01T01:02:03_99364", - "gs://registry-project-id-datastore-export-test/2014-08-01T01:02:03_99364", - "one"); - } - - @Test - void testPost_forCompleteBackup_withEmptyKindsToLoad_skipsLoadTask() throws Exception { - setCompleteBackup(); - action.kindsToLoadParam = ""; - - action.run(); - cloudTasksHelper.assertNoTasksEnqueued("export-snapshot"); - } - - @MockitoSettings(strictness = Strictness.LENIENT) - @Test - void testPost_forBadBackup_returnsBadRequest() throws Exception { - setBackupNotFound(); - - BadRequestException thrown = assertThrows(BadRequestException.class, action::run); - assertThat(thrown).hasMessageThat().contains("Bad backup name some_backup: No backup found"); - } - - @Test - void testGet_returnsInformation() throws Exception { - setCompleteBackup(); - action.requestMethod = Method.GET; - - action.run(); - assertThat(response.getPayload()) - .isEqualTo( - TestDataHelper.loadFile( - CheckBackupActionTest.class, "pretty_printed_success_backup_operation.json") - .trim()); - } - - @MockitoSettings(strictness = Strictness.LENIENT) - @Test - void testGet_forBadBackup_returnsError() throws Exception { - setBackupNotFound(); - action.requestMethod = Method.GET; - - BadRequestException thrown = assertThrows(BadRequestException.class, action::run); - assertThat(thrown).hasMessageThat().contains("Bad backup name some_backup: No backup found"); - } -} diff --git a/core/src/test/java/google/registry/export/ExportDomainListsActionTest.java b/core/src/test/java/google/registry/export/ExportDomainListsActionTest.java index 5c6de250b..712b747e2 100644 --- a/core/src/test/java/google/registry/export/ExportDomainListsActionTest.java +++ b/core/src/test/java/google/registry/export/ExportDomainListsActionTest.java @@ -38,18 +38,16 @@ import google.registry.model.tld.Registry; import google.registry.model.tld.Registry.TldType; import google.registry.storage.drive.DriveConnection; import google.registry.testing.AppEngineExtension; -import google.registry.testing.DualDatabaseTest; import google.registry.testing.FakeClock; import google.registry.testing.InjectExtension; -import google.registry.testing.TestOfyAndSql; import org.joda.time.DateTime; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.mockito.ArgumentCaptor; /** Unit tests for {@link ExportDomainListsAction}. */ -@DualDatabaseTest class ExportDomainListsActionTest { private final GcsUtils gcsUtils = new GcsUtils(LocalStorageHelper.getOptions()); @@ -60,11 +58,7 @@ class ExportDomainListsActionTest { @RegisterExtension public final AppEngineExtension appEngine = - AppEngineExtension.builder() - .withDatastoreAndCloudSql() - .withLocalModules() - .withTaskQueue() - .build(); + AppEngineExtension.builder().withCloudSql().withLocalModules().withTaskQueue().build(); @Order(Order.DEFAULT - 1) @RegisterExtension @@ -95,7 +89,7 @@ class ExportDomainListsActionTest { assertThat(new String(bytesExportedToDrive.getValue(), UTF_8)).isEqualTo(domains); } - @TestOfyAndSql + @Test void test_outputsOnlyActiveDomains() throws Exception { persistActiveDomain("onetwo.tld"); persistActiveDomain("rudnitzky.tld"); @@ -109,7 +103,7 @@ class ExportDomainListsActionTest { verifyNoMoreInteractions(driveConnection); } - @TestOfyAndSql + @Test void test_outputsOnlyDomainsOnRealTlds() throws Exception { persistActiveDomain("onetwo.tld"); persistActiveDomain("rudnitzky.tld"); @@ -128,7 +122,7 @@ class ExportDomainListsActionTest { verifyNoMoreInteractions(driveConnection); } - @TestOfyAndSql + @Test void test_outputsDomainsFromDifferentTldsToMultipleFiles() throws Exception { createTld("tldtwo"); persistResource(Registry.get("tldtwo").asBuilder().setDriveFolderId("hooray").build()); diff --git a/core/src/test/java/google/registry/export/ExportPremiumTermsActionTest.java b/core/src/test/java/google/registry/export/ExportPremiumTermsActionTest.java index efeb17a45..adebb0110 100644 --- a/core/src/test/java/google/registry/export/ExportPremiumTermsActionTest.java +++ b/core/src/test/java/google/registry/export/ExportPremiumTermsActionTest.java @@ -58,8 +58,7 @@ public class ExportPremiumTermsActionTest { DISCLAIMER_WITH_NEWLINE + "0, 549.00\n" + "2048, 549.00\n"; @RegisterExtension - public final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().build(); + public final AppEngineExtension appEngine = AppEngineExtension.builder().withCloudSql().build(); private final DriveConnection driveConnection = mock(DriveConnection.class); private final Response response = mock(Response.class); diff --git a/core/src/test/java/google/registry/export/ExportReservedTermsActionTest.java b/core/src/test/java/google/registry/export/ExportReservedTermsActionTest.java index 83ec241d0..159c7f3ce 100644 --- a/core/src/test/java/google/registry/export/ExportReservedTermsActionTest.java +++ b/core/src/test/java/google/registry/export/ExportReservedTermsActionTest.java @@ -46,8 +46,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; public class ExportReservedTermsActionTest { @RegisterExtension - public final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().build(); + public final AppEngineExtension appEngine = AppEngineExtension.builder().withCloudSql().build(); private final DriveConnection driveConnection = mock(DriveConnection.class); private final Response response = mock(Response.class); diff --git a/core/src/test/java/google/registry/export/ExportUtilsTest.java b/core/src/test/java/google/registry/export/ExportUtilsTest.java index 149355e30..699b127d8 100644 --- a/core/src/test/java/google/registry/export/ExportUtilsTest.java +++ b/core/src/test/java/google/registry/export/ExportUtilsTest.java @@ -29,8 +29,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; class ExportUtilsTest { @RegisterExtension - public final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().build(); + public final AppEngineExtension appEngine = AppEngineExtension.builder().withCloudSql().build(); @Test void test_exportReservedTerms() { diff --git a/core/src/test/java/google/registry/export/SyncGroupMembersActionTest.java b/core/src/test/java/google/registry/export/SyncGroupMembersActionTest.java index 2e62b7016..c9358c493 100644 --- a/core/src/test/java/google/registry/export/SyncGroupMembersActionTest.java +++ b/core/src/test/java/google/registry/export/SyncGroupMembersActionTest.java @@ -40,13 +40,12 @@ import google.registry.model.registrar.Registrar; import google.registry.model.registrar.RegistrarPoc; import google.registry.request.Response; import google.registry.testing.AppEngineExtension; -import google.registry.testing.DualDatabaseTest; import google.registry.testing.FakeClock; import google.registry.testing.FakeSleeper; import google.registry.testing.InjectExtension; -import google.registry.testing.TestOfyAndSql; import google.registry.util.Retrier; import java.io.IOException; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; /** @@ -55,12 +54,10 @@ import org.junit.jupiter.api.extension.RegisterExtension; *

Note that this relies on the registrars NewRegistrar and TheRegistrar created by default in * {@link AppEngineExtension}. */ -@DualDatabaseTest public class SyncGroupMembersActionTest { @RegisterExtension - public final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().build(); + public final AppEngineExtension appEngine = AppEngineExtension.builder().withCloudSql().build(); @RegisterExtension public final InjectExtension inject = new InjectExtension(); @@ -76,7 +73,7 @@ public class SyncGroupMembersActionTest { action.run(); } - @TestOfyAndSql + @Test void test_getGroupEmailAddressForContactType_convertsToLowercase() { assertThat( getGroupEmailAddressForContactType( @@ -84,7 +81,7 @@ public class SyncGroupMembersActionTest { .isEqualTo("someregistrar-primary-contacts@domain-registry.example"); } - @TestOfyAndSql + @Test void test_getGroupEmailAddressForContactType_convertsNonAlphanumericChars() { assertThat(getGroupEmailAddressForContactType( "Weird.ಠ_ಠRegistrar", @@ -93,7 +90,7 @@ public class SyncGroupMembersActionTest { .isEqualTo("weirdregistrar-marketing-contacts@domain-registry.example"); } - @TestOfyAndSql + @Test void test_doPost_noneModified() { persistResource( loadRegistrar("NewRegistrar").asBuilder().setContactsRequireSyncing(false).build()); @@ -106,7 +103,7 @@ public class SyncGroupMembersActionTest { assertThat(loadRegistrar("NewRegistrar").getContactsRequireSyncing()).isFalse(); } - @TestOfyAndSql + @Test void test_doPost_syncsNewContact() throws Exception { runAction(); verify(connection).addMemberToGroup( @@ -118,7 +115,7 @@ public class SyncGroupMembersActionTest { assertThat(loadRegistrar("NewRegistrar").getContactsRequireSyncing()).isFalse(); } - @TestOfyAndSql + @Test void test_doPost_removesOldContact() throws Exception { when(connection.getMembersOfGroup("newregistrar-primary-contacts@domain-registry.example")) .thenReturn(ImmutableSet.of("defunct@example.com", "janedoe@theregistrar.com")); @@ -129,7 +126,7 @@ public class SyncGroupMembersActionTest { assertThat(loadRegistrar("NewRegistrar").getContactsRequireSyncing()).isFalse(); } - @TestOfyAndSql + @Test void test_doPost_removesAllContactsFromGroup() throws Exception { when(connection.getMembersOfGroup("newregistrar-primary-contacts@domain-registry.example")) .thenReturn(ImmutableSet.of("defunct@example.com", "janedoe@theregistrar.com")); @@ -144,7 +141,7 @@ public class SyncGroupMembersActionTest { assertThat(loadRegistrar("NewRegistrar").getContactsRequireSyncing()).isFalse(); } - @TestOfyAndSql + @Test void test_doPost_addsAndRemovesContacts_acrossMultipleRegistrars() throws Exception { when(connection.getMembersOfGroup("newregistrar-primary-contacts@domain-registry.example")) .thenReturn(ImmutableSet.of("defunct@example.com", "janedoe@theregistrar.com")); @@ -192,7 +189,7 @@ public class SyncGroupMembersActionTest { .isEmpty(); } - @TestOfyAndSql + @Test void test_doPost_gracefullyHandlesExceptionForSingleRegistrar() throws Exception { when(connection.getMembersOfGroup("newregistrar-primary-contacts@domain-registry.example")) .thenReturn(ImmutableSet.of()); @@ -211,7 +208,7 @@ public class SyncGroupMembersActionTest { assertThat(loadRegistrar("TheRegistrar").getContactsRequireSyncing()).isTrue(); } - @TestOfyAndSql + @Test void test_doPost_retriesOnTransientException() throws Exception { doThrow(IOException.class) .doNothing() diff --git a/core/src/test/java/google/registry/export/UpdateSnapshotViewActionTest.java b/core/src/test/java/google/registry/export/UpdateSnapshotViewActionTest.java deleted file mode 100644 index e435b92ad..000000000 --- a/core/src/test/java/google/registry/export/UpdateSnapshotViewActionTest.java +++ /dev/null @@ -1,110 +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.export; - -import static com.google.common.truth.Truth.assertThat; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.inOrder; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import com.google.api.services.bigquery.Bigquery; -import com.google.api.services.bigquery.model.Dataset; -import com.google.api.services.bigquery.model.Table; -import com.google.common.collect.Iterables; -import google.registry.bigquery.CheckedBigquery; -import google.registry.request.HttpException.InternalServerErrorException; -import google.registry.testing.AppEngineExtension; -import java.io.IOException; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.mockito.ArgumentCaptor; -import org.mockito.InOrder; - -/** Unit tests for {@link UpdateSnapshotViewAction}. */ -public class UpdateSnapshotViewActionTest { - - @RegisterExtension - public final AppEngineExtension appEngine = AppEngineExtension.builder().withTaskQueue().build(); - - private final CheckedBigquery checkedBigquery = mock(CheckedBigquery.class); - private final Bigquery bigquery = mock(Bigquery.class); - private final Bigquery.Datasets bigqueryDatasets = mock(Bigquery.Datasets.class); - private final Bigquery.Datasets.Insert bigqueryDatasetsInsert = - mock(Bigquery.Datasets.Insert.class); - private final Bigquery.Tables bigqueryTables = mock(Bigquery.Tables.class); - private final Bigquery.Tables.Update bigqueryTablesUpdate = mock(Bigquery.Tables.Update.class); - - private UpdateSnapshotViewAction action; - - @BeforeEach - void beforeEach() throws Exception { - when(checkedBigquery.ensureDataSetExists(anyString(), anyString())).thenReturn(bigquery); - when(bigquery.datasets()).thenReturn(bigqueryDatasets); - when(bigqueryDatasets.insert(anyString(), any(Dataset.class))) - .thenReturn(bigqueryDatasetsInsert); - when(bigquery.tables()).thenReturn(bigqueryTables); - when(bigqueryTables.update(anyString(), anyString(), anyString(), any(Table.class))) - .thenReturn(bigqueryTablesUpdate); - - action = new UpdateSnapshotViewAction(); - action.checkedBigquery = checkedBigquery; - action.datasetId = "some_dataset"; - action.kindName = "fookind"; - action.viewName = "latest_datastore_export"; - action.projectId = "myproject"; - action.tableId = "12345_fookind"; - } - - @Test - void testSuccess_doPost() throws Exception { - action.run(); - - InOrder factoryOrder = inOrder(checkedBigquery); - // Check that the BigQuery factory was called in such a way that the dataset would be created - // if it didn't already exist. - factoryOrder - .verify(checkedBigquery) - .ensureDataSetExists("myproject", "latest_datastore_export"); - - // Check that we updated both views - InOrder tableOrder = inOrder(bigqueryTables); - ArgumentCaptor tableArg = ArgumentCaptor.forClass(Table.class); - tableOrder - .verify(bigqueryTables) - .update(eq("myproject"), eq("latest_datastore_export"), eq("fookind"), tableArg.capture()); - Iterable actualQueries = - Iterables.transform(tableArg.getAllValues(), table -> table.getView().getQuery()); - assertThat(actualQueries) - .containsExactly("#standardSQL\nSELECT * FROM `myproject.some_dataset.12345_fookind`"); - } - - @Test - void testFailure_bigqueryConnectionThrowsError() throws Exception { - when(bigqueryTables.update(anyString(), anyString(), anyString(), any(Table.class))) - .thenThrow(new IOException("I'm sorry Dave, I can't let you do that")); - InternalServerErrorException thrown = - assertThrows(InternalServerErrorException.class, action::run); - assertThat(thrown) - .hasMessageThat() - .isEqualTo( - "Could not update snapshot view latest_datastore_export for table 12345_fookind"); - assertThat(thrown).hasCauseThat().hasMessageThat().contains("I'm sorry Dave"); - } -} diff --git a/core/src/test/java/google/registry/export/UploadDatastoreBackupActionTest.java b/core/src/test/java/google/registry/export/UploadDatastoreBackupActionTest.java deleted file mode 100644 index 5d11e861d..000000000 --- a/core/src/test/java/google/registry/export/UploadDatastoreBackupActionTest.java +++ /dev/null @@ -1,255 +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.export; - -import static com.google.common.collect.Iterables.transform; -import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.Truth8.assertThat; -import static google.registry.export.BigqueryPollJobAction.CHAINED_TASK_QUEUE_HEADER; -import static google.registry.export.BigqueryPollJobAction.JOB_ID_HEADER; -import static google.registry.export.BigqueryPollJobAction.PROJECT_ID_HEADER; -import static google.registry.export.UpdateSnapshotViewAction.UPDATE_SNAPSHOT_DATASET_ID_PARAM; -import static google.registry.export.UpdateSnapshotViewAction.UPDATE_SNAPSHOT_KIND_PARAM; -import static google.registry.export.UpdateSnapshotViewAction.UPDATE_SNAPSHOT_TABLE_ID_PARAM; -import static google.registry.export.UpdateSnapshotViewAction.UPDATE_SNAPSHOT_VIEWNAME_PARAM; -import static google.registry.export.UploadDatastoreBackupAction.BACKUP_DATASET; -import static google.registry.export.UploadDatastoreBackupAction.getBackupInfoFileForKind; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import com.google.api.services.bigquery.Bigquery; -import com.google.api.services.bigquery.model.Dataset; -import com.google.api.services.bigquery.model.Job; -import com.google.api.services.bigquery.model.JobConfigurationLoad; -import com.google.cloud.tasks.v2.HttpMethod; -import com.google.common.collect.ImmutableMultimap; -import com.google.common.collect.Iterables; -import com.google.protobuf.util.Timestamps; -import google.registry.bigquery.CheckedBigquery; -import google.registry.request.HttpException.InternalServerErrorException; -import google.registry.testing.AppEngineExtension; -import google.registry.testing.CloudTasksHelper; -import google.registry.testing.CloudTasksHelper.TaskMatcher; -import google.registry.testing.FakeClock; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.util.List; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.mockito.ArgumentCaptor; - -/** Unit tests for {@link UploadDatastoreBackupAction}. */ -public class UploadDatastoreBackupActionTest { - - @RegisterExtension - public final AppEngineExtension appEngine = AppEngineExtension.builder().withTaskQueue().build(); - - private final CheckedBigquery checkedBigquery = mock(CheckedBigquery.class); - private final Bigquery bigquery = mock(Bigquery.class); - private final Bigquery.Jobs bigqueryJobs = mock(Bigquery.Jobs.class); - private final Bigquery.Jobs.Insert bigqueryJobsInsert = mock(Bigquery.Jobs.Insert.class); - private final Bigquery.Datasets bigqueryDatasets = mock(Bigquery.Datasets.class); - private final Bigquery.Datasets.Insert bigqueryDatasetsInsert = - mock(Bigquery.Datasets.Insert.class); - private UploadDatastoreBackupAction action; - private CloudTasksHelper cloudTasksHelper = new CloudTasksHelper(); - - @BeforeEach - void beforeEach() throws Exception { - when(checkedBigquery.ensureDataSetExists("Project-Id", BACKUP_DATASET)).thenReturn(bigquery); - when(bigquery.jobs()).thenReturn(bigqueryJobs); - when(bigqueryJobs.insert(eq("Project-Id"), any(Job.class))).thenReturn(bigqueryJobsInsert); - when(bigquery.datasets()).thenReturn(bigqueryDatasets); - when(bigqueryDatasets.insert(eq("Project-Id"), any(Dataset.class))) - .thenReturn(bigqueryDatasetsInsert); - action = new UploadDatastoreBackupAction(); - action.checkedBigquery = checkedBigquery; - action.projectId = "Project-Id"; - action.backupFolderUrl = "gs://bucket/path"; - action.backupId = "2018-12-05T17:46:39_92612"; - action.backupKinds = "one,two,three"; - action.cloudTasksUtils = cloudTasksHelper.getTestCloudTasksUtils(); - action.clock = new FakeClock(); - } - - - @Test - void testSuccess_doPost() throws Exception { - action.run(); - - // Verify that checkedBigquery was called in a way that would create the dataset if it didn't - // already exist. - verify(checkedBigquery).ensureDataSetExists("Project-Id", BACKUP_DATASET); - - // Capture the load jobs we inserted to do additional checking on them. - ArgumentCaptor jobArgument = ArgumentCaptor.forClass(Job.class); - verify(bigqueryJobs, times(3)).insert(eq("Project-Id"), jobArgument.capture()); - List jobs = jobArgument.getAllValues(); - assertThat(jobs).hasSize(3); - - // Check properties that should be common to all load jobs. - for (Job job : jobs) { - assertThat(job.getJobReference().getProjectId()).isEqualTo("Project-Id"); - JobConfigurationLoad config = job.getConfiguration().getLoad(); - assertThat(config.getSourceFormat()).isEqualTo("DATASTORE_BACKUP"); - assertThat(config.getDestinationTable().getProjectId()).isEqualTo("Project-Id"); - assertThat(config.getDestinationTable().getDatasetId()).isEqualTo(BACKUP_DATASET); - } - - // Check the job IDs for each load job. - assertThat(transform(jobs, job -> job.getJobReference().getJobId())) - .containsExactly( - "load-backup-2018_12_05T17_46_39_92612-one", - "load-backup-2018_12_05T17_46_39_92612-two", - "load-backup-2018_12_05T17_46_39_92612-three"); - - // Check the source URI for each load job. - assertThat( - transform( - jobs, - job -> Iterables.getOnlyElement(job.getConfiguration().getLoad().getSourceUris()))) - .containsExactly( - "gs://bucket/path/all_namespaces/kind_one/all_namespaces_kind_one.export_metadata", - "gs://bucket/path/all_namespaces/kind_two/all_namespaces_kind_two.export_metadata", - "gs://bucket/path/all_namespaces/kind_three/all_namespaces_kind_three.export_metadata"); - - // Check the destination table ID for each load job. - assertThat( - transform( - jobs, job -> job.getConfiguration().getLoad().getDestinationTable().getTableId())) - .containsExactly( - "2018_12_05T17_46_39_92612_one", - "2018_12_05T17_46_39_92612_two", - "2018_12_05T17_46_39_92612_three"); - - // Check that we executed the inserted jobs. - verify(bigqueryJobsInsert, times(3)).execute(); - - // Check that the poll tasks for each load job were enqueued. - cloudTasksHelper.assertTasksEnqueued( - BigqueryPollJobAction.QUEUE, - new TaskMatcher() - .method(HttpMethod.POST) - .header(PROJECT_ID_HEADER, "Project-Id") - .header(JOB_ID_HEADER, "load-backup-2018_12_05T17_46_39_92612-one") - .header(CHAINED_TASK_QUEUE_HEADER, UpdateSnapshotViewAction.QUEUE) - .scheduleTime( - Timestamps.fromMillis( - action.clock.nowUtc().plus(BigqueryPollJobAction.POLL_COUNTDOWN).getMillis())), - new TaskMatcher() - .method(HttpMethod.POST) - .header(PROJECT_ID_HEADER, "Project-Id") - .header(JOB_ID_HEADER, "load-backup-2018_12_05T17_46_39_92612-two") - .header(CHAINED_TASK_QUEUE_HEADER, UpdateSnapshotViewAction.QUEUE) - .scheduleTime( - Timestamps.fromMillis( - action.clock.nowUtc().plus(BigqueryPollJobAction.POLL_COUNTDOWN).getMillis())), - new TaskMatcher() - .method(HttpMethod.POST) - .header(PROJECT_ID_HEADER, "Project-Id") - .header(JOB_ID_HEADER, "load-backup-2018_12_05T17_46_39_92612-three") - .header(CHAINED_TASK_QUEUE_HEADER, UpdateSnapshotViewAction.QUEUE) - .scheduleTime( - Timestamps.fromMillis( - action.clock.nowUtc().plus(BigqueryPollJobAction.POLL_COUNTDOWN).getMillis()))); - - // assert the chained task of each enqueud task is correct - assertThat( - cloudTasksHelper.getTestTasksFor(BigqueryPollJobAction.QUEUE).stream() - .map( - testTask -> { - try { - return new ObjectInputStream( - new ByteArrayInputStream( - testTask.getAppEngineHttpRequest().getBody().toByteArray())) - .readObject(); - } catch (ClassNotFoundException | IOException e) { - return null; - } - })) - .containsExactly( - cloudTasksHelper - .getTestCloudTasksUtils() - .createPostTask( - UpdateSnapshotViewAction.PATH, - "BACKEND", - ImmutableMultimap.of( - UPDATE_SNAPSHOT_DATASET_ID_PARAM, - "datastore_backups", - UPDATE_SNAPSHOT_TABLE_ID_PARAM, - "2018_12_05T17_46_39_92612_one", - UPDATE_SNAPSHOT_KIND_PARAM, - "one", - UPDATE_SNAPSHOT_VIEWNAME_PARAM, - "latest_datastore_export")), - cloudTasksHelper - .getTestCloudTasksUtils() - .createPostTask( - UpdateSnapshotViewAction.PATH, - "BACKEND", - ImmutableMultimap.of( - UPDATE_SNAPSHOT_DATASET_ID_PARAM, - "datastore_backups", - UPDATE_SNAPSHOT_TABLE_ID_PARAM, - "2018_12_05T17_46_39_92612_two", - UPDATE_SNAPSHOT_KIND_PARAM, - "two", - UPDATE_SNAPSHOT_VIEWNAME_PARAM, - "latest_datastore_export")), - cloudTasksHelper - .getTestCloudTasksUtils() - .createPostTask( - UpdateSnapshotViewAction.PATH, - "BACKEND", - ImmutableMultimap.of( - UPDATE_SNAPSHOT_DATASET_ID_PARAM, - "datastore_backups", - UPDATE_SNAPSHOT_TABLE_ID_PARAM, - "2018_12_05T17_46_39_92612_three", - UPDATE_SNAPSHOT_KIND_PARAM, - "three", - UPDATE_SNAPSHOT_VIEWNAME_PARAM, - "latest_datastore_export"))) - .inOrder(); - } - - @Test - void testFailure_doPost_bigqueryThrowsException() throws Exception { - when(bigqueryJobsInsert.execute()).thenThrow(new IOException("The Internet has gone missing")); - InternalServerErrorException thrown = - assertThrows(InternalServerErrorException.class, action::run); - assertThat(thrown) - .hasMessageThat() - .contains("Error loading backup: The Internet has gone missing"); - } - - @Test - void testgetBackupInfoFileForKind() { - assertThat( - getBackupInfoFileForKind( - "gs://BucketName/2018-11-11T00:00:00_12345", "AllocationToken")) - .isEqualTo( - "gs://BucketName/2018-11-11T00:00:00_12345/" - + "all_namespaces/kind_AllocationToken/" - + "all_namespaces_kind_AllocationToken.export_metadata"); - } -} diff --git a/core/src/test/java/google/registry/export/datastore/DatastoreAdminTest.java b/core/src/test/java/google/registry/export/datastore/DatastoreAdminTest.java deleted file mode 100644 index 0b1bd678d..000000000 --- a/core/src/test/java/google/registry/export/datastore/DatastoreAdminTest.java +++ /dev/null @@ -1,166 +0,0 @@ -// Copyright 2018 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.export.datastore; - -import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.Truth8.assertThat; - -import com.google.api.client.http.GenericUrl; -import com.google.api.client.http.HttpRequest; -import com.google.auth.oauth2.AccessToken; -import com.google.auth.oauth2.GoogleCredentials; -import com.google.common.collect.ImmutableList; -import google.registry.testing.TestDataHelper; -import google.registry.util.GoogleCredentialsBundle; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.Date; -import java.util.Optional; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.junit.jupiter.MockitoExtension; - -/** Unit tests for {@link DatastoreAdmin}. */ -@ExtendWith(MockitoExtension.class) -class DatastoreAdminTest { - - private static final String AUTH_HEADER_PREFIX = "Bearer "; - private static final String ACCESS_TOKEN = "MyAccessToken"; - private static final ImmutableList KINDS = - ImmutableList.of("Registry", "Registrar", "DomainBase"); - - private DatastoreAdmin datastoreAdmin; - - private static HttpRequest simulateSendRequest(HttpRequest httpRequest) { - try { - httpRequest.setUrl(new GenericUrl("https://localhost:65537")).execute(); - } catch (Exception expected) { - } - return httpRequest; - } - - private static Optional getAccessToken(HttpRequest httpRequest) { - return httpRequest.getHeaders().getAuthorizationAsList().stream() - .filter(header -> header.startsWith(AUTH_HEADER_PREFIX)) - .map(header -> header.substring(AUTH_HEADER_PREFIX.length())) - .findAny(); - } - - private static Optional getRequestContent(HttpRequest httpRequest) throws IOException { - if (httpRequest.getContent() == null) { - return Optional.empty(); - } - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - httpRequest.getContent().writeTo(outputStream); - outputStream.close(); - return Optional.of(outputStream.toString(StandardCharsets.UTF_8.name())); - } - - @BeforeEach - void beforeEach() { - Date oneHourLater = new Date(System.currentTimeMillis() + 3_600_000); - GoogleCredentials googleCredentials = GoogleCredentials - .create(new AccessToken(ACCESS_TOKEN, oneHourLater)); - GoogleCredentialsBundle credentialsBundle = GoogleCredentialsBundle.create(googleCredentials); - datastoreAdmin = - new DatastoreAdmin.Builder( - credentialsBundle.getHttpTransport(), - credentialsBundle.getJsonFactory(), - credentialsBundle.getHttpRequestInitializer()) - .setApplicationName("MyApplication") - .setProjectId("MyCloudProject") - .build(); - } - - @Test - void testExport() throws IOException { - DatastoreAdmin.Export export = datastoreAdmin.export("gs://mybucket/path", KINDS); - HttpRequest httpRequest = export.buildHttpRequest(); - assertThat(httpRequest.getUrl().toString()) - .isEqualTo("https://datastore.googleapis.com/v1/projects/MyCloudProject:export"); - assertThat(httpRequest.getRequestMethod()).isEqualTo("POST"); - - assertThat(getRequestContent(httpRequest)) - .hasValue( - TestDataHelper.loadFile(getClass(), "export_request_content.json") - .replaceAll("[\\s\\n]+", "")); - - simulateSendRequest(httpRequest); - assertThat(getAccessToken(httpRequest)).hasValue(ACCESS_TOKEN); - } - - @Test - void testGetOperation() throws IOException { - DatastoreAdmin.Get get = - datastoreAdmin.get("projects/MyCloudProject/operations/ASAzNjMwOTEyNjUJ"); - HttpRequest httpRequest = get.buildHttpRequest(); - assertThat(httpRequest.getUrl().toString()) - .isEqualTo( - "https://datastore.googleapis.com/v1/projects/MyCloudProject/operations/ASAzNjMwOTEyNjUJ"); - assertThat(httpRequest.getRequestMethod()).isEqualTo("GET"); - assertThat(httpRequest.getContent()).isNull(); - - simulateSendRequest(httpRequest); - assertThat(getAccessToken(httpRequest)).hasValue(ACCESS_TOKEN); - } - - @Test - void testListOperations_all() throws IOException { - DatastoreAdmin.ListOperations listOperations = datastoreAdmin.listAll(); - HttpRequest httpRequest = listOperations.buildHttpRequest(); - assertThat(httpRequest.getUrl().toString()) - .isEqualTo("https://datastore.googleapis.com/v1/projects/MyCloudProject/operations"); - assertThat(httpRequest.getRequestMethod()).isEqualTo("GET"); - assertThat(httpRequest.getContent()).isNull(); - - simulateSendRequest(httpRequest); - assertThat(getAccessToken(httpRequest)).hasValue(ACCESS_TOKEN); - } - - @Test - void testListOperations_filterByStartTime() throws IOException { - DatastoreAdmin.ListOperations listOperations = - datastoreAdmin.list("metadata.common.startTime>\"2018-10-31T00:00:00.0Z\""); - HttpRequest httpRequest = listOperations.buildHttpRequest(); - assertThat(httpRequest.getUrl().toString()) - .isEqualTo( - "https://datastore.googleapis.com/v1/projects/MyCloudProject/operations" - + "?filter=metadata.common.startTime%3E%222018-10-31T00:00:00.0Z%22"); - assertThat(httpRequest.getRequestMethod()).isEqualTo("GET"); - assertThat(httpRequest.getContent()).isNull(); - - simulateSendRequest(httpRequest); - assertThat(getAccessToken(httpRequest)).hasValue(ACCESS_TOKEN); - } - - @Test - void testListOperations_filterByState() throws IOException { - // TODO(weiminyu): consider adding a method to DatastoreAdmin to support query by state. - DatastoreAdmin.ListOperations listOperations = - datastoreAdmin.list("metadata.common.state=PROCESSING"); - HttpRequest httpRequest = listOperations.buildHttpRequest(); - assertThat(httpRequest.getUrl().toString()) - .isEqualTo( - "https://datastore.googleapis.com/v1/projects/MyCloudProject/operations" - + "?filter=metadata.common.state%3DPROCESSING"); - assertThat(httpRequest.getRequestMethod()).isEqualTo("GET"); - assertThat(httpRequest.getContent()).isNull(); - - simulateSendRequest(httpRequest); - assertThat(getAccessToken(httpRequest)).hasValue(ACCESS_TOKEN); - } -} diff --git a/core/src/test/java/google/registry/export/datastore/EntityFilterTest.java b/core/src/test/java/google/registry/export/datastore/EntityFilterTest.java deleted file mode 100644 index b91a6e48d..000000000 --- a/core/src/test/java/google/registry/export/datastore/EntityFilterTest.java +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2018 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.export.datastore; - -import static com.google.common.truth.Truth.assertThat; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import com.google.api.client.json.JsonFactory; -import com.google.api.client.json.jackson2.JacksonFactory; -import com.google.common.collect.ImmutableList; -import google.registry.testing.TestDataHelper; -import java.io.IOException; -import org.junit.jupiter.api.Test; - -/** Unit tests for the instantiation, marshalling and unmarshalling of {@link EntityFilter}. */ -class EntityFilterTest { - - private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance(); - - @Test - void testEntityFilter_create_nullKinds() { - assertThrows(NullPointerException.class, () -> new EntityFilter(null)); - } - - @Test - void testEntityFilter_marshall() throws IOException { - EntityFilter entityFilter = - new EntityFilter(ImmutableList.of("Registry", "Registrar", "DomainBase")); - assertThat(JSON_FACTORY.toString(entityFilter)) - .isEqualTo(loadJsonString("entity_filter.json").replaceAll("[\\s\\n]+", "")); - } - - @Test - void testEntityFilter_unmarshall() throws IOException { - EntityFilter entityFilter = loadJson("entity_filter.json", EntityFilter.class); - assertThat(entityFilter.getKinds()) - .containsExactly("Registry", "Registrar", "DomainBase") - .inOrder(); - } - - @Test - void testEntityFilter_unmarshall_noKinds() throws IOException { - EntityFilter entityFilter = JSON_FACTORY.fromString("{}", EntityFilter.class); - assertThat(entityFilter.getKinds()).isEmpty(); - } - - @Test - void testEntityFilter_unmarshall_emptyKinds() throws IOException { - EntityFilter entityFilter = JSON_FACTORY.fromString("{ \"kinds\" : [] }", EntityFilter.class); - assertThat(entityFilter.getKinds()).isEmpty(); - } - - private static T loadJson(String fileName, Class type) throws IOException { - return JSON_FACTORY.fromString(loadJsonString(fileName), type); - } - - private static String loadJsonString(String fileName) { - return TestDataHelper.loadFile(EntityFilterTest.class, fileName); - } -} diff --git a/core/src/test/java/google/registry/export/datastore/OperationTest.java b/core/src/test/java/google/registry/export/datastore/OperationTest.java deleted file mode 100644 index fb515bfce..000000000 --- a/core/src/test/java/google/registry/export/datastore/OperationTest.java +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright 2018 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.export.datastore; - -import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.Truth8.assertThat; - -import com.google.api.client.json.JsonFactory; -import com.google.api.client.json.jackson2.JacksonFactory; -import google.registry.export.datastore.Operation.CommonMetadata; -import google.registry.export.datastore.Operation.Metadata; -import google.registry.export.datastore.Operation.Progress; -import google.registry.testing.FakeClock; -import google.registry.testing.TestDataHelper; -import java.io.IOException; -import org.joda.time.DateTime; -import org.joda.time.Duration; -import org.junit.jupiter.api.Test; - -/** Unit tests for unmarshalling {@link Operation} and its member types. */ -class OperationTest { - - private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance(); - - @Test - void testCommonMetadata_unmarshall() throws IOException { - CommonMetadata commonMetadata = loadJson("common_metadata.json", CommonMetadata.class); - assertThat(commonMetadata.getState()).isEqualTo("SUCCESSFUL"); - assertThat(commonMetadata.getOperationType()).isEqualTo("EXPORT_ENTITIES"); - assertThat(commonMetadata.getStartTime()) - .isEqualTo(DateTime.parse("2018-10-29T16:01:04.645299Z")); - assertThat(commonMetadata.getEndTime()).isEmpty(); - } - - @Test - void testProgress_unmarshall() throws IOException { - Progress progress = loadJson("progress.json", Progress.class); - assertThat(progress.getWorkCompleted()).isEqualTo(51797); - assertThat(progress.getWorkEstimated()).isEqualTo(54513); - } - - @Test - void testMetadata_unmarshall() throws IOException { - Metadata metadata = loadJson("metadata.json", Metadata.class); - assertThat(metadata.getCommonMetadata().getOperationType()).isEqualTo("EXPORT_ENTITIES"); - assertThat(metadata.getCommonMetadata().getState()).isEqualTo("SUCCESSFUL"); - assertThat(metadata.getCommonMetadata().getStartTime()) - .isEqualTo(DateTime.parse("2018-10-29T16:01:04.645299Z")); - assertThat(metadata.getCommonMetadata().getEndTime()) - .hasValue(DateTime.parse("2018-10-29T16:02:19.009859Z")); - assertThat(metadata.getOutputUrlPrefix()) - .isEqualTo("gs://domain-registry-alpha-datastore-export-test/2018-10-29T16:01:04_99364"); - } - - @Test - void testOperation_unmarshall() throws IOException { - Operation operation = loadJson("operation.json", Operation.class); - assertThat(operation.getName()) - .startsWith("projects/domain-registry-alpha/operations/ASAzNjMwOTEyNjUJ"); - assertThat(operation.isProcessing()).isTrue(); - assertThat(operation.isSuccessful()).isFalse(); - assertThat(operation.isDone()).isFalse(); - assertThat(operation.getStartTime()).isEqualTo(DateTime.parse("2018-10-29T16:01:04.645299Z")); - assertThat(operation.getExportFolderUrl()) - .isEqualTo("gs://domain-registry-alpha-datastore-export-test/2018-10-29T16:01:04_99364"); - assertThat(operation.getExportId()).isEqualTo("2018-10-29T16:01:04_99364"); - assertThat(operation.getKinds()).containsExactly("Registry", "Registrar", "DomainBase"); - assertThat(operation.toPrettyString()) - .isEqualTo( - TestDataHelper.loadFile(OperationTest.class, "prettyprinted_operation.json").trim()); - assertThat(operation.getProgress()).isEqualTo("Progress: N/A"); - } - - @Test - void testOperationList_unmarshall() throws IOException { - Operation.OperationList operationList = - loadJson("operation_list.json", Operation.OperationList.class); - assertThat(operationList.toList()).hasSize(2); - FakeClock clock = new FakeClock(DateTime.parse("2018-10-29T16:01:04.645299Z")); - clock.advanceOneMilli(); - assertThat(operationList.toList().get(0).getRunningTime(clock)).isEqualTo(Duration.millis(1)); - assertThat(operationList.toList().get(0).getProgress()) - .isEqualTo("Progress: [51797/54513 entities]"); - assertThat(operationList.toList().get(1).getRunningTime(clock)) - .isEqualTo(Duration.standardMinutes(1)); - // Work completed may exceed work estimated - assertThat(operationList.toList().get(1).getProgress()) - .isEqualTo("Progress: [96908367/73773755 bytes] [51797/54513 entities]"); - } - - private static T loadJson(String fileName, Class type) throws IOException { - return JSON_FACTORY.fromString(TestDataHelper.loadFile(OperationTest.class, fileName), type); - } -} diff --git a/core/src/test/java/google/registry/export/sheet/SyncRegistrarsSheetActionTest.java b/core/src/test/java/google/registry/export/sheet/SyncRegistrarsSheetActionTest.java index d5a508f8d..d0765e6d2 100644 --- a/core/src/test/java/google/registry/export/sheet/SyncRegistrarsSheetActionTest.java +++ b/core/src/test/java/google/registry/export/sheet/SyncRegistrarsSheetActionTest.java @@ -38,7 +38,7 @@ public class SyncRegistrarsSheetActionTest { @RegisterExtension public final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().withTaskQueue().build(); + AppEngineExtension.builder().withCloudSql().withTaskQueue().build(); private final FakeResponse response = new FakeResponse(); private final SyncRegistrarsSheet syncRegistrarsSheet = mock(SyncRegistrarsSheet.class); diff --git a/core/src/test/java/google/registry/export/sheet/SyncRegistrarsSheetTest.java b/core/src/test/java/google/registry/export/sheet/SyncRegistrarsSheetTest.java index ab2fe6425..81b00b0a1 100644 --- a/core/src/test/java/google/registry/export/sheet/SyncRegistrarsSheetTest.java +++ b/core/src/test/java/google/registry/export/sheet/SyncRegistrarsSheetTest.java @@ -41,12 +41,11 @@ import google.registry.model.registrar.RegistrarAddress; import google.registry.model.registrar.RegistrarPoc; import google.registry.testing.AppEngineExtension; import google.registry.testing.DatabaseHelper; -import google.registry.testing.DualDatabaseTest; import google.registry.testing.FakeClock; import google.registry.testing.InjectExtension; -import google.registry.testing.TestOfyAndSql; import org.joda.time.DateTime; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.RegisterExtension; import org.mockito.ArgumentCaptor; @@ -56,12 +55,10 @@ import org.mockito.junit.jupiter.MockitoExtension; /** Unit tests for {@link SyncRegistrarsSheet}. */ @ExtendWith(MockitoExtension.class) -@DualDatabaseTest public class SyncRegistrarsSheetTest { @RegisterExtension - public final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().build(); + public final AppEngineExtension appEngine = AppEngineExtension.builder().withCloudSql().build(); @RegisterExtension public final InjectExtension inject = new InjectExtension(); @@ -91,12 +88,12 @@ public class SyncRegistrarsSheetTest { Registrar.loadAll().forEach(DatabaseHelper::deleteResource); } - @TestOfyAndSql + @Test void test_wereRegistrarsModified_noRegistrars_returnsFalse() { assertThat(newSyncRegistrarsSheet().wereRegistrarsModified()).isFalse(); } - @TestOfyAndSql + @Test void test_wereRegistrarsModified_atDifferentCursorTimes() { persistNewRegistrar("SomeRegistrar", "Some Registrar Inc.", Registrar.Type.REAL, 8L); persistResource(Cursor.createGlobal(SYNC_REGISTRAR_SHEET, clock.nowUtc().minusHours(1))); @@ -105,7 +102,7 @@ public class SyncRegistrarsSheetTest { assertThat(newSyncRegistrarsSheet().wereRegistrarsModified()).isFalse(); } - @TestOfyAndSql + @Test void testRun() throws Exception { persistResource( new Registrar.Builder() @@ -333,7 +330,7 @@ public class SyncRegistrarsSheetTest { assertThat(cursor.getCursorTime()).isGreaterThan(registrarCreationTime); } - @TestOfyAndSql + @Test void testRun_missingValues_stillWorks() throws Exception { persistResource( persistNewRegistrar("SomeRegistrar", "Some Registrar", Registrar.Type.REAL, 8L) diff --git a/core/src/test/java/google/registry/flows/CheckApiActionTest.java b/core/src/test/java/google/registry/flows/CheckApiActionTest.java index c520c4b88..b37314771 100644 --- a/core/src/test/java/google/registry/flows/CheckApiActionTest.java +++ b/core/src/test/java/google/registry/flows/CheckApiActionTest.java @@ -55,8 +55,7 @@ class CheckApiActionTest { private static final DateTime START_TIME = DateTime.parse("2000-01-01T00:00:00.0Z"); @RegisterExtension - final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().build(); + final AppEngineExtension appEngine = AppEngineExtension.builder().withCloudSql().build(); @Mock private CheckApiMetrics checkApiMetrics; @Captor private ArgumentCaptor metricCaptor; diff --git a/core/src/test/java/google/registry/flows/EppControllerTest.java b/core/src/test/java/google/registry/flows/EppControllerTest.java index fddd1c5ae..5c6f37ad9 100644 --- a/core/src/test/java/google/registry/flows/EppControllerTest.java +++ b/core/src/test/java/google/registry/flows/EppControllerTest.java @@ -67,8 +67,7 @@ import org.mockito.quality.Strictness; class EppControllerTest { @RegisterExtension - AppEngineExtension appEngineExtension = - new AppEngineExtension.Builder().withDatastoreAndCloudSql().build(); + AppEngineExtension appEngineExtension = new AppEngineExtension.Builder().withCloudSql().build(); @Mock SessionMetadata sessionMetadata; @Mock TransportCredentials transportCredentials; diff --git a/core/src/test/java/google/registry/flows/EppLifecycleContactTest.java b/core/src/test/java/google/registry/flows/EppLifecycleContactTest.java index ee2340c37..d1355fad1 100644 --- a/core/src/test/java/google/registry/flows/EppLifecycleContactTest.java +++ b/core/src/test/java/google/registry/flows/EppLifecycleContactTest.java @@ -21,23 +21,17 @@ import static google.registry.testing.EppMetricSubject.assertThat; import com.google.common.collect.ImmutableMap; import google.registry.testing.AppEngineExtension; -import google.registry.testing.DualDatabaseTest; -import google.registry.testing.TestOfyAndSql; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; /** Tests for contact lifecycle. */ -@DualDatabaseTest class EppLifecycleContactTest extends EppTestCase { @RegisterExtension final AppEngineExtension appEngine = - AppEngineExtension.builder() - .withDatastoreAndCloudSql() - .withClock(clock) - .withTaskQueue() - .build(); + AppEngineExtension.builder().withCloudSql().withClock(clock).withTaskQueue().build(); - @TestOfyAndSql + @Test void testContactLifecycle() throws Exception { assertThatLoginSucceeds("NewRegistrar", "foo-BAR2"); assertThatCommand("contact_create_sh8013.xml") @@ -73,7 +67,7 @@ class EppLifecycleContactTest extends EppTestCase { assertThatLogoutSucceeds(); } - @TestOfyAndSql + @Test void testContactTransferPollMessage() throws Exception { assertThatLoginSucceeds("NewRegistrar", "foo-BAR2"); assertThatCommand("contact_create_sh8013.xml") diff --git a/core/src/test/java/google/registry/flows/EppLifecycleDomainTest.java b/core/src/test/java/google/registry/flows/EppLifecycleDomainTest.java index 341792eed..74a4e497f 100644 --- a/core/src/test/java/google/registry/flows/EppLifecycleDomainTest.java +++ b/core/src/test/java/google/registry/flows/EppLifecycleDomainTest.java @@ -47,15 +47,13 @@ import google.registry.model.reporting.HistoryEntry.Type; import google.registry.model.tld.Registry; import google.registry.model.tld.Registry.TldState; import google.registry.testing.AppEngineExtension; -import google.registry.testing.DualDatabaseTest; -import google.registry.testing.TestOfyAndSql; import org.joda.money.Money; import org.joda.time.DateTime; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; /** Tests for domain lifecycle. */ -@DualDatabaseTest class EppLifecycleDomainTest extends EppTestCase { private static final ImmutableMap DEFAULT_TRANSFER_RESPONSE_PARMS = @@ -66,18 +64,14 @@ class EppLifecycleDomainTest extends EppTestCase { @RegisterExtension final AppEngineExtension appEngine = - AppEngineExtension.builder() - .withDatastoreAndCloudSql() - .withClock(clock) - .withTaskQueue() - .build(); + AppEngineExtension.builder().withCloudSql().withClock(clock).withTaskQueue().build(); @BeforeEach void beforeEach() { createTlds("example", "tld"); } - @TestOfyAndSql + @Test void testDomainDeleteRestore() throws Exception { assertThatLoginSucceeds("NewRegistrar", "foo-BAR2"); createContacts(DateTime.parse("2000-06-01T00:00:00Z")); @@ -137,7 +131,7 @@ class EppLifecycleDomainTest extends EppTestCase { assertThatLogoutSucceeds(); } - @TestOfyAndSql + @Test void testDomainDeleteRestore_duringAutorenewGracePeriod() throws Exception { assertThatLoginSucceeds("NewRegistrar", "foo-BAR2"); createContacts(DateTime.parse("2000-06-01T00:00:00Z")); @@ -211,7 +205,7 @@ class EppLifecycleDomainTest extends EppTestCase { assertThatLogoutSucceeds(); } - @TestOfyAndSql + @Test void testDomainDeleteRestore_duringRenewalGracePeriod() throws Exception { assertThatLoginSucceeds("NewRegistrar", "foo-BAR2"); createContacts(DateTime.parse("2000-06-01T00:00:00Z")); @@ -293,7 +287,7 @@ class EppLifecycleDomainTest extends EppTestCase { assertThatLogoutSucceeds(); } - @TestOfyAndSql + @Test void testDomainDelete_duringAddAndRenewalGracePeriod_deletesImmediately() throws Exception { assertThatLoginSucceeds("NewRegistrar", "foo-BAR2"); createContacts(DateTime.parse("2000-06-01T00:00:00Z")); @@ -388,7 +382,7 @@ class EppLifecycleDomainTest extends EppTestCase { assertThatLogoutSucceeds(); } - @TestOfyAndSql + @Test void testDomainDeletion_withinAddGracePeriod_deletesImmediately() throws Exception { assertThatLoginSucceeds("NewRegistrar", "foo-BAR2"); createContacts(DateTime.parse("2000-06-01T00:00:00Z")); @@ -444,7 +438,7 @@ class EppLifecycleDomainTest extends EppTestCase { assertThatLogoutSucceeds(); } - @TestOfyAndSql + @Test void testDomainDeletion_outsideAddGracePeriod_showsRedemptionPeriod() throws Exception { assertThatLoginSucceeds("NewRegistrar", "foo-BAR2"); createContacts(DateTime.parse("2000-06-01T00:00:00Z")); @@ -506,7 +500,7 @@ class EppLifecycleDomainTest extends EppTestCase { .isEqualTo(createTime.plusYears(2)); } - @TestOfyAndSql + @Test void testEapDomainDeletion_withinAddGracePeriod_eapFeeIsNotRefunded() throws Exception { assertThatCommand("login_valid_fee_extension.xml").hasSuccessfulLogin(); createContacts(DateTime.parse("2000-06-01T00:00:00Z")); @@ -571,7 +565,7 @@ class EppLifecycleDomainTest extends EppTestCase { assertThatLogoutSucceeds(); } - @TestOfyAndSql + @Test void testDomainDeletionWithSubordinateHost_fails() throws Exception { assertThatLoginSucceeds("NewRegistrar", "foo-BAR2"); createFakesite(); @@ -584,7 +578,7 @@ class EppLifecycleDomainTest extends EppTestCase { assertThatLogoutSucceeds(); } - @TestOfyAndSql + @Test void testDeletionOfDomain_afterRenameOfSubordinateHost_succeeds() throws Exception { assertThatLoginSucceeds("NewRegistrar", "foo-BAR2"); assertThat(getRecordedEppMetric()) @@ -639,7 +633,7 @@ class EppLifecycleDomainTest extends EppTestCase { .hasStatus(SUCCESS_AND_CLOSE); } - @TestOfyAndSql + @Test void testDeletionOfDomain_afterUpdateThatCreatesSubordinateHost_fails() throws Exception { assertThatLoginSucceeds("NewRegistrar", "foo-BAR2"); createFakesite(); @@ -682,7 +676,7 @@ class EppLifecycleDomainTest extends EppTestCase { assertThatLogoutSucceeds(); } - @TestOfyAndSql + @Test void testDomainCreation_failsBeforeSunrise() throws Exception { DateTime sunriseDate = DateTime.parse("2000-05-30T00:00:00Z"); createTld( @@ -716,7 +710,7 @@ class EppLifecycleDomainTest extends EppTestCase { assertThatLogoutSucceeds(); } - @TestOfyAndSql + @Test void testDomainCheckFee_succeeds() throws Exception { DateTime gaDate = DateTime.parse("2000-05-30T00:00:00Z"); createTld( @@ -742,7 +736,7 @@ class EppLifecycleDomainTest extends EppTestCase { assertThatLogoutSucceeds(); } - @TestOfyAndSql + @Test void testDomainCreate_annualAutoRenewPollMessages_haveUniqueIds() throws Exception { assertThatLoginSucceeds("NewRegistrar", "foo-BAR2"); // Create the domain. @@ -792,7 +786,7 @@ class EppLifecycleDomainTest extends EppTestCase { assertThatLogoutSucceeds(); } - @TestOfyAndSql + @Test void testDomainTransferPollMessage_serverApproved() throws Exception { // As the losing registrar, create the domain. assertThatLoginSucceeds("NewRegistrar", "foo-BAR2"); @@ -846,7 +840,7 @@ class EppLifecycleDomainTest extends EppTestCase { assertThatLogoutSucceeds(); } - @TestOfyAndSql + @Test void testTransfer_autoRenewGraceActive_onlyAtAutomaticTransferTime_getsSubsumed() throws Exception { // Register the domain as the first registrar. @@ -884,7 +878,7 @@ class EppLifecycleDomainTest extends EppTestCase { assertThatLogoutSucceeds(); } - @TestOfyAndSql + @Test void testNameserversTransferWithDomain_successfully() throws Exception { // Log in as the first registrar and set up domains with hosts. assertThatLoginSucceeds("NewRegistrar", "foo-BAR2"); @@ -921,7 +915,7 @@ class EppLifecycleDomainTest extends EppTestCase { assertThatLogoutSucceeds(); } - @TestOfyAndSql + @Test void testRenewalFails_whenTotalTermExceeds10Years() throws Exception { assertThatLoginSucceeds("NewRegistrar", "foo-BAR2"); // Creates domain with 2 year expiration. @@ -935,7 +929,7 @@ class EppLifecycleDomainTest extends EppTestCase { assertThatLogoutSucceeds(); } - @TestOfyAndSql + @Test void testDomainDeletionCancelsPendingTransfer() throws Exception { // Register the domain as the first registrar. assertThatLoginSucceeds("NewRegistrar", "foo-BAR2"); @@ -973,7 +967,7 @@ class EppLifecycleDomainTest extends EppTestCase { assertThatLogoutSucceeds(); } - @TestOfyAndSql + @Test void testDomainTransfer_subordinateHost_showsChangeInTransferQuery() throws Exception { assertThatLoginSucceeds("NewRegistrar", "foo-BAR2"); createFakesite(); @@ -1009,7 +1003,7 @@ class EppLifecycleDomainTest extends EppTestCase { * to be subordinate to a different domain, that the host retains the transfer time of the first * superordinate domain, not whatever the transfer time from the second domain is. */ - @TestOfyAndSql + @Test void testSuccess_lastTransferTime_superordinateDomainTransferFollowedByHostUpdate() throws Exception { assertThatLoginSucceeds("NewRegistrar", "foo-BAR2"); @@ -1063,7 +1057,7 @@ class EppLifecycleDomainTest extends EppTestCase { * Tests that when a superordinate domain of a host is transferred, and then the host is updated * to be external, that the host retains the transfer time of the first superordinate domain. */ - @TestOfyAndSql + @Test void testSuccess_lastTransferTime_superordinateDomainTransferThenHostUpdateToExternal() throws Exception { assertThatLoginSucceeds("NewRegistrar", "foo-BAR2"); @@ -1106,7 +1100,7 @@ class EppLifecycleDomainTest extends EppTestCase { assertThatLogoutSucceeds(); } - @TestOfyAndSql + @Test void testSuccess_multipartTldsWithSharedSuffixes() throws Exception { createTlds("bar.foo.tld", "foo.tld"); @@ -1150,7 +1144,7 @@ class EppLifecycleDomainTest extends EppTestCase { assertThatLogoutSucceeds(); } - @TestOfyAndSql + @Test void testSuccess_multipartTldsWithSharedPrefixes() throws Exception { createTld("tld.foo"); @@ -1189,7 +1183,7 @@ class EppLifecycleDomainTest extends EppTestCase { * during start-date sunrise - which we can then delete "as normal" (no need for a signed mark or * anything for delete), and then use "regular" create during general-availability. */ - @TestOfyAndSql + @Test void testDomainCreation_startDateSunriseFull() throws Exception { // The signed mark is valid between 2013 and 2017 DateTime sunriseDate = DateTime.parse("2014-09-08T09:09:09Z"); @@ -1285,7 +1279,7 @@ class EppLifecycleDomainTest extends EppTestCase { } /** Test that missing type= argument on launch create works in start-date sunrise. */ - @TestOfyAndSql + @Test void testDomainCreation_startDateSunrise_noType() throws Exception { // The signed mark is valid between 2013 and 2017 DateTime sunriseDate = DateTime.parse("2014-09-08T09:09:09Z"); @@ -1334,7 +1328,7 @@ class EppLifecycleDomainTest extends EppTestCase { assertThatLogoutSucceeds(); } - @TestOfyAndSql + @Test void testDomainTransfer_duringAutorenewGrace() throws Exception { // Creation date of fakesite: 2000-06-01T00:04:00.0Z // Expiration date: 2002-06-01T00:04:00.0Z @@ -1420,7 +1414,7 @@ class EppLifecycleDomainTest extends EppTestCase { "EXDATE", "2003-06-01T00:04:00Z")); } - @TestOfyAndSql + @Test void testDomainTransfer_queryForServerApproved() throws Exception { // Creation date of fakesite: 2000-06-01T00:04:00.0Z // Expiration date: 2002-06-01T00:04:00.0Z @@ -1450,7 +1444,7 @@ class EppLifecycleDomainTest extends EppTestCase { .hasResponse("domain_transfer_query_response_completed_fakesite.xml"); } - @TestOfyAndSql + @Test void testDomainUpdateBySuperuser_sendsPollMessage() throws Exception { setIsSuperuser(false); assertThatLoginSucceeds("NewRegistrar", "foo-BAR2"); diff --git a/core/src/test/java/google/registry/flows/EppLifecycleHostTest.java b/core/src/test/java/google/registry/flows/EppLifecycleHostTest.java index e03e33ae8..40d22084e 100644 --- a/core/src/test/java/google/registry/flows/EppLifecycleHostTest.java +++ b/core/src/test/java/google/registry/flows/EppLifecycleHostTest.java @@ -26,24 +26,18 @@ import com.google.common.collect.ImmutableMap; import google.registry.model.domain.DomainBase; import google.registry.model.host.HostResource; import google.registry.testing.AppEngineExtension; -import google.registry.testing.DualDatabaseTest; -import google.registry.testing.TestOfyAndSql; import org.joda.time.DateTime; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; /** Tests for host lifecycle. */ -@DualDatabaseTest class EppLifecycleHostTest extends EppTestCase { @RegisterExtension final AppEngineExtension appEngine = - AppEngineExtension.builder() - .withDatastoreAndCloudSql() - .withClock(clock) - .withTaskQueue() - .build(); + AppEngineExtension.builder().withCloudSql().withClock(clock).withTaskQueue().build(); - @TestOfyAndSql + @Test void testLifecycle() throws Exception { assertThatLoginSucceeds("NewRegistrar", "foo-BAR2"); assertThatCommand("hello.xml") @@ -91,7 +85,7 @@ class EppLifecycleHostTest extends EppTestCase { assertThatLogoutSucceeds(); } - @TestOfyAndSql + @Test void testRenamingHostToExistingHost_fails() throws Exception { createTld("example"); assertThatLoginSucceeds("NewRegistrar", "foo-BAR2"); @@ -141,7 +135,7 @@ class EppLifecycleHostTest extends EppTestCase { assertThatLogoutSucceeds(); } - @TestOfyAndSql + @Test void testSuccess_multipartTldsWithSharedSuffixes() throws Exception { createTlds("bar.foo.tld", "foo.tld", "tld"); diff --git a/core/src/test/java/google/registry/flows/EppLifecycleLoginTest.java b/core/src/test/java/google/registry/flows/EppLifecycleLoginTest.java index f75d7a0d2..ffeb86d87 100644 --- a/core/src/test/java/google/registry/flows/EppLifecycleLoginTest.java +++ b/core/src/test/java/google/registry/flows/EppLifecycleLoginTest.java @@ -27,7 +27,7 @@ class EppLifecycleLoginTest extends EppTestCase { @RegisterExtension final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().withTaskQueue().build(); + AppEngineExtension.builder().withCloudSql().withTaskQueue().build(); @Test void testLoginAndLogout_recordsEppMetric() throws Exception { diff --git a/core/src/test/java/google/registry/flows/EppLoggedOutTest.java b/core/src/test/java/google/registry/flows/EppLoggedOutTest.java index c8f0201b8..03a2c03a2 100644 --- a/core/src/test/java/google/registry/flows/EppLoggedOutTest.java +++ b/core/src/test/java/google/registry/flows/EppLoggedOutTest.java @@ -27,8 +27,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; class EppLoggedOutTest extends EppTestCase { @RegisterExtension - final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().build(); + final AppEngineExtension appEngine = AppEngineExtension.builder().withCloudSql().build(); @Test void testHello() throws Exception { diff --git a/core/src/test/java/google/registry/flows/EppLoginTlsTest.java b/core/src/test/java/google/registry/flows/EppLoginTlsTest.java index bedb6bb92..9e54ef63f 100644 --- a/core/src/test/java/google/registry/flows/EppLoginTlsTest.java +++ b/core/src/test/java/google/registry/flows/EppLoginTlsTest.java @@ -44,8 +44,7 @@ import org.testcontainers.shaded.org.bouncycastle.util.io.pem.PemWriter; class EppLoginTlsTest extends EppTestCase { @RegisterExtension - final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().build(); + final AppEngineExtension appEngine = AppEngineExtension.builder().withCloudSql().build(); @RegisterExtension @Order(value = Integer.MAX_VALUE) diff --git a/core/src/test/java/google/registry/flows/EppPointInTimeTest.java b/core/src/test/java/google/registry/flows/EppPointInTimeTest.java index 21eca5321..33ecaaa57 100644 --- a/core/src/test/java/google/registry/flows/EppPointInTimeTest.java +++ b/core/src/test/java/google/registry/flows/EppPointInTimeTest.java @@ -34,29 +34,23 @@ import google.registry.model.domain.DomainBase; import google.registry.model.ofy.Ofy; import google.registry.monitoring.whitebox.EppMetric; import google.registry.testing.AppEngineExtension; -import google.registry.testing.DualDatabaseTest; import google.registry.testing.EppLoader; import google.registry.testing.FakeClock; import google.registry.testing.FakeHttpSession; import google.registry.testing.InjectExtension; -import google.registry.testing.TestOfyAndSql; import org.joda.time.DateTime; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; /** Test that we can reload EPP resources as they were in the past. */ -@DualDatabaseTest class EppPointInTimeTest { private final FakeClock clock = new FakeClock(DateTime.now(UTC)); @RegisterExtension final AppEngineExtension appEngine = - AppEngineExtension.builder() - .withDatastoreAndCloudSql() - .withClock(clock) - .withTaskQueue() - .build(); + AppEngineExtension.builder().withCloudSql().withClock(clock).withTaskQueue().build(); @RegisterExtension final InjectExtension inject = new InjectExtension(); @@ -91,7 +85,7 @@ class EppPointInTimeTest { .run(EppMetric.builder()); } - @TestOfyAndSql + @Test void testLoadAtPointInTime() throws Exception { clock.setTo(DateTime.parse("1984-12-18T12:30Z")); // not midnight diff --git a/core/src/test/java/google/registry/flows/EppXxeAttackTest.java b/core/src/test/java/google/registry/flows/EppXxeAttackTest.java index e2fb52226..cf2ab941f 100644 --- a/core/src/test/java/google/registry/flows/EppXxeAttackTest.java +++ b/core/src/test/java/google/registry/flows/EppXxeAttackTest.java @@ -23,8 +23,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; class EppXxeAttackTest extends EppTestCase { @RegisterExtension - final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().build(); + final AppEngineExtension appEngine = AppEngineExtension.builder().withCloudSql().build(); @Test void testRemoteXmlExternalEntity() throws Exception { diff --git a/core/src/test/java/google/registry/flows/ExtensionManagerTest.java b/core/src/test/java/google/registry/flows/ExtensionManagerTest.java index e6adbde2a..1028fb30c 100644 --- a/core/src/test/java/google/registry/flows/ExtensionManagerTest.java +++ b/core/src/test/java/google/registry/flows/ExtensionManagerTest.java @@ -45,8 +45,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; class ExtensionManagerTest { @RegisterExtension - final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().build(); + final AppEngineExtension appEngine = AppEngineExtension.builder().withCloudSql().build(); @Test void testDuplicateExtensionsForbidden() { diff --git a/core/src/test/java/google/registry/flows/FlowRunnerTest.java b/core/src/test/java/google/registry/flows/FlowRunnerTest.java index 39f072527..27e15b238 100644 --- a/core/src/test/java/google/registry/flows/FlowRunnerTest.java +++ b/core/src/test/java/google/registry/flows/FlowRunnerTest.java @@ -52,7 +52,7 @@ class FlowRunnerTest { @RegisterExtension final AppEngineExtension appEngineExtension = - new AppEngineExtension.Builder().withDatastoreAndCloudSql().build(); + new AppEngineExtension.Builder().withCloudSql().build(); private final FlowRunner flowRunner = new FlowRunner(); private final EppMetric.Builder eppMetricBuilder = EppMetric.builderForRequest(new FakeClock()); diff --git a/core/src/test/java/google/registry/flows/FlowTestCase.java b/core/src/test/java/google/registry/flows/FlowTestCase.java index 49194532d..95c31a6bf 100644 --- a/core/src/test/java/google/registry/flows/FlowTestCase.java +++ b/core/src/test/java/google/registry/flows/FlowTestCase.java @@ -21,7 +21,6 @@ import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; import static google.registry.model.eppcommon.EppXmlTransformer.marshal; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import static google.registry.testing.DatabaseHelper.stripBillingEventId; import static google.registry.util.DateTimeUtils.END_OF_TIME; import static google.registry.util.DateTimeUtils.START_OF_TIME; @@ -69,7 +68,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; */ public abstract class FlowTestCase { - /** Whether to actually write to Datastore or just simulate. */ + /** Whether to actually write to the database or just simulate. */ public enum CommitMode { LIVE, DRY_RUN @@ -99,11 +98,7 @@ public abstract class FlowTestCase { @RegisterExtension final AppEngineExtension appEngine = - AppEngineExtension.builder() - .withClock(clock) - .withDatastoreAndCloudSql() - .withTaskQueue() - .build(); + AppEngineExtension.builder().withClock(clock).withCloudSql().withTaskQueue().build(); @BeforeEach public void beforeEachFlowTestCase() { @@ -202,12 +197,12 @@ public abstract class FlowTestCase { assertWithMessage("Billing event is present for grace period: " + gracePeriod) .that(gracePeriod.hasBillingEvent()) .isTrue(); - return transactIfJpaTm( - () -> - tm().loadByKey( - firstNonNull( - gracePeriod.getOneTimeBillingEvent(), - gracePeriod.getRecurringBillingEvent()))); + return tm().transact( + () -> + tm().loadByKey( + firstNonNull( + gracePeriod.getOneTimeBillingEvent(), + gracePeriod.getRecurringBillingEvent()))); } /** diff --git a/core/src/test/java/google/registry/flows/ResourceFlowTestCase.java b/core/src/test/java/google/registry/flows/ResourceFlowTestCase.java index 6ba415659..abecd600c 100644 --- a/core/src/test/java/google/registry/flows/ResourceFlowTestCase.java +++ b/core/src/test/java/google/registry/flows/ResourceFlowTestCase.java @@ -18,7 +18,6 @@ import static google.registry.batch.AsyncTaskEnqueuer.PARAM_RESOURCE_KEY; import static google.registry.model.EppResourceUtils.loadByForeignKey; import static google.registry.model.ImmutableObjectSubject.assertAboutImmutableObjects; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import static google.registry.testing.LogsSubject.assertAboutLogs; import static google.registry.testing.TaskQueueHelper.assertTasksEnqueued; @@ -87,7 +86,7 @@ public abstract class ResourceFlowTestCase tm().loadByEntity(resource)).cloneProjectedAtTime(now); + (T) tm().transact(() -> tm().loadByEntity(resource)).cloneProjectedAtTime(now); return refreshedResource; } diff --git a/core/src/test/java/google/registry/flows/TlsCredentialsTest.java b/core/src/test/java/google/registry/flows/TlsCredentialsTest.java index d9d9f1ffe..35bc770d2 100644 --- a/core/src/test/java/google/registry/flows/TlsCredentialsTest.java +++ b/core/src/test/java/google/registry/flows/TlsCredentialsTest.java @@ -44,8 +44,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; final class TlsCredentialsTest { @RegisterExtension - final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().build(); + final AppEngineExtension appEngine = AppEngineExtension.builder().withCloudSql().build(); protected final FakeClock clock = new FakeClock(); diff --git a/core/src/test/java/google/registry/flows/contact/ContactCheckFlowTest.java b/core/src/test/java/google/registry/flows/contact/ContactCheckFlowTest.java index 9cc94975b..54495dcfe 100644 --- a/core/src/test/java/google/registry/flows/contact/ContactCheckFlowTest.java +++ b/core/src/test/java/google/registry/flows/contact/ContactCheckFlowTest.java @@ -25,25 +25,23 @@ import google.registry.flows.FlowUtils.NotLoggedInException; import google.registry.flows.ResourceCheckFlowTestCase; import google.registry.flows.exceptions.TooManyResourceChecksException; import google.registry.model.contact.ContactResource; -import google.registry.testing.DualDatabaseTest; -import google.registry.testing.TestOfyAndSql; +import org.junit.jupiter.api.Test; /** Unit tests for {@link ContactCheckFlow}. */ -@DualDatabaseTest class ContactCheckFlowTest extends ResourceCheckFlowTestCase { ContactCheckFlowTest() { setEppInput("contact_check.xml"); } - @TestOfyAndSql + @Test void testNotLoggedIn() { sessionMetadata.setRegistrarId(null); EppException thrown = assertThrows(NotLoggedInException.class, this::runFlow); assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testNothingExists() throws Exception { // These ids come from the check xml. doCheckTest( @@ -52,7 +50,7 @@ class ContactCheckFlowTest extends ResourceCheckFlowTestCase { ContactCreateFlowTest() { @@ -55,31 +53,31 @@ class ContactCreateFlowTest extends ResourceFlowTestCase { @BeforeEach @@ -66,20 +63,20 @@ class ContactDeleteFlowTest extends ResourceFlowTestCase { ContactInfoFlowTest() { @@ -100,14 +98,14 @@ class ContactInfoFlowTest extends ResourceFlowTestCase { @@ -126,31 +124,31 @@ class ContactTransferApproveFlowTest runFlow(); } - @TestOfyAndSql + @Test void testNotLoggedIn() { sessionMetadata.setRegistrarId(null); EppException thrown = assertThrows(NotLoggedInException.class, this::runFlow); assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testDryRun() throws Exception { setEppInput("contact_transfer_approve.xml"); dryRunFlowAssertResponse(loadFile("contact_transfer_approve_response.xml")); } - @TestOfyAndSql + @Test void testSuccess() throws Exception { doSuccessfulTest("contact_transfer_approve.xml", "contact_transfer_approve_response.xml"); } - @TestOfyAndSql + @Test void testSuccess_withAuthinfo() throws Exception { doSuccessfulTest("contact_transfer_approve_with_authinfo.xml", "contact_transfer_approve_response.xml"); } - @TestOfyAndSql + @Test void testFailure_badContactPassword() { // Change the contact's password so it does not match the password in the file. contact = persistResource( @@ -164,7 +162,7 @@ class ContactTransferApproveFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_neverBeenTransferred() { changeTransferStatus(null); EppException thrown = @@ -173,7 +171,7 @@ class ContactTransferApproveFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_clientApproved() { changeTransferStatus(TransferStatus.CLIENT_APPROVED); EppException thrown = @@ -182,7 +180,7 @@ class ContactTransferApproveFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_clientRejected() { changeTransferStatus(TransferStatus.CLIENT_REJECTED); EppException thrown = @@ -191,7 +189,7 @@ class ContactTransferApproveFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_clientCancelled() { changeTransferStatus(TransferStatus.CLIENT_CANCELLED); EppException thrown = @@ -200,7 +198,7 @@ class ContactTransferApproveFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_serverApproved() { changeTransferStatus(TransferStatus.SERVER_APPROVED); EppException thrown = @@ -209,7 +207,7 @@ class ContactTransferApproveFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_serverCancelled() { changeTransferStatus(TransferStatus.SERVER_CANCELLED); EppException thrown = @@ -218,7 +216,7 @@ class ContactTransferApproveFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_gainingClient() { setRegistrarIdForFlow("NewRegistrar"); EppException thrown = @@ -227,7 +225,7 @@ class ContactTransferApproveFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_unrelatedClient() { setRegistrarIdForFlow("ClientZ"); EppException thrown = @@ -236,7 +234,7 @@ class ContactTransferApproveFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_deletedContact() throws Exception { contact = persistResource( contact.asBuilder().setDeletionTime(clock.nowUtc().minusDays(1)).build()); @@ -248,7 +246,7 @@ class ContactTransferApproveFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_nonexistentContact() throws Exception { persistResource(contact.asBuilder().setDeletionTime(clock.nowUtc().minusDays(1)).build()); contact = persistResource( @@ -261,7 +259,7 @@ class ContactTransferApproveFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testIcannActivityReportField_getsLogged() throws Exception { runFlow(); assertIcannReportingActivityFieldLogged("srs-cont-transfer-approve"); diff --git a/core/src/test/java/google/registry/flows/contact/ContactTransferCancelFlowTest.java b/core/src/test/java/google/registry/flows/contact/ContactTransferCancelFlowTest.java index b5f5e1ce4..1ca98f827 100644 --- a/core/src/test/java/google/registry/flows/contact/ContactTransferCancelFlowTest.java +++ b/core/src/test/java/google/registry/flows/contact/ContactTransferCancelFlowTest.java @@ -38,12 +38,10 @@ import google.registry.model.reporting.HistoryEntry; import google.registry.model.transfer.TransferData; import google.registry.model.transfer.TransferResponse; import google.registry.model.transfer.TransferStatus; -import google.registry.testing.DualDatabaseTest; -import google.registry.testing.TestOfyAndSql; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; /** Unit tests for {@link ContactTransferCancelFlow}. */ -@DualDatabaseTest class ContactTransferCancelFlowTest extends ContactTransferFlowTestCase { @@ -110,31 +108,31 @@ class ContactTransferCancelFlowTest runFlow(); } - @TestOfyAndSql + @Test void testNotLoggedIn() { sessionMetadata.setRegistrarId(null); EppException thrown = assertThrows(NotLoggedInException.class, this::runFlow); assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testDryRun() throws Exception { setEppInput("contact_transfer_cancel.xml"); dryRunFlowAssertResponse(loadFile("contact_transfer_cancel_response.xml")); } - @TestOfyAndSql + @Test void testSuccess() throws Exception { doSuccessfulTest("contact_transfer_cancel.xml", "contact_transfer_cancel_response.xml"); } - @TestOfyAndSql + @Test void testSuccess_withAuthinfo() throws Exception { doSuccessfulTest("contact_transfer_cancel_with_authinfo.xml", "contact_transfer_cancel_response.xml"); } - @TestOfyAndSql + @Test void testFailure_badContactPassword() { // Change the contact's password so it does not match the password in the file. contact = @@ -150,7 +148,7 @@ class ContactTransferCancelFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_neverBeenTransferred() { changeTransferStatus(null); EppException thrown = @@ -159,7 +157,7 @@ class ContactTransferCancelFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_clientApproved() { changeTransferStatus(TransferStatus.CLIENT_APPROVED); EppException thrown = @@ -168,7 +166,7 @@ class ContactTransferCancelFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_clientRejected() { changeTransferStatus(TransferStatus.CLIENT_REJECTED); EppException thrown = @@ -177,7 +175,7 @@ class ContactTransferCancelFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_clientCancelled() { changeTransferStatus(TransferStatus.CLIENT_CANCELLED); EppException thrown = @@ -186,7 +184,7 @@ class ContactTransferCancelFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_serverApproved() { changeTransferStatus(TransferStatus.SERVER_APPROVED); EppException thrown = @@ -195,7 +193,7 @@ class ContactTransferCancelFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_serverCancelled() { changeTransferStatus(TransferStatus.SERVER_CANCELLED); EppException thrown = @@ -204,7 +202,7 @@ class ContactTransferCancelFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_sponsoringClient() { setRegistrarIdForFlow("TheRegistrar"); EppException thrown = @@ -214,7 +212,7 @@ class ContactTransferCancelFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_unrelatedClient() { setRegistrarIdForFlow("ClientZ"); EppException thrown = @@ -224,7 +222,7 @@ class ContactTransferCancelFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_deletedContact() throws Exception { contact = persistResource(contact.asBuilder().setDeletionTime(clock.nowUtc().minusDays(1)).build()); @@ -236,7 +234,7 @@ class ContactTransferCancelFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_nonexistentContact() throws Exception { persistResource(contact.asBuilder().setDeletionTime(clock.nowUtc().minusDays(1)).build()); ResourceDoesNotExistException thrown = @@ -247,7 +245,7 @@ class ContactTransferCancelFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testIcannActivityReportField_getsLogged() throws Exception { runFlow(); assertIcannReportingActivityFieldLogged("srs-cont-transfer-cancel"); diff --git a/core/src/test/java/google/registry/flows/contact/ContactTransferQueryFlowTest.java b/core/src/test/java/google/registry/flows/contact/ContactTransferQueryFlowTest.java index ec95d81ca..505b21631 100644 --- a/core/src/test/java/google/registry/flows/contact/ContactTransferQueryFlowTest.java +++ b/core/src/test/java/google/registry/flows/contact/ContactTransferQueryFlowTest.java @@ -32,13 +32,11 @@ import google.registry.model.contact.ContactResource; import google.registry.model.eppcommon.AuthInfo.PasswordAuth; import google.registry.model.reporting.HistoryEntry; import google.registry.model.transfer.TransferStatus; -import google.registry.testing.DualDatabaseTest; -import google.registry.testing.TestOfyAndSql; import org.joda.time.DateTime; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; /** Unit tests for {@link ContactTransferQueryFlow}. */ -@DualDatabaseTest class ContactTransferQueryFlowTest extends ContactTransferFlowTestCase { @@ -70,72 +68,72 @@ class ContactTransferQueryFlowTest runFlow(); } - @TestOfyAndSql + @Test void testNotLoggedIn() { sessionMetadata.setRegistrarId(null); EppException thrown = assertThrows(NotLoggedInException.class, this::runFlow); assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testSuccess() throws Exception { doSuccessfulTest("contact_transfer_query.xml", "contact_transfer_query_response.xml"); } - @TestOfyAndSql + @Test void testSuccess_withContactRoid() throws Exception { doSuccessfulTest("contact_transfer_query_with_roid.xml", "contact_transfer_query_response.xml"); } - @TestOfyAndSql + @Test void testSuccess_sponsoringClient() throws Exception { setRegistrarIdForFlow("TheRegistrar"); doSuccessfulTest("contact_transfer_query.xml", "contact_transfer_query_response.xml"); } - @TestOfyAndSql + @Test void testSuccess_withAuthinfo() throws Exception { setRegistrarIdForFlow("ClientZ"); doSuccessfulTest("contact_transfer_query_with_authinfo.xml", "contact_transfer_query_response.xml"); } - @TestOfyAndSql + @Test void testSuccess_clientApproved() throws Exception { changeTransferStatus(TransferStatus.CLIENT_APPROVED); doSuccessfulTest("contact_transfer_query.xml", "contact_transfer_query_response_client_approved.xml"); } - @TestOfyAndSql + @Test void testSuccess_clientRejected() throws Exception { changeTransferStatus(TransferStatus.CLIENT_REJECTED); doSuccessfulTest("contact_transfer_query.xml", "contact_transfer_query_response_client_rejected.xml"); } - @TestOfyAndSql + @Test void testSuccess_clientCancelled() throws Exception { changeTransferStatus(TransferStatus.CLIENT_CANCELLED); doSuccessfulTest("contact_transfer_query.xml", "contact_transfer_query_response_client_cancelled.xml"); } - @TestOfyAndSql + @Test void testSuccess_serverApproved() throws Exception { changeTransferStatus(TransferStatus.SERVER_APPROVED); doSuccessfulTest("contact_transfer_query.xml", "contact_transfer_query_response_server_approved.xml"); } - @TestOfyAndSql + @Test void testSuccess_serverCancelled() throws Exception { changeTransferStatus(TransferStatus.SERVER_CANCELLED); doSuccessfulTest("contact_transfer_query.xml", "contact_transfer_query_response_server_cancelled.xml"); } - @TestOfyAndSql + @Test void testFailure_pendingDeleteContact() throws Exception { changeTransferStatus(TransferStatus.SERVER_CANCELLED); contact = persistResource( @@ -144,7 +142,7 @@ class ContactTransferQueryFlowTest "contact_transfer_query_response_server_cancelled.xml"); } - @TestOfyAndSql + @Test void testFailure_badContactPassword() { // Change the contact's password so it does not match the password in the file. contact = @@ -160,7 +158,7 @@ class ContactTransferQueryFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_badContactRoid() { // Set the contact to a different ROID, but don't persist it; this is just so the substitution // code above will write the wrong ROID into the file. @@ -172,7 +170,7 @@ class ContactTransferQueryFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_neverBeenTransferred() { changeTransferStatus(null); EppException thrown = @@ -182,7 +180,7 @@ class ContactTransferQueryFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_unrelatedClient() { setRegistrarIdForFlow("ClientZ"); EppException thrown = @@ -192,7 +190,7 @@ class ContactTransferQueryFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_deletedContact() throws Exception { contact = persistResource(contact.asBuilder().setDeletionTime(clock.nowUtc().minusDays(1)).build()); @@ -203,7 +201,7 @@ class ContactTransferQueryFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_nonexistentContact() throws Exception { persistResource(contact.asBuilder().setDeletionTime(clock.nowUtc().minusDays(1)).build()); ResourceDoesNotExistException thrown = @@ -213,7 +211,7 @@ class ContactTransferQueryFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testIcannActivityReportField_getsLogged() throws Exception { runFlow(); assertIcannReportingActivityFieldLogged("srs-cont-transfer-query"); diff --git a/core/src/test/java/google/registry/flows/contact/ContactTransferRejectFlowTest.java b/core/src/test/java/google/registry/flows/contact/ContactTransferRejectFlowTest.java index 7fee44c8d..88a712a21 100644 --- a/core/src/test/java/google/registry/flows/contact/ContactTransferRejectFlowTest.java +++ b/core/src/test/java/google/registry/flows/contact/ContactTransferRejectFlowTest.java @@ -40,12 +40,10 @@ import google.registry.model.reporting.HistoryEntry; import google.registry.model.transfer.TransferData; import google.registry.model.transfer.TransferResponse; import google.registry.model.transfer.TransferStatus; -import google.registry.testing.DualDatabaseTest; -import google.registry.testing.TestOfyAndSql; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; /** Unit tests for {@link ContactTransferRejectFlow}. */ -@DualDatabaseTest class ContactTransferRejectFlowTest extends ContactTransferFlowTestCase { @@ -125,31 +123,31 @@ class ContactTransferRejectFlowTest runFlow(); } - @TestOfyAndSql + @Test void testNotLoggedIn() { sessionMetadata.setRegistrarId(null); EppException thrown = assertThrows(NotLoggedInException.class, this::runFlow); assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testDryRun() throws Exception { setEppInput("contact_transfer_reject.xml"); dryRunFlowAssertResponse(loadFile("contact_transfer_reject_response.xml")); } - @TestOfyAndSql + @Test void testSuccess() throws Exception { doSuccessfulTest("contact_transfer_reject.xml", "contact_transfer_reject_response.xml"); } - @TestOfyAndSql + @Test void testSuccess_domainAuthInfo() throws Exception { doSuccessfulTest("contact_transfer_reject_with_authinfo.xml", "contact_transfer_reject_response.xml"); } - @TestOfyAndSql + @Test void testFailure_badPassword() { // Change the contact's password so it does not match the password in the file. contact = @@ -165,7 +163,7 @@ class ContactTransferRejectFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_neverBeenTransferred() { changeTransferStatus(null); EppException thrown = @@ -174,7 +172,7 @@ class ContactTransferRejectFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_clientApproved() { changeTransferStatus(TransferStatus.CLIENT_APPROVED); EppException thrown = @@ -183,7 +181,7 @@ class ContactTransferRejectFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_clientRejected() { changeTransferStatus(TransferStatus.CLIENT_REJECTED); EppException thrown = @@ -192,7 +190,7 @@ class ContactTransferRejectFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_clientCancelled() { changeTransferStatus(TransferStatus.CLIENT_CANCELLED); EppException thrown = @@ -201,7 +199,7 @@ class ContactTransferRejectFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_serverApproved() { changeTransferStatus(TransferStatus.SERVER_APPROVED); EppException thrown = @@ -210,7 +208,7 @@ class ContactTransferRejectFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_serverCancelled() { changeTransferStatus(TransferStatus.SERVER_CANCELLED); EppException thrown = @@ -219,7 +217,7 @@ class ContactTransferRejectFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_gainingClient() { setRegistrarIdForFlow("NewRegistrar"); EppException thrown = @@ -228,7 +226,7 @@ class ContactTransferRejectFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_unrelatedClient() { setRegistrarIdForFlow("ClientZ"); EppException thrown = @@ -237,7 +235,7 @@ class ContactTransferRejectFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_deletedContact() throws Exception { contact = persistResource(contact.asBuilder().setDeletionTime(clock.nowUtc().minusDays(1)).build()); @@ -249,7 +247,7 @@ class ContactTransferRejectFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_nonexistentContact() throws Exception { persistResource(contact.asBuilder().setDeletionTime(clock.nowUtc().minusDays(1)).build()); ResourceDoesNotExistException thrown = @@ -260,7 +258,7 @@ class ContactTransferRejectFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testIcannActivityReportField_getsLogged() throws Exception { runFlow(); assertIcannReportingActivityFieldLogged("srs-cont-transfer-reject"); diff --git a/core/src/test/java/google/registry/flows/contact/ContactTransferRequestFlowTest.java b/core/src/test/java/google/registry/flows/contact/ContactTransferRequestFlowTest.java index 5c2c8ce99..d12b30dcf 100644 --- a/core/src/test/java/google/registry/flows/contact/ContactTransferRequestFlowTest.java +++ b/core/src/test/java/google/registry/flows/contact/ContactTransferRequestFlowTest.java @@ -51,13 +51,11 @@ import google.registry.model.poll.PollMessage; import google.registry.model.reporting.HistoryEntry; import google.registry.model.transfer.ContactTransferData; import google.registry.model.transfer.TransferStatus; -import google.registry.testing.DualDatabaseTest; -import google.registry.testing.TestOfyAndSql; import org.joda.time.DateTime; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; /** Unit tests for {@link ContactTransferRequestFlow}. */ -@DualDatabaseTest class ContactTransferRequestFlowTest extends ContactTransferFlowTestCase { @@ -146,25 +144,25 @@ class ContactTransferRequestFlowTest runFlow(); } - @TestOfyAndSql + @Test void testNotLoggedIn() { sessionMetadata.setRegistrarId(null); EppException thrown = assertThrows(NotLoggedInException.class, this::runFlow); assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testDryRun() throws Exception { setEppInput("contact_transfer_request.xml"); dryRunFlowAssertResponse(loadFile("contact_transfer_request_response.xml")); } - @TestOfyAndSql + @Test void testSuccess() throws Exception { doSuccessfulTest("contact_transfer_request.xml", "contact_transfer_request_response.xml"); } - @TestOfyAndSql + @Test void testFailure_noAuthInfo() { EppException thrown = assertThrows( @@ -173,7 +171,7 @@ class ContactTransferRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_badPassword() { // Change the contact's password so it does not match the password in the file. contact = @@ -189,37 +187,37 @@ class ContactTransferRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testSuccess_clientApproved() throws Exception { changeTransferStatus(TransferStatus.CLIENT_APPROVED); doSuccessfulTest("contact_transfer_request.xml", "contact_transfer_request_response.xml"); } - @TestOfyAndSql + @Test void testSuccess_clientRejected() throws Exception { changeTransferStatus(TransferStatus.CLIENT_REJECTED); doSuccessfulTest("contact_transfer_request.xml", "contact_transfer_request_response.xml"); } - @TestOfyAndSql + @Test void testSuccess_clientCancelled() throws Exception { changeTransferStatus(TransferStatus.CLIENT_CANCELLED); doSuccessfulTest("contact_transfer_request.xml", "contact_transfer_request_response.xml"); } - @TestOfyAndSql + @Test void testSuccess_serverApproved() throws Exception { changeTransferStatus(TransferStatus.SERVER_APPROVED); doSuccessfulTest("contact_transfer_request.xml", "contact_transfer_request_response.xml"); } - @TestOfyAndSql + @Test void testSuccess_serverCancelled() throws Exception { changeTransferStatus(TransferStatus.SERVER_CANCELLED); doSuccessfulTest("contact_transfer_request.xml", "contact_transfer_request_response.xml"); } - @TestOfyAndSql + @Test void testFailure_pending() { contact = persistResource( @@ -240,7 +238,7 @@ class ContactTransferRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_sponsoringClient() { setRegistrarIdForFlow("TheRegistrar"); EppException thrown = @@ -250,7 +248,7 @@ class ContactTransferRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_deletedContact() throws Exception { contact = persistResource(contact.asBuilder().setDeletionTime(clock.nowUtc().minusDays(1)).build()); @@ -262,7 +260,7 @@ class ContactTransferRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_nonexistentContact() throws Exception { deleteResource(contact); ResourceDoesNotExistException thrown = @@ -273,7 +271,7 @@ class ContactTransferRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_clientTransferProhibited() { contact = persistResource( @@ -286,7 +284,7 @@ class ContactTransferRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_serverTransferProhibited() { contact = persistResource( @@ -299,7 +297,7 @@ class ContactTransferRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_pendingDelete() { contact = persistResource(contact.asBuilder().addStatusValue(StatusValue.PENDING_DELETE).build()); @@ -311,7 +309,7 @@ class ContactTransferRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testIcannActivityReportField_getsLogged() throws Exception { runFlow(); assertIcannReportingActivityFieldLogged("srs-cont-transfer-request"); diff --git a/core/src/test/java/google/registry/flows/contact/ContactUpdateFlowTest.java b/core/src/test/java/google/registry/flows/contact/ContactUpdateFlowTest.java index b4fdc6b2f..c718c51e0 100644 --- a/core/src/test/java/google/registry/flows/contact/ContactUpdateFlowTest.java +++ b/core/src/test/java/google/registry/flows/contact/ContactUpdateFlowTest.java @@ -42,11 +42,9 @@ import google.registry.model.contact.ContactResource; import google.registry.model.contact.PostalInfo; import google.registry.model.contact.PostalInfo.Type; import google.registry.model.eppcommon.StatusValue; -import google.registry.testing.DualDatabaseTest; -import google.registry.testing.TestOfyAndSql; +import org.junit.jupiter.api.Test; /** Unit tests for {@link ContactUpdateFlow}. */ -@DualDatabaseTest class ContactUpdateFlowTest extends ResourceFlowTestCase { ContactUpdateFlowTest() { @@ -70,25 +68,25 @@ class ContactUpdateFlowTest extends ResourceFlowTestCase { @Order(value = Order.DEFAULT - 3) @@ -120,14 +118,14 @@ class DomainCheckFlowTest extends ResourceCheckFlowTestCase { @@ -67,32 +65,32 @@ public class DomainClaimsCheckFlowTest runFlowAssertResponse(loadFile(expectedXmlFilename)); } - @TestOfyAndSql + @Test void testNotLoggedIn() { sessionMetadata.setRegistrarId(null); EppException thrown = assertThrows(NotLoggedInException.class, this::runFlow); assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testSuccess_noClaims() throws Exception { doSuccessfulTest("domain_check_claims_response_none.xml"); } - @TestOfyAndSql + @Test void testSuccess_quietPeriod() throws Exception { createTld("tld", TldState.QUIET_PERIOD); doSuccessfulTest("domain_check_claims_response_none.xml"); } - @TestOfyAndSql + @Test void testSuccess_oneClaim() throws Exception { persistClaimsList( ImmutableMap.of("example2", "2013041500/2/6/9/rJ1NrDO92vDsAzf7EQzgjX4R0000000001")); doSuccessfulTest("domain_check_claims_response.xml"); } - @TestOfyAndSql + @Test void testSuccess_multipleTlds() throws Exception { setEppInput("domain_check_claims_multiple_tlds.xml"); createTld("tld1"); @@ -102,28 +100,28 @@ public class DomainClaimsCheckFlowTest doSuccessfulTest("domain_check_claims_response_multiple_tlds.xml"); } - @TestOfyAndSql + @Test void testSuccess_50IdsAllowed() throws Exception { // Make sure we don't have a regression that reduces the number of allowed checks. setEppInput("domain_check_claims_50.xml"); runFlow(); } - @TestOfyAndSql + @Test void testFailure_TooManyIds() { setEppInput("domain_check_claims_51.xml"); EppException thrown = assertThrows(TooManyResourceChecksException.class, this::runFlow); assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_tldDoesntExist() { setEppInput("domain_check_claims_bad_tld.xml"); EppException thrown = assertThrows(TldDoesNotExistException.class, this::runFlow); assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_notAuthorizedForTld() { persistResource( loadRegistrar("TheRegistrar").asBuilder().setAllowedTlds(ImmutableSet.of()).build()); @@ -131,7 +129,7 @@ public class DomainClaimsCheckFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_missingBillingAccount() { persistResource( Registry.get("tld") @@ -149,7 +147,7 @@ public class DomainClaimsCheckFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testSuccess_superuserNotAuthorizedForTld() throws Exception { persistClaimsList( ImmutableMap.of("example2", "2013041500/2/6/9/rJ1NrDO92vDsAzf7EQzgjX4R0000000001")); @@ -162,7 +160,7 @@ public class DomainClaimsCheckFlowTest CommitMode.LIVE, UserPrivileges.SUPERUSER, loadFile("domain_check_claims_response.xml")); } - @TestOfyAndSql + @Test void testFailure_predelgation() { createTld("tld", PREDELEGATION); setEppInput("domain_check_claims.xml"); @@ -170,7 +168,7 @@ public class DomainClaimsCheckFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_allocationToken() { createTld("tld"); setEppInput("domain_check_claims_allocationtoken.xml"); @@ -179,7 +177,7 @@ public class DomainClaimsCheckFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_multipleTlds_oneHasEndedClaims() { createTlds("tld1", "tld2"); persistResource( @@ -189,7 +187,7 @@ public class DomainClaimsCheckFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testIcannActivityReportField_getsLogged() throws Exception { runFlow(); assertIcannReportingActivityFieldLogged("srs-dom-check"); diff --git a/core/src/test/java/google/registry/flows/domain/DomainCreateFlowTest.java b/core/src/test/java/google/registry/flows/domain/DomainCreateFlowTest.java index baef214ef..e843a03c3 100644 --- a/core/src/test/java/google/registry/flows/domain/DomainCreateFlowTest.java +++ b/core/src/test/java/google/registry/flows/domain/DomainCreateFlowTest.java @@ -34,7 +34,6 @@ import static google.registry.model.tld.Registry.TldState.PREDELEGATION; import static google.registry.model.tld.Registry.TldState.QUIET_PERIOD; import static google.registry.model.tld.Registry.TldState.START_DATE_SUNRISE; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import static google.registry.pricing.PricingEngineProxy.isDomainPremium; import static google.registry.testing.DatabaseHelper.assertBillingEvents; import static google.registry.testing.DatabaseHelper.assertPollMessagesForResource; @@ -174,9 +173,7 @@ import google.registry.model.tld.Registry.TldState; import google.registry.model.tld.Registry.TldType; import google.registry.monitoring.whitebox.EppMetric; import google.registry.persistence.VKey; -import google.registry.testing.DualDatabaseTest; import google.registry.testing.TaskQueueHelper.TaskMatcher; -import google.registry.testing.TestOfyAndSql; import java.math.BigDecimal; import java.util.Map; import java.util.Optional; @@ -185,9 +182,9 @@ import org.joda.money.Money; import org.joda.time.DateTime; import org.joda.time.Duration; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; /** Unit tests for {@link DomainCreateFlow}. */ -@DualDatabaseTest class DomainCreateFlowTest extends ResourceFlowTestCase { private static final String CLAIMS_KEY = "2013041500/2/6/9/rJ1NrDO92vDsAzf7EQzgjX4R0000000001"; @@ -283,7 +280,7 @@ class DomainCreateFlowTest extends ResourceFlowTestCase tm().loadByKey(domain.getAutorenewBillingEvent()).getEventTime())) + tm().transact(() -> tm().loadByKey(domain.getAutorenewBillingEvent()).getEventTime())) .and() .hasOnlyOneHistoryEntryWhich() .hasType(HistoryEntry.Type.DOMAIN_CREATE) @@ -430,27 +427,27 @@ class DomainCreateFlowTest extends ResourceFlowTestCase tm().loadByEntity(token)).getRedemptionHistoryEntry()) + assertThat(tm().transact(() -> tm().loadByEntity(token)).getRedemptionHistoryEntry()) .hasValue(HistoryEntry.createVKey(Key.create(historyEntry))); } // DomainTransactionRecord is not propagated. - @TestOfyAndSql + @Test void testSuccess_validAllocationToken_multiUse() throws Exception { setEppInput( "domain_create_allocationtoken.xml", @@ -588,7 +585,7 @@ class DomainCreateFlowTest extends ResourceFlowTestCase tm().loadByKey(VKey.create(AllocationToken.class, token))); + tm().transact(() -> tm().loadByKey(VKey.create(AllocationToken.class, token))); assertThat(reloadedToken.isRedeemed()).isTrue(); assertThat(reloadedToken.getRedemptionHistoryEntry()) .hasValue( @@ -1347,11 +1344,11 @@ class DomainCreateFlowTest extends ResourceFlowTestCase tm().loadByKey(VKey.create(AllocationToken.class, token))); + tm().transact(() -> tm().loadByKey(VKey.create(AllocationToken.class, token))); assertThat(reloadedToken.isRedeemed()).isFalse(); } - @TestOfyAndSql + @Test void testSuccess_allocationTokenPromotion() throws Exception { // A discount of 0.5 means that the first-year cost (13) is cut in half, so a discount of 6.5 // Note: we're asking to register it for two years so the total cost should be 13 + (13/2) @@ -1375,18 +1372,18 @@ class DomainCreateFlowTest extends ResourceFlowTestCase tm().loadAllOf(BillingEvent.OneTime.class))); + Iterables.getOnlyElement(tm().transact(() -> tm().loadAllOf(BillingEvent.OneTime.class))); assertThat(billingEvent.getTargetId()).isEqualTo("example.tld"); assertThat(billingEvent.getCost()).isEqualTo(Money.of(USD, BigDecimal.valueOf(19.5))); } - @TestOfyAndSql + @Test void testSuccess_allocationToken_multiYearDiscount_maxesAtTokenDiscountYears() throws Exception { // 2yrs @ $13 + 3yrs @ $13 * (1 - 0.73) = $36.53 runTest_allocationToken_multiYearDiscount(false, 0.73, 3, Money.of(USD, 36.53)); } - @TestOfyAndSql + @Test void testSuccess_allocationToken_multiYearDiscount_maxesAtNumRegistrationYears() throws Exception { // 5yrs @ $13 * (1 - 0.276) = $47.06 @@ -1425,12 +1422,12 @@ class DomainCreateFlowTest extends ResourceFlowTestCase tm().loadAllOf(BillingEvent.OneTime.class))); + Iterables.getOnlyElement(tm().transact(() -> tm().loadAllOf(BillingEvent.OneTime.class))); assertThat(billingEvent.getTargetId()).isEqualTo("example.tld"); assertThat(billingEvent.getCost()).isEqualTo(expectedPrice); } - @TestOfyAndSql + @Test void testSuccess_allocationToken_multiYearDiscount_worksForPremiums() throws Exception { createTld("example"); persistContactsAndHosts(); @@ -1458,13 +1455,13 @@ class DomainCreateFlowTest extends ResourceFlowTestCase tm().loadAllOf(BillingEvent.OneTime.class))); + Iterables.getOnlyElement(tm().transact(() -> tm().loadAllOf(BillingEvent.OneTime.class))); assertThat(billingEvent.getTargetId()).isEqualTo("rich.example"); // 1yr @ $100 + 2yrs @ $100 * (1 - 0.98) = $104 assertThat(billingEvent.getCost()).isEqualTo(Money.of(USD, 104.00)); } - @TestOfyAndSql + @Test void testSuccess_allocationToken_singleYearDiscount_worksForPremiums() throws Exception { createTld("example"); persistContactsAndHosts(); @@ -1491,13 +1488,13 @@ class DomainCreateFlowTest extends ResourceFlowTestCase tm().loadAllOf(BillingEvent.OneTime.class))); + Iterables.getOnlyElement(tm().transact(() -> tm().loadAllOf(BillingEvent.OneTime.class))); assertThat(billingEvent.getTargetId()).isEqualTo("rich.example"); // 2yrs @ $100 + 1yr @ $100 * (1 - 0.95555) = $204.44 assertThat(billingEvent.getCost()).isEqualTo(Money.of(USD, 204.44)); } - @TestOfyAndSql + @Test void testSuccess_promotionDoesNotApplyToPremiumPrice() { // Discounts only apply to premium domains if the token is explicitly configured to allow it. createTld("example"); @@ -1523,7 +1520,7 @@ class DomainCreateFlowTest extends ResourceFlowTestCase substitutions = ImmutableMap.of("DOMAIN", "custom-logic-test.tld"); @@ -1822,7 +1819,7 @@ class DomainCreateFlowTest extends ResourceFlowTestCase { private DomainBase domain; @@ -286,14 +284,14 @@ class DomainDeleteFlowTest extends ResourceFlowTestCase { @BeforeEach @@ -56,12 +54,12 @@ class DomainFlowUtilsTest extends ResourceFlowTestCase { @Order(value = Order.DEFAULT - 3) @@ -202,94 +195,94 @@ class DomainInfoFlowTest extends ResourceFlowTestCase - keys.stream() - .map(com.google.appengine.api.datastore.Key::getKind) - .anyMatch( - Predicates.in( - ImmutableSet.of( - Key.getKind(ContactResource.class), - Key.getKind(HostResource.class))))) - .count(); - // Nameserver keys now get persisted twice (because they are stored in nsHostsVKeys), so we - // check for two loads instead of 1. - assertThat(numReadsWithContactsOrHosts).isEqualTo(2); - } - - @TestOfyAndSql + @Test void testIcannActivityReportField_getsLogged() throws Exception { persistTestEntities(false); runFlow(); diff --git a/core/src/test/java/google/registry/flows/domain/DomainPricingLogicTest.java b/core/src/test/java/google/registry/flows/domain/DomainPricingLogicTest.java index f8a739e1d..3ff3db71a 100644 --- a/core/src/test/java/google/registry/flows/domain/DomainPricingLogicTest.java +++ b/core/src/test/java/google/registry/flows/domain/DomainPricingLogicTest.java @@ -48,27 +48,24 @@ import google.registry.model.domain.fee.Fee; import google.registry.model.eppinput.EppInput; import google.registry.model.tld.Registry; import google.registry.testing.AppEngineExtension; -import google.registry.testing.DualDatabaseTest; import google.registry.testing.FakeClock; import google.registry.testing.FakeHttpSession; -import google.registry.testing.TestOfyAndSql; import google.registry.util.Clock; import java.util.Optional; import javax.inject.Inject; import org.joda.money.Money; import org.joda.time.DateTime; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.mockito.Mock; /** Unit tests for {@link DomainPricingLogic}. */ -@DualDatabaseTest public class DomainPricingLogicTest { DomainPricingLogic domainPricingLogic; @RegisterExtension - public final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().build(); + public final AppEngineExtension appEngine = AppEngineExtension.builder().withCloudSql().build(); @Inject Clock clock = new FakeClock(DateTime.now(UTC)); @Mock EppInput eppInput; @@ -130,7 +127,7 @@ public class DomainPricingLogicTest { return recurring; } - @TestOfyAndSql + @Test void testGetDomainRenewPrice_oneYear_standardDomain_noBilling_isStandardPrice() throws EppException { assertThat( @@ -142,7 +139,7 @@ public class DomainPricingLogicTest { .build()); } - @TestOfyAndSql + @Test void testGetDomainRenewPrice_multiYear_standardDomain_noBilling_isStandardPrice() throws EppException { assertThat( @@ -154,7 +151,7 @@ public class DomainPricingLogicTest { .build()); } - @TestOfyAndSql + @Test void testGetDomainRenewPrice_oneYear_premiumDomain_noBilling_isPremiumPrice() throws EppException { assertThat( @@ -166,7 +163,7 @@ public class DomainPricingLogicTest { .build()); } - @TestOfyAndSql + @Test void testGetDomainRenewPrice_multiYear_premiumDomain_noBilling_isPremiumPrice() throws EppException { assertThat( @@ -178,7 +175,7 @@ public class DomainPricingLogicTest { .build()); } - @TestOfyAndSql + @Test void testGetDomainRenewPrice_oneYear_premiumDomain_default_isPremiumPrice() throws EppException { assertThat( domainPricingLogic.getRenewPrice( @@ -195,7 +192,7 @@ public class DomainPricingLogicTest { .build()); } - @TestOfyAndSql + @Test void testGetDomainRenewPrice_multiYear_premiumDomain_default_isPremiumCost() throws EppException { assertThat( domainPricingLogic.getRenewPrice( @@ -212,7 +209,7 @@ public class DomainPricingLogicTest { .build()); } - @TestOfyAndSql + @Test void testGetDomainRenewPrice_oneYear_standardDomain_default_isNonPremiumPrice() throws EppException { assertThat( @@ -230,7 +227,7 @@ public class DomainPricingLogicTest { .build()); } - @TestOfyAndSql + @Test void testGetDomainRenewPrice_multiYear_standardDomain_default_isNonPremiumCost() throws EppException { assertThat( @@ -248,7 +245,7 @@ public class DomainPricingLogicTest { .build()); } - @TestOfyAndSql + @Test void testGetDomainRenewPrice_oneYear_premiumDomain_anchorTenant_isNonPremiumPrice() throws EppException { assertThat( @@ -266,7 +263,7 @@ public class DomainPricingLogicTest { .build()); } - @TestOfyAndSql + @Test void testGetDomainRenewPrice_multiYear_premiumDomain_anchorTenant_isNonPremiumCost() throws EppException { assertThat( @@ -284,7 +281,7 @@ public class DomainPricingLogicTest { .build()); } - @TestOfyAndSql + @Test void testGetDomainRenewPrice_oneYear_standardDomain_anchorTenant_isNonPremiumPrice() throws EppException { assertThat( @@ -302,7 +299,7 @@ public class DomainPricingLogicTest { .build()); } - @TestOfyAndSql + @Test void testGetDomainRenewPrice_multiYear_standardDomain_anchorTenant_isNonPremiumCost() throws EppException { assertThat( @@ -320,7 +317,7 @@ public class DomainPricingLogicTest { .build()); } - @TestOfyAndSql + @Test void testGetDomainRenewPrice_oneYear_standardDomain_internalRegistration_isSpecifiedPrice() throws EppException { assertThat( @@ -338,7 +335,7 @@ public class DomainPricingLogicTest { .build()); } - @TestOfyAndSql + @Test void testGetDomainRenewPrice_multiYear_standardDomain_internalRegistration_isSpecifiedPrice() throws EppException { assertThat( @@ -356,7 +353,7 @@ public class DomainPricingLogicTest { .build()); } - @TestOfyAndSql + @Test void testGetDomainRenewPrice_oneYear_premiumDomain_internalRegistration_isSpecifiedPrice() throws EppException { assertThat( @@ -374,7 +371,7 @@ public class DomainPricingLogicTest { .build()); } - @TestOfyAndSql + @Test void testGetDomainRenewPrice_multiYear_premiumDomain_internalRegistration_isSpecifiedPrice() throws EppException { assertThat( @@ -392,7 +389,7 @@ public class DomainPricingLogicTest { .build()); } - @TestOfyAndSql + @Test void testGetDomainRenewPrice_negativeYear_throwsException() throws EppException { IllegalArgumentException thrown = assertThrows( diff --git a/core/src/test/java/google/registry/flows/domain/DomainRenewFlowTest.java b/core/src/test/java/google/registry/flows/domain/DomainRenewFlowTest.java index 2899067f4..2f9003bce 100644 --- a/core/src/test/java/google/registry/flows/domain/DomainRenewFlowTest.java +++ b/core/src/test/java/google/registry/flows/domain/DomainRenewFlowTest.java @@ -81,9 +81,7 @@ import google.registry.model.reporting.DomainTransactionRecord; import google.registry.model.reporting.DomainTransactionRecord.TransactionReportField; import google.registry.model.reporting.HistoryEntry; import google.registry.model.tld.Registry; -import google.registry.testing.DualDatabaseTest; import google.registry.testing.SetClockExtension; -import google.registry.testing.TestOfyAndSql; import java.util.Map; import javax.annotation.Nullable; import org.joda.money.Money; @@ -91,10 +89,10 @@ import org.joda.time.DateTime; import org.joda.time.Duration; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; /** Unit tests for {@link DomainRenewFlow}. */ -@DualDatabaseTest class DomainRenewFlowTest extends ResourceFlowTestCase { private static final ImmutableMap FEE_BASE_MAP = @@ -323,14 +321,14 @@ class DomainRenewFlowTest extends ResourceFlowTestCase { @@ -146,21 +144,21 @@ class DomainRestoreRequestFlowTest clock.advanceOneMilli(); } - @TestOfyAndSql + @Test void testNotLoggedIn() { sessionMetadata.setRegistrarId(null); EppException thrown = assertThrows(NotLoggedInException.class, this::runFlow); assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testDryRun() throws Exception { setEppInput("domain_update_restore_request.xml", ImmutableMap.of("DOMAIN", "example.tld")); persistPendingDeleteDomain(); dryRunFlowAssertResponse(loadFile("generic_success_response.xml")); } - @TestOfyAndSql + @Test void testSuccess_expiryStillInFuture_notExtended() throws Exception { setEppInput("domain_update_restore_request.xml", ImmutableMap.of("DOMAIN", "example.tld")); DateTime expirationTime = clock.nowUtc().plusYears(5).plusDays(45); @@ -228,7 +226,7 @@ class DomainRestoreRequestFlowTest .build()); } - @TestOfyAndSql + @Test void testSuccess_expiryInPast_extendedByOneYear() throws Exception { setEppInput("domain_update_restore_request.xml", ImmutableMap.of("DOMAIN", "example.tld")); DateTime expirationTime = clock.nowUtc().minusDays(20); @@ -307,7 +305,7 @@ class DomainRestoreRequestFlowTest .build()); } - @TestOfyAndSql + @Test void testSuccess_autorenewEndTimeIsCleared() throws Exception { setEppInput("domain_update_restore_request_fee.xml", FEE_06_MAP); persistPendingDeleteDomain(); @@ -321,14 +319,14 @@ class DomainRestoreRequestFlowTest assertThat(reloadResourceByForeignKey().getAutorenewEndTime()).isEmpty(); } - @TestOfyAndSql + @Test void testSuccess_fee_v06() throws Exception { setEppInput("domain_update_restore_request_fee.xml", FEE_06_MAP); persistPendingDeleteDomain(); runFlowAssertResponse(loadFile("domain_update_restore_request_response_fee.xml", FEE_06_MAP)); } - @TestOfyAndSql + @Test void testSuccess_fee_v06_noRenewal() throws Exception { setEppInput("domain_update_restore_request_fee_no_renewal.xml", FEE_06_MAP); persistPendingDeleteDomain(clock.nowUtc().plusMonths(6)); @@ -336,42 +334,42 @@ class DomainRestoreRequestFlowTest loadFile("domain_update_restore_request_response_fee_no_renewal.xml", FEE_06_MAP)); } - @TestOfyAndSql + @Test void testSuccess_fee_v11() throws Exception { setEppInput("domain_update_restore_request_fee.xml", FEE_11_MAP); persistPendingDeleteDomain(); runFlowAssertResponse(loadFile("domain_update_restore_request_response_fee.xml", FEE_11_MAP)); } - @TestOfyAndSql + @Test void testSuccess_fee_v12() throws Exception { setEppInput("domain_update_restore_request_fee.xml", FEE_12_MAP); persistPendingDeleteDomain(); runFlowAssertResponse(loadFile("domain_update_restore_request_response_fee.xml", FEE_12_MAP)); } - @TestOfyAndSql + @Test void testSuccess_fee_withDefaultAttributes_v06() throws Exception { setEppInput("domain_update_restore_request_fee_defaults.xml", FEE_06_MAP); persistPendingDeleteDomain(); runFlowAssertResponse(loadFile("domain_update_restore_request_response_fee.xml", FEE_06_MAP)); } - @TestOfyAndSql + @Test void testSuccess_fee_withDefaultAttributes_v11() throws Exception { setEppInput("domain_update_restore_request_fee_defaults.xml", FEE_11_MAP); persistPendingDeleteDomain(); runFlowAssertResponse(loadFile("domain_update_restore_request_response_fee.xml", FEE_11_MAP)); } - @TestOfyAndSql + @Test void testSuccess_fee_withDefaultAttributes_v12() throws Exception { setEppInput("domain_update_restore_request_fee_defaults.xml", FEE_12_MAP); persistPendingDeleteDomain(); runFlowAssertResponse(loadFile("domain_update_restore_request_response_fee.xml", FEE_12_MAP)); } - @TestOfyAndSql + @Test void testFailure_fee_unknownCurrency() { ImmutableMap substitutions = ImmutableMap.of("FEE_VERSION", "0.12", "FEE_NS", "fee12", "CURRENCY", "BAD"); @@ -381,7 +379,7 @@ class DomainRestoreRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_refundableFee_v06() throws Exception { setEppInput("domain_update_restore_request_fee_refundable.xml", FEE_06_MAP); persistPendingDeleteDomain(); @@ -389,7 +387,7 @@ class DomainRestoreRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_refundableFee_v11() throws Exception { setEppInput("domain_update_restore_request_fee_refundable.xml", FEE_11_MAP); persistPendingDeleteDomain(); @@ -397,7 +395,7 @@ class DomainRestoreRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_refundableFee_v12() throws Exception { setEppInput("domain_update_restore_request_fee_refundable.xml", FEE_12_MAP); persistPendingDeleteDomain(); @@ -405,7 +403,7 @@ class DomainRestoreRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_gracePeriodFee_v06() throws Exception { setEppInput("domain_update_restore_request_fee_grace_period.xml", FEE_06_MAP); persistPendingDeleteDomain(); @@ -413,7 +411,7 @@ class DomainRestoreRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_gracePeriodFee_v11() throws Exception { setEppInput("domain_update_restore_request_fee_grace_period.xml", FEE_11_MAP); persistPendingDeleteDomain(); @@ -421,7 +419,7 @@ class DomainRestoreRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_gracePeriodFee_v12() throws Exception { setEppInput("domain_update_restore_request_fee_grace_period.xml", FEE_12_MAP); persistPendingDeleteDomain(); @@ -429,7 +427,7 @@ class DomainRestoreRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_appliedFee_v06() throws Exception { setEppInput("domain_update_restore_request_fee_applied.xml", FEE_06_MAP); persistPendingDeleteDomain(); @@ -437,7 +435,7 @@ class DomainRestoreRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_appliedFee_v11() throws Exception { setEppInput("domain_update_restore_request_fee_applied.xml", FEE_11_MAP); persistPendingDeleteDomain(); @@ -445,7 +443,7 @@ class DomainRestoreRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_appliedFee_v12() throws Exception { setEppInput("domain_update_restore_request_fee_applied.xml", FEE_12_MAP); persistPendingDeleteDomain(); @@ -453,7 +451,7 @@ class DomainRestoreRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testSuccess_premiumNotBlocked() throws Exception { createTld("example"); setEppInput("domain_update_restore_request_premium.xml"); @@ -461,7 +459,7 @@ class DomainRestoreRequestFlowTest runFlowAssertResponse(loadFile("domain_update_restore_request_response_premium.xml")); } - @TestOfyAndSql + @Test void testSuccess_premiumNotBlocked_andNoRenewal() throws Exception { createTld("example"); setEppInput("domain_update_restore_request_premium_no_renewal.xml"); @@ -470,7 +468,7 @@ class DomainRestoreRequestFlowTest loadFile("domain_update_restore_request_response_fee_no_renewal.xml", FEE_12_MAP)); } - @TestOfyAndSql + @Test void testSuccess_superuserOverridesReservedList() throws Exception { persistResource( Registry.get("tld") @@ -482,7 +480,7 @@ class DomainRestoreRequestFlowTest CommitMode.LIVE, UserPrivileges.SUPERUSER, loadFile("generic_success_response.xml")); } - @TestOfyAndSql + @Test void testSuccess_superuserOverridesPremiumNameBlock() throws Exception { createTld("example"); setEppInput("domain_update_restore_request_premium.xml"); @@ -495,7 +493,7 @@ class DomainRestoreRequestFlowTest loadFile("domain_update_restore_request_response_premium.xml")); } - @TestOfyAndSql + @Test void testFailure_doesNotExist() throws Exception { ResourceDoesNotExistException thrown = assertThrows(ResourceDoesNotExistException.class, this::runFlow); @@ -503,7 +501,7 @@ class DomainRestoreRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_suspendedRegistrarCantRestoreDomain() { persistResource( Registrar.loadByRegistrarId("TheRegistrar") @@ -516,7 +514,7 @@ class DomainRestoreRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_pendingRegistrarCantRestoreDomain() { persistResource( Registrar.loadByRegistrarId("TheRegistrar") @@ -529,7 +527,7 @@ class DomainRestoreRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_wrongFeeAmount_v06() throws Exception { setEppInput("domain_update_restore_request_fee.xml", FEE_06_MAP); persistPendingDeleteDomain(); @@ -539,7 +537,7 @@ class DomainRestoreRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_wrongFeeAmount_v11() throws Exception { setEppInput("domain_update_restore_request_fee.xml", FEE_11_MAP); persistPendingDeleteDomain(); @@ -549,7 +547,7 @@ class DomainRestoreRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_wrongFeeAmount_v12() throws Exception { setEppInput("domain_update_restore_request_fee.xml", FEE_12_MAP); persistPendingDeleteDomain(); @@ -577,22 +575,22 @@ class DomainRestoreRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_wrongCurrency_v06() throws Exception { runWrongCurrencyTest(FEE_06_MAP); } - @TestOfyAndSql + @Test void testFailure_wrongCurrency_v11() throws Exception { runWrongCurrencyTest(FEE_11_MAP); } - @TestOfyAndSql + @Test void testFailure_wrongCurrency_v12() throws Exception { runWrongCurrencyTest(FEE_12_MAP); } - @TestOfyAndSql + @Test void testFailure_feeGivenInWrongScale_v06() throws Exception { setEppInput("domain_update_restore_request_fee_bad_scale.xml", FEE_06_MAP); persistPendingDeleteDomain(); @@ -600,7 +598,7 @@ class DomainRestoreRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_feeGivenInWrongScale_v11() throws Exception { setEppInput("domain_update_restore_request_fee_bad_scale.xml", FEE_11_MAP); persistPendingDeleteDomain(); @@ -608,7 +606,7 @@ class DomainRestoreRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_feeGivenInWrongScale_v12() throws Exception { setEppInput("domain_update_restore_request_fee_bad_scale.xml", FEE_12_MAP); persistPendingDeleteDomain(); @@ -616,7 +614,7 @@ class DomainRestoreRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_notInRedemptionPeriod() throws Exception { persistResource( newDomainBase(getUniqueIdFromCommand()) @@ -628,21 +626,21 @@ class DomainRestoreRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_notDeleted() throws Exception { persistActiveDomain(getUniqueIdFromCommand()); EppException thrown = assertThrows(DomainNotEligibleForRestoreException.class, this::runFlow); assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_fullyDeleted() throws Exception { persistDeletedDomain(getUniqueIdFromCommand(), clock.nowUtc().minusDays(1)); EppException thrown = assertThrows(ResourceDoesNotExistException.class, this::runFlow); assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_withChange() throws Exception { persistPendingDeleteDomain(); setEppInput("domain_update_restore_request_with_change.xml"); @@ -650,7 +648,7 @@ class DomainRestoreRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_withAdd() throws Exception { persistPendingDeleteDomain(); setEppInput("domain_update_restore_request_with_add.xml"); @@ -658,7 +656,7 @@ class DomainRestoreRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_withRemove() throws Exception { persistPendingDeleteDomain(); setEppInput("domain_update_restore_request_with_remove.xml"); @@ -666,7 +664,7 @@ class DomainRestoreRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_withSecDnsExtension() throws Exception { persistPendingDeleteDomain(); setEppInput("domain_update_restore_request_with_secdns.xml"); @@ -674,7 +672,7 @@ class DomainRestoreRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_unauthorizedClient() throws Exception { sessionMetadata.setRegistrarId("NewRegistrar"); persistPendingDeleteDomain(); @@ -682,7 +680,7 @@ class DomainRestoreRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testSuccess_superuserUnauthorizedClient() throws Exception { sessionMetadata.setRegistrarId("NewRegistrar"); persistPendingDeleteDomain(); @@ -693,7 +691,7 @@ class DomainRestoreRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_notAuthorizedForTld() throws Exception { persistResource( loadRegistrar("TheRegistrar").asBuilder().setAllowedTlds(ImmutableSet.of()).build()); @@ -702,7 +700,7 @@ class DomainRestoreRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_missingBillingAccount() throws Exception { persistPendingDeleteDomain(); persistResource( @@ -721,7 +719,7 @@ class DomainRestoreRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testSuccess_superuserNotAuthorizedForTld() throws Exception { persistResource( loadRegistrar("TheRegistrar").asBuilder().setAllowedTlds(ImmutableSet.of()).build()); @@ -730,7 +728,7 @@ class DomainRestoreRequestFlowTest CommitMode.LIVE, UserPrivileges.SUPERUSER, loadFile("generic_success_response.xml")); } - @TestOfyAndSql + @Test void testFailure_premiumBlocked() throws Exception { createTld("example"); setEppInput("domain_update_restore_request_premium.xml"); @@ -741,7 +739,7 @@ class DomainRestoreRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_reservedBlocked() throws Exception { createTld("tld"); persistResource( @@ -754,7 +752,7 @@ class DomainRestoreRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_premiumNotAcked() throws Exception { createTld("example"); setEppInput("domain_update_restore_request.xml", ImmutableMap.of("DOMAIN", "rich.example")); @@ -763,7 +761,7 @@ class DomainRestoreRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testIcannActivityReportField_getsLogged() throws Exception { persistPendingDeleteDomain(); runFlow(); @@ -771,7 +769,7 @@ class DomainRestoreRequestFlowTest assertTldsFieldLogged("tld"); } - @TestOfyAndSql + @Test void testIcannTransactionReportField_getsStored() throws Exception { persistPendingDeleteDomain(); runFlow(); @@ -787,7 +785,7 @@ class DomainRestoreRequestFlowTest 1)); } - @TestOfyAndSql + @Test void testFailure_restoreReportsAreNotSupported() { setEppInput("domain_update_restore_report.xml"); // This exception is referred to by its fully qualified path (rather than being imported) so diff --git a/core/src/test/java/google/registry/flows/domain/DomainTransferApproveFlowTest.java b/core/src/test/java/google/registry/flows/domain/DomainTransferApproveFlowTest.java index f41b2a1f0..57c8dce8f 100644 --- a/core/src/test/java/google/registry/flows/domain/DomainTransferApproveFlowTest.java +++ b/core/src/test/java/google/registry/flows/domain/DomainTransferApproveFlowTest.java @@ -73,17 +73,15 @@ import google.registry.model.transfer.DomainTransferData; import google.registry.model.transfer.TransferResponse.DomainTransferResponse; import google.registry.model.transfer.TransferStatus; import google.registry.persistence.VKey; -import google.registry.testing.DualDatabaseTest; -import google.registry.testing.TestOfyAndSql; import java.util.Arrays; import java.util.stream.Stream; import org.joda.money.Money; import org.joda.time.DateTime; import org.joda.time.Duration; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; /** Unit tests for {@link DomainTransferApproveFlow}. */ -@DualDatabaseTest class DomainTransferApproveFlowTest extends DomainTransferFlowTestCase { @@ -344,25 +342,25 @@ class DomainTransferApproveFlowTest runFlow(); } - @TestOfyAndSql + @Test void testNotLoggedIn() { sessionMetadata.setRegistrarId(null); EppException thrown = assertThrows(NotLoggedInException.class, this::runFlow); assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testDryRun() throws Exception { setEppLoader("domain_transfer_approve.xml"); dryRunFlowAssertResponse(loadFile("domain_transfer_approve_response.xml")); } - @TestOfyAndSql + @Test void testSuccess() throws Exception { doSuccessfulTest("tld", "domain_transfer_approve.xml", "domain_transfer_approve_response.xml"); } - @TestOfyAndSql + @Test void testSuccess_nonDefaultTransferGracePeriod() throws Exception { // We have to set up a new domain in a different TLD so that the billing event will be persisted // with the new transfer grace period in mind. @@ -377,7 +375,7 @@ class DomainTransferApproveFlowTest "net", "domain_transfer_approve_net.xml", "domain_transfer_approve_response_net.xml"); } - @TestOfyAndSql + @Test void testSuccess_domainAuthInfo() throws Exception { doSuccessfulTest( "tld", @@ -385,7 +383,7 @@ class DomainTransferApproveFlowTest "domain_transfer_approve_response.xml"); } - @TestOfyAndSql + @Test void testSuccess_contactAuthInfo() throws Exception { doSuccessfulTest( "tld", @@ -393,7 +391,7 @@ class DomainTransferApproveFlowTest "domain_transfer_approve_response.xml"); } - @TestOfyAndSql + @Test void testSuccess_autorenewBeforeTransfer() throws Exception { domain = reloadResourceByForeignKey(); DateTime oldExpirationTime = clock.nowUtc().minusDays(1); @@ -417,7 +415,7 @@ class DomainTransferApproveFlowTest .setRecurringEventKey(domain.getAutorenewBillingEvent())); } - @TestOfyAndSql + @Test void testFailure_badContactPassword() { // Change the contact's password so it does not match the password in the file. contact = @@ -433,7 +431,7 @@ class DomainTransferApproveFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_badDomainPassword() { // Change the domain's password so it does not match the password in the file. persistResource( @@ -448,7 +446,7 @@ class DomainTransferApproveFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_neverBeenTransferred() { changeTransferStatus(null); EppException thrown = @@ -457,7 +455,7 @@ class DomainTransferApproveFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_clientApproved() { changeTransferStatus(TransferStatus.CLIENT_APPROVED); EppException thrown = @@ -466,7 +464,7 @@ class DomainTransferApproveFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_clientRejected() { changeTransferStatus(TransferStatus.CLIENT_REJECTED); EppException thrown = @@ -475,7 +473,7 @@ class DomainTransferApproveFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_clientCancelled() { changeTransferStatus(TransferStatus.CLIENT_CANCELLED); EppException thrown = @@ -484,7 +482,7 @@ class DomainTransferApproveFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_serverApproved() { changeTransferStatus(TransferStatus.SERVER_APPROVED); EppException thrown = @@ -493,7 +491,7 @@ class DomainTransferApproveFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_serverCancelled() { changeTransferStatus(TransferStatus.SERVER_CANCELLED); EppException thrown = @@ -502,7 +500,7 @@ class DomainTransferApproveFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_gainingClient() { setRegistrarIdForFlow("NewRegistrar"); EppException thrown = @@ -511,7 +509,7 @@ class DomainTransferApproveFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_unrelatedClient() { setRegistrarIdForFlow("ClientZ"); EppException thrown = @@ -520,7 +518,7 @@ class DomainTransferApproveFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_deletedDomain() throws Exception { persistResource(domain.asBuilder().setDeletionTime(clock.nowUtc().minusDays(1)).build()); ResourceDoesNotExistException thrown = @@ -530,7 +528,7 @@ class DomainTransferApproveFlowTest assertThat(thrown).hasMessageThat().contains(String.format("(%s)", getUniqueIdFromCommand())); } - @TestOfyAndSql + @Test void testFailure_nonexistentDomain() throws Exception { deleteTestDomain(domain, clock.nowUtc()); ResourceDoesNotExistException thrown = @@ -540,7 +538,7 @@ class DomainTransferApproveFlowTest assertThat(thrown).hasMessageThat().contains(String.format("(%s)", getUniqueIdFromCommand())); } - @TestOfyAndSql + @Test void testFailure_notAuthorizedForTld() { persistResource( loadRegistrar("TheRegistrar").asBuilder().setAllowedTlds(ImmutableSet.of()).build()); @@ -553,7 +551,7 @@ class DomainTransferApproveFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testSuccess_superuserNotAuthorizedForTld() throws Exception { persistResource( loadRegistrar("TheRegistrar").asBuilder().setAllowedTlds(ImmutableSet.of()).build()); @@ -566,7 +564,7 @@ class DomainTransferApproveFlowTest // NB: No need to test pending delete status since pending transfers will get cancelled upon // entering pending delete phase. So it's already handled in that test case. - @TestOfyAndSql + @Test void testIcannActivityReportField_getsLogged() throws Exception { runFlow(); assertIcannReportingActivityFieldLogged("srs-dom-transfer-approve"); @@ -582,7 +580,7 @@ class DomainTransferApproveFlowTest .build()); } - @TestOfyAndSql + @Test void testIcannTransactionRecord_noRecordsToCancel() throws Exception { setUpGracePeriodDurations(); clock.advanceOneMilli(); @@ -595,7 +593,7 @@ class DomainTransferApproveFlowTest "tld", clock.nowUtc().plusDays(3), TRANSFER_SUCCESSFUL, 1)); } - @TestOfyAndSql + @Test void testIcannTransactionRecord_cancelsPreviousRecords() throws Exception { clock.advanceOneMilli(); setUpGracePeriodDurations(); @@ -624,7 +622,7 @@ class DomainTransferApproveFlowTest "tld", clock.nowUtc().plusDays(3), TRANSFER_SUCCESSFUL, 1)); } - @TestOfyAndSql + @Test void testSuccess_superuserExtension_transferPeriodZero() throws Exception { domain = reloadResourceByForeignKey(); DomainTransferData.Builder transferDataBuilder = domain.getTransferData().asBuilder(); @@ -643,7 +641,7 @@ class DomainTransferApproveFlowTest assertHistoryEntriesDoNotContainTransferBillingEventsOrGracePeriods(); } - @TestOfyAndSql + @Test void testSuccess_superuserExtension_transferPeriodZero_autorenewGraceActive() throws Exception { DomainBase domain = reloadResourceByForeignKey(); VKey existingAutorenewEvent = domain.getAutorenewBillingEvent(); diff --git a/core/src/test/java/google/registry/flows/domain/DomainTransferCancelFlowTest.java b/core/src/test/java/google/registry/flows/domain/DomainTransferCancelFlowTest.java index 884665523..2417f0d16 100644 --- a/core/src/test/java/google/registry/flows/domain/DomainTransferCancelFlowTest.java +++ b/core/src/test/java/google/registry/flows/domain/DomainTransferCancelFlowTest.java @@ -56,14 +56,12 @@ import google.registry.model.tld.Registry; import google.registry.model.transfer.DomainTransferData; import google.registry.model.transfer.TransferResponse.DomainTransferResponse; import google.registry.model.transfer.TransferStatus; -import google.registry.testing.DualDatabaseTest; -import google.registry.testing.TestOfyAndSql; import org.joda.time.DateTime; import org.joda.time.Duration; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; /** Unit tests for {@link DomainTransferCancelFlow}. */ -@DualDatabaseTest class DomainTransferCancelFlowTest extends DomainTransferFlowTestCase { @@ -196,36 +194,36 @@ class DomainTransferCancelFlowTest runFlow(); } - @TestOfyAndSql + @Test void testNotLoggedIn() { sessionMetadata.setRegistrarId(null); EppException thrown = assertThrows(NotLoggedInException.class, this::runFlow); assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testDryRun() throws Exception { setEppInput("domain_transfer_cancel.xml"); eppLoader.replaceAll("JD1234-REP", contact.getRepoId()); dryRunFlowAssertResponse(loadFile("domain_transfer_cancel_response.xml")); } - @TestOfyAndSql + @Test void testSuccess() throws Exception { doSuccessfulTest("domain_transfer_cancel.xml"); } - @TestOfyAndSql + @Test void testSuccess_domainAuthInfo() throws Exception { doSuccessfulTest("domain_transfer_cancel_domain_authinfo.xml"); } - @TestOfyAndSql + @Test void testSuccess_contactAuthInfo() throws Exception { doSuccessfulTest("domain_transfer_cancel_contact_authinfo.xml"); } - @TestOfyAndSql + @Test void testFailure_badContactPassword() { // Change the contact's password so it does not match the password in the file. contact = @@ -241,7 +239,7 @@ class DomainTransferCancelFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_badDomainPassword() { // Change the domain's password so it does not match the password in the file. domain = @@ -257,7 +255,7 @@ class DomainTransferCancelFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_neverBeenTransferred() { changeTransferStatus(null); EppException thrown = @@ -266,7 +264,7 @@ class DomainTransferCancelFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_clientApproved() { changeTransferStatus(TransferStatus.CLIENT_APPROVED); EppException thrown = @@ -275,7 +273,7 @@ class DomainTransferCancelFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_clientRejected() { changeTransferStatus(TransferStatus.CLIENT_REJECTED); EppException thrown = @@ -284,7 +282,7 @@ class DomainTransferCancelFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_clientCancelled() { changeTransferStatus(TransferStatus.CLIENT_CANCELLED); EppException thrown = @@ -293,7 +291,7 @@ class DomainTransferCancelFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_serverApproved() { changeTransferStatus(TransferStatus.SERVER_APPROVED); EppException thrown = @@ -302,7 +300,7 @@ class DomainTransferCancelFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_serverCancelled() { changeTransferStatus(TransferStatus.SERVER_CANCELLED); EppException thrown = @@ -311,7 +309,7 @@ class DomainTransferCancelFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_sponsoringClient() { setRegistrarIdForFlow("TheRegistrar"); EppException thrown = @@ -320,7 +318,7 @@ class DomainTransferCancelFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_unrelatedClient() { setRegistrarIdForFlow("ClientZ"); EppException thrown = @@ -329,7 +327,7 @@ class DomainTransferCancelFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_deletedDomain() throws Exception { domain = persistResource(domain.asBuilder().setDeletionTime(clock.nowUtc().minusDays(1)).build()); @@ -339,7 +337,7 @@ class DomainTransferCancelFlowTest assertThat(thrown).hasMessageThat().contains(String.format("(%s)", getUniqueIdFromCommand())); } - @TestOfyAndSql + @Test void testFailure_nonexistentDomain() throws Exception { deleteTestDomain(domain, clock.nowUtc()); ResourceDoesNotExistException thrown = @@ -348,7 +346,7 @@ class DomainTransferCancelFlowTest assertThat(thrown).hasMessageThat().contains(String.format("(%s)", getUniqueIdFromCommand())); } - @TestOfyAndSql + @Test void testFailure_notAuthorizedForTld() { persistResource( loadRegistrar("NewRegistrar").asBuilder().setAllowedTlds(ImmutableSet.of()).build()); @@ -359,7 +357,7 @@ class DomainTransferCancelFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testSuccess_superuserNotAuthorizedForTld() throws Exception { persistResource( loadRegistrar("NewRegistrar").asBuilder().setAllowedTlds(ImmutableSet.of()).build()); @@ -371,7 +369,7 @@ class DomainTransferCancelFlowTest // NB: No need to test pending delete status since pending transfers will get cancelled upon // entering pending delete phase. So it's already handled in that test case. - @TestOfyAndSql + @Test void testIcannActivityReportField_getsLogged() throws Exception { clock.advanceOneMilli(); runFlow(); @@ -379,7 +377,7 @@ class DomainTransferCancelFlowTest assertTldsFieldLogged("tld"); } - @TestOfyAndSql + @Test void testIcannTransactionRecord_noRecordsToCancel() throws Exception { clock.advanceOneMilli(); runFlow(); @@ -388,7 +386,7 @@ class DomainTransferCancelFlowTest assertThat(persistedEntry.getDomainTransactionRecords()).isEmpty(); } - @TestOfyAndSql + @Test void testIcannTransactionRecord_cancelsPreviousRecords() throws Exception { clock.advanceOneMilli(); persistResource( diff --git a/core/src/test/java/google/registry/flows/domain/DomainTransferQueryFlowTest.java b/core/src/test/java/google/registry/flows/domain/DomainTransferQueryFlowTest.java index 52cb340d0..b22044c89 100644 --- a/core/src/test/java/google/registry/flows/domain/DomainTransferQueryFlowTest.java +++ b/core/src/test/java/google/registry/flows/domain/DomainTransferQueryFlowTest.java @@ -35,12 +35,10 @@ import google.registry.model.domain.DomainBase; import google.registry.model.eppcommon.AuthInfo.PasswordAuth; import google.registry.model.reporting.HistoryEntry; import google.registry.model.transfer.TransferStatus; -import google.registry.testing.DualDatabaseTest; -import google.registry.testing.TestOfyAndSql; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; /** Unit tests for {@link DomainTransferQueryFlow}. */ -@DualDatabaseTest class DomainTransferQueryFlowTest extends DomainTransferFlowTestCase { @@ -82,74 +80,74 @@ class DomainTransferQueryFlowTest runFlow(); } - @TestOfyAndSql + @Test void testNotLoggedIn() { sessionMetadata.setRegistrarId(null); EppException thrown = assertThrows(NotLoggedInException.class, this::runFlow); assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testSuccess() throws Exception { doSuccessfulTest("domain_transfer_query.xml", "domain_transfer_query_response.xml", 1); } - @TestOfyAndSql + @Test void testSuccess_sponsoringClient() throws Exception { setRegistrarIdForFlow("TheRegistrar"); doSuccessfulTest("domain_transfer_query.xml", "domain_transfer_query_response.xml", 1); } - @TestOfyAndSql + @Test void testSuccess_domainAuthInfo() throws Exception { setRegistrarIdForFlow("ClientZ"); doSuccessfulTest( "domain_transfer_query_domain_authinfo.xml", "domain_transfer_query_response.xml", 1); } - @TestOfyAndSql + @Test void testSuccess_contactAuthInfo() throws Exception { setRegistrarIdForFlow("ClientZ"); doSuccessfulTest( "domain_transfer_query_contact_authinfo.xml", "domain_transfer_query_response.xml", 1); } - @TestOfyAndSql + @Test void testSuccess_clientApproved() throws Exception { changeTransferStatus(TransferStatus.CLIENT_APPROVED); doSuccessfulTest( "domain_transfer_query.xml", "domain_transfer_query_response_client_approved.xml", 1); } - @TestOfyAndSql + @Test void testSuccess_clientRejected() throws Exception { changeTransferStatus(TransferStatus.CLIENT_REJECTED); doSuccessfulTest( "domain_transfer_query.xml", "domain_transfer_query_response_client_rejected.xml", 1); } - @TestOfyAndSql + @Test void testSuccess_clientCancelled() throws Exception { changeTransferStatus(TransferStatus.CLIENT_CANCELLED); doSuccessfulTest( "domain_transfer_query.xml", "domain_transfer_query_response_client_cancelled.xml", 1); } - @TestOfyAndSql + @Test void testSuccess_serverApproved() throws Exception { changeTransferStatus(TransferStatus.SERVER_APPROVED); doSuccessfulTest( "domain_transfer_query.xml", "domain_transfer_query_response_server_approved.xml", 1); } - @TestOfyAndSql + @Test void testSuccess_serverCancelled() throws Exception { changeTransferStatus(TransferStatus.SERVER_CANCELLED); doSuccessfulTest( "domain_transfer_query.xml", "domain_transfer_query_response_server_cancelled.xml", 1); } - @TestOfyAndSql + @Test void testSuccess_tenYears() throws Exception { // Extend registration by 9 years here; with the extra 1 year from the transfer, we should // hit the 10-year capping. @@ -162,7 +160,7 @@ class DomainTransferQueryFlowTest doSuccessfulTest("domain_transfer_query.xml", "domain_transfer_query_response_10_years.xml", 1); } - @TestOfyAndSql + @Test void testFailure_pendingDeleteDomain() throws Exception { changeTransferStatus(TransferStatus.SERVER_CANCELLED); domain = @@ -171,7 +169,7 @@ class DomainTransferQueryFlowTest "domain_transfer_query.xml", "domain_transfer_query_response_server_cancelled.xml", 1); } - @TestOfyAndSql + @Test void testFailure_badContactPassword() { // Change the contact's password so it does not match the password in the file. contact = @@ -187,7 +185,7 @@ class DomainTransferQueryFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_badDomainPassword() { // Change the domain's password so it does not match the password in the file. domain = @@ -203,7 +201,7 @@ class DomainTransferQueryFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_neverBeenTransferred() { changeTransferStatus(null); EppException thrown = @@ -213,7 +211,7 @@ class DomainTransferQueryFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_unrelatedClient() { setRegistrarIdForFlow("ClientZ"); EppException thrown = @@ -223,7 +221,7 @@ class DomainTransferQueryFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_deletedDomain() throws Exception { domain = persistResource(domain.asBuilder().setDeletionTime(clock.nowUtc().minusDays(1)).build()); @@ -233,7 +231,7 @@ class DomainTransferQueryFlowTest assertThat(thrown).hasMessageThat().contains(String.format("(%s)", getUniqueIdFromCommand())); } - @TestOfyAndSql + @Test void testFailure_nonexistentDomain() throws Exception { deleteTestDomain(domain, clock.nowUtc()); ResourceDoesNotExistException thrown = @@ -242,14 +240,14 @@ class DomainTransferQueryFlowTest assertThat(thrown).hasMessageThat().contains(String.format("(%s)", getUniqueIdFromCommand())); } - @TestOfyAndSql + @Test void testIcannActivityReportField_getsLogged() throws Exception { runFlow(); assertIcannReportingActivityFieldLogged("srs-dom-transfer-query"); assertTldsFieldLogged("tld"); } - @TestOfyAndSql + @Test void testSuccess_serverApproved_afterAutorenews() throws Exception { // Set the clock to just past the extended registration time. We'd expect the domain to have // auto-renewed once, but the transfer query response should be the same. diff --git a/core/src/test/java/google/registry/flows/domain/DomainTransferRejectFlowTest.java b/core/src/test/java/google/registry/flows/domain/DomainTransferRejectFlowTest.java index 1d256cf18..d7dd9509d 100644 --- a/core/src/test/java/google/registry/flows/domain/DomainTransferRejectFlowTest.java +++ b/core/src/test/java/google/registry/flows/domain/DomainTransferRejectFlowTest.java @@ -58,14 +58,12 @@ import google.registry.model.tld.Registry; import google.registry.model.transfer.TransferData; import google.registry.model.transfer.TransferResponse; import google.registry.model.transfer.TransferStatus; -import google.registry.testing.DualDatabaseTest; -import google.registry.testing.TestOfyAndSql; import org.joda.time.DateTime; import org.joda.time.Duration; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; /** Unit tests for {@link DomainTransferRejectFlow}. */ -@DualDatabaseTest class DomainTransferRejectFlowTest extends DomainTransferFlowTestCase { @@ -156,38 +154,38 @@ class DomainTransferRejectFlowTest runFlow(); } - @TestOfyAndSql + @Test void testNotLoggedIn() { sessionMetadata.setRegistrarId(null); EppException thrown = assertThrows(NotLoggedInException.class, this::runFlow); assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testSuccess() throws Exception { doSuccessfulTest("domain_transfer_reject.xml", "domain_transfer_reject_response.xml"); } - @TestOfyAndSql + @Test void testDryRun() throws Exception { setEppInput("domain_transfer_reject.xml"); eppLoader.replaceAll("JD1234-REP", contact.getRepoId()); dryRunFlowAssertResponse(loadFile("domain_transfer_reject_response.xml")); } - @TestOfyAndSql + @Test void testSuccess_domainAuthInfo() throws Exception { doSuccessfulTest( "domain_transfer_reject_domain_authinfo.xml", "domain_transfer_reject_response.xml"); } - @TestOfyAndSql + @Test void testSuccess_contactAuthInfo() throws Exception { doSuccessfulTest( "domain_transfer_reject_contact_authinfo.xml", "domain_transfer_reject_response.xml"); } - @TestOfyAndSql + @Test void testFailure_notAuthorizedForTld() { persistResource( loadRegistrar("TheRegistrar").asBuilder().setAllowedTlds(ImmutableSet.of()).build()); @@ -200,7 +198,7 @@ class DomainTransferRejectFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testSuccess_superuserNotAuthorizedForTld() throws Exception { persistResource( loadRegistrar("TheRegistrar").asBuilder().setAllowedTlds(ImmutableSet.of()).build()); @@ -208,7 +206,7 @@ class DomainTransferRejectFlowTest CommitMode.LIVE, UserPrivileges.SUPERUSER, loadFile("domain_transfer_reject_response.xml")); } - @TestOfyAndSql + @Test void testFailure_badContactPassword() { // Change the contact's password so it does not match the password in the file. contact = @@ -224,7 +222,7 @@ class DomainTransferRejectFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_badDomainPassword() { // Change the domain's password so it does not match the password in the file. domain = @@ -240,7 +238,7 @@ class DomainTransferRejectFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_neverBeenTransferred() { changeTransferStatus(null); EppException thrown = @@ -249,7 +247,7 @@ class DomainTransferRejectFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_clientApproved() { changeTransferStatus(TransferStatus.CLIENT_APPROVED); EppException thrown = @@ -258,7 +256,7 @@ class DomainTransferRejectFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_clientRejected() { changeTransferStatus(TransferStatus.CLIENT_REJECTED); EppException thrown = @@ -267,7 +265,7 @@ class DomainTransferRejectFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_clientCancelled() { changeTransferStatus(TransferStatus.CLIENT_CANCELLED); EppException thrown = @@ -276,7 +274,7 @@ class DomainTransferRejectFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_serverApproved() { changeTransferStatus(TransferStatus.SERVER_APPROVED); EppException thrown = @@ -285,7 +283,7 @@ class DomainTransferRejectFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_serverCancelled() { changeTransferStatus(TransferStatus.SERVER_CANCELLED); EppException thrown = @@ -294,7 +292,7 @@ class DomainTransferRejectFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_gainingClient() { setRegistrarIdForFlow("NewRegistrar"); EppException thrown = @@ -303,7 +301,7 @@ class DomainTransferRejectFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_unrelatedClient() { setRegistrarIdForFlow("ClientZ"); EppException thrown = @@ -312,7 +310,7 @@ class DomainTransferRejectFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_deletedDomain() throws Exception { domain = persistResource(domain.asBuilder().setDeletionTime(clock.nowUtc().minusDays(1)).build()); @@ -322,7 +320,7 @@ class DomainTransferRejectFlowTest assertThat(thrown).hasMessageThat().contains(String.format("(%s)", getUniqueIdFromCommand())); } - @TestOfyAndSql + @Test void testFailure_nonexistentDomain() throws Exception { persistDomainAsDeleted(domain, clock.nowUtc()); ResourceDoesNotExistException thrown = @@ -334,7 +332,7 @@ class DomainTransferRejectFlowTest // NB: No need to test pending delete status since pending transfers will get cancelled upon // entering pending delete phase. So it's already handled in that test case. - @TestOfyAndSql + @Test void testIcannActivityReportField_getsLogged() throws Exception { runFlow(); assertIcannReportingActivityFieldLogged("srs-dom-transfer-reject"); @@ -350,7 +348,7 @@ class DomainTransferRejectFlowTest .build()); } - @TestOfyAndSql + @Test void testIcannTransactionRecord_noRecordsToCancel() throws Exception { setUpGracePeriodDurations(); runFlow(); @@ -360,7 +358,7 @@ class DomainTransferRejectFlowTest .containsExactly(DomainTransactionRecord.create("tld", clock.nowUtc(), TRANSFER_NACKED, 1)); } - @TestOfyAndSql + @Test void testIcannTransactionRecord_cancelsPreviousRecords() throws Exception { setUpGracePeriodDurations(); DomainTransactionRecord previousSuccessRecord = diff --git a/core/src/test/java/google/registry/flows/domain/DomainTransferRequestFlowTest.java b/core/src/test/java/google/registry/flows/domain/DomainTransferRequestFlowTest.java index 4b60bfb57..675ddd2f4 100644 --- a/core/src/test/java/google/registry/flows/domain/DomainTransferRequestFlowTest.java +++ b/core/src/test/java/google/registry/flows/domain/DomainTransferRequestFlowTest.java @@ -26,7 +26,6 @@ import static google.registry.model.reporting.HistoryEntry.Type.DOMAIN_CREATE; import static google.registry.model.reporting.HistoryEntry.Type.DOMAIN_TRANSFER_REQUEST; import static google.registry.model.tld.Registry.TldState.QUIET_PERIOD; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import static google.registry.testing.DatabaseHelper.assertBillingEvents; import static google.registry.testing.DatabaseHelper.assertBillingEventsEqual; import static google.registry.testing.DatabaseHelper.assertPollMessagesEqual; @@ -107,8 +106,6 @@ import google.registry.model.transfer.TransferResponse; import google.registry.model.transfer.TransferStatus; import google.registry.persistence.VKey; import google.registry.testing.CloudTasksHelper.TaskMatcher; -import google.registry.testing.DualDatabaseTest; -import google.registry.testing.TestOfyAndSql; import java.util.Map; import java.util.Optional; import java.util.stream.Stream; @@ -116,9 +113,9 @@ import org.joda.money.Money; import org.joda.time.DateTime; import org.joda.time.Duration; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; /** Unit tests for {@link DomainTransferRequestFlow}. */ -@DualDatabaseTest class DomainTransferRequestFlowTest extends DomainTransferFlowTestCase { @@ -578,7 +575,7 @@ class DomainTransferRequestFlowTest if (expectedAutomaticTransferLength.equals(Duration.ZERO)) { // The transfer is going to happen immediately. To observe the domain in the pending transfer // state, grab it directly from the database. - domain = Iterables.getOnlyElement(transactIfJpaTm(() -> tm().loadAllOf(DomainBase.class))); + domain = Iterables.getOnlyElement(tm().transact(() -> tm().loadAllOf(DomainBase.class))); assertThat(domain.getDomainName()).isEqualTo("example.tld"); } else { // Transfer should have been requested. @@ -639,14 +636,14 @@ class DomainTransferRequestFlowTest runTest(commandFilename, UserPrivileges.NORMAL, ImmutableMap.of()); } - @TestOfyAndSql + @Test void testNotLoggedIn() { sessionMetadata.setRegistrarId(null); EppException thrown = assertThrows(NotLoggedInException.class, this::runFlow); assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testDryRun() throws Exception { setupDomain("example", "tld"); setEppInput("domain_transfer_request.xml"); @@ -654,34 +651,34 @@ class DomainTransferRequestFlowTest dryRunFlowAssertResponse(loadFile("domain_transfer_request_response.xml")); } - @TestOfyAndSql + @Test void testSuccess() throws Exception { setupDomain("example", "tld"); doSuccessfulTest("domain_transfer_request.xml", "domain_transfer_request_response.xml"); } - @TestOfyAndSql + @Test void testSuccess_fee_v06() throws Exception { setupDomain("example", "tld"); doSuccessfulTest( "domain_transfer_request_fee.xml", "domain_transfer_request_response_fee.xml", FEE_06_MAP); } - @TestOfyAndSql + @Test void testSuccess_fee_v11() throws Exception { setupDomain("example", "tld"); doSuccessfulTest( "domain_transfer_request_fee.xml", "domain_transfer_request_response_fee.xml", FEE_11_MAP); } - @TestOfyAndSql + @Test void testSuccess_fee_v12() throws Exception { setupDomain("example", "tld"); doSuccessfulTest( "domain_transfer_request_fee.xml", "domain_transfer_request_response_fee.xml", FEE_12_MAP); } - @TestOfyAndSql + @Test void testSuccess_fee_withDefaultAttributes_v06() throws Exception { setupDomain("example", "tld"); doSuccessfulTest( @@ -690,7 +687,7 @@ class DomainTransferRequestFlowTest FEE_06_MAP); } - @TestOfyAndSql + @Test void testSuccess_fee_withDefaultAttributes_v11() throws Exception { setupDomain("example", "tld"); doSuccessfulTest( @@ -699,7 +696,7 @@ class DomainTransferRequestFlowTest FEE_11_MAP); } - @TestOfyAndSql + @Test void testSuccess_fee_withDefaultAttributes_v12() throws Exception { setupDomain("example", "tld"); doSuccessfulTest( @@ -708,7 +705,7 @@ class DomainTransferRequestFlowTest FEE_12_MAP); } - @TestOfyAndSql + @Test void testFailure_refundableFee_v06() { setupDomain("example", "tld"); EppException thrown = @@ -718,7 +715,7 @@ class DomainTransferRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_refundableFee_v11() { setupDomain("example", "tld"); EppException thrown = @@ -728,7 +725,7 @@ class DomainTransferRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_refundableFee_v12() { setupDomain("example", "tld"); EppException thrown = @@ -738,7 +735,7 @@ class DomainTransferRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_gracePeriodFee_v06() { setupDomain("example", "tld"); EppException thrown = @@ -748,7 +745,7 @@ class DomainTransferRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_gracePeriodFee_v11() { setupDomain("example", "tld"); EppException thrown = @@ -758,7 +755,7 @@ class DomainTransferRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_gracePeriodFee_v12() { setupDomain("example", "tld"); EppException thrown = @@ -768,7 +765,7 @@ class DomainTransferRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_appliedFee_v06() { setupDomain("example", "tld"); EppException thrown = @@ -778,7 +775,7 @@ class DomainTransferRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_appliedFee_v11() { setupDomain("example", "tld"); EppException thrown = @@ -788,7 +785,7 @@ class DomainTransferRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_appliedFee_v12() { setupDomain("example", "tld"); EppException thrown = @@ -798,7 +795,7 @@ class DomainTransferRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_suspendedRegistrarCantTransferDomain() { setupDomain("example", "tld"); clock.advanceOneMilli(); @@ -815,7 +812,7 @@ class DomainTransferRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_pendingRegistrarCantTransferDomain() { setupDomain("example", "tld"); clock.advanceOneMilli(); @@ -832,7 +829,7 @@ class DomainTransferRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testSuccess_nonDefaultAutomaticTransferLength() throws Exception { setupDomain("example", "tld"); persistResource( @@ -844,7 +841,7 @@ class DomainTransferRequestFlowTest "domain_transfer_request.xml", "domain_transfer_request_response_15_minutes.xml"); } - @TestOfyAndSql + @Test void testSuccess_nonDefaultTransferGracePeriod() throws Exception { setupDomain("example", "tld"); persistResource( @@ -855,14 +852,14 @@ class DomainTransferRequestFlowTest doSuccessfulTest("domain_transfer_request.xml", "domain_transfer_request_response.xml"); } - @TestOfyAndSql + @Test void testSuccess_missingPeriod_defaultsToOneYear() throws Exception { setupDomain("example", "tld"); doSuccessfulTest( "domain_transfer_request_missing_period.xml", "domain_transfer_request_response.xml"); } - @TestOfyAndSql + @Test void testSuccess_canTransferAwayFromSuspendedRegistrar() throws Exception { setupDomain("example", "tld"); clock.advanceOneMilli(); @@ -875,7 +872,7 @@ class DomainTransferRequestFlowTest doSuccessfulTest("domain_transfer_request.xml", "domain_transfer_request_response.xml"); } - @TestOfyAndSql + @Test void testSuccess_inQuietPeriod() throws Exception { setupDomain("example", "tld"); persistResource( @@ -886,7 +883,7 @@ class DomainTransferRequestFlowTest doSuccessfulTest("domain_transfer_request.xml", "domain_transfer_request_response.xml"); } - @TestOfyAndSql + @Test void testFailure_multiYearPeriod() { setupDomain("example", "tld"); clock.advanceOneMilli(); @@ -897,7 +894,7 @@ class DomainTransferRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testSuccess_superuserExtension_zeroPeriod_nonZeroAutomaticTransferLength() throws Exception { setupDomain("example", "tld"); clock.advanceOneMilli(); @@ -911,7 +908,7 @@ class DomainTransferRequestFlowTest Duration.standardDays(5)); } - @TestOfyAndSql + @Test void testSuccess_superuserExtension_zeroPeriod_zeroAutomaticTransferLength() throws Exception { setupDomain("example", "tld"); clock.advanceOneMilli(); @@ -925,7 +922,7 @@ class DomainTransferRequestFlowTest Duration.ZERO); } - @TestOfyAndSql + @Test void testSuccess_superuserExtension_nonZeroPeriod_nonZeroAutomaticTransferLength() throws Exception { setupDomain("example", "tld"); @@ -940,7 +937,7 @@ class DomainTransferRequestFlowTest Duration.standardDays(5)); } - @TestOfyAndSql + @Test void testSuccess_superuserExtension_zeroPeriod_autorenewGraceActive() throws Exception { setupDomain("example", "tld"); VKey existingAutorenewEvent = domain.getAutorenewBillingEvent(); @@ -972,7 +969,7 @@ class DomainTransferRequestFlowTest Duration.ZERO); } - @TestOfyAndSql + @Test void testFailure_superuserExtension_twoYearPeriod() { setupDomain("example", "tld"); eppRequestSource = EppRequestSource.TOOL; @@ -986,7 +983,7 @@ class DomainTransferRequestFlowTest ImmutableMap.of("PERIOD", "2", "AUTOMATIC_TRANSFER_LENGTH", "5"))); } - @TestOfyAndSql + @Test void testFailure_superuserExtension_zeroPeriod_feeTransferExtension() { setupDomain("example", "tld"); eppRequestSource = EppRequestSource.TOOL; @@ -1000,7 +997,7 @@ class DomainTransferRequestFlowTest ImmutableMap.of("PERIOD", "0", "AUTOMATIC_TRANSFER_LENGTH", "5"))); } - @TestOfyAndSql + @Test void testSuccess_cappedExpiration() throws Exception { setupDomain("example", "tld"); // Set the domain to expire 10 years from now (as if it were just created with a 10-year term). @@ -1017,14 +1014,14 @@ class DomainTransferRequestFlowTest clock.nowUtc().plus(Registry.get("tld").getAutomaticTransferLength()).plusYears(10)); } - @TestOfyAndSql + @Test void testSuccess_domainAuthInfo() throws Exception { setupDomain("example", "tld"); doSuccessfulTest( "domain_transfer_request_domain_authinfo.xml", "domain_transfer_request_response.xml"); } - @TestOfyAndSql + @Test void testSuccess_customLogicFee() throws Exception { setupDomain("expensive-domain", "foo"); clock.advanceOneMilli(); @@ -1043,7 +1040,7 @@ class DomainTransferRequestFlowTest Optional.of(Money.of(USD, 111))); } - @TestOfyAndSql + @Test void testFailure_notAuthorizedForTld() { setupDomain("example", "tld"); persistResource( @@ -1057,7 +1054,7 @@ class DomainTransferRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_missingBillingAccount() { setupDomain("example", "tld"); persistResource( @@ -1081,7 +1078,7 @@ class DomainTransferRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testSuccess_superuserNotAuthorizedForTld() throws Exception { setupDomain("example", "tld"); persistResource( @@ -1091,7 +1088,7 @@ class DomainTransferRequestFlowTest runTest("domain_transfer_request.xml", UserPrivileges.SUPERUSER); } - @TestOfyAndSql + @Test void testSuccess_autorenewGraceActive_onlyAtTransferRequestTime() throws Exception { setupDomain("example", "tld"); // Set the domain to have auto-renewed long enough ago that it is still in the autorenew grace @@ -1121,7 +1118,7 @@ class DomainTransferRequestFlowTest expirationTime.plusYears(1)); } - @TestOfyAndSql + @Test void testSuccess_autorenewGraceActive_throughoutTransferWindow() throws Exception { setupDomain("example", "tld"); VKey existingAutorenewEvent = domain.getAutorenewBillingEvent(); @@ -1160,7 +1157,7 @@ class DomainTransferRequestFlowTest .setRecurringEventKey(existingAutorenewEvent)); } - @TestOfyAndSql + @Test void testSuccess_autorenewGraceActive_onlyAtAutomaticTransferTime() throws Exception { setupDomain("example", "tld"); VKey existingAutorenewEvent = domain.getAutorenewBillingEvent(); @@ -1188,7 +1185,7 @@ class DomainTransferRequestFlowTest .setRecurringEventKey(existingAutorenewEvent)); } - @TestOfyAndSql + @Test void testSuccess_premiumNotBlocked() throws Exception { setupDomain("rich", "example"); clock.advanceOneMilli(); @@ -1196,7 +1193,7 @@ class DomainTransferRequestFlowTest runTest("domain_transfer_request_fee.xml", UserPrivileges.NORMAL, RICH_DOMAIN_MAP); } - @TestOfyAndSql + @Test void testSuccess_premiumNotBlockedInSuperuserMode() throws Exception { setupDomain("rich", "example"); clock.advanceOneMilli(); @@ -1218,22 +1215,22 @@ class DomainTransferRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_wrongCurrency_v06() { runWrongCurrencyTest(FEE_06_MAP); } - @TestOfyAndSql + @Test void testFailure_wrongCurrency_v11() { runWrongCurrencyTest(FEE_11_MAP); } - @TestOfyAndSql + @Test void testFailure_wrongCurrency_v12() { runWrongCurrencyTest(FEE_12_MAP); } - @TestOfyAndSql + @Test void testFailure_unknownCurrency() { Map substitutions = Maps.newHashMap(); substitutions.putAll(FEE_06_MAP); @@ -1244,7 +1241,7 @@ class DomainTransferRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_feeGivenInWrongScale_v06() { setupDomain("example", "tld"); EppException thrown = @@ -1254,7 +1251,7 @@ class DomainTransferRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_feeGivenInWrongScale_v11() { setupDomain("example", "tld"); EppException thrown = @@ -1264,7 +1261,7 @@ class DomainTransferRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_feeGivenInWrongScale_v12() { setupDomain("example", "tld"); EppException thrown = @@ -1287,25 +1284,25 @@ class DomainTransferRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_wrongFeeAmount_v06() { setupDomain("example", "tld"); runWrongFeeAmountTest(FEE_06_MAP); } - @TestOfyAndSql + @Test void testFailure_wrongFeeAmount_v11() { setupDomain("example", "tld"); runWrongFeeAmountTest(FEE_11_MAP); } - @TestOfyAndSql + @Test void testFailure_wrongFeeAmount_v12() { setupDomain("example", "tld"); runWrongFeeAmountTest(FEE_12_MAP); } - @TestOfyAndSql + @Test void testFailure_premiumBlocked() { setupDomain("rich", "example"); // Modify the Registrar to block premium names. @@ -1317,7 +1314,7 @@ class DomainTransferRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_feeNotProvidedOnPremiumName() { setupDomain("rich", "example"); EppException thrown = @@ -1327,7 +1324,7 @@ class DomainTransferRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_noAuthInfo() { setupDomain("example", "tld"); EppException thrown = @@ -1337,7 +1334,7 @@ class DomainTransferRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_badContactPassword() { setupDomain("example", "tld"); // Change the contact's password so it does not match the password in the file. @@ -1354,7 +1351,7 @@ class DomainTransferRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_badContactRepoId() { setupDomain("example", "tld"); // Set the contact to a different ROID, but don't persist it; this is just so the substitution @@ -1367,42 +1364,42 @@ class DomainTransferRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testSuccess_clientApproved() throws Exception { setupDomain("example", "tld"); changeTransferStatus(TransferStatus.CLIENT_APPROVED); doSuccessfulTest("domain_transfer_request.xml", "domain_transfer_request_response.xml"); } - @TestOfyAndSql + @Test void testSuccess_clientRejected() throws Exception { setupDomain("example", "tld"); changeTransferStatus(TransferStatus.CLIENT_REJECTED); doSuccessfulTest("domain_transfer_request.xml", "domain_transfer_request_response.xml"); } - @TestOfyAndSql + @Test void testSuccess_clientCancelled() throws Exception { setupDomain("example", "tld"); changeTransferStatus(TransferStatus.CLIENT_CANCELLED); doSuccessfulTest("domain_transfer_request.xml", "domain_transfer_request_response.xml"); } - @TestOfyAndSql + @Test void testSuccess_serverApproved() throws Exception { setupDomain("example", "tld"); changeTransferStatus(TransferStatus.SERVER_APPROVED); doSuccessfulTest("domain_transfer_request.xml", "domain_transfer_request_response.xml"); } - @TestOfyAndSql + @Test void testSuccess_serverCancelled() throws Exception { setupDomain("example", "tld"); changeTransferStatus(TransferStatus.SERVER_CANCELLED); doSuccessfulTest("domain_transfer_request.xml", "domain_transfer_request_response.xml"); } - @TestOfyAndSql + @Test void testFailure_pending() { setupDomain("example", "tld"); domain = @@ -1424,7 +1421,7 @@ class DomainTransferRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_badDomainPassword() { setupDomain("example", "tld"); // Change the domain's password so it does not match the password in the file. @@ -1441,7 +1438,7 @@ class DomainTransferRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_sponsoringClient() { setupDomain("example", "tld"); setRegistrarIdForFlow("TheRegistrar"); @@ -1452,7 +1449,7 @@ class DomainTransferRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_deletedDomain() throws Exception { setupDomain("example", "tld"); domain = @@ -1464,7 +1461,7 @@ class DomainTransferRequestFlowTest assertThat(thrown).hasMessageThat().contains(String.format("(%s)", getUniqueIdFromCommand())); } - @TestOfyAndSql + @Test void testFailure_invalidDomain() throws Exception { setupDomain("example", "tld"); setEppInput( @@ -1479,7 +1476,7 @@ class DomainTransferRequestFlowTest assertThat(thrown).hasMessageThat().contains("(--invalid)"); } - @TestOfyAndSql + @Test void testFailure_nonexistentDomain() { createTld("tld"); contact = persistActiveContact("jd1234"); @@ -1490,7 +1487,7 @@ class DomainTransferRequestFlowTest assertThat(thrown).hasMessageThat().contains(String.format("(%s)", "example.tld")); } - @TestOfyAndSql + @Test void testFailure_periodInMonths() { setupDomain("example", "tld"); EppException thrown = @@ -1500,7 +1497,7 @@ class DomainTransferRequestFlowTest assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_clientTransferProhibited() { setupDomain("example", "tld"); domain = @@ -1513,7 +1510,7 @@ class DomainTransferRequestFlowTest assertThat(thrown).hasMessageThat().contains("clientTransferProhibited"); } - @TestOfyAndSql + @Test void testFailure_serverTransferProhibited() { setupDomain("example", "tld"); domain = @@ -1526,7 +1523,7 @@ class DomainTransferRequestFlowTest assertThat(thrown).hasMessageThat().contains("serverTransferProhibited"); } - @TestOfyAndSql + @Test void testFailure_pendingDelete() { setupDomain("example", "tld"); domain = persistResource(domain.asBuilder().addStatusValue(StatusValue.PENDING_DELETE).build()); @@ -1537,7 +1534,7 @@ class DomainTransferRequestFlowTest assertThat(thrown).hasMessageThat().contains("pendingDelete"); } - @TestOfyAndSql + @Test void testIcannActivityReportField_getsLogged() throws Exception { setupDomain("example", "tld"); clock.advanceOneMilli(); @@ -1546,7 +1543,7 @@ class DomainTransferRequestFlowTest assertTldsFieldLogged("tld"); } - @TestOfyAndSql + @Test void testIcannTransactionRecord_getsStored() throws Exception { setupDomain("example", "tld"); persistResource( diff --git a/core/src/test/java/google/registry/flows/domain/DomainUpdateFlowTest.java b/core/src/test/java/google/registry/flows/domain/DomainUpdateFlowTest.java index 6f83a1cd9..872835b04 100644 --- a/core/src/test/java/google/registry/flows/domain/DomainUpdateFlowTest.java +++ b/core/src/test/java/google/registry/flows/domain/DomainUpdateFlowTest.java @@ -105,15 +105,13 @@ import google.registry.model.poll.PendingActionNotificationResponse.DomainPendin import google.registry.model.poll.PollMessage; import google.registry.model.tld.Registry; import google.registry.persistence.VKey; -import google.registry.testing.DualDatabaseTest; -import google.registry.testing.TestOfyAndSql; import java.util.Optional; import org.joda.money.Money; import org.joda.time.DateTime; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; /** Unit tests for {@link DomainUpdateFlow}. */ -@DualDatabaseTest class DomainUpdateFlowTest extends ResourceFlowTestCase { private static final DelegationSignerData SOME_DSDATA = @@ -226,28 +224,28 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase builder = new ImmutableSet.Builder<>(); for (int i = 0; i < 7; ++i) { @@ -708,7 +706,7 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase builder = new ImmutableSet.Builder<>(); for (int i = 0; i < 7; ++i) { @@ -780,7 +778,7 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase builder = new ImmutableSet.Builder<>(); for (int i = 0; i < 8; ++i) { @@ -1039,7 +1037,7 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase historyEntryKey = Key.create(Key.create(domain), HistoryEntry.class, 1051L); @@ -219,7 +216,7 @@ class AllocationTokenFlowUtilsTest { .inOrder(); } - @TestOfyAndSql + @Test void test_checkDomainsWithToken_callsCustomLogic() { persistResource( new AllocationToken.Builder().setToken("tokeN").setTokenType(SINGLE_USE).build()); @@ -238,7 +235,7 @@ class AllocationTokenFlowUtilsTest { assertThat(thrown).hasMessageThat().isEqualTo("failed for tests"); } - @TestOfyAndSql + @Test void test_checkDomainsWithToken_resultsFromCustomLogicAreIntegrated() { persistResource( new AllocationToken.Builder().setToken("tokeN").setTokenType(SINGLE_USE).build()); diff --git a/core/src/test/java/google/registry/flows/host/HostCheckFlowTest.java b/core/src/test/java/google/registry/flows/host/HostCheckFlowTest.java index 6bff29301..ddd32436a 100644 --- a/core/src/test/java/google/registry/flows/host/HostCheckFlowTest.java +++ b/core/src/test/java/google/registry/flows/host/HostCheckFlowTest.java @@ -25,25 +25,23 @@ import google.registry.flows.FlowUtils.NotLoggedInException; import google.registry.flows.ResourceCheckFlowTestCase; import google.registry.flows.exceptions.TooManyResourceChecksException; import google.registry.model.host.HostResource; -import google.registry.testing.DualDatabaseTest; -import google.registry.testing.TestOfyAndSql; +import org.junit.jupiter.api.Test; /** Unit tests for {@link HostCheckFlow}. */ -@DualDatabaseTest class HostCheckFlowTest extends ResourceCheckFlowTestCase { HostCheckFlowTest() { setEppInput("host_check.xml"); } - @TestOfyAndSql + @Test void testNotLoggedIn() { sessionMetadata.setRegistrarId(null); EppException thrown = assertThrows(NotLoggedInException.class, this::runFlow); assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testNothingExists() throws Exception { // These ids come from the check xml. doCheckTest( @@ -52,7 +50,7 @@ class HostCheckFlowTest extends ResourceCheckFlowTestCase { private void setEppHostCreateInput(String hostName, String hostAddrs) { @@ -104,26 +102,26 @@ class HostCreateFlowTest extends ResourceFlowTestCase { @BeforeEach @@ -64,20 +62,20 @@ class HostDeleteFlowTest extends ResourceFlowTestCase validateHostName("host.co.uk").toString()); } - @TestOfyAndSql + @Test void test_validateHostName_hostNameTooLong() { assertThrows( HostNameTooLongException.class, () -> validateHostName(Strings.repeat("na", 200) + ".wat.man")); } - @TestOfyAndSql + @Test void test_validateHostName_hostNameNotLowerCase() { assertThrows(HostNameNotLowerCaseException.class, () -> validateHostName("NA.CAPS.TLD")); } - @TestOfyAndSql + @Test void test_validateHostName_hostNameNotPunyCoded() { assertThrows( HostNameNotPunyCodedException.class, () -> validateHostName("motörhead.death.metal")); } - @TestOfyAndSql + @Test void test_validateHostName_hostNameNotNormalized() { assertThrows(HostNameNotNormalizedException.class, () -> validateHostName("root.node.yeah.")); } - @TestOfyAndSql + @Test void test_validateHostName_hostNameHasLeadingHyphen() { assertThrows(InvalidHostNameException.class, () -> validateHostName("-giga.mega.tld")); } - @TestOfyAndSql + @Test void test_validateHostName_hostNameTooShallow() { assertThrows(HostNameTooShallowException.class, () -> validateHostName("domain.tld")); } diff --git a/core/src/test/java/google/registry/flows/host/HostInfoFlowTest.java b/core/src/test/java/google/registry/flows/host/HostInfoFlowTest.java index bf21b36fc..b74ca60e1 100644 --- a/core/src/test/java/google/registry/flows/host/HostInfoFlowTest.java +++ b/core/src/test/java/google/registry/flows/host/HostInfoFlowTest.java @@ -37,14 +37,12 @@ import google.registry.flows.host.HostFlowUtils.HostNameNotPunyCodedException; import google.registry.model.domain.DomainBase; import google.registry.model.eppcommon.StatusValue; import google.registry.model.host.HostResource; -import google.registry.testing.DualDatabaseTest; -import google.registry.testing.TestOfyAndSql; import javax.annotation.Nullable; import org.joda.time.DateTime; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; /** Unit tests for {@link HostInfoFlow}. */ -@DualDatabaseTest class HostInfoFlowTest extends ResourceFlowTestCase { @BeforeEach @@ -74,14 +72,14 @@ class HostInfoFlowTest extends ResourceFlowTestCase .build()); } - @TestOfyAndSql + @Test void testNotLoggedIn() { sessionMetadata.setRegistrarId(null); EppException thrown = assertThrows(NotLoggedInException.class, this::runFlow); assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testSuccess() throws Exception { persistHostResource(); assertTransactionalFlow(false); @@ -94,7 +92,7 @@ class HostInfoFlowTest extends ResourceFlowTestCase assertNoBillingEvents(); } - @TestOfyAndSql + @Test void testSuccess_linked() throws Exception { persistHostResource(); persistResource( @@ -142,31 +140,31 @@ class HostInfoFlowTest extends ResourceFlowTestCase assertNoBillingEvents(); } - @TestOfyAndSql + @Test void testSuccess_withSuperordinateDomain_hostMovedAfterDomainTransfer() throws Exception { runTest_superordinateDomain( DateTime.parse("2000-01-08T09:00:00.0Z"), DateTime.parse("2000-03-01T01:00:00.0Z")); } - @TestOfyAndSql + @Test void testSuccess_withSuperordinateDomain_hostMovedBeforeDomainTransfer() throws Exception { runTest_superordinateDomain( DateTime.parse("2000-04-08T09:00:00.0Z"), DateTime.parse("2000-02-08T09:00:00.0Z")); } - @TestOfyAndSql + @Test void testSuccess_withSuperordinateDomain() throws Exception { runTest_superordinateDomain(DateTime.parse("2000-04-08T09:00:00.0Z"), null); } - @TestOfyAndSql + @Test void testFailure_neverExisted() throws Exception { ResourceDoesNotExistException thrown = assertThrows(ResourceDoesNotExistException.class, this::runFlow); assertThat(thrown).hasMessageThat().contains(String.format("(%s)", getUniqueIdFromCommand())); } - @TestOfyAndSql + @Test void testFailure_existedButWasDeleted() throws Exception { persistResource( persistHostResource().asBuilder().setDeletionTime(clock.nowUtc().minusDays(1)).build()); @@ -175,14 +173,14 @@ class HostInfoFlowTest extends ResourceFlowTestCase assertThat(thrown).hasMessageThat().contains(String.format("(%s)", getUniqueIdFromCommand())); } - @TestOfyAndSql + @Test void testFailure_nonLowerCaseHostname() { setEppInput("host_info.xml", ImmutableMap.of("HOSTNAME", "NS1.EXAMPLE.NET")); EppException thrown = assertThrows(HostNameNotLowerCaseException.class, this::runFlow); assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testFailure_nonPunyCodedHostname() { setEppInput("host_info.xml", ImmutableMap.of("HOSTNAME", "ns1.çauçalito.tld")); HostNameNotPunyCodedException thrown = @@ -190,14 +188,14 @@ class HostInfoFlowTest extends ResourceFlowTestCase assertThat(thrown).hasMessageThat().contains("expected ns1.xn--aualito-txac.tld"); } - @TestOfyAndSql + @Test void testFailure_nonCanonicalHostname() { setEppInput("host_info.xml", ImmutableMap.of("HOSTNAME", "ns1.example.tld.")); EppException thrown = assertThrows(HostNameNotNormalizedException.class, this::runFlow); assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @TestOfyAndSql + @Test void testIcannActivityReportField_getsLogged() throws Exception { persistHostResource(); runFlow(); diff --git a/core/src/test/java/google/registry/flows/host/HostUpdateFlowTest.java b/core/src/test/java/google/registry/flows/host/HostUpdateFlowTest.java index e3614ed23..3ab01b47a 100644 --- a/core/src/test/java/google/registry/flows/host/HostUpdateFlowTest.java +++ b/core/src/test/java/google/registry/flows/host/HostUpdateFlowTest.java @@ -78,14 +78,12 @@ import google.registry.model.reporting.HistoryEntry; import google.registry.model.tld.Registry; import google.registry.model.transfer.DomainTransferData; import google.registry.model.transfer.TransferStatus; -import google.registry.testing.DualDatabaseTest; import google.registry.testing.TaskQueueHelper.TaskMatcher; -import google.registry.testing.TestOfyAndSql; import javax.annotation.Nullable; import org.joda.time.DateTime; +import org.junit.jupiter.api.Test; /** Unit tests for {@link HostUpdateFlow}. */ -@DualDatabaseTest class HostUpdateFlowTest extends ResourceFlowTestCase { private void setEppHostUpdateInput( @@ -136,14 +134,14 @@ class HostUpdateFlowTest extends ResourceFlowTestCase192.0.2.22", null); @@ -425,7 +423,7 @@ class HostUpdateFlowTest extends ResourceFlowTestCase192.0.2.22", null); @@ -449,7 +447,7 @@ class HostUpdateFlowTest extends ResourceFlowTestCase192.0.2.22", null); @@ -979,7 +977,7 @@ class HostUpdateFlowTest extends ResourceFlowTestCase192.0.2.22", null); @@ -1202,7 +1200,7 @@ class HostUpdateFlowTest extends ResourceFlowTestCase192.0.2.22", null); @@ -1220,7 +1218,7 @@ class HostUpdateFlowTest extends ResourceFlowTestCase192.0.2.22", null); @@ -1259,17 +1257,17 @@ class HostUpdateFlowTest extends ResourceFlowTestCase { @Order(value = Order.DEFAULT - 3) @@ -87,13 +85,13 @@ class PollAckFlowTest extends FlowTestCase { .build()); } - @TestOfyAndSql + @Test void testDryRun() throws Exception { persistOneTimePollMessage(MESSAGE_ID); dryRunFlowAssertResponse(loadFile("poll_ack_response_empty.xml")); } - @TestOfyAndSql + @Test void testSuccess_contactPollMessage() throws Exception { setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "2-2-ROID-4-3-2011")); persistResource( @@ -108,7 +106,7 @@ class PollAckFlowTest extends FlowTestCase { runFlowAssertResponse(loadFile("poll_ack_response_empty.xml")); } - @TestOfyAndSql + @Test void testFailure_contactPollMessage_withIncorrectYearField() throws Exception { setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "2-2-ROID-4-3-1999")); persistResource( @@ -123,14 +121,14 @@ class PollAckFlowTest extends FlowTestCase { assertThrows(MessageDoesNotExistException.class, this::runFlow); } - @TestOfyAndSql + @Test void testSuccess_messageOnContactResource() throws Exception { persistOneTimePollMessage(MESSAGE_ID); assertTransactionalFlow(true); runFlowAssertResponse(loadFile("poll_ack_response_empty.xml")); } - @TestOfyAndSql + @Test void testSuccess_recentActiveAutorenew() throws Exception { setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "1-3-EXAMPLE-4-3-2010")); persistAutorenewPollMessage(clock.nowUtc().minusMonths(6), END_OF_TIME); @@ -138,7 +136,7 @@ class PollAckFlowTest extends FlowTestCase { runFlowAssertResponse(loadFile("poll_ack_response_empty.xml")); } - @TestOfyAndSql + @Test void testSuccess_oldActiveAutorenew() throws Exception { setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "1-3-EXAMPLE-4-3-2009")); persistAutorenewPollMessage(clock.nowUtc().minusYears(2), END_OF_TIME); @@ -154,7 +152,7 @@ class PollAckFlowTest extends FlowTestCase { ImmutableMap.of("MSGID", "1-3-EXAMPLE-4-3-2009", "COUNT", "4"))); } - @TestOfyAndSql + @Test void testSuccess_oldInactiveAutorenew() throws Exception { setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "1-3-EXAMPLE-4-3-2010")); persistAutorenewPollMessage(clock.nowUtc().minusMonths(6), clock.nowUtc()); @@ -162,7 +160,7 @@ class PollAckFlowTest extends FlowTestCase { runFlowAssertResponse(loadFile("poll_ack_response_empty.xml")); } - @TestOfyAndSql + @Test void testSuccess_moreMessages() throws Exception { // Create five messages to be queued for retrieval, one of which will be acked. for (int i = 0; i < 5; i++) { @@ -175,28 +173,28 @@ class PollAckFlowTest extends FlowTestCase { ImmutableMap.of("MSGID", "1-3-EXAMPLE-4-3-2011", "COUNT", "4"))); } - @TestOfyAndSql + @Test void testFailure_noSuchMessage() throws Exception { assertTransactionalFlow(true); Exception e = assertThrows(MessageDoesNotExistException.class, this::runFlow); assertThat(e).hasMessageThat().contains(String.format("(1-3-EXAMPLE-4-%d-2011)", MESSAGE_ID)); } - @TestOfyAndSql + @Test void testFailure_invalidId_tooFewComponents() throws Exception { setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "1-2-3")); assertTransactionalFlow(true); assertThrows(InvalidMessageIdException.class, this::runFlow); } - @TestOfyAndSql + @Test void testFailure_invalidId_tooManyComponents() throws Exception { setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "2-2-ROID-4-3-1999-2007")); assertTransactionalFlow(true); assertThrows(InvalidMessageIdException.class, this::runFlow); } - @TestOfyAndSql + @Test void testFailure_contactPollMessage_withMissingYearField() throws Exception { setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "2-2-ROID-4-3")); persistResource( @@ -211,28 +209,28 @@ class PollAckFlowTest extends FlowTestCase { assertThrows(InvalidMessageIdException.class, this::runFlow); } - @TestOfyAndSql + @Test void testFailure_invalidId_stringInsteadOfNumeric() throws Exception { setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "ABC-12345")); assertTransactionalFlow(true); assertThrows(InvalidMessageIdException.class, this::runFlow); } - @TestOfyAndSql + @Test void testFailure_invalidEppResourceClassId() throws Exception { setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "999-1-1-1")); assertTransactionalFlow(true); assertThrows(InvalidMessageIdException.class, this::runFlow); } - @TestOfyAndSql + @Test void testFailure_missingId() throws Exception { setEppInput("poll_ack_missing_id.xml"); assertTransactionalFlow(true); assertThrows(MissingMessageIdException.class, this::runFlow); } - @TestOfyAndSql + @Test void testFailure_differentRegistrar() throws Exception { persistResource( new PollMessage.OneTime.Builder() @@ -246,7 +244,7 @@ class PollAckFlowTest extends FlowTestCase { assertThrows(NotAuthorizedToAckMessageException.class, this::runFlow); } - @TestOfyAndSql + @Test void testFailure_messageInFuture() throws Exception { persistResource( new PollMessage.OneTime.Builder() diff --git a/core/src/test/java/google/registry/flows/poll/PollRequestFlowTest.java b/core/src/test/java/google/registry/flows/poll/PollRequestFlowTest.java index ed7e8a90c..5210baee8 100644 --- a/core/src/test/java/google/registry/flows/poll/PollRequestFlowTest.java +++ b/core/src/test/java/google/registry/flows/poll/PollRequestFlowTest.java @@ -40,15 +40,13 @@ import google.registry.model.reporting.HistoryEntry; import google.registry.model.transfer.TransferResponse.ContactTransferResponse; import google.registry.model.transfer.TransferResponse.DomainTransferResponse; import google.registry.model.transfer.TransferStatus; -import google.registry.testing.DualDatabaseTest; import google.registry.testing.SetClockExtension; -import google.registry.testing.TestOfyAndSql; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; /** Unit tests for {@link PollRequestFlow}. */ -@DualDatabaseTest class PollRequestFlowTest extends FlowTestCase { @Order(value = Order.DEFAULT - 3) @@ -91,14 +89,14 @@ class PollRequestFlowTest extends FlowTestCase { .build()); } - @TestOfyAndSql + @Test void testSuccess_domainTransferApproved() throws Exception { persistPendingTransferPollMessage(); assertTransactionalFlow(false); runFlowAssertResponse(loadFile("poll_response_domain_transfer.xml")); } - @TestOfyAndSql + @Test void testSuccess_clTridNotSpecified() throws Exception { setEppInput("poll_no_cltrid.xml"); persistPendingTransferPollMessage(); @@ -106,7 +104,7 @@ class PollRequestFlowTest extends FlowTestCase { runFlowAssertResponse(loadFile("poll_response_domain_transfer_no_cltrid.xml")); } - @TestOfyAndSql + @Test void testSuccess_contactTransferPending() throws Exception { setRegistrarIdForFlow("TheRegistrar"); persistResource( @@ -131,7 +129,7 @@ class PollRequestFlowTest extends FlowTestCase { runFlowAssertResponse(loadFile("poll_response_contact_transfer.xml")); } - @TestOfyAndSql + @Test void testSuccess_domainPendingActionComplete() throws Exception { persistResource( new PollMessage.OneTime.Builder() @@ -151,7 +149,7 @@ class PollRequestFlowTest extends FlowTestCase { runFlowAssertResponse(loadFile("poll_response_domain_pending_notification.xml")); } - @TestOfyAndSql + @Test void testSuccess_domainPendingActionImmediateDelete() throws Exception { persistResource( new PollMessage.OneTime.Builder() @@ -175,7 +173,7 @@ class PollRequestFlowTest extends FlowTestCase { runFlowAssertResponse(loadFile("poll_message_domain_pending_action_immediate_delete.xml")); } - @TestOfyAndSql + @Test void testSuccess_domainAutorenewMessage() throws Exception { persistResource( new PollMessage.Autorenew.Builder() @@ -189,12 +187,12 @@ class PollRequestFlowTest extends FlowTestCase { runFlowAssertResponse(loadFile("poll_response_autorenew.xml")); } - @TestOfyAndSql + @Test void testSuccess_empty() throws Exception { runFlowAssertResponse(loadFile("poll_response_empty.xml")); } - @TestOfyAndSql + @Test void testSuccess_wrongRegistrar() throws Exception { persistResource( new PollMessage.OneTime.Builder() @@ -206,7 +204,7 @@ class PollRequestFlowTest extends FlowTestCase { runFlowAssertResponse(loadFile("poll_response_empty.xml")); } - @TestOfyAndSql + @Test void testSuccess_futurePollMessage() throws Exception { persistResource( new PollMessage.OneTime.Builder() @@ -218,7 +216,7 @@ class PollRequestFlowTest extends FlowTestCase { runFlowAssertResponse(loadFile("poll_response_empty.xml")); } - @TestOfyAndSql + @Test void testSuccess_futureAutorenew() throws Exception { persistResource( new PollMessage.Autorenew.Builder() @@ -232,7 +230,7 @@ class PollRequestFlowTest extends FlowTestCase { runFlowAssertResponse(loadFile("poll_response_empty.xml")); } - @TestOfyAndSql + @Test void testSuccess_contactDelete() throws Exception { // Contact delete poll messages do not have any response data, so ensure that no // response data block is produced in the poll message. @@ -255,7 +253,7 @@ class PollRequestFlowTest extends FlowTestCase { runFlowAssertResponse(loadFile("poll_response_contact_delete.xml")); } - @TestOfyAndSql + @Test void testSuccess_hostDelete() throws Exception { // Host delete poll messages do not have any response data, so ensure that no // response data block is produced in the poll message. @@ -279,7 +277,7 @@ class PollRequestFlowTest extends FlowTestCase { runFlowAssertResponse(loadFile("poll_response_host_delete.xml")); } - @TestOfyAndSql + @Test void testFailure_messageIdProvided() throws Exception { setEppInput("poll_with_id.xml"); assertTransactionalFlow(false); diff --git a/core/src/test/java/google/registry/model/CreateAutoTimestampTest.java b/core/src/test/java/google/registry/model/CreateAutoTimestampTest.java index 663ec6894..dfc714372 100644 --- a/core/src/test/java/google/registry/model/CreateAutoTimestampTest.java +++ b/core/src/test/java/google/registry/model/CreateAutoTimestampTest.java @@ -23,19 +23,17 @@ import com.googlecode.objectify.annotation.Entity; import com.googlecode.objectify.annotation.Ignore; import google.registry.model.common.CrossTldSingleton; import google.registry.testing.AppEngineExtension; -import google.registry.testing.DualDatabaseTest; -import google.registry.testing.TestOfyAndSql; import org.joda.time.DateTime; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; /** Unit tests for {@link CreateAutoTimestamp}. */ -@DualDatabaseTest public class CreateAutoTimestampTest { @RegisterExtension public final AppEngineExtension appEngine = AppEngineExtension.builder() - .withDatastoreAndCloudSql() + .withCloudSql() .withOfyTestEntities(CreateAutoTimestampTestObject.class) .withJpaUnitTestEntities(CreateAutoTimestampTestObject.class) .build(); @@ -52,7 +50,7 @@ public class CreateAutoTimestampTest { return loadByEntity(new CreateAutoTimestampTestObject()); } - @TestOfyAndSql + @Test void testSaveSetsTime() { DateTime transactionTime = tm().transact( @@ -66,7 +64,7 @@ public class CreateAutoTimestampTest { assertThat(reload().createTime.timestamp).isEqualTo(transactionTime); } - @TestOfyAndSql + @Test void testResavingRespectsOriginalTime() { final DateTime oldCreateTime = DateTime.now(UTC).minusDays(1); tm().transact( diff --git a/core/src/test/java/google/registry/model/EntityTestCase.java b/core/src/test/java/google/registry/model/EntityTestCase.java index bf0e8c34b..1f956f95b 100644 --- a/core/src/test/java/google/registry/model/EntityTestCase.java +++ b/core/src/test/java/google/registry/model/EntityTestCase.java @@ -14,33 +14,12 @@ package google.registry.model; -import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.Truth.assertWithMessage; -import static google.registry.model.ofy.ObjectifyService.auditedOfy; import static org.joda.time.DateTimeZone.UTC; -import com.google.common.base.Splitter; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Sets; -import com.googlecode.objectify.annotation.Id; -import com.googlecode.objectify.annotation.Ignore; -import com.googlecode.objectify.annotation.Parent; -import com.googlecode.objectify.annotation.Serialize; -import com.googlecode.objectify.cmd.Query; import google.registry.model.ofy.Ofy; -import google.registry.persistence.EppHistoryVKey; -import google.registry.persistence.VKey; import google.registry.testing.AppEngineExtension; import google.registry.testing.FakeClock; import google.registry.testing.InjectExtension; -import google.registry.util.CidrAddressBlock; -import java.lang.reflect.Array; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.util.Collection; -import java.util.Set; import org.joda.time.DateTime; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.extension.RegisterExtension; @@ -71,7 +50,7 @@ public abstract class EntityTestCase { protected EntityTestCase(JpaEntityCoverageCheck jpaEntityCoverageCheck) { appEngine = AppEngineExtension.builder() - .withDatastoreAndCloudSql() + .withCloudSql() .enableJpaEntityCoverageCheck(jpaEntityCoverageCheck == JpaEntityCoverageCheck.ENABLED) .withClock(fakeClock) .build(); @@ -81,121 +60,4 @@ public abstract class EntityTestCase { public void injectClock() { inject.setStaticField(Ofy.class, "clock", fakeClock); } - - // Helper method to find private fields including inherited ones. - private Field getField(Class clazz, String name) { - while (clazz != Object.class) { - try { - return clazz.getDeclaredField(name); - } catch (NoSuchFieldException e) { - clazz = clazz.getSuperclass(); - } - } - return null; - } - - /** Verify that fields are either indexed or not, depending on the parameter. */ - private void verifyIndexingHelper(Object obj, boolean indexed, Collection fieldPaths) - throws Exception { - outer: - for (String fieldPath : fieldPaths) { - // Walk the field path and grab the value referred to on the object using reflection. - Object fieldValue = obj; - for (String fieldName : Splitter.on('.').split(fieldPath)) { - if (fieldValue == null) { - throw new RuntimeException( - String.format( - "field '%s' not found on %s", fieldPath, obj.getClass().getSimpleName())); - } - Field field = getField(fieldValue.getClass(), fieldName); - field.setAccessible(true); - // Check if the field is annotated with @Id. If it is, it's always indexed. Although we - // might want to double check that fact, it's a bad idea, because filtering on a @Id field - // will fail if the class also contains an @Parent field. - if (field.isAnnotationPresent(Id.class)) { - continue outer; - } - fieldValue = field.get(fieldValue); - // Check if the field is a collection. If so, take the first value from the collection, - // since we can't query on collections themselves. - if (fieldValue instanceof Collection) { - fieldValue = ((Collection) fieldValue).iterator().next(); - } - // Same for an array. - if (fieldValue != null && fieldValue.getClass().isArray()) { - fieldValue = Array.getLength(fieldValue) == 0 ? null : Array.get(fieldValue, 0); - } - // CidrAddressBlock objects implement the Iterable interface, which makes - // Objectify think we're querying for a list (which is not allowed unless we use the IN - // keyword). Convert the object to a String to make sure we do a query for a single value. - if (fieldValue instanceof CidrAddressBlock) { - fieldValue = fieldValue.toString(); - } - } - try { - // Objectify happily filters on an unindexed field, and just returns zero results. - // Do a query for that value and verify that the expected number of results are returned. - Query query = auditedOfy().load().type(obj.getClass()); - int results = query.filter(fieldPath, fieldValue).count(); - assertWithMessage(String.format("%s was %sindexed", fieldPath, indexed ? "not " : "")) - .that(indexed) - .isEqualTo(results != 0); - } catch (IllegalArgumentException e) { - // If the field's type was not indexable (because it's not a supported Datastore type) then - // this error will be thrown. If we expected no indexing, that's fine. Otherwise, fail. - if (indexed || !e.getMessage().endsWith(" is not a supported property type.")) { - assertWithMessage("%s was %sindexed", fieldPath, indexed ? "not " : "").fail(); - } - } catch (IllegalStateException e) { - assertWithMessage("%s (indexed=%b): %s", fieldPath, indexed, e.getMessage()).fail(); - } - } - } - - /** List all field paths so we can verify that we checked everything. */ - private Set getAllPotentiallyIndexedFieldPaths(Class clazz) { - Set fields = Sets.newHashSet(); - for (; clazz != Object.class; clazz = clazz.getSuperclass()) { - for (final Field field : clazz.getDeclaredFields()) { - // Ignore static, @Serialize, @Parent and @Ignore fields, since these are never indexed. - if (!Modifier.isStatic(field.getModifiers()) - && !field.isAnnotationPresent(Ignore.class) - && !field.isAnnotationPresent(Parent.class) - && !field.isAnnotationPresent(Serialize.class)) { - Class fieldClass = field.getType(); - // If the field is a collection, just pretend that it was a field of that type, - // because verifyIndexingHelper knows how to descend into collections. - if (Collection.class.isAssignableFrom(fieldClass)) { - Type inner = ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0]; - fieldClass = - inner instanceof ParameterizedType - ? (Class) ((ParameterizedType) inner).getRawType() - : (Class) inner; - } - // Descend into persisted ImmutableObject classes, but not anything else. - if (ImmutableObject.class.isAssignableFrom(fieldClass) - && !VKey.class.isAssignableFrom(fieldClass) - && !EppHistoryVKey.class.isAssignableFrom(fieldClass)) { - getAllPotentiallyIndexedFieldPaths(fieldClass).stream() - .map(subfield -> field.getName() + "." + subfield) - .distinct() - .forEachOrdered(fields::add); - } else { - fields.add(field.getName()); - } - } - } - } - return fields; - } - - /** Verify Datastore indexing for an entity. */ - public void verifyDatastoreIndexing(Object obj, String... indexed) throws Exception { - Set indexedSet = ImmutableSet.copyOf(indexed); - Set allSet = getAllPotentiallyIndexedFieldPaths(obj.getClass()); - // Sanity test that the indexed fields we listed were found. - assertThat(Sets.intersection(allSet, indexedSet)).containsExactlyElementsIn(indexedSet); - verifyIndexingHelper(obj, true, indexedSet); - verifyIndexingHelper(obj, false, Sets.difference(allSet, indexedSet)); - } } diff --git a/core/src/test/java/google/registry/model/EppResourceUtilsTest.java b/core/src/test/java/google/registry/model/EppResourceUtilsTest.java index 5db309976..d8900e878 100644 --- a/core/src/test/java/google/registry/model/EppResourceUtilsTest.java +++ b/core/src/test/java/google/registry/model/EppResourceUtilsTest.java @@ -25,28 +25,22 @@ import static org.joda.time.DateTimeZone.UTC; import google.registry.model.host.HostResource; import google.registry.model.ofy.Ofy; import google.registry.testing.AppEngineExtension; -import google.registry.testing.DualDatabaseTest; import google.registry.testing.FakeClock; import google.registry.testing.InjectExtension; -import google.registry.testing.TestOfyAndSql; import org.joda.time.DateTime; import org.joda.time.Duration; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; /** Tests for {@link EppResourceUtils}. */ -@DualDatabaseTest class EppResourceUtilsTest { private final FakeClock clock = new FakeClock(DateTime.now(UTC)); @RegisterExtension public final AppEngineExtension appEngine = - AppEngineExtension.builder() - .withDatastoreAndCloudSql() - .withClock(clock) - .withTaskQueue() - .build(); + AppEngineExtension.builder().withCloudSql().withClock(clock).withTaskQueue().build(); @RegisterExtension public final InjectExtension inject = new InjectExtension(); @@ -56,7 +50,7 @@ class EppResourceUtilsTest { inject.setStaticField(Ofy.class, "clock", clock); } - @TestOfyAndSql + @Test void testLoadAtPointInTime_beforeCreated_returnsNull() { clock.advanceOneMilli(); // Don't save a commit log, we shouldn't need one. @@ -67,7 +61,7 @@ class EppResourceUtilsTest { assertThat(loadAtPointInTime(host, clock.nowUtc().minus(Duration.millis(1)))).isNull(); } - @TestOfyAndSql + @Test void testLoadAtPointInTime_atOrAfterLastAutoUpdateTime_returnsResource() { clock.advanceOneMilli(); // Don't save a commit log, we shouldn't need one. diff --git a/core/src/test/java/google/registry/model/ImmutableObjectTest.java b/core/src/test/java/google/registry/model/ImmutableObjectTest.java index 5c1c02ae3..f645916b3 100644 --- a/core/src/test/java/google/registry/model/ImmutableObjectTest.java +++ b/core/src/test/java/google/registry/model/ImmutableObjectTest.java @@ -48,7 +48,7 @@ public class ImmutableObjectTest { @RegisterExtension public final AppEngineExtension appEngine = AppEngineExtension.builder() - .withDatastoreAndCloudSql() + .withCloudSql() .withJpaUnitTestEntities(ValueObject.class) .withOfyTestEntities(ValueObject.class) .build(); diff --git a/core/src/test/java/google/registry/model/OteAccountBuilderTest.java b/core/src/test/java/google/registry/model/OteAccountBuilderTest.java index 83a936d8e..4dc538f79 100644 --- a/core/src/test/java/google/registry/model/OteAccountBuilderTest.java +++ b/core/src/test/java/google/registry/model/OteAccountBuilderTest.java @@ -34,8 +34,6 @@ import google.registry.model.registrar.RegistrarPoc; import google.registry.model.tld.Registry; import google.registry.model.tld.Registry.TldState; import google.registry.testing.AppEngineExtension; -import google.registry.testing.DualDatabaseTest; -import google.registry.testing.TestOfyAndSql; import google.registry.util.CidrAddressBlock; import google.registry.util.SystemClock; import org.joda.money.Money; @@ -43,16 +41,15 @@ import org.joda.time.DateTime; import org.joda.time.DateTimeZone; import org.joda.time.Duration; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; -@DualDatabaseTest public final class OteAccountBuilderTest { @RegisterExtension - public final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().build(); + public final AppEngineExtension appEngine = AppEngineExtension.builder().withCloudSql().build(); - @TestOfyAndSql + @Test void testGetRegistrarToTldMap() { assertThat(OteAccountBuilder.forRegistrarId("myclientid").getRegistrarIdToTldMap()) .containsExactly( @@ -103,7 +100,7 @@ public final class OteAccountBuilderTest { assertThat(contact.getGaeUserId()).isNotEmpty(); } - @TestOfyAndSql + @Test void testCreateOteEntities_success() { OteAccountBuilder.forRegistrarId("myclientid") .addContact("email@example.com") @@ -122,7 +119,7 @@ public final class OteAccountBuilderTest { assertContactExists("myclientid-5", "email@example.com"); } - @TestOfyAndSql + @Test void testCreateOteEntities_multipleContacts_success() { OteAccountBuilder.forRegistrarId("myclientid") .addContact("email@example.com") @@ -151,7 +148,7 @@ public final class OteAccountBuilderTest { assertContactExists("myclientid-5", "someone@example.com"); } - @TestOfyAndSql + @Test void testCreateOteEntities_setPassword() { OteAccountBuilder.forRegistrarId("myclientid").setPassword("myPassword").buildAndPersist(); @@ -159,7 +156,7 @@ public final class OteAccountBuilderTest { .isTrue(); } - @TestOfyAndSql + @Test void testCreateOteEntities_setCertificate() { OteAccountBuilder.forRegistrarId("myclientid") .setCertificate(SAMPLE_CERT, new SystemClock().nowUtc()) @@ -171,7 +168,7 @@ public final class OteAccountBuilderTest { .hasValue(SAMPLE_CERT); } - @TestOfyAndSql + @Test void testCreateOteEntities_setIpAllowList() { OteAccountBuilder.forRegistrarId("myclientid") .setIpAllowList(ImmutableList.of("1.1.1.0/24")) @@ -181,7 +178,7 @@ public final class OteAccountBuilderTest { .containsExactly(CidrAddressBlock.create("1.1.1.0/24")); } - @TestOfyAndSql + @Test void testCreateOteEntities_invalidRegistrarId_fails() { assertThat( assertThrows( @@ -190,7 +187,7 @@ public final class OteAccountBuilderTest { .isEqualTo("Invalid registrar name: 3blo-bio"); } - @TestOfyAndSql + @Test void testCreateOteEntities_clientIdTooShort_fails() { assertThat( assertThrows( @@ -199,7 +196,7 @@ public final class OteAccountBuilderTest { .isEqualTo("Invalid registrar name: bl"); } - @TestOfyAndSql + @Test void testCreateOteEntities_clientIdTooLong_fails() { assertThat( assertThrows( @@ -209,7 +206,7 @@ public final class OteAccountBuilderTest { .isEqualTo("Invalid registrar name: blobiotoooolong"); } - @TestOfyAndSql + @Test void testCreateOteEntities_clientIdBadCharacter_fails() { assertThat( assertThrows( @@ -218,7 +215,7 @@ public final class OteAccountBuilderTest { .isEqualTo("Invalid registrar name: blo#bio"); } - @TestOfyAndSql + @Test void testCreateOteEntities_registrarExists_failsWhenNotReplaceExisting() { persistSimpleResource(makeRegistrar1().asBuilder().setRegistrarId("myclientid-1").build()); @@ -231,7 +228,7 @@ public final class OteAccountBuilderTest { .contains("Found existing object(s) conflicting with OT&E objects"); } - @TestOfyAndSql + @Test void testCreateOteEntities_tldExists_failsWhenNotReplaceExisting() { createTld("myclientid-ga", START_DATE_SUNRISE); @@ -244,7 +241,7 @@ public final class OteAccountBuilderTest { .contains("Found existing object(s) conflicting with OT&E objects"); } - @TestOfyAndSql + @Test void testCreateOteEntities_entitiesExist_succeedsWhenReplaceExisting() { persistSimpleResource(makeRegistrar1().asBuilder().setRegistrarId("myclientid-1").build()); // we intentionally create the -ga TLD with the wrong state, to make sure it's overwritten. @@ -259,7 +256,7 @@ public final class OteAccountBuilderTest { assertRegistrarExists("myclientid-3", "myclientid-ga"); } - @TestOfyAndSql + @Test void testCreateOteEntities_doubleCreation_actuallyReplaces() { OteAccountBuilder.forRegistrarId("myclientid") .setPassword("oldPassword") @@ -281,7 +278,7 @@ public final class OteAccountBuilderTest { .isTrue(); } - @TestOfyAndSql + @Test void testCreateOteEntities_doubleCreation_keepsOldContacts() { OteAccountBuilder.forRegistrarId("myclientid") .addContact("email@example.com") @@ -298,7 +295,7 @@ public final class OteAccountBuilderTest { assertContactExists("myclientid-3", "email@example.com"); } - @TestOfyAndSql + @Test void testCreateRegistrarIdToTldMap_validEntries() { assertThat(OteAccountBuilder.createRegistrarIdToTldMap("myclientid")) .containsExactly( @@ -308,7 +305,7 @@ public final class OteAccountBuilderTest { "myclientid-5", "myclientid-eap"); } - @TestOfyAndSql + @Test void testCreateRegistrarIdToTldMap_invalidId() { IllegalArgumentException exception = assertThrows( @@ -316,12 +313,12 @@ public final class OteAccountBuilderTest { assertThat(exception).hasMessageThat().isEqualTo("Invalid registrar name: a"); } - @TestOfyAndSql + @Test void testGetBaseRegistrarId_validOteId() { assertThat(OteAccountBuilder.getBaseRegistrarId("myclientid-4")).isEqualTo("myclientid"); } - @TestOfyAndSql + @Test void testGetBaseRegistrarId_invalidInput_malformed() { assertThat( assertThrows( @@ -331,7 +328,7 @@ public final class OteAccountBuilderTest { .isEqualTo("Invalid OT&E registrar ID: myclientid"); } - @TestOfyAndSql + @Test void testGetBaseRegistrarId_invalidInput_wrongForBase() { assertThat( assertThrows( diff --git a/core/src/test/java/google/registry/model/OteStatsTest.java b/core/src/test/java/google/registry/model/OteStatsTest.java index 8a88d15ba..e3f69d3a8 100644 --- a/core/src/test/java/google/registry/model/OteStatsTest.java +++ b/core/src/test/java/google/registry/model/OteStatsTest.java @@ -19,24 +19,21 @@ import static google.registry.testing.DatabaseHelper.createTld; import google.registry.model.OteStats.StatType; import google.registry.testing.AppEngineExtension; -import google.registry.testing.DualDatabaseTest; -import google.registry.testing.TestOfyAndSql; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; -@DualDatabaseTest public final class OteStatsTest { @RegisterExtension - public final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().build(); + public final AppEngineExtension appEngine = AppEngineExtension.builder().withCloudSql().build(); @BeforeEach void beforeEach() { createTld("tld"); } - @TestOfyAndSql + @Test void testSuccess_allPass() throws Exception { OteStatsTestHelper.setupCompleteOte("blobio"); OteStats stats = OteStats.getFromRegistrar("blobio"); @@ -44,7 +41,7 @@ public final class OteStatsTest { assertThat(stats.getSize()).isEqualTo(30); } - @TestOfyAndSql + @Test void testSuccess_incomplete() throws Exception { OteStatsTestHelper.setupIncompleteOte("blobio"); OteStats stats = OteStats.getFromRegistrar("blobio"); @@ -55,7 +52,7 @@ public final class OteStatsTest { assertThat(stats.getSize()).isEqualTo(34); } - @TestOfyAndSql + @Test void testSuccess_toString() throws Exception { OteStatsTestHelper.setupCompleteOte("blobio"); OteStats stats = OteStats.getFromRegistrar("blobio"); @@ -96,7 +93,7 @@ public final class OteStatsTest { assertThat(stats.toString()).isEqualTo(expected); } - @TestOfyAndSql + @Test void testIncomplete_toString() throws Exception { OteStatsTestHelper.setupIncompleteOte("blobio"); OteStats stats = OteStats.getFromRegistrar("blobio"); diff --git a/core/src/test/java/google/registry/model/SchemaVersionTest.java b/core/src/test/java/google/registry/model/SchemaVersionTest.java index dbd3936e8..f596d6938 100644 --- a/core/src/test/java/google/registry/model/SchemaVersionTest.java +++ b/core/src/test/java/google/registry/model/SchemaVersionTest.java @@ -27,8 +27,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; public class SchemaVersionTest { @RegisterExtension - public final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().build(); + public final AppEngineExtension appEngine = AppEngineExtension.builder().withCloudSql().build(); @Test void testGoldenSchemaFile() { diff --git a/core/src/test/java/google/registry/model/UpdateAutoTimestampTest.java b/core/src/test/java/google/registry/model/UpdateAutoTimestampTest.java index 69be69cc8..a4a8f1190 100644 --- a/core/src/test/java/google/registry/model/UpdateAutoTimestampTest.java +++ b/core/src/test/java/google/registry/model/UpdateAutoTimestampTest.java @@ -25,16 +25,14 @@ import google.registry.model.common.CrossTldSingleton; import google.registry.model.ofy.Ofy; import google.registry.persistence.VKey; import google.registry.testing.AppEngineExtension; -import google.registry.testing.DualDatabaseTest; import google.registry.testing.FakeClock; import google.registry.testing.InjectExtension; -import google.registry.testing.TestOfyAndSql; import org.joda.time.DateTime; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; /** Unit tests for {@link UpdateAutoTimestamp}. */ -@DualDatabaseTest public class UpdateAutoTimestampTest { FakeClock clock = new FakeClock(); @@ -42,7 +40,7 @@ public class UpdateAutoTimestampTest { @RegisterExtension public final AppEngineExtension appEngine = AppEngineExtension.builder() - .withDatastoreAndCloudSql() + .withCloudSql() .withJpaUnitTestEntities(UpdateAutoTimestampTestObject.class) .withOfyTestEntities(UpdateAutoTimestampTestObject.class) .withClock(clock) @@ -73,7 +71,7 @@ public class UpdateAutoTimestampTest { Key.create(new UpdateAutoTimestampTestObject())))); } - @TestOfyAndSql + @Test void testSaveSetsTime() { DateTime transactionTime = tm().transact( @@ -88,7 +86,7 @@ public class UpdateAutoTimestampTest { assertThat(reload().updateTime.timestamp).isEqualTo(transactionTime); } - @TestOfyAndSql + @Test void testDisabledUpdates() throws Exception { DateTime initialTime = tm().transact( @@ -114,7 +112,7 @@ public class UpdateAutoTimestampTest { assertThat(reload().updateTime.timestamp).isEqualTo(initialTime); } - @TestOfyAndSql + @Test void testResavingOverwritesOriginalTime() { DateTime transactionTime = tm().transact( @@ -129,7 +127,7 @@ public class UpdateAutoTimestampTest { assertThat(reload().updateTime.timestamp).isEqualTo(transactionTime); } - @TestOfyAndSql + @Test void testReadingTwiceDoesNotModify() { DateTime originalTime = DateTime.parse("1999-01-01T00:00:00Z"); clock.setTo(originalTime); diff --git a/core/src/test/java/google/registry/model/billing/BillingEventTest.java b/core/src/test/java/google/registry/model/billing/BillingEventTest.java index f587d8d14..3cb9df769 100644 --- a/core/src/test/java/google/registry/model/billing/BillingEventTest.java +++ b/core/src/test/java/google/registry/model/billing/BillingEventTest.java @@ -17,9 +17,6 @@ package google.registry.model.billing; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth8.assertThat; import static google.registry.model.domain.token.AllocationToken.TokenType.UNLIMITED_USE; -import static google.registry.model.ofy.ObjectifyService.auditedOfy; -import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.ofyTmOrDoNothing; import static google.registry.testing.DatabaseHelper.createTld; import static google.registry.testing.DatabaseHelper.loadByEntity; import static google.registry.testing.DatabaseHelper.loadByKey; @@ -46,18 +43,14 @@ import google.registry.model.domain.token.AllocationToken; import google.registry.model.domain.token.AllocationToken.TokenStatus; import google.registry.model.reporting.HistoryEntry; import google.registry.persistence.VKey; -import google.registry.testing.DualDatabaseTest; -import google.registry.testing.TestOfyAndSql; -import google.registry.testing.TestOfyOnly; -import google.registry.testing.TestSqlOnly; import google.registry.util.DateTimeUtils; import java.math.BigDecimal; import org.joda.money.Money; import org.joda.time.DateTime; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; /** Unit tests for {@link BillingEvent}. */ -@DualDatabaseTest public class BillingEventTest extends EntityTestCase { private final DateTime now = DateTime.now(UTC); @@ -73,7 +66,6 @@ public class BillingEventTest extends EntityTestCase { private BillingEvent.Recurring recurring; private BillingEvent.Cancellation cancellationOneTime; private BillingEvent.Cancellation cancellationRecurring; - private BillingEvent.Modification modification; @BeforeEach void setUp() { @@ -171,36 +163,22 @@ public class BillingEventTest extends EntityTestCase { .setEventTime(now.plusDays(1)) .setBillingTime(now.plusYears(1).plusDays(45)) .setRecurringEventKey(recurring.createVKey()))); - modification = - ofyTmOrDoNothing( - () -> - persistResource( - commonInit( - new BillingEvent.Modification.Builder() - .setParent(domainHistory2) - .setReason(Reason.CREATE) - .setCost(Money.of(USD, 1)) - .setDescription("Something happened") - .setEventTime(now.plusDays(1)) - .setEventKey(Key.create(oneTime))))); } private > E commonInit(B builder) { return builder.setRegistrarId("TheRegistrar").setTargetId("foo.tld").build(); } - @TestOfyAndSql + @Test void testPersistence() { assertThat(loadByEntity(oneTime)).isEqualTo(oneTime); assertThat(loadByEntity(oneTimeSynthetic)).isEqualTo(oneTimeSynthetic); assertThat(loadByEntity(recurring)).isEqualTo(recurring); assertThat(loadByEntity(cancellationOneTime)).isEqualTo(cancellationOneTime); assertThat(loadByEntity(cancellationRecurring)).isEqualTo(cancellationRecurring); - - ofyTmOrDoNothing(() -> assertThat(tm().loadByEntity(modification)).isEqualTo(modification)); } - @TestSqlOnly + @Test void testSerializable() { BillingEvent persisted = loadByEntity(oneTime); assertThat(serializeDeserialize(persisted)).isEqualTo(persisted); @@ -214,68 +192,13 @@ public class BillingEventTest extends EntityTestCase { assertThat(serializeDeserialize(persisted)).isEqualTo(persisted); } - @TestOfyOnly - void testParenting() { - // Note that these are all tested separately because BillingEvent is an abstract base class that - // lacks the @Entity annotation, and thus we cannot call .type(BillingEvent.class) - assertThat(auditedOfy().load().type(BillingEvent.OneTime.class).ancestor(domain).list()) - .containsExactly(oneTime, oneTimeSynthetic); - assertThat(auditedOfy().load().type(BillingEvent.Recurring.class).ancestor(domain).list()) - .containsExactly(recurring); - assertThat(auditedOfy().load().type(BillingEvent.Cancellation.class).ancestor(domain).list()) - .containsExactly(cancellationOneTime, cancellationRecurring); - assertThat(auditedOfy().load().type(BillingEvent.Modification.class).ancestor(domain).list()) - .containsExactly(modification); - assertThat(auditedOfy().load().type(BillingEvent.OneTime.class).ancestor(domainHistory).list()) - .containsExactly(oneTime, oneTimeSynthetic); - assertThat( - auditedOfy().load().type(BillingEvent.Recurring.class).ancestor(domainHistory).list()) - .containsExactly(recurring); - assertThat( - auditedOfy() - .load() - .type(BillingEvent.Cancellation.class) - .ancestor(domainHistory2) - .list()) - .containsExactly(cancellationOneTime, cancellationRecurring); - assertThat( - auditedOfy() - .load() - .type(BillingEvent.Modification.class) - .ancestor(domainHistory2) - .list()) - .containsExactly(modification); - } - - @TestOfyAndSql + @Test void testCancellationMatching() { VKey recurringKey = loadByEntity(oneTimeSynthetic).getCancellationMatchingBillingEvent(); assertThat(loadByKey(recurringKey)).isEqualTo(recurring); } - @TestOfyOnly - void testIndexing() throws Exception { - verifyDatastoreIndexing( - oneTime, - "clientId", - "eventTime", - "billingTime", - "syntheticCreationTime", - "allocationToken"); - verifyDatastoreIndexing( - oneTimeSynthetic, - "clientId", - "eventTime", - "billingTime", - "syntheticCreationTime", - "allocationToken"); - verifyDatastoreIndexing( - recurring, "clientId", "eventTime", "recurrenceEndTime", "recurrenceTimeOfYear.timeString"); - verifyDatastoreIndexing(cancellationOneTime, "clientId", "eventTime", "billingTime"); - verifyDatastoreIndexing(modification, "clientId", "eventTime"); - } - - @TestOfyAndSql + @Test void testFailure_syntheticFlagWithoutCreationTime() { IllegalStateException thrown = assertThrows( @@ -291,7 +214,7 @@ public class BillingEventTest extends EntityTestCase { .contains("Synthetic creation time must be set if and only if the SYNTHETIC flag is set."); } - @TestOfyAndSql + @Test void testFailure_syntheticCreationTimeWithoutFlag() { IllegalStateException thrown = assertThrows( @@ -302,7 +225,7 @@ public class BillingEventTest extends EntityTestCase { .contains("Synthetic creation time must be set if and only if the SYNTHETIC flag is set"); } - @TestOfyAndSql + @Test void testFailure_syntheticFlagWithoutCancellationMatchingKey() { IllegalStateException thrown = assertThrows( @@ -320,7 +243,7 @@ public class BillingEventTest extends EntityTestCase { + "if and only if the SYNTHETIC flag is set"); } - @TestOfyAndSql + @Test void testFailure_cancellationMatchingKeyWithoutFlag() { IllegalStateException thrown = assertThrows( @@ -337,7 +260,7 @@ public class BillingEventTest extends EntityTestCase { + "if and only if the SYNTHETIC flag is set"); } - @TestOfyAndSql + @Test void testSuccess_cancellation_forGracePeriod_withOneTime() { BillingEvent.Cancellation newCancellation = BillingEvent.Cancellation.forGracePeriod( @@ -350,7 +273,7 @@ public class BillingEventTest extends EntityTestCase { .isEqualTo(cancellationOneTime); } - @TestOfyAndSql + @Test void testSuccess_cancellation_forGracePeriod_withRecurring() { BillingEvent.Cancellation newCancellation = BillingEvent.Cancellation.forGracePeriod( @@ -368,7 +291,7 @@ public class BillingEventTest extends EntityTestCase { .isEqualTo(cancellationRecurring); } - @TestOfyAndSql + @Test void testFailure_cancellation_forGracePeriodWithoutBillingEvent() { IllegalArgumentException thrown = assertThrows( @@ -386,7 +309,7 @@ public class BillingEventTest extends EntityTestCase { assertThat(thrown).hasMessageThat().contains("grace period without billing event"); } - @TestOfyAndSql + @Test void testFailure_cancellationWithNoBillingEvent() { IllegalStateException thrown = assertThrows( @@ -400,7 +323,7 @@ public class BillingEventTest extends EntityTestCase { assertThat(thrown).hasMessageThat().contains("exactly one billing event"); } - @TestOfyAndSql + @Test void testFailure_cancellationWithBothBillingEvents() { IllegalStateException thrown = assertThrows( @@ -414,13 +337,13 @@ public class BillingEventTest extends EntityTestCase { assertThat(thrown).hasMessageThat().contains("exactly one billing event"); } - @TestOfyAndSql + @Test void testDeadCodeThatDeletedScrapCommandsReference() { assertThat(recurring.getParentKey()).isEqualTo(Key.create(domainHistory)); new BillingEvent.OneTime.Builder().setParent(Key.create(domainHistory)); } - @TestOfyAndSql + @Test void testReasonRequiringPeriodYears_missingPeriodYears_throwsException() { IllegalStateException thrown = assertThrows( @@ -441,7 +364,7 @@ public class BillingEventTest extends EntityTestCase { .contains("Period years must be set if and only if reason is"); } - @TestOfyAndSql + @Test void testReasonNotRequiringPeriodYears_havingPeriodYears_throwsException() { IllegalStateException thrown = assertThrows( @@ -463,7 +386,7 @@ public class BillingEventTest extends EntityTestCase { .contains("Period years must be set if and only if reason is"); } - @TestOfyAndSql + @Test void testReasonRequiringPeriodYears_missingPeriodYears_isAllowedOnOldData() { // This won't throw even though periodYears is missing on a RESTORE because the event time // is before 2019. @@ -478,13 +401,13 @@ public class BillingEventTest extends EntityTestCase { .build(); } - @TestOfyAndSql + @Test void testSuccess_defaultRenewalPriceBehavior_assertsIsDefault() { assertThat(recurring.getRenewalPriceBehavior()).isEqualTo(RenewalPriceBehavior.DEFAULT); assertThat(recurring.getRenewalPrice()).isEmpty(); } - @TestOfyAndSql + @Test void testSuccess_getRenewalPriceBehavior_returnsRightBehavior() { BillingEvent.Recurring recurringEvent = persistResource( @@ -500,7 +423,7 @@ public class BillingEventTest extends EntityTestCase { assertThat(recurringEvent.getRenewalPrice()).isEmpty(); } - @TestOfyAndSql + @Test void testSuccess_setRenewalPriceBehaviorThenBuild_defaultToSpecified() { BillingEvent.Recurring recurringEvent = persistResource( @@ -527,7 +450,7 @@ public class BillingEventTest extends EntityTestCase { assertThat(loadByEntity(recurringEvent).getRenewalPrice()).hasValue(Money.of(USD, 100)); } - @TestOfyAndSql + @Test void testSuccess_setRenewalPriceBehaviorThenBuild_defaultToNonPremium() { BillingEvent.Recurring recurringEvent = persistResource( @@ -550,7 +473,7 @@ public class BillingEventTest extends EntityTestCase { assertThat(loadByEntity(recurringEvent).getRenewalPrice()).isEmpty(); } - @TestOfyAndSql + @Test void testSuccess_setRenewalPriceBehaviorThenBuild_nonPremiumToSpecified() { BillingEvent.Recurring recurringEvent = persistResource( @@ -577,7 +500,7 @@ public class BillingEventTest extends EntityTestCase { assertThat(loadByEntity(recurringEvent).getRenewalPrice()).hasValue(Money.of(USD, 100)); } - @TestOfyAndSql + @Test void testSuccess_setRenewalPriceBehaviorThenBuild_nonPremiumToDefault() { BillingEvent.Recurring recurringEvent = persistResource( @@ -600,7 +523,7 @@ public class BillingEventTest extends EntityTestCase { assertThat(loadByEntity(recurringEvent).getRenewalPrice()).isEmpty(); } - @TestOfyAndSql + @Test void testSuccess_setRenewalPriceBehaviorThenBuild_specifiedToDefault() { BillingEvent.Recurring recurringEvent = persistResource( @@ -628,7 +551,7 @@ public class BillingEventTest extends EntityTestCase { assertThat(loadByEntity(recurringEvent).getRenewalPrice()).isEmpty(); } - @TestOfyAndSql + @Test void testSuccess_setRenewalPriceBehaviorThenBuild_specifiedToNonPremium() { BillingEvent.Recurring recurringEvent = persistResource( @@ -656,7 +579,7 @@ public class BillingEventTest extends EntityTestCase { assertThat(loadByEntity(recurringEvent).getRenewalPrice()).isEmpty(); } - @TestOfyAndSql + @Test void testFailure_setRenewalPriceBehaviorThenBuild_defaultToSpecified_needRenewalPrice() { BillingEvent.Recurring recurringEvent = persistResource( @@ -687,7 +610,7 @@ public class BillingEventTest extends EntityTestCase { + "renewal price behavior is SPECIFIED"); } - @TestOfyAndSql + @Test void testFailure_setRenewalPriceBehaviorThenBuild_defaultToPremium_noNeedToAddRenewalPrice() { BillingEvent.Recurring recurringEvent = persistResource( @@ -719,7 +642,7 @@ public class BillingEventTest extends EntityTestCase { + "renewal price behavior is SPECIFIED"); } - @TestOfyAndSql + @Test void testFailure_setRenewalPriceBehaviorThenBuild_nonPremiumToDefault_noNeedToAddRenewalPrice() { BillingEvent.Recurring recurringEvent = persistResource( @@ -751,7 +674,7 @@ public class BillingEventTest extends EntityTestCase { + "renewal price behavior is SPECIFIED"); } - @TestOfyAndSql + @Test void testFailure_setRenewalPriceBehaviorThenBuild_nonPremiumToSpecified_needRenewalPrice() { BillingEvent.Recurring recurringEvent = persistResource( @@ -782,7 +705,7 @@ public class BillingEventTest extends EntityTestCase { + "renewal price behavior is SPECIFIED"); } - @TestOfyAndSql + @Test void testFailure_setRenewalPriceBehaviorThenBuild_specifiedToNonPremium_removeRenewalPrice() { BillingEvent.Recurring recurringEvent = persistResource( @@ -814,7 +737,7 @@ public class BillingEventTest extends EntityTestCase { + "renewal price behavior is SPECIFIED"); } - @TestOfyAndSql + @Test void testFailure_setRenewalPriceBehaviorThenBuild_specifiedToDefault_removeRenewalPrice() { BillingEvent.Recurring recurringEvent = persistResource( @@ -846,7 +769,7 @@ public class BillingEventTest extends EntityTestCase { + "renewal price behavior is SPECIFIED"); } - @TestOfyAndSql + @Test void testSuccess_buildWithDefaultRenewalBehavior() { BillingEvent.Recurring recurringEvent = persistResource( @@ -863,7 +786,7 @@ public class BillingEventTest extends EntityTestCase { assertThat(recurringEvent.getRenewalPrice()).hasValue(Money.of(USD, 100)); } - @TestOfyAndSql + @Test void testSuccess_buildWithNonPremiumRenewalBehavior() { BillingEvent.Recurring recurringEvent = persistResource( @@ -879,7 +802,7 @@ public class BillingEventTest extends EntityTestCase { assertThat(loadByEntity(recurringEvent).getRenewalPrice()).isEmpty(); } - @TestOfyAndSql + @Test void testSuccess_buildWithSpecifiedRenewalBehavior() { BillingEvent.Recurring recurringEvent = persistResource( @@ -896,7 +819,7 @@ public class BillingEventTest extends EntityTestCase { assertThat(recurringEvent.getRenewalPrice()).hasValue(Money.of(USD, 100)); } - @TestOfyAndSql + @Test void testFailure_buildWithSpecifiedRenewalBehavior_requiresNonNullRenewalPrice() { IllegalArgumentException thrown = assertThrows( @@ -917,7 +840,7 @@ public class BillingEventTest extends EntityTestCase { + "renewal price behavior is SPECIFIED"); } - @TestOfyAndSql + @Test void testFailure_buildWithNonPremiumRenewalBehavior_requiresNullRenewalPrice() { IllegalArgumentException thrown = assertThrows( @@ -939,7 +862,7 @@ public class BillingEventTest extends EntityTestCase { + "renewal price behavior is SPECIFIED"); } - @TestOfyAndSql + @Test void testFailure_buildWithDefaultRenewalBehavior_requiresNullRenewalPrice() { IllegalArgumentException thrown = assertThrows( diff --git a/core/src/test/java/google/registry/model/bulkquery/DomainBaseLiteTest.java b/core/src/test/java/google/registry/model/bulkquery/DomainBaseLiteTest.java index 9b015071d..2c6bf9cbb 100644 --- a/core/src/test/java/google/registry/model/bulkquery/DomainBaseLiteTest.java +++ b/core/src/test/java/google/registry/model/bulkquery/DomainBaseLiteTest.java @@ -40,7 +40,7 @@ class DomainBaseLiteTest { @RegisterExtension public final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().withClock(fakeClock).build(); + AppEngineExtension.builder().withCloudSql().withClock(fakeClock).build(); private final TestSetupHelper setupHelper = new TestSetupHelper(fakeClock); diff --git a/core/src/test/java/google/registry/model/bulkquery/DomainHistoryLiteTest.java b/core/src/test/java/google/registry/model/bulkquery/DomainHistoryLiteTest.java index 73c431764..db9ed65d9 100644 --- a/core/src/test/java/google/registry/model/bulkquery/DomainHistoryLiteTest.java +++ b/core/src/test/java/google/registry/model/bulkquery/DomainHistoryLiteTest.java @@ -40,7 +40,7 @@ public class DomainHistoryLiteTest { @RegisterExtension public final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().withClock(fakeClock).build(); + AppEngineExtension.builder().withCloudSql().withClock(fakeClock).build(); private final TestSetupHelper setupHelper = new TestSetupHelper(fakeClock); diff --git a/core/src/test/java/google/registry/model/common/GaeUserIdConverterTest.java b/core/src/test/java/google/registry/model/common/GaeUserIdConverterTest.java index 0fe605aef..8b935aa7d 100644 --- a/core/src/test/java/google/registry/model/common/GaeUserIdConverterTest.java +++ b/core/src/test/java/google/registry/model/common/GaeUserIdConverterTest.java @@ -26,8 +26,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; public class GaeUserIdConverterTest { @RegisterExtension - public final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().build(); + public final AppEngineExtension appEngine = AppEngineExtension.builder().withCloudSql().build(); @AfterEach void verifyNoLingeringEntities() { diff --git a/core/src/test/java/google/registry/model/contact/ContactCommandTest.java b/core/src/test/java/google/registry/model/contact/ContactCommandTest.java index 448a5a218..61d50e216 100644 --- a/core/src/test/java/google/registry/model/contact/ContactCommandTest.java +++ b/core/src/test/java/google/registry/model/contact/ContactCommandTest.java @@ -34,8 +34,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; public class ContactCommandTest { @RegisterExtension - public final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().build(); + public final AppEngineExtension appEngine = AppEngineExtension.builder().withCloudSql().build(); private void doXmlRoundtripTest(String inputFilename) throws Exception { EppLoader eppLoader = new EppLoader(this, inputFilename); diff --git a/core/src/test/java/google/registry/model/contact/ContactResourceTest.java b/core/src/test/java/google/registry/model/contact/ContactResourceTest.java index eb32b8633..bcf8c0a8e 100644 --- a/core/src/test/java/google/registry/model/contact/ContactResourceTest.java +++ b/core/src/test/java/google/registry/model/contact/ContactResourceTest.java @@ -39,15 +39,11 @@ import google.registry.model.eppcommon.StatusValue; import google.registry.model.eppcommon.Trid; import google.registry.model.transfer.ContactTransferData; import google.registry.model.transfer.TransferStatus; -import google.registry.testing.DualDatabaseTest; -import google.registry.testing.TestOfyAndSql; -import google.registry.testing.TestOfyOnly; -import google.registry.testing.TestSqlOnly; import google.registry.util.SerializeUtils; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; /** Unit tests for {@link ContactResource}. */ -@DualDatabaseTest public class ContactResourceTest extends EntityTestCase { private ContactResource originalContact; @@ -126,14 +122,14 @@ public class ContactResourceTest extends EntityTestCase { contactResource = persistResource(cloneAndSetAutoTimestamps(originalContact)); } - @TestOfyAndSql + @Test void testContactBaseToContactResource() { assertAboutImmutableObjects() .that(new ContactResource.Builder().copyFrom(contactResource).build()) .isEqualExceptFields(contactResource, "updateTimestamp", "revisions"); } - @TestSqlOnly + @Test void testCloudSqlPersistence_failWhenViolateForeignKeyConstraint() { assertThrowForeignKeyViolation( () -> @@ -145,7 +141,7 @@ public class ContactResourceTest extends EntityTestCase { .build())); } - @TestSqlOnly + @Test void testCloudSqlPersistence_succeed() { ContactResource persisted = loadByEntity(originalContact); ContactResource fixed = @@ -162,7 +158,7 @@ public class ContactResourceTest extends EntityTestCase { assertAboutImmutableObjects().that(persisted).isEqualExceptFields(fixed, "updateTimestamp"); } - @TestOfyAndSql + @Test void testPersistence() { assertThat( loadByForeignKey( @@ -170,7 +166,7 @@ public class ContactResourceTest extends EntityTestCase { .hasValue(contactResource); } - @TestSqlOnly + @Test void testSerializable() { ContactResource persisted = loadByForeignKey(ContactResource.class, contactResource.getForeignKey(), fakeClock.nowUtc()) @@ -178,13 +174,7 @@ public class ContactResourceTest extends EntityTestCase { assertThat(SerializeUtils.serializeDeserialize(persisted)).isEqualTo(persisted); } - @TestOfyOnly - void testIndexing() throws Exception { - verifyDatastoreIndexing( - contactResource, "deletionTime", "currentSponsorClientId", "searchName"); - } - - @TestOfyAndSql + @Test void testEmptyStringsBecomeNull() { assertThat(new ContactResource.Builder().setContactId(null).build().getContactId()).isNull(); assertThat(new ContactResource.Builder().setContactId("").build().getContactId()).isNull(); @@ -216,7 +206,7 @@ public class ContactResourceTest extends EntityTestCase { .isNotNull(); } - @TestOfyAndSql + @Test void testEmptyTransferDataBecomesNull() { ContactResource withNull = new ContactResource.Builder().setTransferData(null).build(); ContactResource withEmpty = @@ -225,7 +215,7 @@ public class ContactResourceTest extends EntityTestCase { assertThat(withEmpty.transferData).isNull(); } - @TestOfyAndSql + @Test void testImplicitStatusValues() { // OK is implicit if there's no other statuses. assertAboutContacts() @@ -247,7 +237,7 @@ public class ContactResourceTest extends EntityTestCase { .hasExactlyStatusValues(StatusValue.CLIENT_HOLD); } - @TestOfyAndSql + @Test void testExpiredTransfer() { ContactResource afterTransfer = contactResource @@ -268,7 +258,7 @@ public class ContactResourceTest extends EntityTestCase { assertThat(afterTransfer.getLastTransferTime()).isEqualTo(fakeClock.nowUtc().plusDays(1)); } - @TestOfyAndSql + @Test void testSetCreationTime_cantBeCalledTwice() { IllegalStateException thrown = assertThrows( @@ -277,7 +267,7 @@ public class ContactResourceTest extends EntityTestCase { assertThat(thrown).hasMessageThat().contains("creationTime can only be set once"); } - @TestOfyAndSql + @Test void testToHydratedString_notCircular() { // If there are circular references, this will overflow the stack. contactResource.toHydratedString(); diff --git a/core/src/test/java/google/registry/model/domain/DomainBaseSqlTest.java b/core/src/test/java/google/registry/model/domain/DomainBaseSqlTest.java index aa30b99be..27a8277a5 100644 --- a/core/src/test/java/google/registry/model/domain/DomainBaseSqlTest.java +++ b/core/src/test/java/google/registry/model/domain/DomainBaseSqlTest.java @@ -53,19 +53,17 @@ import google.registry.model.transfer.ContactTransferData; import google.registry.model.transfer.DomainTransferData; import google.registry.persistence.VKey; import google.registry.testing.AppEngineExtension; -import google.registry.testing.DualDatabaseTest; import google.registry.testing.FakeClock; -import google.registry.testing.TestSqlOnly; import google.registry.util.SerializeUtils; import java.util.Arrays; import org.joda.money.Money; import org.joda.time.DateTime; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.testcontainers.shaded.com.google.common.collect.ImmutableList; /** Verify that we can store/retrieve DomainBase objects from a SQL database. */ -@DualDatabaseTest public class DomainBaseSqlTest { protected FakeClock fakeClock = new FakeClock(DateTime.now(UTC)); @@ -73,7 +71,7 @@ public class DomainBaseSqlTest { @RegisterExtension public final AppEngineExtension appEngine = AppEngineExtension.builder() - .withDatastoreAndCloudSql() + .withCloudSql() .enableJpaEntityCoverageCheck(true) .withClock(fakeClock) .build(); @@ -141,25 +139,25 @@ public class DomainBaseSqlTest { contact2 = makeContact("contact_id2"); } - @TestSqlOnly + @Test void testDomainBasePersistence() { persistDomain(); assertEqualDomainExcept(loadByKey(domain.createVKey())); } - @TestSqlOnly + @Test void testHostForeignKeyConstraints() { // Persist the domain without the associated host object. assertThrowForeignKeyViolation(() -> insertInDb(contact, contact2, domain)); } - @TestSqlOnly + @Test void testContactForeignKeyConstraints() { // Persist the domain without the associated contact objects. assertThrowForeignKeyViolation(() -> insertInDb(domain, host)); } - @TestSqlOnly + @Test void testResaveDomain_succeeds() { persistDomain(); jpaTm() @@ -172,7 +170,7 @@ public class DomainBaseSqlTest { assertEqualDomainExcept(loadByKey(domain.createVKey())); } - @TestSqlOnly + @Test void testModifyGracePeriod_setEmptyCollectionSuccessfully() { persistDomain(); jpaTm() @@ -192,7 +190,7 @@ public class DomainBaseSqlTest { }); } - @TestSqlOnly + @Test void testModifyGracePeriod_setNullCollectionSuccessfully() { persistDomain(); jpaTm() @@ -211,7 +209,7 @@ public class DomainBaseSqlTest { }); } - @TestSqlOnly + @Test void testModifyGracePeriod_addThenRemoveSuccessfully() { persistDomain(); jpaTm() @@ -267,7 +265,7 @@ public class DomainBaseSqlTest { }); } - @TestSqlOnly + @Test void testModifyGracePeriod_removeThenAddSuccessfully() { persistDomain(); jpaTm() @@ -311,7 +309,7 @@ public class DomainBaseSqlTest { }); } - @TestSqlOnly + @Test void testModifyDsData_addThenRemoveSuccessfully() { persistDomain(); DelegationSignerData extraDsData = @@ -355,7 +353,7 @@ public class DomainBaseSqlTest { }); } - @TestSqlOnly + @Test void testSerializable() { createTld("com"); insertInDb(contact, contact2, domain, host); @@ -363,7 +361,7 @@ public class DomainBaseSqlTest { assertThat(SerializeUtils.serializeDeserialize(persisted)).isEqualTo(persisted); } - @TestSqlOnly + @Test void testUpdates() { createTld("com"); insertInDb(contact, contact2, domain, host); @@ -388,7 +386,7 @@ public class DomainBaseSqlTest { insertInDb(contact, contact2, domain, host); } - @TestSqlOnly + @Test void persistDomainWithCompositeVKeys() { createTld("com"); historyEntry = @@ -515,7 +513,7 @@ public class DomainBaseSqlTest { assertThat(persisted.getGracePeriods()).isEqualTo(gracePeriods); } - @TestSqlOnly + @Test void persistDomainWithLegacyVKeys() { createTld("com"); historyEntry = @@ -676,7 +674,7 @@ public class DomainBaseSqlTest { .isEqualExceptFields(thatDomain.getTransferData(), "serverApproveEntities"); } - @TestSqlOnly + @Test void testUpdateTimeAfterNameserverUpdate() { persistDomain(); DomainBase persisted = loadByKey(domain.createVKey()); @@ -703,7 +701,7 @@ public class DomainBaseSqlTest { assertThat(domain.getUpdateTimestamp().getTimestamp()).isNotEqualTo(originalUpdateTime); } - @TestSqlOnly + @Test void testUpdateTimeAfterDsDataUpdate() { persistDomain(); DomainBase persisted = loadByKey(domain.createVKey()); diff --git a/core/src/test/java/google/registry/model/domain/DomainBaseTest.java b/core/src/test/java/google/registry/model/domain/DomainBaseTest.java index cde8e2e7e..850759afa 100644 --- a/core/src/test/java/google/registry/model/domain/DomainBaseTest.java +++ b/core/src/test/java/google/registry/model/domain/DomainBaseTest.java @@ -81,7 +81,7 @@ public class DomainBaseTest { @RegisterExtension public final AppEngineExtension appEngine = AppEngineExtension.builder() - .withDatastoreAndCloudSql() + .withCloudSql() .enableJpaEntityCoverageCheck(true) .withClock(fakeClock) .build(); diff --git a/core/src/test/java/google/registry/model/domain/GracePeriodTest.java b/core/src/test/java/google/registry/model/domain/GracePeriodTest.java index b58e6aaae..ef68e3cea 100644 --- a/core/src/test/java/google/registry/model/domain/GracePeriodTest.java +++ b/core/src/test/java/google/registry/model/domain/GracePeriodTest.java @@ -39,7 +39,7 @@ public class GracePeriodTest { @RegisterExtension public final AppEngineExtension appEngine = AppEngineExtension.builder() - .withDatastoreAndCloudSql() // Needed to be able to construct Keys. + .withCloudSql() // Needed to be able to construct Keys. .build(); private final DateTime now = DateTime.now(UTC); diff --git a/core/src/test/java/google/registry/model/domain/token/AllocationTokenTest.java b/core/src/test/java/google/registry/model/domain/token/AllocationTokenTest.java index 6b4738d7b..a2655db32 100644 --- a/core/src/test/java/google/registry/model/domain/token/AllocationTokenTest.java +++ b/core/src/test/java/google/registry/model/domain/token/AllocationTokenTest.java @@ -39,16 +39,12 @@ import google.registry.model.domain.DomainBase; import google.registry.model.domain.token.AllocationToken.TokenStatus; import google.registry.model.domain.token.AllocationToken.TokenType; import google.registry.model.reporting.HistoryEntry; -import google.registry.testing.DualDatabaseTest; -import google.registry.testing.TestOfyAndSql; -import google.registry.testing.TestOfyOnly; -import google.registry.testing.TestSqlOnly; import google.registry.util.SerializeUtils; import org.joda.time.DateTime; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; /** Unit tests for {@link AllocationToken}. */ -@DualDatabaseTest public class AllocationTokenTest extends EntityTestCase { public AllocationTokenTest() { @@ -60,7 +56,7 @@ public class AllocationTokenTest extends EntityTestCase { createTld("foo"); } - @TestOfyAndSql + @Test void testPersistence() { AllocationToken unlimitedUseToken = persistResource( @@ -96,7 +92,7 @@ public class AllocationTokenTest extends EntityTestCase { assertThat(loadByEntity(singleUseToken)).isEqualTo(singleUseToken); } - @TestSqlOnly + @Test void testSerializable() { AllocationToken unlimitedUseToken = persistResource( @@ -134,25 +130,7 @@ public class AllocationTokenTest extends EntityTestCase { assertThat(SerializeUtils.serializeDeserialize(persisted)).isEqualTo(persisted); } - @TestOfyOnly - void testIndexing() throws Exception { - DomainBase domain = persistActiveDomain("blahdomain.foo"); - Key historyEntryKey = Key.create(Key.create(domain), HistoryEntry.class, 1); - verifyDatastoreIndexing( - persistResource( - new AllocationToken.Builder() - .setToken("abc123") - .setTokenType(SINGLE_USE) - .setRedemptionHistoryEntry(HistoryEntry.createVKey(historyEntryKey)) - .setDomainName("blahdomain.foo") - .setCreationTimeForTest(DateTime.parse("2010-11-12T05:00:00Z")) - .build()), - "token", - "redemptionHistoryEntry", - "domainName"); - } - - @TestOfyAndSql + @Test void testCreationTime_autoPopulates() { AllocationToken tokenBeforePersisting = new AllocationToken.Builder().setToken("abc123").setTokenType(SINGLE_USE).build(); @@ -161,7 +139,7 @@ public class AllocationTokenTest extends EntityTestCase { assertThat(tokenAfterPersisting.getCreationTime()).hasValue(fakeClock.nowUtc()); } - @TestOfyAndSql + @Test void testGetRenewalBehavior_returnsDefaultRenewBehavior() { assertThat( persistResource( @@ -173,7 +151,7 @@ public class AllocationTokenTest extends EntityTestCase { .isEqualTo(RenewalPriceBehavior.DEFAULT); } - @TestOfyAndSql + @Test void testSetRenewalBehavior_assertsRenewalBehaviorIsNotDefault() { assertThat( persistResource( @@ -186,7 +164,7 @@ public class AllocationTokenTest extends EntityTestCase { .isEqualTo(RenewalPriceBehavior.SPECIFIED); } - @TestOfyAndSql + @Test void testSetRenewalBehavior_assertRenewalBehaviorIsModified() { AllocationToken token = persistResource( @@ -203,7 +181,7 @@ public class AllocationTokenTest extends EntityTestCase { .isEqualTo(RenewalPriceBehavior.SPECIFIED); } - @TestOfyAndSql + @Test void testSetCreationTime_cantCallMoreThanOnce() { AllocationToken.Builder builder = new AllocationToken.Builder() @@ -217,7 +195,7 @@ public class AllocationTokenTest extends EntityTestCase { assertThat(thrown).hasMessageThat().isEqualTo("Creation time can only be set once"); } - @TestOfyAndSql + @Test void testSetToken_cantCallMoreThanOnce() { AllocationToken.Builder builder = new AllocationToken.Builder().setToken("foobar"); IllegalStateException thrown = @@ -225,7 +203,7 @@ public class AllocationTokenTest extends EntityTestCase { assertThat(thrown).hasMessageThat().isEqualTo("Token can only be set once"); } - @TestOfyAndSql + @Test void testSetTokenType_cantCallMoreThanOnce() { AllocationToken.Builder builder = new AllocationToken.Builder().setTokenType(TokenType.UNLIMITED_USE); @@ -234,7 +212,7 @@ public class AllocationTokenTest extends EntityTestCase { assertThat(thrown).hasMessageThat().isEqualTo("Token type can only be set once"); } - @TestOfyAndSql + @Test void testBuild_DomainNameWithLessThanTwoParts() { IllegalArgumentException thrown = assertThrows( @@ -252,7 +230,7 @@ public class AllocationTokenTest extends EntityTestCase { assertThat(thrown).hasMessageThat().isEqualTo("Invalid domain name: example"); } - @TestOfyAndSql + @Test void testBuild_invalidTld() { IllegalArgumentException thrown = assertThrows( @@ -270,7 +248,7 @@ public class AllocationTokenTest extends EntityTestCase { assertThat(thrown).hasMessageThat().isEqualTo("Invalid domain name: example.nosuchtld"); } - @TestOfyAndSql + @Test void testBuild_domainNameOnlyOnSingleUse() { AllocationToken.Builder builder = new AllocationToken.Builder() @@ -283,7 +261,7 @@ public class AllocationTokenTest extends EntityTestCase { .isEqualTo("Domain name can only be specified for SINGLE_USE tokens"); } - @TestOfyAndSql + @Test void testBuild_redemptionHistoryEntryOnlyInSingleUse() { DomainBase domain = persistActiveDomain("blahdomain.foo"); Key historyEntryKey = Key.create(Key.create(domain), HistoryEntry.class, 1); @@ -298,7 +276,7 @@ public class AllocationTokenTest extends EntityTestCase { .isEqualTo("Redemption history entry can only be specified for SINGLE_USE tokens"); } - @TestOfyAndSql + @Test void testSetTransitions_notStartOfTime() { IllegalArgumentException thrown = assertThrows( @@ -316,7 +294,7 @@ public class AllocationTokenTest extends EntityTestCase { .isEqualTo("tokenStatusTransitions map must start at START_OF_TIME."); } - @TestOfyAndSql + @Test void testSetTransitions_badInitialValue() { IllegalArgumentException thrown = assertThrows( @@ -333,14 +311,14 @@ public class AllocationTokenTest extends EntityTestCase { .isEqualTo("tokenStatusTransitions must start with NOT_STARTED"); } - @TestOfyAndSql + @Test void testSetTransitions_invalidInitialTransitions() { // NOT_STARTED can only go to VALID or CANCELLED assertBadInitialTransition(NOT_STARTED); assertBadInitialTransition(ENDED); } - @TestOfyAndSql + @Test void testSetTransitions_badTransitionsFromValid() { // VALID can only go to ENDED or CANCELLED assertBadTransition( @@ -361,14 +339,14 @@ public class AllocationTokenTest extends EntityTestCase { NOT_STARTED); } - @TestOfyAndSql + @Test void testSetTransitions_terminalTransitions() { // both ENDED and CANCELLED are terminal assertTerminal(ENDED); assertTerminal(CANCELLED); } - @TestOfyAndSql + @Test void testSetDiscountFractionTooHigh() { IllegalArgumentException thrown = assertThrows( @@ -379,7 +357,7 @@ public class AllocationTokenTest extends EntityTestCase { .isEqualTo("Discount fraction must be between 0 and 1 inclusive"); } - @TestOfyAndSql + @Test void testSetDiscountFractionTooLow() { IllegalArgumentException thrown = assertThrows( @@ -390,7 +368,7 @@ public class AllocationTokenTest extends EntityTestCase { .isEqualTo("Discount fraction must be between 0 and 1 inclusive"); } - @TestOfyAndSql + @Test void testSetDiscountYearsTooHigh() { IllegalArgumentException thrown = assertThrows( @@ -401,7 +379,7 @@ public class AllocationTokenTest extends EntityTestCase { .isEqualTo("Discount years must be between 1 and 10 inclusive"); } - @TestOfyAndSql + @Test void testSetDiscountYearsTooLow() { IllegalArgumentException thrown = assertThrows( @@ -412,7 +390,7 @@ public class AllocationTokenTest extends EntityTestCase { .isEqualTo("Discount years must be between 1 and 10 inclusive"); } - @TestOfyAndSql + @Test void testBuild_noTokenType() { IllegalArgumentException thrown = assertThrows( @@ -421,7 +399,7 @@ public class AllocationTokenTest extends EntityTestCase { assertThat(thrown).hasMessageThat().isEqualTo("Token type must be specified"); } - @TestOfyAndSql + @Test void testBuild_noToken() { IllegalArgumentException thrown = assertThrows( @@ -430,7 +408,7 @@ public class AllocationTokenTest extends EntityTestCase { assertThat(thrown).hasMessageThat().isEqualTo("Token must not be null or empty"); } - @TestOfyAndSql + @Test void testBuild_emptyToken() { IllegalArgumentException thrown = assertThrows( @@ -439,7 +417,7 @@ public class AllocationTokenTest extends EntityTestCase { assertThat(thrown).hasMessageThat().isEqualTo("Token must not be blank"); } - @TestOfyAndSql + @Test void testBuild_discountPremiumsRequiresDiscountFraction() { IllegalArgumentException thrown = assertThrows( @@ -455,7 +433,7 @@ public class AllocationTokenTest extends EntityTestCase { .isEqualTo("Discount premiums can only be specified along with a discount fraction"); } - @TestOfyAndSql + @Test void testBuild_discountYearsRequiresDiscountFraction() { IllegalArgumentException thrown = assertThrows( diff --git a/core/src/test/java/google/registry/model/history/ContactHistoryTest.java b/core/src/test/java/google/registry/model/history/ContactHistoryTest.java index 5bc8d75ba..92b3e048f 100644 --- a/core/src/test/java/google/registry/model/history/ContactHistoryTest.java +++ b/core/src/test/java/google/registry/model/history/ContactHistoryTest.java @@ -17,14 +17,12 @@ package google.registry.model.history; import static com.google.common.truth.Truth.assertThat; import static google.registry.model.ImmutableObjectSubject.assertAboutImmutableObjects; import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm; -import static google.registry.persistence.transaction.TransactionManagerFactory.tm; import static google.registry.testing.DatabaseHelper.insertInDb; import static google.registry.testing.DatabaseHelper.loadByEntity; import static google.registry.testing.DatabaseHelper.newContactResourceWithRoid; import static java.nio.charset.StandardCharsets.UTF_8; import com.google.common.collect.ImmutableList; -import com.googlecode.objectify.Key; import google.registry.model.EntityTestCase; import google.registry.model.contact.ContactAddress; import google.registry.model.contact.ContactBase; @@ -34,21 +32,17 @@ import google.registry.model.contact.ContactResource; import google.registry.model.contact.PostalInfo; import google.registry.model.eppcommon.Trid; import google.registry.model.reporting.HistoryEntry; -import google.registry.persistence.VKey; -import google.registry.testing.DualDatabaseTest; -import google.registry.testing.TestOfyOnly; -import google.registry.testing.TestSqlOnly; import google.registry.util.SerializeUtils; +import org.junit.jupiter.api.Test; /** Tests for {@link ContactHistory}. */ -@DualDatabaseTest public class ContactHistoryTest extends EntityTestCase { ContactHistoryTest() { super(JpaEntityCoverageCheck.ENABLED); } - @TestSqlOnly + @Test void testPersistence() { ContactResource contact = newContactResourceWithRoid("contactId", "contact1"); insertInDb(contact); @@ -64,7 +58,7 @@ public class ContactHistoryTest extends EntityTestCase { }); } - @TestSqlOnly + @Test void testSerializable() { ContactResource contact = newContactResourceWithRoid("contactId", "contact1"); insertInDb(contact); @@ -76,7 +70,7 @@ public class ContactHistoryTest extends EntityTestCase { assertThat(SerializeUtils.serializeDeserialize(fromDatabase)).isEqualTo(fromDatabase); } - @TestSqlOnly + @Test void testLegacyPersistence_nullContactBase() { ContactResource contact = newContactResourceWithRoid("contactId", "contact1"); insertInDb(contact); @@ -94,29 +88,7 @@ public class ContactHistoryTest extends EntityTestCase { }); } - @TestOfyOnly - void testOfyPersistence() { - ContactResource contact = newContactResourceWithRoid("contactId", "contact1"); - tm().transact(() -> tm().insert(contact)); - VKey contactVKey = contact.createVKey(); - ContactResource contactFromDb = tm().transact(() -> tm().loadByKey(contactVKey)); - fakeClock.advanceOneMilli(); - ContactHistory contactHistory = createContactHistory(contactFromDb); - tm().transact(() -> tm().insert(contactHistory)); - - // retrieving a HistoryEntry or a ContactHistory with the same key should return the same object - // note: due to the @EntitySubclass annotation. all Keys for ContactHistory objects will have - // type HistoryEntry - VKey contactHistoryVKey = contactHistory.createVKey(); - VKey historyEntryVKey = - VKey.createOfy(HistoryEntry.class, Key.create(contactHistory.asHistoryEntry())); - ContactHistory hostHistoryFromDb = tm().transact(() -> tm().loadByKey(contactHistoryVKey)); - HistoryEntry historyEntryFromDb = tm().transact(() -> tm().loadByKey(historyEntryVKey)); - - assertThat(hostHistoryFromDb).isEqualTo(historyEntryFromDb); - } - - @TestSqlOnly + @Test void testWipeOutPii_assertsAllPiiFieldsAreNull() { ContactHistory originalEntity = createContactHistory( diff --git a/core/src/test/java/google/registry/model/history/DomainHistoryTest.java b/core/src/test/java/google/registry/model/history/DomainHistoryTest.java index 5a89c3f32..01f703b12 100644 --- a/core/src/test/java/google/registry/model/history/DomainHistoryTest.java +++ b/core/src/test/java/google/registry/model/history/DomainHistoryTest.java @@ -16,23 +16,16 @@ package google.registry.model.history; import static com.google.common.truth.Truth.assertThat; import static google.registry.model.ImmutableObjectSubject.assertAboutImmutableObjects; -import static google.registry.model.tld.Registry.TldState.GENERAL_AVAILABILITY; import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm; -import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.testing.AppEngineExtension.makeRegistrar2; import static google.registry.testing.DatabaseHelper.createTld; import static google.registry.testing.DatabaseHelper.insertInDb; import static google.registry.testing.DatabaseHelper.newContactResourceWithRoid; import static google.registry.testing.DatabaseHelper.newDomainBase; import static google.registry.testing.DatabaseHelper.newHostResourceWithRoid; -import static google.registry.testing.DatabaseHelper.putInDb; import static google.registry.util.DateTimeUtils.END_OF_TIME; -import static google.registry.util.DateTimeUtils.START_OF_TIME; import static java.nio.charset.StandardCharsets.UTF_8; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.ImmutableSortedMap; -import com.googlecode.objectify.Key; import google.registry.model.EntityTestCase; import google.registry.model.contact.ContactResource; import google.registry.model.domain.DomainBase; @@ -47,20 +40,13 @@ import google.registry.model.host.HostResource; import google.registry.model.reporting.DomainTransactionRecord; import google.registry.model.reporting.DomainTransactionRecord.TransactionReportField; import google.registry.model.reporting.HistoryEntry; -import google.registry.model.tld.Registries; -import google.registry.model.tld.Registry; -import google.registry.persistence.VKey; -import google.registry.testing.DatabaseHelper; -import google.registry.testing.DualDatabaseTest; -import google.registry.testing.TestOfyOnly; -import google.registry.testing.TestSqlOnly; import google.registry.util.SerializeUtils; import java.util.Optional; import org.joda.time.DateTime; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; /** Tests for {@link DomainHistory}. */ -@DualDatabaseTest public class DomainHistoryTest extends EntityTestCase { DomainHistoryTest() { @@ -72,7 +58,7 @@ public class DomainHistoryTest extends EntityTestCase { fakeClock.setAutoIncrementByOneMilli(); } - @TestSqlOnly + @Test void testPersistence() { DomainBase domain = addGracePeriodForSql(createDomainWithContactsAndHosts()); DomainHistory domainHistory = createDomainHistory(domain); @@ -87,7 +73,7 @@ public class DomainHistoryTest extends EntityTestCase { }); } - @TestSqlOnly + @Test void testSerializable() { DomainBase domain = addGracePeriodForSql(createDomainWithContactsAndHosts()); DomainHistory domainHistory = createDomainHistory(domain); @@ -97,7 +83,7 @@ public class DomainHistoryTest extends EntityTestCase { assertThat(SerializeUtils.serializeDeserialize(fromDatabase)).isEqualTo(fromDatabase); } - @TestSqlOnly + @Test void testLegacyPersistence_nullResource() { DomainBase domain = addGracePeriodForSql(createDomainWithContactsAndHosts()); DomainHistory domainHistory = createDomainHistory(domain).asBuilder().setDomain(null).build(); @@ -114,84 +100,6 @@ public class DomainHistoryTest extends EntityTestCase { }); } - @TestOfyOnly - void testOfyPersistence() { - HostResource host = newHostResourceWithRoid("ns1.example.com", "host1"); - ContactResource contact = newContactResourceWithRoid("contactId", "contact1"); - - tm().transact( - () -> { - tm().insert(host); - tm().insert(contact); - }); - - DomainBase domain = - newDomainBase("example.tld", "domainRepoId", contact) - .asBuilder() - .setNameservers(host.createVKey()) - .build(); - tm().transact(() -> tm().insert(domain)); - - DomainHistory domainHistory = createDomainHistory(domain); - tm().transact(() -> tm().insert(domainHistory)); - - // retrieving a HistoryEntry or a DomainHistory with the same key should return the same object - // note: due to the @EntitySubclass annotation. all Keys for DomainHistory objects will have - // type HistoryEntry - VKey domainHistoryVKey = domainHistory.createVKey(); - VKey historyEntryVKey = - VKey.createOfy(HistoryEntry.class, Key.create(domainHistory.asHistoryEntry())); - DomainHistory domainHistoryFromDb = tm().transact(() -> tm().loadByKey(domainHistoryVKey)); - HistoryEntry historyEntryFromDb = tm().transact(() -> tm().loadByKey(historyEntryVKey)); - - assertThat(domainHistoryFromDb).isEqualTo(historyEntryFromDb); - } - - @TestOfyOnly - void testDoubleWriteOfOfyResource() { - // We have to add the registry to ofy, since we're currently loading the cache from ofy. We - // also have to add it to SQL to satisfy the foreign key constraints of the registrar. - Registry registry = - DatabaseHelper.newRegistry( - "tld", "TLD", ImmutableSortedMap.of(START_OF_TIME, GENERAL_AVAILABILITY)); - tm().transact(() -> tm().insert(registry)); - Registries.resetCache(); - insertInDb( - registry, makeRegistrar2().asBuilder().setAllowedTlds(ImmutableSet.of("tld")).build()); - - HostResource host = newHostResourceWithRoid("ns1.example.com", "host1"); - ContactResource contact = newContactResourceWithRoid("contactId", "contact1"); - - // Set up the host and domain objects in both databases. - tm().transact( - () -> { - tm().insert(host); - tm().insert(contact); - }); - insertInDb(host, contact); - DomainBase domain = - newDomainBase("example.tld", "domainRepoId", contact) - .asBuilder() - .setNameservers(host.createVKey()) - .build(); - tm().transact(() -> tm().insert(domain)); - insertInDb(domain); - - DomainHistory domainHistory = createDomainHistory(domain); - tm().transact(() -> tm().insert(domainHistory)); - - // Load the DomainHistory object from the datastore. - VKey domainHistoryVKey = domainHistory.createVKey(); - DomainHistory domainHistoryFromDb = tm().transact(() -> tm().loadByKey(domainHistoryVKey)); - - // attempt to write to SQL. - insertInDb(domainHistoryFromDb); - - // Reload and rewrite. - DomainHistory domainHistoryFromDb2 = tm().transact(() -> tm().loadByKey(domainHistoryVKey)); - putInDb(domainHistoryFromDb2); - } - static DomainBase createDomainWithContactsAndHosts() { createTld("tld"); HostResource host = newHostResourceWithRoid("ns1.example.com", "host1"); diff --git a/core/src/test/java/google/registry/model/history/HostHistoryTest.java b/core/src/test/java/google/registry/model/history/HostHistoryTest.java index d02af82d2..d76d5a259 100644 --- a/core/src/test/java/google/registry/model/history/HostHistoryTest.java +++ b/core/src/test/java/google/registry/model/history/HostHistoryTest.java @@ -17,35 +17,28 @@ package google.registry.model.history; import static com.google.common.truth.Truth.assertThat; import static google.registry.model.ImmutableObjectSubject.assertAboutImmutableObjects; import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm; -import static google.registry.persistence.transaction.TransactionManagerFactory.tm; import static google.registry.testing.DatabaseHelper.insertInDb; import static google.registry.testing.DatabaseHelper.loadByEntity; import static google.registry.testing.DatabaseHelper.newHostResourceWithRoid; -import static google.registry.testing.SqlHelper.saveRegistrar; import static java.nio.charset.StandardCharsets.UTF_8; -import com.googlecode.objectify.Key; import google.registry.model.EntityTestCase; import google.registry.model.eppcommon.Trid; import google.registry.model.host.HostBase; import google.registry.model.host.HostHistory; import google.registry.model.host.HostResource; import google.registry.model.reporting.HistoryEntry; -import google.registry.persistence.VKey; -import google.registry.testing.DualDatabaseTest; -import google.registry.testing.TestOfyOnly; -import google.registry.testing.TestSqlOnly; import google.registry.util.SerializeUtils; +import org.junit.jupiter.api.Test; /** Tests for {@link HostHistory}. */ -@DualDatabaseTest public class HostHistoryTest extends EntityTestCase { HostHistoryTest() { super(JpaEntityCoverageCheck.ENABLED); } - @TestSqlOnly + @Test void testPersistence() { HostResource host = newHostResourceWithRoid("ns1.example.com", "host1"); insertInDb(host); @@ -61,7 +54,7 @@ public class HostHistoryTest extends EntityTestCase { }); } - @TestSqlOnly + @Test void testSerializable() { HostResource host = newHostResourceWithRoid("ns1.example.com", "host1"); insertInDb(host); @@ -72,7 +65,7 @@ public class HostHistoryTest extends EntityTestCase { assertThat(SerializeUtils.serializeDeserialize(fromDatabase)).isEqualTo(fromDatabase); } - @TestSqlOnly + @Test void testLegacyPersistence_nullHostBase() { HostResource host = newHostResourceWithRoid("ns1.example.com", "host1"); insertInDb(host); @@ -90,31 +83,6 @@ public class HostHistoryTest extends EntityTestCase { }); } - @TestOfyOnly - void testOfySave() { - saveRegistrar("registrar1"); - - HostResource host = newHostResourceWithRoid("ns1.example.com", "host1"); - tm().transact(() -> tm().insert(host)); - VKey hostVKey = - VKey.create(HostResource.class, "host1", Key.create(HostResource.class, "host1")); - HostResource hostFromDb = tm().transact(() -> tm().loadByKey(hostVKey)); - HostHistory hostHistory = createHostHistory(hostFromDb); - fakeClock.advanceOneMilli(); - tm().transact(() -> tm().insert(hostHistory)); - - // retrieving a HistoryEntry or a HostHistory with the same key should return the same object - // note: due to the @EntitySubclass annotation. all Keys for HostHistory objects will have - // type HistoryEntry - VKey hostHistoryVKey = hostHistory.createVKey(); - VKey historyEntryVKey = - VKey.createOfy(HistoryEntry.class, Key.create(hostHistory.asHistoryEntry())); - HostHistory hostHistoryFromDb = tm().transact(() -> tm().loadByKey(hostHistoryVKey)); - HistoryEntry historyEntryFromDb = tm().transact(() -> tm().loadByKey(historyEntryVKey)); - - assertThat(hostHistoryFromDb).isEqualTo(historyEntryFromDb); - } - private void assertHostHistoriesEqual(HostHistory one, HostHistory two) { assertAboutImmutableObjects().that(one).isEqualExceptFields(two, "hostBase"); assertAboutImmutableObjects() diff --git a/core/src/test/java/google/registry/model/history/LegacyHistoryObjectTest.java b/core/src/test/java/google/registry/model/history/LegacyHistoryObjectTest.java deleted file mode 100644 index e4487919f..000000000 --- a/core/src/test/java/google/registry/model/history/LegacyHistoryObjectTest.java +++ /dev/null @@ -1,203 +0,0 @@ -// Copyright 2020 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.model.history; - -import static com.google.common.truth.Truth.assertThat; -import static google.registry.model.ImmutableObjectSubject.assertAboutImmutableObjects; -import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm; -import static google.registry.persistence.transaction.TransactionManagerFactory.ofyTm; -import static google.registry.testing.DatabaseHelper.createTld; -import static google.registry.testing.DatabaseHelper.insertInDb; -import static google.registry.testing.DatabaseHelper.loadByKey; -import static google.registry.testing.DatabaseHelper.newContactResourceWithRoid; -import static google.registry.testing.DatabaseHelper.newHostResourceWithRoid; -import static google.registry.util.CollectionUtils.nullToEmpty; -import static java.nio.charset.StandardCharsets.UTF_8; - -import com.google.common.collect.ImmutableSet; -import com.googlecode.objectify.Key; -import google.registry.model.EntityTestCase; -import google.registry.model.EppResource; -import google.registry.model.contact.ContactHistory; -import google.registry.model.contact.ContactResource; -import google.registry.model.domain.DomainBase; -import google.registry.model.domain.DomainHistory; -import google.registry.model.domain.Period; -import google.registry.model.eppcommon.Trid; -import google.registry.model.host.HostHistory; -import google.registry.model.host.HostResource; -import google.registry.model.reporting.DomainTransactionRecord; -import google.registry.model.reporting.DomainTransactionRecord.TransactionReportField; -import google.registry.model.reporting.HistoryEntry; -import google.registry.persistence.VKey; -import google.registry.testing.DualDatabaseTest; -import google.registry.testing.TestSqlOnly; - -/** Tests to check {@link HistoryEntry} + its subclasses' transitions to/from Datastore/SQL. */ -@DualDatabaseTest -public class LegacyHistoryObjectTest extends EntityTestCase { - - public LegacyHistoryObjectTest() { - super(JpaEntityCoverageCheck.ENABLED); - } - - @TestSqlOnly - void testFullConversion_contact() { - // Create+save an old contact HistoryEntry, reload it, and verify it's a proper ContactHistory - ContactResource contact = newContactResourceWithRoid("contactId", "contact1"); - HistoryEntry legacyHistoryEntry = historyEntryBuilderFor(contact).build(); - ofyTm().transact(() -> ofyTm().insert(legacyHistoryEntry)); - - // In Datastore, we will save it as HistoryEntry but retrieve it as ContactHistory - long historyEntryId = legacyHistoryEntry.getId(); - HistoryEntry fromObjectify = - ofyTm() - .transact( - () -> - ofyTm() - .loadByKey( - VKey.create( - HistoryEntry.class, - historyEntryId, - Key.create(legacyHistoryEntry)))); - // The objects will be mostly the same, but the ContactHistory object has a couple extra fields - assertAboutImmutableObjects() - .that(legacyHistoryEntry) - .isEqualExceptFields(fromObjectify, "contactBase", "contactRepoId"); - assertThat(fromObjectify).isInstanceOf(ContactHistory.class); - ContactHistory legacyContactHistory = (ContactHistory) fromObjectify; - - // Next, save that from-Datastore object in SQL and verify we can load it back in - insertInDb(contact, legacyContactHistory); - ContactHistory legacyHistoryFromSql = loadByKey(legacyContactHistory.createVKey()); - assertAboutImmutableObjects() - .that(legacyContactHistory) - .isEqualExceptFields(legacyHistoryFromSql); - // can't compare contactRepoId directly since it doesn't save the ofy key - assertThat(legacyContactHistory.getParentVKey().getSqlKey()) - .isEqualTo(legacyHistoryFromSql.getParentVKey().getSqlKey()); - } - - @TestSqlOnly - void testFullConversion_domain() { - createTld("foobar"); - // Create+save an old domain HistoryEntry, reload it, and verify it's a proper DomainHistory - DomainBase domain = DomainHistoryTest.createDomainWithContactsAndHosts(); - HistoryEntry legacyHistoryEntry = historyEntryForDomain(domain); - ofyTm().transact(() -> ofyTm().insert(legacyHistoryEntry)); - - // In Datastore, we will save it as HistoryEntry but retrieve it as DomainHistory - long historyEntryId = legacyHistoryEntry.getId(); - HistoryEntry fromObjectify = - ofyTm() - .transact( - () -> - ofyTm() - .loadByKey( - VKey.create( - HistoryEntry.class, - historyEntryId, - Key.create(legacyHistoryEntry)))); - // The objects will be mostly the same, but the DomainHistory object has a couple extra fields - assertAboutImmutableObjects() - .that(legacyHistoryEntry) - .isEqualExceptFields( - fromObjectify, - "domainContent", - "domainRepoId", - "nsHosts", - "dsDataHistories", - "gracePeriodHistories"); - assertThat(fromObjectify).isInstanceOf(DomainHistory.class); - DomainHistory legacyDomainHistory = (DomainHistory) fromObjectify; - - // Next, save that from-Datastore object in SQL and verify we can load it back in - insertInDb(legacyDomainHistory); - jpaTm() - .transact( - () -> { - DomainHistory legacyHistoryFromSql = - jpaTm().loadByKey(legacyDomainHistory.createVKey()); - // Don't compare nsHosts directly because one is null and the other is empty - assertAboutImmutableObjects() - .that(legacyDomainHistory) - .isEqualExceptFields(legacyHistoryFromSql, "nsHosts"); - assertThat(nullToEmpty(legacyDomainHistory.getNsHosts())) - .isEqualTo(nullToEmpty(legacyHistoryFromSql.getNsHosts())); - }); - } - - @TestSqlOnly - void testFullConversion_host() { - // Create+save an old host HistoryEntry, reload it, and verify it's a proper HostHistory - HostResource host = newHostResourceWithRoid("hs1.example.com", "host1"); - HistoryEntry legacyHistoryEntry = historyEntryBuilderFor(host).build(); - ofyTm().transact(() -> ofyTm().insert(legacyHistoryEntry)); - - // In Datastore, we will save it as HistoryEntry but retrieve it as HostHistory - long historyEntryId = legacyHistoryEntry.getId(); - HistoryEntry fromObjectify = - ofyTm() - .transact( - () -> - ofyTm() - .loadByKey( - VKey.create( - HistoryEntry.class, - historyEntryId, - Key.create(legacyHistoryEntry)))); - // The objects will be mostly the same, but the HostHistory object has a couple extra fields - assertAboutImmutableObjects() - .that(legacyHistoryEntry) - .isEqualExceptFields(fromObjectify, "hostBase", "hostRepoId"); - assertThat(fromObjectify).isInstanceOf(HostHistory.class); - HostHistory legacyHostHistory = (HostHistory) fromObjectify; - - // Next, save that from-Datastore object in SQL and verify we can load it back in - insertInDb(host, legacyHostHistory); - HostHistory legacyHistoryFromSql = loadByKey(legacyHostHistory.createVKey()); - assertAboutImmutableObjects().that(legacyHostHistory).isEqualExceptFields(legacyHistoryFromSql); - // can't compare hostRepoId directly since it doesn't save the ofy key in SQL - assertThat(legacyHostHistory.getParentVKey().getSqlKey()) - .isEqualTo(legacyHistoryFromSql.getParentVKey().getSqlKey()); - } - - private HistoryEntry historyEntryForDomain(DomainBase domain) { - DomainTransactionRecord transactionRecord = - new DomainTransactionRecord.Builder() - .setTld("foobar") - .setReportingTime(fakeClock.nowUtc()) - .setReportField(TransactionReportField.NET_ADDS_1_YR) - .setReportAmount(1) - .build(); - return historyEntryBuilderFor(domain) - .setPeriod(Period.create(1, Period.Unit.YEARS)) - .setDomainTransactionRecords(ImmutableSet.of(transactionRecord)) - .setOtherRegistrarId("TheRegistrar") - .build(); - } - - private HistoryEntry.Builder historyEntryBuilderFor(EppResource parent) { - return HistoryEntry.createBuilderForResource(parent) - .setType(HistoryEntry.Type.DOMAIN_CREATE) - .setXmlBytes("".getBytes(UTF_8)) - .setModificationTime(fakeClock.nowUtc()) - .setRegistrarId("TheRegistrar") - .setTrid(Trid.create("ABC-123", "server-trid")) - .setBySuperuser(false) - .setReason("reason") - .setRequestedByRegistrar(false); - } -} diff --git a/core/src/test/java/google/registry/model/host/HostResourceTest.java b/core/src/test/java/google/registry/model/host/HostResourceTest.java index 2e0b05a75..763ca27b3 100644 --- a/core/src/test/java/google/registry/model/host/HostResourceTest.java +++ b/core/src/test/java/google/registry/model/host/HostResourceTest.java @@ -15,8 +15,6 @@ package google.registry.model.host; import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.Truth8.assertThat; -import static google.registry.model.EppResourceUtils.loadByForeignKey; import static google.registry.model.ImmutableObjectSubject.immutableObjectCorrespondence; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; import static google.registry.testing.DatabaseHelper.cloneAndSetAutoTimestamps; @@ -37,16 +35,12 @@ import google.registry.model.eppcommon.StatusValue; import google.registry.model.eppcommon.Trid; import google.registry.model.transfer.DomainTransferData; import google.registry.model.transfer.TransferStatus; -import google.registry.testing.DualDatabaseTest; -import google.registry.testing.TestOfyAndSql; -import google.registry.testing.TestOfyOnly; -import google.registry.testing.TestSqlOnly; import google.registry.util.SerializeUtils; import org.joda.time.DateTime; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; /** Unit tests for {@link HostResource}. */ -@DualDatabaseTest class HostResourceTest extends EntityTestCase { private final DateTime day3 = fakeClock.nowUtc(); @@ -92,14 +86,14 @@ class HostResourceTest extends EntityTestCase { .build())); } - @TestOfyAndSql + @Test void testHostBaseToHostResource() { ImmutableObjectSubject.assertAboutImmutableObjects() .that(new HostResource.Builder().copyFrom(host).build()) .isEqualExceptFields(host, "updateTimestamp", "revisions"); } - @TestOfyAndSql + @Test void testPersistence() { HostResource newHost = host.asBuilder().setRepoId("NEWHOST").build(); tm().transact(() -> tm().insert(newHost)); @@ -108,7 +102,7 @@ class HostResourceTest extends EntityTestCase { .containsExactly(newHost); } - @TestSqlOnly + @Test void testSerializable() { HostResource newHost = host.asBuilder().setRepoId("NEWHOST").build(); tm().transact(() -> tm().insert(newHost)); @@ -116,26 +110,7 @@ class HostResourceTest extends EntityTestCase { assertThat(SerializeUtils.serializeDeserialize(persisted)).isEqualTo(persisted); } - @TestOfyOnly - void testLoadingByForeignKey() { - assertThat(loadByForeignKey(HostResource.class, host.getForeignKey(), fakeClock.nowUtc())) - .hasValue(host); - } - - @TestOfyOnly - void testIndexing() throws Exception { - // Clone it and save it before running the indexing test so that its transferData fields are - // populated from the superordinate domain. - verifyDatastoreIndexing( - persistResource(host), - "deletionTime", - "fullyQualifiedHostName", - "inetAddresses", - "superordinateDomain", - "currentSponsorClientId"); - } - - @TestOfyAndSql + @Test void testEmptyStringsBecomeNull() { assertThat( new HostResource.Builder() @@ -157,7 +132,7 @@ class HostResourceTest extends EntityTestCase { .isNotNull(); } - @TestOfyAndSql + @Test void testEmptySetsBecomeNull() { assertThat(new HostResource.Builder().setInetAddresses(null).build().inetAddresses).isNull(); assertThat(new HostResource.Builder().setInetAddresses(ImmutableSet.of()).build().inetAddresses) @@ -170,7 +145,7 @@ class HostResourceTest extends EntityTestCase { .isNotNull(); } - @TestOfyAndSql + @Test void testImplicitStatusValues() { // OK is implicit if there's no other statuses. assertAboutHosts() @@ -192,13 +167,13 @@ class HostResourceTest extends EntityTestCase { .hasExactlyStatusValues(StatusValue.CLIENT_HOLD); } - @TestOfyAndSql + @Test void testToHydratedString_notCircular() { // If there are circular references, this will overflow the stack. host.toHydratedString(); } - @TestOfyAndSql + @Test void testFailure_uppercaseHostName() { IllegalArgumentException thrown = assertThrows( @@ -208,7 +183,7 @@ class HostResourceTest extends EntityTestCase { .isEqualTo("Host name AAA.BBB.CCC not in puny-coded, lower-case form"); } - @TestOfyAndSql + @Test void testFailure_utf8HostName() { IllegalArgumentException thrown = assertThrows( @@ -218,14 +193,14 @@ class HostResourceTest extends EntityTestCase { .isEqualTo("Host name みんな.みんな.みんな not in puny-coded, lower-case form"); } - @TestOfyAndSql + @Test void testComputeLastTransferTime_hostNeverSwitchedDomains_domainWasNeverTransferred() { domain = domain.asBuilder().setLastTransferTime(null).build(); host = host.asBuilder().setLastTransferTime(null).setLastSuperordinateChange(null).build(); assertThat(host.computeLastTransferTime(domain)).isNull(); } - @TestOfyAndSql + @Test void testComputeLastTransferTime_hostNeverSwitchedDomains_domainWasTransferred() { // Host was created on Day 1. // Domain was transferred on Day 2. @@ -240,7 +215,7 @@ class HostResourceTest extends EntityTestCase { assertThat(host.computeLastTransferTime(domain)).isEqualTo(day2); } - @TestOfyAndSql + @Test void testComputeLastTransferTime_hostCreatedAfterDomainWasTransferred() { // Domain was transferred on Day 1. // Host was created subordinate to domain on Day 2. @@ -262,7 +237,7 @@ class HostResourceTest extends EntityTestCase { assertThat(host.computeLastTransferTime(domain)).isNull(); } - @TestOfyAndSql + @Test void testComputeLastTransferTime_hostWasTransferred_domainWasNeverTransferred() { // Host was transferred on Day 1. // Host was made subordinate to domain on Day 2. @@ -272,7 +247,7 @@ class HostResourceTest extends EntityTestCase { assertThat(host.computeLastTransferTime(domain)).isEqualTo(day1); } - @TestOfyAndSql + @Test void testComputeLastTransferTime_domainWasTransferredBeforeHostBecameSubordinate() { // Host was transferred on Day 1. // Domain was transferred on Day 2. @@ -282,7 +257,7 @@ class HostResourceTest extends EntityTestCase { assertThat(host.computeLastTransferTime(domain)).isEqualTo(day1); } - @TestOfyAndSql + @Test void testComputeLastTransferTime_domainWasTransferredAfterHostBecameSubordinate() { // Host was transferred on Day 1. // Host was made subordinate to domain on Day 2. diff --git a/core/src/test/java/google/registry/model/index/ForeignKeyIndexTest.java b/core/src/test/java/google/registry/model/index/ForeignKeyIndexTest.java index 6f0f5865f..f0c3a8c19 100644 --- a/core/src/test/java/google/registry/model/index/ForeignKeyIndexTest.java +++ b/core/src/test/java/google/registry/model/index/ForeignKeyIndexTest.java @@ -15,35 +15,24 @@ package google.registry.model.index; import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.Truth8.assertThat; -import static google.registry.model.EppResourceUtils.loadByForeignKey; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; import static google.registry.testing.DatabaseHelper.createTld; -import static google.registry.testing.DatabaseHelper.deleteResource; import static google.registry.testing.DatabaseHelper.newDomainBase; -import static google.registry.testing.DatabaseHelper.persistActiveContact; import static google.registry.testing.DatabaseHelper.persistActiveHost; -import static google.registry.testing.DatabaseHelper.persistDeletedHost; import static google.registry.testing.DatabaseHelper.persistResource; -import static google.registry.util.DateTimeUtils.END_OF_TIME; import com.google.common.collect.ImmutableList; import google.registry.model.EntityTestCase; -import google.registry.model.contact.ContactResource; import google.registry.model.domain.DomainBase; import google.registry.model.host.HostResource; import google.registry.model.index.ForeignKeyIndex.ForeignKeyHostIndex; -import google.registry.testing.DualDatabaseTest; import google.registry.testing.TestCacheExtension; -import google.registry.testing.TestOfyAndSql; -import google.registry.testing.TestOfyOnly; -import google.registry.testing.TestSqlOnly; import java.time.Duration; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; /** Unit tests for {@link ForeignKeyIndex}. */ -@DualDatabaseTest class ForeignKeyIndexTest extends EntityTestCase { @RegisterExtension @@ -55,7 +44,7 @@ class ForeignKeyIndexTest extends EntityTestCase { createTld("com"); } - @TestSqlOnly + @Test void testModifyForeignKeyIndex_notThrowExceptionInSql() { DomainBase domainBase = newDomainBase("test.com"); ForeignKeyIndex fki = ForeignKeyIndex.create(domainBase, fakeClock.nowUtc()); @@ -65,32 +54,13 @@ class ForeignKeyIndexTest extends EntityTestCase { tm().transact(() -> tm().update(fki)); } - @TestOfyOnly - void testPersistence() { - // Persist a host and implicitly persist a ForeignKeyIndex for it. - HostResource host = persistActiveHost("ns1.example.com"); - ForeignKeyIndex fki = - ForeignKeyIndex.load(HostResource.class, "ns1.example.com", fakeClock.nowUtc()); - assertThat(tm().loadByKey(fki.getResourceKey())).isEqualTo(host); - assertThat(fki.getDeletionTime()).isEqualTo(END_OF_TIME); - } - - @TestOfyOnly - void testIndexing() throws Exception { - // Persist a host and implicitly persist a ForeignKeyIndex for it. - persistActiveHost("ns1.example.com"); - verifyDatastoreIndexing( - ForeignKeyIndex.load(HostResource.class, "ns1.example.com", fakeClock.nowUtc()), - "deletionTime"); - } - - @TestOfyAndSql + @Test void testLoadForNonexistentForeignKey_returnsNull() { assertThat(ForeignKeyIndex.load(HostResource.class, "ns1.example.com", fakeClock.nowUtc())) .isNull(); } - @TestOfyAndSql + @Test void testLoadForDeletedForeignKey_returnsNull() { HostResource host = persistActiveHost("ns1.example.com"); if (tm().isOfy()) { @@ -102,7 +72,7 @@ class ForeignKeyIndexTest extends EntityTestCase { .isNull(); } - @TestOfyAndSql + @Test void testLoad_newerKeyHasBeenSoftDeleted() { HostResource host1 = persistActiveHost("ns1.example.com"); fakeClock.advanceOneMilli(); @@ -119,7 +89,7 @@ class ForeignKeyIndexTest extends EntityTestCase { .isNull(); } - @TestOfyAndSql + @Test void testBatchLoad_skipsDeletedAndNonexistent() { persistActiveHost("ns1.example.com"); HostResource host = persistActiveHost("ns2.example.com"); @@ -137,130 +107,10 @@ class ForeignKeyIndexTest extends EntityTestCase { .containsExactly("ns1.example.com"); } - @TestOfyAndSql + @Test void testDeadCodeThatDeletedScrapCommandsReference() { persistActiveHost("omg"); assertThat(ForeignKeyIndex.load(HostResource.class, "omg", fakeClock.nowUtc()).getForeignKey()) .isEqualTo("omg"); } - - private ForeignKeyIndex loadHostFki(String hostname) { - return ForeignKeyIndex.load(HostResource.class, hostname, fakeClock.nowUtc()); - } - - private ForeignKeyIndex loadContactFki(String contactId) { - return ForeignKeyIndex.load(ContactResource.class, contactId, fakeClock.nowUtc()); - } - - @TestOfyOnly - void test_loadCached_cachesNonexistenceOfHosts() { - assertThat( - ForeignKeyIndex.loadCached( - HostResource.class, - ImmutableList.of("ns5.example.com", "ns6.example.com"), - fakeClock.nowUtc())) - .isEmpty(); - persistActiveHost("ns4.example.com"); - persistActiveHost("ns5.example.com"); - persistActiveHost("ns6.example.com"); - fakeClock.advanceOneMilli(); - assertThat( - ForeignKeyIndex.loadCached( - HostResource.class, - ImmutableList.of("ns6.example.com", "ns5.example.com", "ns4.example.com"), - fakeClock.nowUtc())) - .containsExactly("ns4.example.com", loadHostFki("ns4.example.com")); - } - - @TestOfyOnly - void test_loadCached_cachesExistenceOfHosts() { - HostResource host1 = persistActiveHost("ns1.example.com"); - HostResource host2 = persistActiveHost("ns2.example.com"); - assertThat( - ForeignKeyIndex.loadCached( - HostResource.class, - ImmutableList.of("ns1.example.com", "ns2.example.com"), - fakeClock.nowUtc())) - .containsExactly( - "ns1.example.com", - loadHostFki("ns1.example.com"), - "ns2.example.com", - loadHostFki("ns2.example.com")); - deleteResource(host1); - deleteResource(host2); - persistActiveHost("ns3.example.com"); - assertThat( - ForeignKeyIndex.loadCached( - HostResource.class, - ImmutableList.of("ns3.example.com", "ns2.example.com", "ns1.example.com"), - fakeClock.nowUtc())) - .containsExactly( - "ns1.example.com", loadHostFki("ns1.example.com"), - "ns2.example.com", loadHostFki("ns2.example.com"), - "ns3.example.com", loadHostFki("ns3.example.com")); - } - - @TestOfyOnly - void test_loadCached_doesntSeeHostChangesWhileCacheIsValid() { - HostResource originalHost = persistActiveHost("ns1.example.com"); - ForeignKeyIndex originalFki = loadHostFki("ns1.example.com"); - fakeClock.advanceOneMilli(); - assertThat( - ForeignKeyIndex.loadCached( - HostResource.class, ImmutableList.of("ns1.example.com"), fakeClock.nowUtc())) - .containsExactly("ns1.example.com", originalFki); - HostResource modifiedHost = - persistResource( - originalHost - .asBuilder() - .setPersistedCurrentSponsorRegistrarId("OtherRegistrar") - .build()); - fakeClock.advanceOneMilli(); - ForeignKeyIndex newFki = loadHostFki("ns1.example.com"); - assertThat(newFki).isNotEqualTo(originalFki); - assertThat(loadByForeignKey(HostResource.class, "ns1.example.com", fakeClock.nowUtc())) - .hasValue(modifiedHost); - assertThat( - ForeignKeyIndex.loadCached( - HostResource.class, ImmutableList.of("ns1.example.com"), fakeClock.nowUtc())) - .containsExactly("ns1.example.com", originalFki); - } - - @TestOfyOnly - void test_loadCached_filtersOutSoftDeletedHosts() { - persistActiveHost("ns1.example.com"); - persistDeletedHost("ns2.example.com", fakeClock.nowUtc().minusDays(1)); - assertThat( - ForeignKeyIndex.loadCached( - HostResource.class, - ImmutableList.of("ns1.example.com", "ns2.example.com"), - fakeClock.nowUtc())) - .containsExactly("ns1.example.com", loadHostFki("ns1.example.com")); - } - - @TestOfyOnly - void test_loadCached_cachesContactFkis() { - persistActiveContact("contactid1"); - ForeignKeyIndex fki1 = loadContactFki("contactid1"); - assertThat( - ForeignKeyIndex.loadCached( - ContactResource.class, - ImmutableList.of("contactid1", "contactid2"), - fakeClock.nowUtc())) - .containsExactly("contactid1", fki1); - persistActiveContact("contactid2"); - deleteResource(fki1); - assertThat( - ForeignKeyIndex.loadCached( - ContactResource.class, - ImmutableList.of("contactid1", "contactid2"), - fakeClock.nowUtc())) - .containsExactly("contactid1", fki1); - assertThat( - ForeignKeyIndex.load( - ContactResource.class, - ImmutableList.of("contactid1", "contactid2"), - fakeClock.nowUtc())) - .containsExactly("contactid2", loadContactFki("contactid2")); - } } diff --git a/core/src/test/java/google/registry/model/ofy/DatastoreTransactionManagerTest.java b/core/src/test/java/google/registry/model/ofy/DatastoreTransactionManagerTest.java deleted file mode 100644 index 40ae13d9b..000000000 --- a/core/src/test/java/google/registry/model/ofy/DatastoreTransactionManagerTest.java +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2021 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.model.ofy; - -import static com.google.common.truth.Truth.assertThat; -import static google.registry.model.common.EntityGroupRoot.getCrossTldKey; -import static google.registry.persistence.transaction.TransactionManagerFactory.ofyTm; -import static google.registry.testing.DatabaseHelper.persistResources; - -import com.google.common.collect.ImmutableList; -import com.googlecode.objectify.Key; -import com.googlecode.objectify.annotation.Entity; -import com.googlecode.objectify.annotation.Id; -import com.googlecode.objectify.annotation.Parent; -import google.registry.model.ImmutableObject; -import google.registry.model.annotations.InCrossTld; -import google.registry.model.common.EntityGroupRoot; -import google.registry.testing.AppEngineExtension; -import google.registry.testing.TmOverrideExtension; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Order; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; - -/** Unit tests for {@link DatastoreTransactionManager}. */ -@Disabled -public class DatastoreTransactionManagerTest { - - @RegisterExtension - @Order(Order.DEFAULT - 1) - TmOverrideExtension tmOverrideExtension = TmOverrideExtension.withOfy(); - - @RegisterExtension - public final AppEngineExtension appEngine = - AppEngineExtension.builder() - .withDatastoreAndCloudSql() - .withOfyTestEntities(InCrossTldTestEntity.class) - .build(); - - @Test - void test_loadAllOf_usesAncestorQuery() { - InCrossTldTestEntity foo = new InCrossTldTestEntity("foo"); - InCrossTldTestEntity bar = new InCrossTldTestEntity("bar"); - InCrossTldTestEntity baz = new InCrossTldTestEntity("baz"); - baz.parent = null; - persistResources(ImmutableList.of(foo, bar, baz)); - // baz is excluded by the cross-TLD ancestor query - assertThat(ofyTm().loadAllOf(InCrossTldTestEntity.class)).containsExactly(foo, bar); - } - - @Entity - @InCrossTld - private static class InCrossTldTestEntity extends ImmutableObject { - - @Id String name; - @Parent Key parent = getCrossTldKey(); - - private InCrossTldTestEntity(String name) { - this.name = name; - } - - // Needs to exist to make Objectify happy. - @SuppressWarnings("unused") - private InCrossTldTestEntity() {} - } -} diff --git a/core/src/test/java/google/registry/model/ofy/ObjectifyServiceTest.java b/core/src/test/java/google/registry/model/ofy/ObjectifyServiceTest.java index 00dedd08e..4402d2091 100644 --- a/core/src/test/java/google/registry/model/ofy/ObjectifyServiceTest.java +++ b/core/src/test/java/google/registry/model/ofy/ObjectifyServiceTest.java @@ -22,8 +22,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; public class ObjectifyServiceTest { @RegisterExtension - public final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().build(); + public final AppEngineExtension appEngine = AppEngineExtension.builder().withCloudSql().build(); @Test void test_initOfy_canBeCalledTwice() { diff --git a/core/src/test/java/google/registry/model/ofy/OfyTest.java b/core/src/test/java/google/registry/model/ofy/OfyTest.java index 274f207c9..fefc8fb1c 100644 --- a/core/src/test/java/google/registry/model/ofy/OfyTest.java +++ b/core/src/test/java/google/registry/model/ofy/OfyTest.java @@ -20,11 +20,9 @@ import static com.google.common.util.concurrent.Uninterruptibles.sleepUninterrup import static google.registry.model.ImmutableObjectSubject.assertAboutImmutableObjects; import static google.registry.model.common.EntityGroupRoot.getCrossTldKey; import static google.registry.model.ofy.ObjectifyService.auditedOfy; +import static google.registry.model.ofy.ObjectifyService.ofy; import static google.registry.model.ofy.Ofy.getBaseEntityClassFromEntityOrKey; -import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.testing.DatabaseHelper.createTld; import static google.registry.testing.DatabaseHelper.newContactResource; -import static google.registry.testing.DatabaseHelper.persistActiveContact; import static google.registry.util.DateTimeUtils.END_OF_TIME; import static google.registry.util.DateTimeUtils.START_OF_TIME; import static java.nio.charset.StandardCharsets.UTF_8; @@ -43,20 +41,16 @@ import com.googlecode.objectify.annotation.Parent; import google.registry.model.ImmutableObject; import google.registry.model.contact.ContactHistory; import google.registry.model.contact.ContactResource; -import google.registry.model.domain.DomainBase; import google.registry.model.eppcommon.Trid; import google.registry.model.reporting.HistoryEntry; import google.registry.testing.AppEngineExtension; -import google.registry.testing.DatabaseHelper; import google.registry.testing.FakeClock; -import google.registry.testing.TmOverrideExtension; import google.registry.util.SystemClock; import java.util.ConcurrentModificationException; import java.util.function.Supplier; import org.joda.time.DateTime; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -66,26 +60,21 @@ public class OfyTest { private final FakeClock fakeClock = new FakeClock(DateTime.parse("2000-01-01TZ")); - @RegisterExtension - @Order(Order.DEFAULT - 1) - TmOverrideExtension tmOverrideExtension = TmOverrideExtension.withOfy(); - @RegisterExtension public final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().withClock(fakeClock).build(); + AppEngineExtension.builder().withCloudSql().withClock(fakeClock).build(); /** An entity to use in save and delete tests. */ private HistoryEntry someObject; @BeforeEach void beforeEach() { - createTld("tld"); someObject = new ContactHistory.Builder() .setRegistrarId("clientid") .setModificationTime(START_OF_TIME) .setType(HistoryEntry.Type.CONTACT_CREATE) - .setContact(persistActiveContact("parentContact")) + .setContact(newContactResource("parentContact")) .setTrid(Trid.create("client", "server")) .setXmlBytes("".getBytes(UTF_8)) .build(); @@ -96,7 +85,7 @@ public class OfyTest { void testSavingKeyTwiceInOneCall() { assertThrows( IllegalArgumentException.class, - () -> tm().transact(() -> auditedOfy().save().entities(someObject, someObject))); + () -> ofy().transact(() -> auditedOfy().save().entities(someObject, someObject))); } /** Simple entity class with lifecycle callbacks. */ @@ -134,7 +123,7 @@ public class OfyTest { void testLifecycleCallbacks_loadFromDatastore() { auditedOfy().factory().register(LifecycleObject.class); final LifecycleObject object = new LifecycleObject(); - tm().transact(() -> auditedOfy().save().entity(object).now()); + ofy().transact(() -> auditedOfy().save().entity(object).now()); assertThat(object.onSaveCalled).isTrue(); auditedOfy().clearSessionCache(); assertThat(auditedOfy().load().entity(object).now().onLoadCalled).isTrue(); @@ -143,7 +132,8 @@ public class OfyTest { /** Avoid regressions of b/21309102 where transaction time did not change on each retry. */ @Test void testTransact_getsNewTimestampOnEachTry() { - tm().transact( + ofy() + .transact( new Runnable() { DateTime firstAttemptTime; @@ -152,11 +142,11 @@ public class OfyTest { public void run() { if (firstAttemptTime == null) { // Sleep a bit to ensure that the next attempt is at a new millisecond. - firstAttemptTime = tm().getTransactionTime(); + firstAttemptTime = ofy().getTransactionTime(); sleepUninterruptibly(java.time.Duration.ofMillis(10)); throw new ConcurrentModificationException(); } - assertThat(tm().getTransactionTime()).isGreaterThan(firstAttemptTime); + assertThat(ofy().getTransactionTime()).isGreaterThan(firstAttemptTime); } }); } @@ -164,7 +154,8 @@ public class OfyTest { @Test void testTransact_transientFailureException_retries() { assertThat( - tm().transact( + ofy() + .transact( new Supplier() { int count = 0; @@ -184,7 +175,8 @@ public class OfyTest { @Test void testTransact_datastoreTimeoutException_noManifest_retries() { assertThat( - tm().transact( + ofy() + .transact( new Supplier() { int count = 0; @@ -207,7 +199,8 @@ public class OfyTest { @Test void testTransact_datastoreTimeoutException_manifestNotWrittenToDatastore_retries() { assertThat( - tm().transact( + ofy() + .transact( new Supplier() { int count = 0; @@ -266,7 +259,8 @@ public class OfyTest { void doReadOnlyRetryTest(final RuntimeException e) { assertThat( - tm().transactNewReadOnly( + ofy() + .transactNewReadOnly( new Supplier() { int count = 0; @@ -306,13 +300,6 @@ public class OfyTest { .isEqualTo(ContactResource.class); } - @Test - void test_getBaseEntityClassFromEntityOrKey_subclassEntity() { - DomainBase domain = DatabaseHelper.newDomainBase("test.tld"); - assertThat(getBaseEntityClassFromEntityOrKey(domain)).isEqualTo(DomainBase.class); - assertThat(getBaseEntityClassFromEntityOrKey(Key.create(domain))).isEqualTo(DomainBase.class); - } - @Test void test_getBaseEntityClassFromEntityOrKey_unregisteredEntity() { IllegalStateException thrown = diff --git a/core/src/test/java/google/registry/model/poll/PollMessageExternalKeyConverterTest.java b/core/src/test/java/google/registry/model/poll/PollMessageExternalKeyConverterTest.java index b2a309d7e..7bab0ac00 100644 --- a/core/src/test/java/google/registry/model/poll/PollMessageExternalKeyConverterTest.java +++ b/core/src/test/java/google/registry/model/poll/PollMessageExternalKeyConverterTest.java @@ -34,21 +34,18 @@ import google.registry.model.reporting.HistoryEntry; import google.registry.persistence.VKey; import google.registry.testing.AppEngineExtension; import google.registry.testing.DatabaseHelper; -import google.registry.testing.DualDatabaseTest; import google.registry.testing.FakeClock; import google.registry.testing.InjectExtension; -import google.registry.testing.TestOfyAndSql; import org.joda.time.DateTime; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; /** Unit tests for {@link PollMessageExternalKeyConverter}. */ -@DualDatabaseTest public class PollMessageExternalKeyConverterTest { @RegisterExtension - public final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().build(); + public final AppEngineExtension appEngine = AppEngineExtension.builder().withCloudSql().build(); @RegisterExtension public InjectExtension inject = new InjectExtension(); @@ -75,7 +72,7 @@ public class PollMessageExternalKeyConverterTest { .build()); } - @TestOfyAndSql + @Test void testSuccess_domain() { PollMessage.OneTime pollMessage = persistResource( @@ -89,7 +86,7 @@ public class PollMessageExternalKeyConverterTest { assertVKeysEqual(parsePollMessageExternalId("1-2-FOOBAR-4-5-2007"), pollMessage.createVKey()); } - @TestOfyAndSql + @Test void testSuccess_contact() { historyEntry = persistResource( @@ -106,7 +103,7 @@ public class PollMessageExternalKeyConverterTest { assertVKeysEqual(parsePollMessageExternalId("2-5-ROID-6-7-2007"), pollMessage.createVKey()); } - @TestOfyAndSql + @Test void testSuccess_host() { historyEntry = persistResource( @@ -123,14 +120,14 @@ public class PollMessageExternalKeyConverterTest { assertVKeysEqual(parsePollMessageExternalId("3-5-ROID-6-7-2007"), pollMessage.createVKey()); } - @TestOfyAndSql + @Test void testFailure_missingYearField() { assertThrows( PollMessageExternalKeyParseException.class, () -> parsePollMessageExternalId("1-2-FOOBAR-4-5")); } - @TestOfyAndSql + @Test void testFailure_invalidEppResourceTypeId() { // Populate the testdata correctly as for 1-2-FOOBAR-4-5 so we know that the only thing that // is wrong here is the EppResourceTypeId. @@ -140,21 +137,21 @@ public class PollMessageExternalKeyConverterTest { () -> parsePollMessageExternalId("4-2-FOOBAR-4-5-2007")); } - @TestOfyAndSql + @Test void testFailure_tooFewComponentParts() { assertThrows( PollMessageExternalKeyParseException.class, () -> parsePollMessageExternalId("1-3-EXAMPLE")); } - @TestOfyAndSql + @Test void testFailure_tooManyComponentParts() { assertThrows( PollMessageExternalKeyParseException.class, () -> parsePollMessageExternalId("1-3-EXAMPLE-4-5-2007-2009")); } - @TestOfyAndSql + @Test void testFailure_nonNumericIds() { assertThrows( PollMessageExternalKeyParseException.class, diff --git a/core/src/test/java/google/registry/model/poll/PollMessageTest.java b/core/src/test/java/google/registry/model/poll/PollMessageTest.java index b4a181bcf..6c33482d8 100644 --- a/core/src/test/java/google/registry/model/poll/PollMessageTest.java +++ b/core/src/test/java/google/registry/model/poll/PollMessageTest.java @@ -34,15 +34,11 @@ import google.registry.model.eppcommon.Trid; import google.registry.model.poll.PendingActionNotificationResponse.HostPendingActionNotificationResponse; import google.registry.model.reporting.HistoryEntry; import google.registry.persistence.VKey; -import google.registry.testing.DualDatabaseTest; -import google.registry.testing.TestOfyAndSql; -import google.registry.testing.TestOfyOnly; -import google.registry.testing.TestSqlOnly; import google.registry.util.SerializeUtils; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; /** Unit tests for {@link PollMessage}. */ -@DualDatabaseTest public class PollMessageTest extends EntityTestCase { private DomainBase domain; @@ -94,7 +90,7 @@ public class PollMessageTest extends EntityTestCase { .build(); } - @TestSqlOnly + @Test void testCloudSqlSupportForPolymorphicVKey() { insertInDb(oneTime); PollMessage persistedOneTime = loadByKey(VKey.createSql(PollMessage.class, oneTime.getId())); @@ -108,7 +104,7 @@ public class PollMessageTest extends EntityTestCase { assertThat(persistedAutoRenew).isEqualTo(autoRenew); } - @TestOfyAndSql + @Test void testPersistenceOneTime() { PollMessage.OneTime pollMessage = persistResource( @@ -121,7 +117,7 @@ public class PollMessageTest extends EntityTestCase { assertThat(tm().transact(() -> tm().loadByEntity(pollMessage))).isEqualTo(pollMessage); } - @TestOfyAndSql + @Test void testPersistenceOneTime_hostPendingActionNotification() { HostPendingActionNotificationResponse hostPendingActionNotificationResponse = HostPendingActionNotificationResponse.create( @@ -146,7 +142,7 @@ public class PollMessageTest extends EntityTestCase { .isEqualTo(hostPendingActionNotificationResponse); } - @TestSqlOnly + @Test void testSerializableOneTime() { PollMessage.OneTime pollMessage = persistResource( @@ -160,7 +156,7 @@ public class PollMessageTest extends EntityTestCase { assertThat(SerializeUtils.serializeDeserialize(persisted)).isEqualTo(persisted); } - @TestOfyAndSql + @Test void testPersistenceAutorenew() { PollMessage.Autorenew pollMessage = persistResource( @@ -175,7 +171,7 @@ public class PollMessageTest extends EntityTestCase { assertThat(tm().transact(() -> tm().loadByEntity(pollMessage))).isEqualTo(pollMessage); } - @TestSqlOnly + @Test void testSerializableAutorenew() { PollMessage.Autorenew pollMessage = persistResource( @@ -190,19 +186,4 @@ public class PollMessageTest extends EntityTestCase { PollMessage persisted = tm().transact(() -> tm().loadByEntity(pollMessage)); assertThat(SerializeUtils.serializeDeserialize(persisted)).isEqualTo(persisted); } - - @TestOfyOnly - void testIndexingAutorenew() throws Exception { - PollMessage.Autorenew pollMessage = - persistResource( - new PollMessage.Autorenew.Builder() - .setRegistrarId("TheRegistrar") - .setEventTime(fakeClock.nowUtc()) - .setMsg("Test poll message") - .setHistoryEntry(historyEntry) - .setAutorenewEndTime(fakeClock.nowUtc().plusDays(365)) - .setTargetId("foobar.foo") - .build()); - verifyDatastoreIndexing(pollMessage); - } } diff --git a/core/src/test/java/google/registry/model/rde/RdeRevisionTest.java b/core/src/test/java/google/registry/model/rde/RdeRevisionTest.java index a1ab776f9..c1f151bfd 100644 --- a/core/src/test/java/google/registry/model/rde/RdeRevisionTest.java +++ b/core/src/test/java/google/registry/model/rde/RdeRevisionTest.java @@ -22,13 +22,11 @@ import static google.registry.persistence.transaction.TransactionManagerFactory. import static org.junit.jupiter.api.Assertions.assertThrows; import google.registry.model.EntityTestCase; -import google.registry.testing.DualDatabaseTest; -import google.registry.testing.TestOfyAndSql; import org.joda.time.DateTime; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; /** Unit tests for {@link RdeRevision}. */ -@DualDatabaseTest public class RdeRevisionTest extends EntityTestCase { public RdeRevisionTest() { @@ -40,20 +38,20 @@ public class RdeRevisionTest extends EntityTestCase { fakeClock.setTo(DateTime.parse("1984-12-18TZ")); } - @TestOfyAndSql + @Test void testGetNextRevision_objectDoesntExist_returnsZero() { tm().transact( () -> assertThat(getNextRevision("torment", fakeClock.nowUtc(), FULL)).isEqualTo(0)); } - @TestOfyAndSql + @Test void testGetNextRevision_objectExistsAtZero_returnsOne() { save("sorrow", fakeClock.nowUtc(), FULL, 0); tm().transact( () -> assertThat(getNextRevision("sorrow", fakeClock.nowUtc(), FULL)).isEqualTo(1)); } - @TestOfyAndSql + @Test void testSaveRevision_objectDoesntExist_newRevisionIsZero_nextRevIsOne() { tm().transact(() -> saveRevision("despondency", fakeClock.nowUtc(), FULL, 0)); tm().transact( @@ -61,7 +59,7 @@ public class RdeRevisionTest extends EntityTestCase { assertThat(getNextRevision("despondency", fakeClock.nowUtc(), FULL)).isEqualTo(1)); } - @TestOfyAndSql + @Test void testSaveRevision_objectDoesntExist_newRevisionIsOne_throwsVe() { IllegalArgumentException thrown = assertThrows( @@ -74,7 +72,7 @@ public class RdeRevisionTest extends EntityTestCase { + "when trying to save new revision 1"); } - @TestOfyAndSql + @Test void testSaveRevision_objectExistsAtZero_newRevisionIsZero_throwsVe() { save("melancholy", fakeClock.nowUtc(), FULL, 0); IllegalArgumentException thrown = @@ -84,7 +82,7 @@ public class RdeRevisionTest extends EntityTestCase { assertThat(thrown).hasMessageThat().contains("object already created"); } - @TestOfyAndSql + @Test void testSaveRevision_objectExistsAtZero_newRevisionIsOne_nextRevIsTwo() { DateTime startOfDay = fakeClock.nowUtc().withTimeAtStartOfDay(); save("melancholy", startOfDay, FULL, 0); @@ -93,7 +91,7 @@ public class RdeRevisionTest extends EntityTestCase { tm().transact(() -> assertThat(getNextRevision("melancholy", startOfDay, FULL)).isEqualTo(2)); } - @TestOfyAndSql + @Test void testSaveRevision_objectExistsAtZero_newRevisionIsTwo_throwsVe() { save("melancholy", fakeClock.nowUtc(), FULL, 0); IllegalArgumentException thrown = @@ -105,7 +103,7 @@ public class RdeRevisionTest extends EntityTestCase { .contains("RDE revision object should be at revision 1 but was"); } - @TestOfyAndSql + @Test void testSaveRevision_negativeRevision_throwsIae() { IllegalArgumentException thrown = assertThrows( @@ -114,7 +112,7 @@ public class RdeRevisionTest extends EntityTestCase { assertThat(thrown).hasMessageThat().contains("Negative revision"); } - @TestOfyAndSql + @Test void testSaveRevision_callerNotInTransaction_throwsIse() { IllegalStateException thrown = assertThrows( diff --git a/core/src/test/java/google/registry/model/registrar/RegistrarTest.java b/core/src/test/java/google/registry/model/registrar/RegistrarTest.java index e18df9626..ed40ad13e 100644 --- a/core/src/test/java/google/registry/model/registrar/RegistrarTest.java +++ b/core/src/test/java/google/registry/model/registrar/RegistrarTest.java @@ -17,7 +17,6 @@ package google.registry.model.registrar; import static com.google.common.base.Preconditions.checkState; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth8.assertThat; -import static google.registry.model.ofy.ObjectifyService.auditedOfy; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; import static google.registry.testing.CertificateSamples.SAMPLE_CERT; import static google.registry.testing.CertificateSamples.SAMPLE_CERT2; @@ -39,7 +38,6 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSortedMap; import com.google.common.collect.ImmutableSortedSet; -import com.googlecode.objectify.Key; import google.registry.config.RegistryConfig; import google.registry.model.EntityTestCase; import google.registry.model.registrar.Registrar.State; @@ -47,19 +45,15 @@ import google.registry.model.registrar.Registrar.Type; import google.registry.model.tld.Registries; import google.registry.model.tld.Registry; import google.registry.model.tld.Registry.TldType; -import google.registry.testing.DualDatabaseTest; -import google.registry.testing.TestOfyAndSql; -import google.registry.testing.TestOfyOnly; -import google.registry.testing.TestSqlOnly; import google.registry.util.CidrAddressBlock; import google.registry.util.SerializeUtils; import java.math.BigDecimal; import org.joda.money.CurrencyUnit; import org.joda.money.Money; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; /** Unit tests for {@link Registrar}. */ -@DualDatabaseTest class RegistrarTest extends EntityTestCase { private Registrar registrar; @@ -150,23 +144,18 @@ class RegistrarTest extends EntityTestCase { .build())); } - @TestOfyAndSql + @Test void testPersistence() { assertThat(tm().transact(() -> tm().loadByKey(registrar.createVKey()))).isEqualTo(registrar); } - @TestSqlOnly + @Test void testSerializable() { Registrar persisted = tm().transact(() -> tm().loadByKey(registrar.createVKey())); assertThat(SerializeUtils.serializeDeserialize(persisted)).isEqualTo(persisted); } - @TestOfyOnly - void testIndexing() throws Exception { - verifyDatastoreIndexing(registrar, "registrarName", "ianaIdentifier"); - } - - @TestOfyAndSql + @Test void testFailure_passwordNull() { IllegalArgumentException thrown = assertThrows( @@ -174,7 +163,7 @@ class RegistrarTest extends EntityTestCase { assertThat(thrown).hasMessageThat().contains("Password must be 6-16 characters long."); } - @TestOfyAndSql + @Test void testFailure_passwordTooShort() { IllegalArgumentException thrown = assertThrows( @@ -182,7 +171,7 @@ class RegistrarTest extends EntityTestCase { assertThat(thrown).hasMessageThat().contains("Password must be 6-16 characters long."); } - @TestOfyAndSql + @Test void testFailure_passwordTooLong() { IllegalArgumentException thrown = assertThrows( @@ -191,7 +180,7 @@ class RegistrarTest extends EntityTestCase { assertThat(thrown).hasMessageThat().contains("Password must be 6-16 characters long."); } - @TestOfyAndSql + @Test void testSuccess_clientId_bounds() { registrar = registrar.asBuilder().setRegistrarId("abc").build(); assertThat(registrar.getRegistrarId()).isEqualTo("abc"); @@ -199,20 +188,20 @@ class RegistrarTest extends EntityTestCase { assertThat(registrar.getRegistrarId()).isEqualTo("abcdefghijklmnop"); } - @TestOfyAndSql + @Test void testFailure_clientId_tooShort() { assertThrows( IllegalArgumentException.class, () -> new Registrar.Builder().setRegistrarId("ab")); } - @TestOfyAndSql + @Test void testFailure_clientId_tooLong() { assertThrows( IllegalArgumentException.class, () -> new Registrar.Builder().setRegistrarId("abcdefghijklmnopq")); } - @TestOfyAndSql + @Test void testSetCertificateHash_alsoSetsHash() { registrar = registrar.asBuilder().setClientCertificate(null, fakeClock.nowUtc()).build(); fakeClock.advanceOneMilli(); @@ -222,7 +211,7 @@ class RegistrarTest extends EntityTestCase { assertThat(registrar.getClientCertificateHash()).hasValue(SAMPLE_CERT_HASH); } - @TestOfyAndSql + @Test void testDeleteCertificateHash_alsoDeletesHash() { assertThat(registrar.getClientCertificateHash()).isPresent(); fakeClock.advanceOneMilli(); @@ -232,7 +221,7 @@ class RegistrarTest extends EntityTestCase { assertThat(registrar.getClientCertificateHash()).isEmpty(); } - @TestOfyAndSql + @Test void testSetFailoverCertificateHash_alsoSetsHash() { fakeClock.advanceOneMilli(); registrar = @@ -245,7 +234,7 @@ class RegistrarTest extends EntityTestCase { assertThat(registrar.getFailoverClientCertificateHash()).hasValue(SAMPLE_CERT2_HASH); } - @TestOfyAndSql + @Test void testDeleteFailoverCertificateHash_alsoDeletesHash() { registrar = registrar.asBuilder().setFailoverClientCertificate(SAMPLE_CERT, fakeClock.nowUtc()).build(); @@ -258,7 +247,7 @@ class RegistrarTest extends EntityTestCase { assertThat(registrar.getFailoverClientCertificateHash()).isEmpty(); } - @TestOfyAndSql + @Test void testSuccess_clearingIanaId() { registrar .asBuilder() @@ -267,7 +256,7 @@ class RegistrarTest extends EntityTestCase { .build(); } - @TestOfyAndSql + @Test void testSuccess_clearingBillingAccountMapAndAllowedTlds() { registrar = registrar.asBuilder().setAllowedTlds(ImmutableSet.of()).setBillingAccountMap(null).build(); @@ -275,24 +264,24 @@ class RegistrarTest extends EntityTestCase { assertThat(registrar.getBillingAccountMap()).isEmpty(); } - @TestOfyAndSql + @Test void testSuccess_ianaIdForInternal() { registrar.asBuilder().setType(Type.INTERNAL).setIanaIdentifier(9998L).build(); registrar.asBuilder().setType(Type.INTERNAL).setIanaIdentifier(9999L).build(); } - @TestOfyAndSql + @Test void testSuccess_ianaIdForPdt() { registrar.asBuilder().setType(Type.PDT).setIanaIdentifier(9995L).build(); registrar.asBuilder().setType(Type.PDT).setIanaIdentifier(9996L).build(); } - @TestOfyAndSql + @Test void testSuccess_ianaIdForExternalMonitoring() { registrar.asBuilder().setType(Type.EXTERNAL_MONITORING).setIanaIdentifier(9997L).build(); } - @TestOfyAndSql + @Test void testSuccess_emptyContactTypesAllowed() { persistSimpleResource( new RegistrarPoc.Builder() @@ -308,7 +297,7 @@ class RegistrarTest extends EntityTestCase { } } - @TestOfyAndSql + @Test void testSuccess_getContactsByType() { RegistrarPoc newTechContact = persistSimpleResource( @@ -342,7 +331,7 @@ class RegistrarTest extends EntityTestCase { assertThat(abuseContacts).containsExactly(newTechAbuseContact, abuseAdminContact).inOrder(); } - @TestOfyAndSql + @Test void testFailure_missingRegistrarType() { IllegalArgumentException thrown = assertThrows( @@ -351,7 +340,7 @@ class RegistrarTest extends EntityTestCase { assertThat(thrown).hasMessageThat().contains("Registrar type cannot be null"); } - @TestOfyAndSql + @Test void testFailure_missingRegistrarName() { IllegalArgumentException thrown = assertThrows( @@ -364,7 +353,7 @@ class RegistrarTest extends EntityTestCase { assertThat(thrown).hasMessageThat().contains("Registrar name cannot be null"); } - @TestOfyAndSql + @Test void testFailure_missingAddress() { IllegalArgumentException thrown = assertThrows( @@ -380,21 +369,21 @@ class RegistrarTest extends EntityTestCase { .contains("Must specify at least one of localized or internationalized address"); } - @TestOfyAndSql + @Test void testFailure_badIanaIdForInternal() { assertThrows( IllegalArgumentException.class, () -> new Registrar.Builder().setType(Type.INTERNAL).setIanaIdentifier(8L).build()); } - @TestOfyAndSql + @Test void testFailure_badIanaIdForPdt() { assertThrows( IllegalArgumentException.class, () -> new Registrar.Builder().setType(Type.PDT).setIanaIdentifier(8L).build()); } - @TestOfyAndSql + @Test void testFailure_badIanaIdForExternalMonitoring() { assertThrows( IllegalArgumentException.class, @@ -402,62 +391,62 @@ class RegistrarTest extends EntityTestCase { registrar.asBuilder().setType(Type.EXTERNAL_MONITORING).setIanaIdentifier(8L).build()); } - @TestOfyAndSql + @Test void testFailure_missingIanaIdForReal() { assertThrows( IllegalArgumentException.class, () -> new Registrar.Builder().setType(Type.REAL).build()); } - @TestOfyAndSql + @Test void testFailure_missingIanaIdForInternal() { assertThrows( IllegalArgumentException.class, () -> new Registrar.Builder().setType(Type.INTERNAL).build()); } - @TestOfyAndSql + @Test void testFailure_missingIanaIdForPdt() { assertThrows( IllegalArgumentException.class, () -> new Registrar.Builder().setType(Type.PDT).build()); } - @TestOfyAndSql + @Test void testFailure_missingIanaIdForExternalMonitoring() { assertThrows( IllegalArgumentException.class, () -> new Registrar.Builder().setType(Type.EXTERNAL_MONITORING).build()); } - @TestOfyAndSql + @Test void testFailure_phonePasscodeTooShort() { assertThrows( IllegalArgumentException.class, () -> new Registrar.Builder().setPhonePasscode("0123")); } - @TestOfyAndSql + @Test void testFailure_phonePasscodeTooLong() { assertThrows( IllegalArgumentException.class, () -> new Registrar.Builder().setPhonePasscode("012345")); } - @TestOfyAndSql + @Test void testFailure_phonePasscodeInvalidCharacters() { assertThrows( IllegalArgumentException.class, () -> new Registrar.Builder().setPhonePasscode("code1")); } - @TestOfyAndSql + @Test void testSuccess_getLastExpiringCertNotificationSentDate_returnsInitialValue() { assertThat(registrar.getLastExpiringCertNotificationSentDate()).isEqualTo(START_OF_TIME); } - @TestOfyAndSql + @Test void testSuccess_getLastExpiringFailoverCertNotificationSentDate_returnsInitialValue() { assertThat(registrar.getLastExpiringFailoverCertNotificationSentDate()) .isEqualTo(START_OF_TIME); } - @TestOfyAndSql + @Test void testSuccess_setLastExpiringCertNotificationSentDate() { assertThat( registrar @@ -468,7 +457,7 @@ class RegistrarTest extends EntityTestCase { .isEqualTo(fakeClock.nowUtc()); } - @TestOfyAndSql + @Test void testFailure_setLastExpiringCertNotificationSentDate_nullDate() { IllegalArgumentException thrown = assertThrows( @@ -479,7 +468,7 @@ class RegistrarTest extends EntityTestCase { .isEqualTo("Registrar lastExpiringCertNotificationSentDate cannot be null"); } - @TestOfyAndSql + @Test void testSuccess_setLastExpiringFailoverCertNotificationSentDate() { assertThat( registrar @@ -490,7 +479,7 @@ class RegistrarTest extends EntityTestCase { .isEqualTo(fakeClock.nowUtc()); } - @TestOfyAndSql + @Test void testFailure_setLastExpiringFailoverCertNotificationSentDate_nullDate() { IllegalArgumentException thrown = assertThrows( @@ -504,7 +493,7 @@ class RegistrarTest extends EntityTestCase { .isEqualTo("Registrar lastExpiringFailoverCertNotificationSentDate cannot be null"); } - @TestOfyAndSql + @Test void testSuccess_setAllowedTlds() { assertThat( registrar @@ -515,7 +504,7 @@ class RegistrarTest extends EntityTestCase { .containsExactly("xn--q9jyb4c"); } - @TestOfyAndSql + @Test void testSuccess_setAllowedTldsUncached() { assertThat( registrar @@ -526,21 +515,21 @@ class RegistrarTest extends EntityTestCase { .containsExactly("xn--q9jyb4c"); } - @TestOfyAndSql + @Test void testFailure_setAllowedTlds_nonexistentTld() { assertThrows( IllegalArgumentException.class, () -> registrar.asBuilder().setAllowedTlds(ImmutableSet.of("bad"))); } - @TestOfyAndSql + @Test void testFailure_setAllowedTldsUncached_nonexistentTld() { assertThrows( IllegalArgumentException.class, () -> registrar.asBuilder().setAllowedTldsUncached(ImmutableSet.of("bad"))); } - @TestOfyAndSql + @Test void testFailure_driveFolderId_asFullUrl() { String driveFolderId = "https://drive.google.com/drive/folders/1j3v7RZkU25DjbTx2-Q93H04zKOBau89M"; @@ -551,14 +540,14 @@ class RegistrarTest extends EntityTestCase { assertThat(thrown).hasMessageThat().isEqualTo("Drive folder ID must not be a full URL"); } - @TestOfyAndSql + @Test void testFailure_nullEmail() { NullPointerException thrown = assertThrows(NullPointerException.class, () -> registrar.asBuilder().setEmailAddress(null)); assertThat(thrown).hasMessageThat().isEqualTo("Provided email was null"); } - @TestOfyAndSql + @Test void testFailure_invalidEmail() { IllegalArgumentException thrown = assertThrows( @@ -568,7 +557,7 @@ class RegistrarTest extends EntityTestCase { .isEqualTo("Provided email lolcat is not a valid email address"); } - @TestOfyAndSql + @Test void testFailure_emptyEmail() { IllegalArgumentException thrown = assertThrows( @@ -576,7 +565,7 @@ class RegistrarTest extends EntityTestCase { assertThat(thrown).hasMessageThat().isEqualTo("Provided email is not a valid email address"); } - @TestOfyAndSql + @Test void testFailure_nullIcannReferralEmail() { NullPointerException thrown = assertThrows( @@ -584,7 +573,7 @@ class RegistrarTest extends EntityTestCase { assertThat(thrown).hasMessageThat().isEqualTo("Provided email was null"); } - @TestOfyAndSql + @Test void testFailure_invalidIcannReferralEmail() { IllegalArgumentException thrown = assertThrows( @@ -595,7 +584,7 @@ class RegistrarTest extends EntityTestCase { .isEqualTo("Provided email lolcat is not a valid email address"); } - @TestOfyAndSql + @Test void testFailure_emptyIcannReferralEmail() { IllegalArgumentException thrown = assertThrows( @@ -603,7 +592,7 @@ class RegistrarTest extends EntityTestCase { assertThat(thrown).hasMessageThat().isEqualTo("Provided email is not a valid email address"); } - @TestOfyAndSql + @Test void testSuccess_setAllowedTldsUncached_newTldNotInCache() { int origSingletonCacheRefreshSeconds = RegistryConfig.CONFIG_SETTINGS.get().caching.singletonCacheRefreshSeconds; @@ -652,52 +641,35 @@ class RegistrarTest extends EntityTestCase { } } - @TestOfyOnly - void testLoadByClientIdCached_isTransactionless() { - tm().transact( - () -> { - assertThat(Registrar.loadByRegistrarIdCached("registrar")).isPresent(); - // Load something as a control to make sure we are seeing loaded keys in the - // session cache. - auditedOfy().load().entity(abuseAdminContact).now(); - assertThat(auditedOfy().getSessionKeys()).contains(Key.create(abuseAdminContact)); - assertThat(auditedOfy().getSessionKeys()).doesNotContain(Key.create(registrar)); - }); - tm().clearSessionCache(); - // Conversely, loads outside of a transaction should end up in the session cache. - assertThat(Registrar.loadByRegistrarIdCached("registrar")).isPresent(); - assertThat(auditedOfy().getSessionKeys()).contains(Key.create(registrar)); - } - - @TestOfyAndSql + @Test void testFailure_loadByClientId_clientIdIsNull() { IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, () -> Registrar.loadByRegistrarId(null)); assertThat(thrown).hasMessageThat().contains("registrarId must be specified"); } - @TestOfyAndSql + @Test void testFailure_loadByClientId_clientIdIsEmpty() { IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, () -> Registrar.loadByRegistrarId("")); assertThat(thrown).hasMessageThat().contains("registrarId must be specified"); } - @TestOfyAndSql + @Test void testFailure_loadByClientIdCached_clientIdIsNull() { IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, () -> Registrar.loadByRegistrarIdCached(null)); assertThat(thrown).hasMessageThat().contains("registrarId must be specified"); } - @TestOfyAndSql + @Test void testFailure_loadByClientIdCached_clientIdIsEmpty() { IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, () -> Registrar.loadByRegistrarIdCached("")); assertThat(thrown).hasMessageThat().contains("registrarId must be specified"); } - @TestOfyAndSql + @Test void testFailure_missingCurrenciesFromBillingMap() { IllegalArgumentException thrown = assertThrows( @@ -713,7 +685,7 @@ class RegistrarTest extends EntityTestCase { .contains("their currency is missing from the billing account map: [tld, xn--q9jyb4c]"); } - @TestOfyAndSql + @Test void testFailure_missingCurrencyFromBillingMap() { IllegalArgumentException thrown = assertThrows( @@ -729,7 +701,7 @@ class RegistrarTest extends EntityTestCase { .contains("their currency is missing from the billing account map: [xn--q9jyb4c]"); } - @TestOfyAndSql + @Test void testSuccess_nonRealTldDoesntNeedEntryInBillingMap() { persistResource(Registry.get("xn--q9jyb4c").asBuilder().setTldType(TldType.TEST).build()); // xn--q9jyb4c bills in JPY and we don't have a JPY entry in this billing account map, but it diff --git a/core/src/test/java/google/registry/model/reporting/HistoryEntryDaoTest.java b/core/src/test/java/google/registry/model/reporting/HistoryEntryDaoTest.java index 5dbacab08..51171faa1 100644 --- a/core/src/test/java/google/registry/model/reporting/HistoryEntryDaoTest.java +++ b/core/src/test/java/google/registry/model/reporting/HistoryEntryDaoTest.java @@ -16,7 +16,7 @@ package google.registry.model.reporting; import static com.google.common.truth.Truth.assertThat; import static google.registry.model.ImmutableObjectSubject.immutableObjectCorrespondence; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; +import static google.registry.persistence.transaction.TransactionManagerFactory.tm; import static google.registry.testing.DatabaseHelper.createTld; import static google.registry.testing.DatabaseHelper.newDomainBase; import static google.registry.testing.DatabaseHelper.persistActiveDomain; @@ -32,12 +32,10 @@ import google.registry.model.domain.DomainHistory; import google.registry.model.domain.Period; import google.registry.model.eppcommon.Trid; import google.registry.model.reporting.DomainTransactionRecord.TransactionReportField; -import google.registry.testing.DualDatabaseTest; -import google.registry.testing.TestOfyAndSql; import org.joda.time.DateTime; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; -@DualDatabaseTest class HistoryEntryDaoTest extends EntityTestCase { private DomainBase domain; @@ -74,36 +72,37 @@ class HistoryEntryDaoTest extends EntityTestCase { persistResource(domainHistory); } - @TestOfyAndSql + @Test void testSimpleLoadAll() { assertThat(HistoryEntryDao.loadAllHistoryObjects(START_OF_TIME, END_OF_TIME)) .comparingElementsUsing(immutableObjectCorrespondence("nsHosts", "domainContent")) .containsExactly(domainHistory); } - @TestOfyAndSql + @Test void testSkips_tooEarly() { assertThat(HistoryEntryDao.loadAllHistoryObjects(fakeClock.nowUtc().plusMillis(1), END_OF_TIME)) .isEmpty(); } - @TestOfyAndSql + @Test void testSkips_tooLate() { assertThat( HistoryEntryDao.loadAllHistoryObjects(START_OF_TIME, fakeClock.nowUtc().minusMillis(1))) .isEmpty(); } - @TestOfyAndSql + @Test void testLoadByResource() { - transactIfJpaTm( - () -> - assertThat(HistoryEntryDao.loadHistoryObjectsForResource(domain.createVKey())) - .comparingElementsUsing(immutableObjectCorrespondence("nsHosts", "domainContent")) - .containsExactly(domainHistory)); + tm().transact( + () -> + assertThat(HistoryEntryDao.loadHistoryObjectsForResource(domain.createVKey())) + .comparingElementsUsing( + immutableObjectCorrespondence("nsHosts", "domainContent")) + .containsExactly(domainHistory)); } - @TestOfyAndSql + @Test void testLoadByResource_skips_tooEarly() { assertThat( HistoryEntryDao.loadHistoryObjectsForResource( @@ -111,7 +110,7 @@ class HistoryEntryDaoTest extends EntityTestCase { .isEmpty(); } - @TestOfyAndSql + @Test void testLoadByResource_skips_tooLate() { assertThat( HistoryEntryDao.loadHistoryObjectsForResource( @@ -119,7 +118,7 @@ class HistoryEntryDaoTest extends EntityTestCase { .isEmpty(); } - @TestOfyAndSql + @Test void testLoadByResource_noEntriesForResource() { DomainBase newDomain = persistResource(newDomainBase("new.foobar")); assertThat(HistoryEntryDao.loadHistoryObjectsForResource(newDomain.createVKey())).isEmpty(); diff --git a/core/src/test/java/google/registry/model/reporting/HistoryEntryTest.java b/core/src/test/java/google/registry/model/reporting/HistoryEntryTest.java index 34ebd912f..6e0a5078b 100644 --- a/core/src/test/java/google/registry/model/reporting/HistoryEntryTest.java +++ b/core/src/test/java/google/registry/model/reporting/HistoryEntryTest.java @@ -17,7 +17,6 @@ package google.registry.model.reporting; import static com.google.common.truth.Truth.assertThat; import static google.registry.model.ImmutableObjectSubject.assertAboutImmutableObjects; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import static google.registry.testing.DatabaseHelper.createTld; import static google.registry.testing.DatabaseHelper.persistActiveDomain; import static google.registry.testing.DatabaseHelper.persistResource; @@ -32,14 +31,12 @@ import google.registry.model.domain.DomainHistory; import google.registry.model.domain.Period; import google.registry.model.eppcommon.Trid; import google.registry.model.reporting.DomainTransactionRecord.TransactionReportField; -import google.registry.testing.DualDatabaseTest; -import google.registry.testing.TestOfyAndSql; -import google.registry.testing.TestOfyOnly; import org.joda.time.DateTime; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; /** Unit tests for {@link HistoryEntry}. */ -@DualDatabaseTest + class HistoryEntryTest extends EntityTestCase { private DomainHistory domainHistory; @@ -74,18 +71,18 @@ class HistoryEntryTest extends EntityTestCase { persistResource(domainHistory); } - @TestOfyAndSql + @Test void testPersistence() { - transactIfJpaTm( - () -> { - DomainHistory fromDatabase = tm().loadByEntity(domainHistory); - assertAboutImmutableObjects() - .that(fromDatabase) - .isEqualExceptFields(domainHistory, "domainContent"); - }); + tm().transact( + () -> { + DomainHistory fromDatabase = tm().loadByEntity(domainHistory); + assertAboutImmutableObjects() + .that(fromDatabase) + .isEqualExceptFields(domainHistory, "domainContent"); + }); } - @TestOfyAndSql + @Test void testBuilder_typeMustBeSpecified() { IllegalArgumentException thrown = assertThrows( @@ -100,7 +97,7 @@ class HistoryEntryTest extends EntityTestCase { assertThat(thrown).hasMessageThat().isEqualTo("History entry type must be specified"); } - @TestOfyAndSql + @Test void testBuilder_modificationTimeMustBeSpecified() { IllegalArgumentException thrown = assertThrows( @@ -115,7 +112,7 @@ class HistoryEntryTest extends EntityTestCase { assertThat(thrown).hasMessageThat().isEqualTo("Modification time must be specified"); } - @TestOfyAndSql + @Test void testBuilder_registrarIdMustBeSpecified() { IllegalArgumentException thrown = assertThrows( @@ -130,7 +127,7 @@ class HistoryEntryTest extends EntityTestCase { assertThat(thrown).hasMessageThat().isEqualTo("Registrar ID must be specified"); } - @TestOfyAndSql + @Test void testBuilder_syntheticHistoryEntries_mustNotBeRequestedByRegistrar() { IllegalArgumentException thrown = assertThrows( @@ -148,9 +145,4 @@ class HistoryEntryTest extends EntityTestCase { .hasMessageThat() .isEqualTo("Synthetic history entries cannot be requested by a registrar"); } - - @TestOfyOnly - void testIndexing() throws Exception { - verifyDatastoreIndexing(domainHistory.asHistoryEntry(), "modificationTime", "clientId"); - } } diff --git a/core/src/test/java/google/registry/model/reporting/Spec11ThreatMatchDaoTest.java b/core/src/test/java/google/registry/model/reporting/Spec11ThreatMatchDaoTest.java index d841ea387..433948548 100644 --- a/core/src/test/java/google/registry/model/reporting/Spec11ThreatMatchDaoTest.java +++ b/core/src/test/java/google/registry/model/reporting/Spec11ThreatMatchDaoTest.java @@ -28,13 +28,11 @@ import google.registry.model.EntityTestCase; import google.registry.model.contact.ContactResource; import google.registry.model.domain.DomainBase; import google.registry.model.reporting.Spec11ThreatMatch.ThreatType; -import google.registry.testing.DualDatabaseTest; -import google.registry.testing.TestSqlOnly; import org.joda.time.LocalDate; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; /** Unit tests for {@link Spec11ThreatMatchDao}. */ -@DualDatabaseTest class Spec11ThreatMatchDaoTest extends EntityTestCase { private static final LocalDate TODAY = new LocalDate(2020, 8, 4); @@ -61,7 +59,7 @@ class Spec11ThreatMatchDaoTest extends EntityTestCase { }); } - @TestSqlOnly + @Test void testDeleteEntriesByDate() { // Verify that all entries with the date TODAY were removed jpaTm() @@ -85,7 +83,7 @@ class Spec11ThreatMatchDaoTest extends EntityTestCase { }); } - @TestSqlOnly + @Test void testLoadEntriesByDate() { jpaTm() .transact( diff --git a/core/src/test/java/google/registry/model/reporting/Spec11ThreatMatchTest.java b/core/src/test/java/google/registry/model/reporting/Spec11ThreatMatchTest.java index f76fd8f88..16ca7f955 100644 --- a/core/src/test/java/google/registry/model/reporting/Spec11ThreatMatchTest.java +++ b/core/src/test/java/google/registry/model/reporting/Spec11ThreatMatchTest.java @@ -31,16 +31,13 @@ import google.registry.model.domain.DomainBase; import google.registry.model.host.HostResource; import google.registry.model.transfer.ContactTransferData; import google.registry.persistence.VKey; -import google.registry.testing.DualDatabaseTest; -import google.registry.testing.TestOfyAndSql; -import google.registry.testing.TestSqlOnly; import org.joda.time.LocalDate; import org.joda.time.format.ISODateTimeFormat; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; /** Unit tests for {@link Spec11ThreatMatch}. */ -@DualDatabaseTest public final class Spec11ThreatMatchTest extends EntityTestCase { private static final String REGISTRAR_ID = "registrar"; @@ -104,7 +101,7 @@ public final class Spec11ThreatMatchTest extends EntityTestCase { .build(); } - @TestSqlOnly + @Test void testPersistence() { createTld("tld"); saveRegistrar(REGISTRAR_ID); @@ -112,7 +109,7 @@ public final class Spec11ThreatMatchTest extends EntityTestCase { assertAboutImmutableObjects().that(loadByEntity(threat)).isEqualExceptFields(threat, "id"); } - @TestSqlOnly + @Test @Disabled("We can't rely on foreign keys until we've migrated to SQL") void testThreatForeignKeyConstraints() { // Persist the threat without the associated registrar. @@ -124,7 +121,7 @@ public final class Spec11ThreatMatchTest extends EntityTestCase { assertThrowForeignKeyViolation(() -> insertInDb(registrantContact, host, threat)); } - @TestOfyAndSql + @Test void testFailure_threatsWithInvalidFields() { assertThrows( IllegalArgumentException.class, () -> threat.asBuilder().setRegistrarId(null).build()); diff --git a/core/src/test/java/google/registry/model/server/LockTest.java b/core/src/test/java/google/registry/model/server/LockTest.java index bd0aeaf24..79864f3dc 100644 --- a/core/src/test/java/google/registry/model/server/LockTest.java +++ b/core/src/test/java/google/registry/model/server/LockTest.java @@ -20,7 +20,6 @@ import static google.registry.model.server.Lock.LockState.FREE; import static google.registry.model.server.Lock.LockState.IN_USE; import static google.registry.model.server.Lock.LockState.OWNER_DIED; import static google.registry.model.server.Lock.LockState.TIMED_OUT; -import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -29,18 +28,14 @@ import static org.mockito.Mockito.when; import google.registry.model.EntityTestCase; import google.registry.model.server.Lock.LockState; -import google.registry.testing.DatabaseHelper; -import google.registry.testing.DualDatabaseTest; -import google.registry.testing.TestOfyAndSql; -import google.registry.testing.TestOfyOnly; import google.registry.util.RequestStatusChecker; import java.util.Optional; import org.joda.time.Duration; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; /** Unit tests for {@link Lock}. */ -@DualDatabaseTest public class LockTest extends EntityTestCase { private static final String RESOURCE_NAME = "foo"; @@ -85,7 +80,7 @@ public class LockTest extends EntityTestCase { Lock.lockMetrics = origLockMetrics; } - @TestOfyAndSql + @Test void testReleasedExplicitly() { Optional lock = acquire("", ONE_DAY, FREE); assertThat(lock).isPresent(); @@ -97,7 +92,7 @@ public class LockTest extends EntityTestCase { assertThat(acquire("", ONE_DAY, FREE)).isPresent(); } - @TestOfyAndSql + @Test void testReleasedAfterTimeout() { assertThat(acquire("", TWO_MILLIS, FREE)).isPresent(); // We can't get it again at the same time. @@ -110,7 +105,7 @@ public class LockTest extends EntityTestCase { assertThat(acquire("", TWO_MILLIS, TIMED_OUT)).isPresent(); } - @TestOfyAndSql + @Test void testReleasedAfterRequestFinish() { assertThat(acquire("", ONE_DAY, FREE)).isPresent(); // We can't get it again while request is active @@ -120,7 +115,7 @@ public class LockTest extends EntityTestCase { assertThat(acquire("", ONE_DAY, OWNER_DIED)).isPresent(); } - @TestOfyAndSql + @Test void testTldsAreIndependent() { Optional lockA = acquire("a", ONE_DAY, FREE); assertThat(lockA).isPresent(); @@ -135,20 +130,7 @@ public class LockTest extends EntityTestCase { assertThat(acquire("b", ONE_DAY, IN_USE)).isEmpty(); } - @TestOfyOnly - void testSqlLock_inOfyMode() { - Lock.lockMetrics = origLockMetrics; - Optional lock = Lock.acquireSql(RESOURCE_NAME, null, ONE_DAY, requestStatusChecker, true); - assertThat(lock).isPresent(); - assertThat(DatabaseHelper.loadAllOf(Lock.class)).isEmpty(); - assertThat(jpaTm().transact(() -> jpaTm().loadAllOf(Lock.class))).containsExactly(lock.get()); - - lock.get().releaseSql(); - assertThat(DatabaseHelper.loadAllOf(Lock.class)).isEmpty(); - assertThat(jpaTm().transact(() -> jpaTm().loadAllOf(Lock.class))).isEmpty(); - } - - @TestOfyAndSql + @Test void testFailure_emptyResourceName() { IllegalArgumentException thrown = assertThrows( diff --git a/core/src/test/java/google/registry/model/server/ServerSecretTest.java b/core/src/test/java/google/registry/model/server/ServerSecretTest.java index b7decf038..26acc7344 100644 --- a/core/src/test/java/google/registry/model/server/ServerSecretTest.java +++ b/core/src/test/java/google/registry/model/server/ServerSecretTest.java @@ -19,15 +19,11 @@ import static google.registry.testing.DatabaseHelper.loadByEntity; import static google.registry.testing.DatabaseHelper.persistResource; import google.registry.model.EntityTestCase; -import google.registry.model.ofy.RequestCapturingAsyncDatastoreService; -import google.registry.testing.DualDatabaseTest; -import google.registry.testing.TestOfyAndSql; -import google.registry.testing.TestOfyOnly; import java.util.UUID; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; /** Unit tests for {@link ServerSecret}. */ -@DualDatabaseTest public class ServerSecretTest extends EntityTestCase { ServerSecretTest() { @@ -39,14 +35,14 @@ public class ServerSecretTest extends EntityTestCase { ServerSecret.resetCache(); } - @TestOfyAndSql + @Test void testGet_bootstrapping_savesSecretToDatastore() { ServerSecret secret = ServerSecret.get(); assertThat(secret).isNotNull(); assertThat(loadByEntity(new ServerSecret())).isEqualTo(secret); } - @TestOfyAndSql + @Test void testGet_existingSecret_returned() { ServerSecret secret = ServerSecret.create(new UUID(123, 456)); persistResource(secret); @@ -54,17 +50,7 @@ public class ServerSecretTest extends EntityTestCase { assertThat(loadByEntity(new ServerSecret())).isEqualTo(secret); } - @TestOfyOnly // relies on request-capturing datastore - void testGet_cachedSecret() { - int numInitialReads = RequestCapturingAsyncDatastoreService.getReads().size(); - ServerSecret secret = ServerSecret.get(); - int numReads = RequestCapturingAsyncDatastoreService.getReads().size(); - assertThat(numReads).isGreaterThan(numInitialReads); - assertThat(ServerSecret.get()).isEqualTo(secret); - assertThat(RequestCapturingAsyncDatastoreService.getReads()).hasSize(numReads); - } - - @TestOfyAndSql + @Test void testAsBytes() { byte[] bytes = ServerSecret.create(new UUID(123, 0x456)).asBytes(); assertThat(bytes).isEqualTo(new byte[] {0, 0, 0, 0, 0, 0, 0, 123, 0, 0, 0, 0, 0, 0, 0x4, 0x56}); diff --git a/core/src/test/java/google/registry/model/smd/SignedMarkRevocationListTest.java b/core/src/test/java/google/registry/model/smd/SignedMarkRevocationListTest.java index bb071285f..07b160d9a 100644 --- a/core/src/test/java/google/registry/model/smd/SignedMarkRevocationListTest.java +++ b/core/src/test/java/google/registry/model/smd/SignedMarkRevocationListTest.java @@ -30,8 +30,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; public class SignedMarkRevocationListTest { @RegisterExtension - public final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().build(); + public final AppEngineExtension appEngine = AppEngineExtension.builder().withCloudSql().build(); private final FakeClock clock = new FakeClock(DateTime.parse("2013-01-01T00:00:00Z")); diff --git a/core/src/test/java/google/registry/model/tld/RegistriesTest.java b/core/src/test/java/google/registry/model/tld/RegistriesTest.java index 4173e4a1d..b6ad68e5c 100644 --- a/core/src/test/java/google/registry/model/tld/RegistriesTest.java +++ b/core/src/test/java/google/registry/model/tld/RegistriesTest.java @@ -24,29 +24,26 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import com.google.common.net.InternetDomainName; import google.registry.model.tld.Registry.TldType; import google.registry.testing.AppEngineExtension; -import google.registry.testing.DualDatabaseTest; -import google.registry.testing.TestOfyAndSql; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; /** Unit tests for {@link Registries}. */ -@DualDatabaseTest class RegistriesTest { @RegisterExtension - final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().build(); + final AppEngineExtension appEngine = AppEngineExtension.builder().withCloudSql().build(); private void initTestTlds() { createTlds("foo", "a.b.c"); // Test a multipart tld. } - @TestOfyAndSql + @Test void testGetTlds() { initTestTlds(); assertThat(Registries.getTlds()).containsExactly("foo", "a.b.c"); } - @TestOfyAndSql + @Test void test_getTldEntities() { initTestTlds(); persistResource(newRegistry("testtld", "TESTTLD").asBuilder().setTldType(TldType.TEST).build()); @@ -56,25 +53,25 @@ class RegistriesTest { .containsExactly(Registry.get("testtld")); } - @TestOfyAndSql + @Test void testGetTlds_withNoRegistriesPersisted_returnsEmptySet() { assertThat(Registries.getTlds()).isEmpty(); } - @TestOfyAndSql + @Test void testAssertTldExists_doesExist() { initTestTlds(); Registries.assertTldExists("foo"); Registries.assertTldExists("a.b.c"); } - @TestOfyAndSql + @Test void testAssertTldExists_doesntExist() { initTestTlds(); assertThrows(IllegalArgumentException.class, () -> Registries.assertTldExists("baz")); } - @TestOfyAndSql + @Test void testFindTldForName() { initTestTlds(); assertThat(Registries.findTldForName(InternetDomainName.from("example.foo")).get().toString()) diff --git a/core/src/test/java/google/registry/model/tld/RegistryTest.java b/core/src/test/java/google/registry/model/tld/RegistryTest.java index 5ad4e8271..9ef85ccbf 100644 --- a/core/src/test/java/google/registry/model/tld/RegistryTest.java +++ b/core/src/test/java/google/registry/model/tld/RegistryTest.java @@ -44,19 +44,15 @@ import google.registry.model.tld.label.PremiumList; import google.registry.model.tld.label.PremiumListDao; import google.registry.model.tld.label.ReservedList; import google.registry.testing.DatabaseHelper; -import google.registry.testing.DualDatabaseTest; -import google.registry.testing.TestOfyAndSql; -import google.registry.testing.TestOfyOnly; -import google.registry.testing.TestSqlOnly; import google.registry.util.SerializeUtils; import java.math.BigDecimal; import java.util.Optional; import org.joda.money.Money; import org.joda.time.DateTime; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; /** Unit tests for {@link Registry}. */ -@DualDatabaseTest public final class RegistryTest extends EntityTestCase { RegistryTest() { @@ -70,7 +66,7 @@ public final class RegistryTest extends EntityTestCase { createTld("tld"); } - @TestOfyAndSql + @Test void testPersistence_updateReservedAndPremiumListSuccessfully() { ReservedList rl15 = persistReservedList("tld-reserved15", "potato,FULLY_BLOCKED"); PremiumList pl = persistPremiumList("tld2", USD, "lol,USD 50", "cat,USD 700"); @@ -81,14 +77,14 @@ public final class RegistryTest extends EntityTestCase { assertThat(persisted).isEqualTo(registry); } - @TestOfyAndSql + @Test void testPersistence() { assertWithMessage("Registry not found").that(Registry.get("tld")).isNotNull(); assertThat(tm().transact(() -> tm().loadByKey(Registry.createVKey("tld")))) .isEqualTo(Registry.get("tld")); } - @TestSqlOnly + @Test void testSerializable() { ReservedList rl15 = persistReservedList("tld-reserved15", "potato,FULLY_BLOCKED"); Registry registry = Registry.get("tld").asBuilder().setReservedLists(rl15).build(); @@ -97,18 +93,13 @@ public final class RegistryTest extends EntityTestCase { assertThat(SerializeUtils.serializeDeserialize(persisted)).isEqualTo(persisted); } - @TestOfyAndSql + @Test void testFailure_registryNotFound() { createTld("foo"); assertThrows(RegistryNotFoundException.class, () -> Registry.get("baz")); } - @TestOfyOnly - void testIndexing() throws Exception { - verifyDatastoreIndexing(Registry.get("tld")); - } - - @TestOfyAndSql + @Test void testSettingEscrowEnabled_null() { assertThat(Registry.get("tld").asBuilder().setEscrowEnabled(true).build().getEscrowEnabled()) .isTrue(); @@ -116,7 +107,7 @@ public final class RegistryTest extends EntityTestCase { .isFalse(); } - @TestOfyAndSql + @Test void testSettingCreateBillingCost() { Registry registry = Registry.get("tld").asBuilder().setCreateBillingCost(Money.of(USD, 42)).build(); @@ -125,7 +116,7 @@ public final class RegistryTest extends EntityTestCase { assertThat(registry.getStandardRestoreCost()).isEqualTo(Money.of(USD, 17)); } - @TestOfyAndSql + @Test void testSettingRestoreBillingCost() { Registry registry = Registry.get("tld").asBuilder().setRestoreBillingCost(Money.of(USD, 42)).build(); @@ -134,19 +125,19 @@ public final class RegistryTest extends EntityTestCase { assertThat(registry.getStandardRestoreCost()).isEqualTo(Money.of(USD, 42)); } - @TestOfyAndSql + @Test void testDefaultNumDnsPublishShards_equalToOne() { Registry registry = Registry.get("tld").asBuilder().build(); assertThat(registry.getNumDnsPublishLocks()).isEqualTo(1); } - @TestOfyAndSql + @Test void testSettingNumDnsPublishShards() { Registry registry = Registry.get("tld").asBuilder().setNumDnsPublishLocks(2).build(); assertThat(registry.getNumDnsPublishLocks()).isEqualTo(2); } - @TestOfyAndSql + @Test void testSetReservedList_doesntMutateExistingRegistry() { ReservedList rl15 = persistReservedList( @@ -178,14 +169,14 @@ public final class RegistryTest extends EntityTestCase { assertThat(registry2.getReservedListNames()).hasSize(2); } - @TestOfyAndSql + @Test void testGetReservedLists_doesntReturnNullWhenUninitialized() { Registry registry = newRegistry("foo", "FOO"); assertThat(registry.getReservedListNames()).isNotNull(); assertThat(registry.getReservedListNames()).isEmpty(); } - @TestOfyAndSql + @Test void testGetAll() { createTld("foo"); assertThat(Registry.get(ImmutableSet.of("foo", "tld"))) @@ -198,7 +189,7 @@ public final class RegistryTest extends EntityTestCase { .values()); } - @TestOfyAndSql + @Test void testSetReservedLists() { ReservedList rl5 = persistReservedList( @@ -225,7 +216,7 @@ public final class RegistryTest extends EntityTestCase { assertThat(r.getReservedListNames()).isEmpty(); } - @TestOfyAndSql + @Test void testSetReservedListsByName() { persistReservedList( new ReservedList.Builder() @@ -253,7 +244,7 @@ public final class RegistryTest extends EntityTestCase { assertThat(r.getReservedListNames()).isEmpty(); } - @TestOfyAndSql + @Test void testSetPremiumList() { PremiumList pl2 = persistPremiumList("tld2", USD, "lol,USD 50", "cat,USD 700"); Registry registry = Registry.get("tld").asBuilder().setPremiumList(pl2).build(); @@ -263,20 +254,20 @@ public final class RegistryTest extends EntityTestCase { assertThat(PremiumListDao.getLatestRevision("tld2").get().getName()).isEqualTo("tld2"); } - @TestOfyAndSql + @Test void testSettingServerStatusChangeBillingCost() { Registry registry = Registry.get("tld").asBuilder().setServerStatusChangeBillingCost(Money.of(USD, 42)).build(); assertThat(registry.getServerStatusChangeCost()).isEqualTo(Money.of(USD, 42)); } - @TestOfyAndSql + @Test void testSettingLordnUsername() { Registry registry = Registry.get("tld").asBuilder().setLordnUsername("username").build(); assertThat(registry.getLordnUsername()).isEqualTo("username"); } - @TestOfyAndSql + @Test void testSettingDnsWriters() { Registry registry = Registry.get("tld"); assertThat(registry.getDnsWriters()).containsExactly(VoidDnsWriter.NAME); @@ -284,7 +275,7 @@ public final class RegistryTest extends EntityTestCase { assertThat(registry.getDnsWriters()).containsExactly("baz", "bang"); } - @TestOfyAndSql + @Test void testPdtLooksLikeGa() { Registry registry = Registry.get("tld") @@ -294,7 +285,7 @@ public final class RegistryTest extends EntityTestCase { assertThat(registry.getTldState(START_OF_TIME)).isEqualTo(GENERAL_AVAILABILITY); } - @TestOfyAndSql + @Test void testTldStateTransitionTimes() { Registry registry = Registry.get("tld") @@ -329,7 +320,7 @@ public final class RegistryTest extends EntityTestCase { assertThat(registry.getTldState(END_OF_TIME)).isEqualTo(GENERAL_AVAILABILITY); } - @TestOfyAndSql + @Test void testQuietPeriodCanAppearMultipleTimesAnywhere() { Registry.get("tld") .asBuilder() @@ -344,7 +335,7 @@ public final class RegistryTest extends EntityTestCase { .build(); } - @TestOfyAndSql + @Test void testRenewBillingCostTransitionTimes() { Registry registry = Registry.get("tld") @@ -383,7 +374,7 @@ public final class RegistryTest extends EntityTestCase { assertThat(registry.getStandardRenewCost(END_OF_TIME)).isEqualTo(Money.of(USD, 3)); } - @TestOfyAndSql + @Test void testRenewBillingCostNoTransitions() { Registry registry = Registry.get("tld"); // The default value of 11 is set in createTld(). @@ -396,21 +387,21 @@ public final class RegistryTest extends EntityTestCase { assertThat(registry.getStandardRenewCost(END_OF_TIME)).isEqualTo(Money.of(USD, 11)); } - @TestOfyAndSql + @Test void testFailure_tldNeverSet() { IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, () -> new Registry.Builder().build()); assertThat(thrown).hasMessageThat().contains("No registry TLD specified"); } - @TestOfyAndSql + @Test void testFailure_setTldStr_null() { IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, () -> new Registry.Builder().setTldStr(null)); assertThat(thrown).hasMessageThat().contains("TLD must not be null"); } - @TestOfyAndSql + @Test void testFailure_setTldStr_invalidTld() { IllegalArgumentException thrown = assertThrows( @@ -420,7 +411,7 @@ public final class RegistryTest extends EntityTestCase { .contains("Cannot create registry for TLD that is not a valid, canonical domain name"); } - @TestOfyAndSql + @Test void testFailure_setTldStr_nonCanonicalTld() { IllegalArgumentException thrown = assertThrows( @@ -430,7 +421,7 @@ public final class RegistryTest extends EntityTestCase { .contains("Cannot create registry for TLD that is not a valid, canonical domain name"); } - @TestOfyAndSql + @Test void testFailure_tldStatesOutOfOrder() { assertThrows( IllegalArgumentException.class, @@ -444,7 +435,7 @@ public final class RegistryTest extends EntityTestCase { .build()); } - @TestOfyAndSql + @Test void testFailure_duplicateTldState() { assertThrows( IllegalArgumentException.class, @@ -458,7 +449,7 @@ public final class RegistryTest extends EntityTestCase { .build()); } - @TestOfyAndSql + @Test void testFailure_pricingEngineIsRequired() { IllegalArgumentException thrown = assertThrows( @@ -469,7 +460,7 @@ public final class RegistryTest extends EntityTestCase { .contains("All registries must have a configured pricing engine"); } - @TestOfyAndSql + @Test void testFailure_negativeRenewBillingCostTransitionValue() { IllegalArgumentException thrown = assertThrows( @@ -482,7 +473,7 @@ public final class RegistryTest extends EntityTestCase { assertThat(thrown).hasMessageThat().contains("billing cost cannot be negative"); } - @TestOfyAndSql + @Test void testFailure_negativeCreateBillingCost() { IllegalArgumentException thrown = assertThrows( @@ -491,7 +482,7 @@ public final class RegistryTest extends EntityTestCase { assertThat(thrown).hasMessageThat().contains("createBillingCost cannot be negative"); } - @TestOfyAndSql + @Test void testFailure_negativeRestoreBillingCost() { IllegalArgumentException thrown = assertThrows( @@ -500,7 +491,7 @@ public final class RegistryTest extends EntityTestCase { assertThat(thrown).hasMessageThat().contains("restoreBillingCost cannot be negative"); } - @TestOfyAndSql + @Test void testFailure_nonPositiveNumDnsPublishLocks() { IllegalArgumentException thrown = assertThrows( @@ -520,7 +511,7 @@ public final class RegistryTest extends EntityTestCase { "numDnsPublishLocks must be positive when set explicitly (use 1 for TLD-wide locks)"); } - @TestOfyAndSql + @Test void testFailure_negativeServerStatusChangeBillingCost() { IllegalArgumentException thrown = assertThrows( @@ -532,7 +523,7 @@ public final class RegistryTest extends EntityTestCase { assertThat(thrown).hasMessageThat().contains("billing cost cannot be negative"); } - @TestOfyAndSql + @Test void testFailure_renewBillingCostTransitionValue_wrongCurrency() { IllegalArgumentException thrown = assertThrows( @@ -546,7 +537,7 @@ public final class RegistryTest extends EntityTestCase { assertThat(thrown).hasMessageThat().contains("cost must be in the registry's currency"); } - @TestOfyAndSql + @Test void testFailure_createBillingCost_wrongCurrency() { IllegalArgumentException thrown = assertThrows( @@ -555,7 +546,7 @@ public final class RegistryTest extends EntityTestCase { assertThat(thrown).hasMessageThat().contains("cost must be in the registry's currency"); } - @TestOfyAndSql + @Test void testFailure_restoreBillingCost_wrongCurrency() { IllegalArgumentException thrown = assertThrows( @@ -564,7 +555,7 @@ public final class RegistryTest extends EntityTestCase { assertThat(thrown).hasMessageThat().contains("cost must be in the registry's currency"); } - @TestOfyAndSql + @Test void testFailure_serverStatusChangeBillingCost_wrongCurrency() { IllegalArgumentException thrown = assertThrows( @@ -577,13 +568,13 @@ public final class RegistryTest extends EntityTestCase { assertThat(thrown).hasMessageThat().contains("cost must be in the registry's currency"); } - @TestOfyAndSql + @Test void testEapFee_undefined() { assertThat(Registry.get("tld").getEapFeeFor(fakeClock.nowUtc()).getCost()) .isEqualTo(BigDecimal.ZERO.setScale(2, UNNECESSARY)); } - @TestOfyAndSql + @Test void testEapFee_specified() { DateTime a = fakeClock.nowUtc().minusDays(1); DateTime b = fakeClock.nowUtc().plusDays(1); @@ -605,7 +596,7 @@ public final class RegistryTest extends EntityTestCase { .isEqualTo(new BigDecimal("50.00")); } - @TestOfyAndSql + @Test void testFailure_eapFee_wrongCurrency() { IllegalArgumentException thrown = assertThrows( @@ -618,7 +609,7 @@ public final class RegistryTest extends EntityTestCase { assertThat(thrown).hasMessageThat().contains("All EAP fees must be in the registry's currency"); } - @TestOfyAndSql + @Test void testFailure_roidSuffixTooLong() { IllegalArgumentException e = assertThrows( @@ -627,14 +618,14 @@ public final class RegistryTest extends EntityTestCase { assertThat(e).hasMessageThat().isEqualTo("ROID suffix must be in format ^[A-Z\\d_]{1,8}$"); } - @TestOfyAndSql + @Test void testFailure_roidSuffixNotUppercased() { assertThrows( IllegalArgumentException.class, () -> Registry.get("tld").asBuilder().setRoidSuffix("abcd")); } - @TestOfyAndSql + @Test void testFailure_roidSuffixContainsInvalidCharacters() { assertThrows( IllegalArgumentException.class, diff --git a/core/src/test/java/google/registry/model/tld/label/GenrulePremiumListTest.java b/core/src/test/java/google/registry/model/tld/label/GenrulePremiumListTest.java index b116b56f2..f8e7033bc 100644 --- a/core/src/test/java/google/registry/model/tld/label/GenrulePremiumListTest.java +++ b/core/src/test/java/google/registry/model/tld/label/GenrulePremiumListTest.java @@ -34,8 +34,7 @@ class GenrulePremiumListTest { private static final String LISTS_DIRECTORY = "google/registry/config/files/premium/"; @RegisterExtension - final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().build(); + final AppEngineExtension appEngine = AppEngineExtension.builder().withCloudSql().build(); @Test void testParse_allPremiumLists() throws Exception { diff --git a/core/src/test/java/google/registry/model/tld/label/GenruleReservedListTest.java b/core/src/test/java/google/registry/model/tld/label/GenruleReservedListTest.java index c468970c0..beb3d06f5 100644 --- a/core/src/test/java/google/registry/model/tld/label/GenruleReservedListTest.java +++ b/core/src/test/java/google/registry/model/tld/label/GenruleReservedListTest.java @@ -34,8 +34,7 @@ class GenruleReservedListTest { private static final String LISTS_DIRECTORY = "google/registry/config/files/reserved/"; @RegisterExtension - final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().build(); + final AppEngineExtension appEngine = AppEngineExtension.builder().withCloudSql().build(); @Test void testParse_allReservedLists() throws Exception { diff --git a/core/src/test/java/google/registry/model/tld/label/PremiumListDaoTest.java b/core/src/test/java/google/registry/model/tld/label/PremiumListDaoTest.java index ee15666a3..ed86874cb 100644 --- a/core/src/test/java/google/registry/model/tld/label/PremiumListDaoTest.java +++ b/core/src/test/java/google/registry/model/tld/label/PremiumListDaoTest.java @@ -28,7 +28,7 @@ import com.google.common.base.Stopwatch; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.flogger.FluentLogger; -import google.registry.persistence.transaction.TransactionManagerUtil; +import google.registry.persistence.transaction.TransactionManagerFactory; import google.registry.testing.AppEngineExtension; import google.registry.testing.FakeClock; import google.registry.testing.TestCacheExtension; @@ -53,7 +53,7 @@ public class PremiumListDaoTest { @RegisterExtension final AppEngineExtension appEngine = AppEngineExtension.builder() - .withDatastoreAndCloudSql() + .withCloudSql() .enableJpaEntityCoverageCheck(true) .withClock(fakeClock) .build(); @@ -260,8 +260,8 @@ public class PremiumListDaoTest { PremiumListDao.save(testList); PremiumList pl = PremiumListDao.getLatestRevision("testname").get(); assertThat(PremiumListDao.premiumListCache.getIfPresent("testname")).hasValue(pl); - TransactionManagerUtil.transactIfJpaTm( - () -> PremiumListDao.save("testname", USD, ImmutableList.of("test,USD 1"))); + TransactionManagerFactory.tm() + .transact(() -> PremiumListDao.save("testname", USD, ImmutableList.of("test,USD 1"))); assertThat(PremiumListDao.premiumListCache.getIfPresent("testname")).isNull(); } diff --git a/core/src/test/java/google/registry/model/tld/label/PremiumListUtilsTest.java b/core/src/test/java/google/registry/model/tld/label/PremiumListUtilsTest.java index c25e7b3d2..9bf40dcf0 100644 --- a/core/src/test/java/google/registry/model/tld/label/PremiumListUtilsTest.java +++ b/core/src/test/java/google/registry/model/tld/label/PremiumListUtilsTest.java @@ -29,8 +29,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; class PremiumListUtilsTest { @RegisterExtension - final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().build(); + final AppEngineExtension appEngine = AppEngineExtension.builder().withCloudSql().build(); @Test void parseInputToPremiumList_works() { diff --git a/core/src/test/java/google/registry/model/transfer/TransferDataTest.java b/core/src/test/java/google/registry/model/transfer/TransferDataTest.java index 72764cb4c..e6827407f 100644 --- a/core/src/test/java/google/registry/model/transfer/TransferDataTest.java +++ b/core/src/test/java/google/registry/model/transfer/TransferDataTest.java @@ -36,8 +36,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; public class TransferDataTest { @RegisterExtension - public final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().build(); + public final AppEngineExtension appEngine = AppEngineExtension.builder().withCloudSql().build(); private final DateTime now = DateTime.now(UTC); diff --git a/core/src/test/java/google/registry/model/translators/StatusValueAdapterTest.java b/core/src/test/java/google/registry/model/translators/StatusValueAdapterTest.java index 318c06216..f8f652948 100644 --- a/core/src/test/java/google/registry/model/translators/StatusValueAdapterTest.java +++ b/core/src/test/java/google/registry/model/translators/StatusValueAdapterTest.java @@ -38,8 +38,7 @@ public class StatusValueAdapterTest { // Needed to create HostResources. @RegisterExtension - public AppEngineExtension appEngine = - new AppEngineExtension.Builder().withDatastoreAndCloudSql().build(); + public AppEngineExtension appEngine = new AppEngineExtension.Builder().withCloudSql().build(); @Test void testMarshalling() throws Exception { diff --git a/core/src/test/java/google/registry/model/translators/VKeyTranslatorFactoryTest.java b/core/src/test/java/google/registry/model/translators/VKeyTranslatorFactoryTest.java index e5a1a77c9..697994b3b 100644 --- a/core/src/test/java/google/registry/model/translators/VKeyTranslatorFactoryTest.java +++ b/core/src/test/java/google/registry/model/translators/VKeyTranslatorFactoryTest.java @@ -35,10 +35,7 @@ public class VKeyTranslatorFactoryTest { @RegisterExtension public final AppEngineExtension appEngine = - AppEngineExtension.builder() - .withDatastoreAndCloudSql() - .withOfyTestEntities(TestObject.class) - .build(); + AppEngineExtension.builder().withCloudSql().withOfyTestEntities(TestObject.class).build(); VKeyTranslatorFactoryTest() {} diff --git a/core/src/test/java/google/registry/module/backend/BackendServletTest.java b/core/src/test/java/google/registry/module/backend/BackendServletTest.java index 096147b60..b5f5b7374 100644 --- a/core/src/test/java/google/registry/module/backend/BackendServletTest.java +++ b/core/src/test/java/google/registry/module/backend/BackendServletTest.java @@ -29,7 +29,7 @@ class BackendServletTest { @RegisterExtension final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().withLocalModules().build(); + AppEngineExtension.builder().withCloudSql().withLocalModules().build(); private final HttpServletRequest req = mock(HttpServletRequest.class); private final HttpServletResponse rsp = mock(HttpServletResponse.class); diff --git a/core/src/test/java/google/registry/module/frontend/FrontendServletTest.java b/core/src/test/java/google/registry/module/frontend/FrontendServletTest.java index a35e8d918..45c776784 100644 --- a/core/src/test/java/google/registry/module/frontend/FrontendServletTest.java +++ b/core/src/test/java/google/registry/module/frontend/FrontendServletTest.java @@ -29,7 +29,7 @@ class FrontendServletTest { @RegisterExtension final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().withLocalModules().build(); + AppEngineExtension.builder().withCloudSql().withLocalModules().build(); private final HttpServletRequest req = mock(HttpServletRequest.class); private final HttpServletResponse rsp = mock(HttpServletResponse.class); diff --git a/core/src/test/java/google/registry/module/pubapi/PubApiServletTest.java b/core/src/test/java/google/registry/module/pubapi/PubApiServletTest.java index 699bd5c29..a49fced1b 100644 --- a/core/src/test/java/google/registry/module/pubapi/PubApiServletTest.java +++ b/core/src/test/java/google/registry/module/pubapi/PubApiServletTest.java @@ -29,7 +29,7 @@ class PubApiServletTest { @RegisterExtension final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().withLocalModules().build(); + AppEngineExtension.builder().withCloudSql().withLocalModules().build(); private final HttpServletRequest req = mock(HttpServletRequest.class); private final HttpServletResponse rsp = mock(HttpServletResponse.class); diff --git a/core/src/test/java/google/registry/monitoring/whitebox/EppMetricTest.java b/core/src/test/java/google/registry/monitoring/whitebox/EppMetricTest.java index 290934b1c..1180c5771 100644 --- a/core/src/test/java/google/registry/monitoring/whitebox/EppMetricTest.java +++ b/core/src/test/java/google/registry/monitoring/whitebox/EppMetricTest.java @@ -28,8 +28,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; class EppMetricTest { @RegisterExtension - final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().build(); + final AppEngineExtension appEngine = AppEngineExtension.builder().withCloudSql().build(); @Test void test_invalidTld_isRecordedAsInvalid() { diff --git a/core/src/test/java/google/registry/persistence/BillingVKeyTest.java b/core/src/test/java/google/registry/persistence/BillingVKeyTest.java index 95024b539..9efa9ec80 100644 --- a/core/src/test/java/google/registry/persistence/BillingVKeyTest.java +++ b/core/src/test/java/google/registry/persistence/BillingVKeyTest.java @@ -30,23 +30,21 @@ import google.registry.model.reporting.HistoryEntry; import google.registry.persistence.BillingVKey.BillingEventVKey; import google.registry.persistence.BillingVKey.BillingRecurrenceVKey; import google.registry.testing.AppEngineExtension; -import google.registry.testing.DualDatabaseTest; -import google.registry.testing.TestOfyAndSql; import javax.persistence.Transient; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; /** Unit test for {@link BillingVKey}. */ -@DualDatabaseTest class BillingVKeyTest { @RegisterExtension final AppEngineExtension appEngine = AppEngineExtension.builder() - .withDatastoreAndCloudSql() + .withCloudSql() .withOfyTestEntities(BillingVKeyTestEntity.class) .withJpaUnitTestEntities(BillingVKeyTestEntity.class) .build(); - @TestOfyAndSql + @Test void testRestoreSymmetricVKey() { Key domainHistoryKey = Key.create(Key.create(DomainBase.class, "domainRepoId"), HistoryEntry.class, 10L); @@ -70,7 +68,7 @@ class BillingVKeyTest { assertThat(persisted.getBillingRecurrenceVKey()).isEqualTo(recurringVKey); } - @TestOfyAndSql + @Test void testHandleNullVKeyCorrectly() { BillingVKeyTestEntity original = new BillingVKeyTestEntity(null, null); tm().transact(() -> tm().insert(original)); diff --git a/core/src/test/java/google/registry/persistence/DomainHistoryVKeyTest.java b/core/src/test/java/google/registry/persistence/DomainHistoryVKeyTest.java index f8d7f55d8..9c5ef83e3 100644 --- a/core/src/test/java/google/registry/persistence/DomainHistoryVKeyTest.java +++ b/core/src/test/java/google/registry/persistence/DomainHistoryVKeyTest.java @@ -28,24 +28,22 @@ import google.registry.model.domain.DomainBase; import google.registry.model.domain.DomainHistory.DomainHistoryId; import google.registry.model.reporting.HistoryEntry; import google.registry.testing.AppEngineExtension; -import google.registry.testing.DualDatabaseTest; -import google.registry.testing.TestOfyAndSql; import javax.persistence.Transient; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; /** Unit test for {@link DomainHistoryVKey}. */ -@DualDatabaseTest class DomainHistoryVKeyTest { @RegisterExtension final AppEngineExtension appEngine = AppEngineExtension.builder() - .withDatastoreAndCloudSql() + .withCloudSql() .withOfyTestEntities(TestEntity.class) .withJpaUnitTestEntities(TestEntity.class) .build(); - @TestOfyAndSql + @Test void testRestoreSymmetricVKey() { Key ofyKey = Key.create(Key.create(DomainBase.class, "domainRepoId"), HistoryEntry.class, 10L); @@ -61,7 +59,7 @@ class DomainHistoryVKeyTest { .isEqualTo(VKey.createSql(HistoryEntry.class, new DomainHistoryId("domainRepoId", 10L))); } - @TestOfyAndSql + @Test void testCreateSymmetricVKeyFromOfyKey() { Key ofyKey = Key.create(Key.create(DomainBase.class, "domainRepoId"), HistoryEntry.class, 10L); diff --git a/core/src/test/java/google/registry/persistence/VKeyTest.java b/core/src/test/java/google/registry/persistence/VKeyTest.java index 075749587..860194117 100644 --- a/core/src/test/java/google/registry/persistence/VKeyTest.java +++ b/core/src/test/java/google/registry/persistence/VKeyTest.java @@ -37,10 +37,7 @@ class VKeyTest { @RegisterExtension final AppEngineExtension appEngineExtension = - AppEngineExtension.builder() - .withDatastoreAndCloudSql() - .withOfyTestEntities(TestObject.class) - .build(); + AppEngineExtension.builder().withCloudSql().withOfyTestEntities(TestObject.class).build(); @BeforeAll static void beforeAll() { diff --git a/core/src/test/java/google/registry/persistence/converter/InetAddressSetConverterTest.java b/core/src/test/java/google/registry/persistence/converter/InetAddressSetConverterTest.java index 4889c527d..6c9d82d87 100644 --- a/core/src/test/java/google/registry/persistence/converter/InetAddressSetConverterTest.java +++ b/core/src/test/java/google/registry/persistence/converter/InetAddressSetConverterTest.java @@ -37,7 +37,7 @@ public class InetAddressSetConverterTest { @RegisterExtension public final AppEngineExtension appEngine = AppEngineExtension.builder() - .withDatastoreAndCloudSql() + .withCloudSql() .withJpaUnitTestEntities(InetAddressSetTestEntity.class) .build(); diff --git a/core/src/test/java/google/registry/persistence/converter/LongVKeyConverterTest.java b/core/src/test/java/google/registry/persistence/converter/LongVKeyConverterTest.java index e49bfb2eb..090d4ca3f 100644 --- a/core/src/test/java/google/registry/persistence/converter/LongVKeyConverterTest.java +++ b/core/src/test/java/google/registry/persistence/converter/LongVKeyConverterTest.java @@ -33,7 +33,7 @@ public class LongVKeyConverterTest { @RegisterExtension public final AppEngineExtension appEngineExtension = new AppEngineExtension.Builder() - .withDatastoreAndCloudSql() + .withCloudSql() .withoutCannedData() .withJpaUnitTestEntities( TestLongEntity.class, diff --git a/core/src/test/java/google/registry/persistence/converter/StringVKeyConverterTest.java b/core/src/test/java/google/registry/persistence/converter/StringVKeyConverterTest.java index 7d0da6425..e03f6b61f 100644 --- a/core/src/test/java/google/registry/persistence/converter/StringVKeyConverterTest.java +++ b/core/src/test/java/google/registry/persistence/converter/StringVKeyConverterTest.java @@ -33,7 +33,7 @@ public class StringVKeyConverterTest { @RegisterExtension public final AppEngineExtension appEngineExtension = new AppEngineExtension.Builder() - .withDatastoreAndCloudSql() + .withCloudSql() .withoutCannedData() .withJpaUnitTestEntities( TestStringEntity.class, diff --git a/core/src/test/java/google/registry/persistence/transaction/QueryComposerTest.java b/core/src/test/java/google/registry/persistence/transaction/QueryComposerTest.java index 396df08d9..4dc060f3e 100644 --- a/core/src/test/java/google/registry/persistence/transaction/QueryComposerTest.java +++ b/core/src/test/java/google/registry/persistence/transaction/QueryComposerTest.java @@ -18,7 +18,6 @@ import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.common.truth.Truth.assertThat; import static google.registry.persistence.transaction.QueryComposer.Comparator; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import static org.junit.Assert.assertThrows; import com.googlecode.objectify.annotation.Entity; @@ -27,19 +26,15 @@ import com.googlecode.objectify.annotation.Index; import google.registry.model.ImmutableObject; import google.registry.testing.AppEngineExtension; import google.registry.testing.DatabaseHelper; -import google.registry.testing.DualDatabaseTest; import google.registry.testing.FakeClock; -import google.registry.testing.TestOfyAndSql; -import google.registry.testing.TestOfyOnly; -import google.registry.testing.TestSqlOnly; import java.util.Optional; import javax.persistence.Column; import javax.persistence.NoResultException; import javax.persistence.NonUniqueResultException; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; -@DualDatabaseTest public class QueryComposerTest { private final FakeClock fakeClock = new FakeClock(); @@ -52,7 +47,7 @@ public class QueryComposerTest { public final AppEngineExtension appEngine = AppEngineExtension.builder() .withClock(fakeClock) - .withDatastoreAndCloudSql() + .withCloudSql() .withOfyTestEntities(TestEntity.class) .withJpaUnitTestEntities(TestEntity.class) .build(); @@ -69,291 +64,261 @@ public class QueryComposerTest { }); } - @TestOfyAndSql + @Test public void testFirstQueries() { assertThat( - transactIfJpaTm( - () -> - tm().createQueryComposer(TestEntity.class) - .where("name", Comparator.GT, "bravo") - .first() - .map(QueryComposerTest::assertDetachedIfJpa) - .get())) + tm().transact( + () -> + tm().createQueryComposer(TestEntity.class) + .where("name", Comparator.GT, "bravo") + .first() + .map(QueryComposerTest::assertDetachedIfJpa) + .get())) .isEqualTo(charlie); assertThat( - transactIfJpaTm( - () -> - tm().createQueryComposer(TestEntity.class) - .where("name", Comparator.GTE, "charlie") - .first() - .map(QueryComposerTest::assertDetachedIfJpa) - .get())) + tm().transact( + () -> + tm().createQueryComposer(TestEntity.class) + .where("name", Comparator.GTE, "charlie") + .first() + .map(QueryComposerTest::assertDetachedIfJpa) + .get())) .isEqualTo(charlie); assertThat( - transactIfJpaTm( - () -> - tm().createQueryComposer(TestEntity.class) - .where("name", Comparator.LT, "bravo") - .first() - .map(QueryComposerTest::assertDetachedIfJpa) - .get())) + tm().transact( + () -> + tm().createQueryComposer(TestEntity.class) + .where("name", Comparator.LT, "bravo") + .first() + .map(QueryComposerTest::assertDetachedIfJpa) + .get())) .isEqualTo(alpha); assertThat( - transactIfJpaTm( - () -> - tm().createQueryComposer(TestEntity.class) - .where("name", Comparator.LTE, "alpha") - .first() - .map(QueryComposerTest::assertDetachedIfJpa) - .get())) + tm().transact( + () -> + tm().createQueryComposer(TestEntity.class) + .where("name", Comparator.LTE, "alpha") + .first() + .map(QueryComposerTest::assertDetachedIfJpa) + .get())) .isEqualTo(alpha); } - @TestOfyAndSql + @Test public void testCount() { assertThat( - transactIfJpaTm( - () -> - tm().createQueryComposer(TestEntity.class) - .where("name", Comparator.GTE, "bravo") - .count())) + tm().transact( + () -> + tm().createQueryComposer(TestEntity.class) + .where("name", Comparator.GTE, "bravo") + .count())) .isEqualTo(2L); } - @TestOfyAndSql + @Test public void testGetSingleResult() { assertThat( - transactIfJpaTm( - () -> - QueryComposerTest.assertDetachedIfJpa( - tm().createQueryComposer(TestEntity.class) - .where("name", Comparator.EQ, "alpha") - .getSingleResult()))) + tm().transact( + () -> + QueryComposerTest.assertDetachedIfJpa( + tm().createQueryComposer(TestEntity.class) + .where("name", Comparator.EQ, "alpha") + .getSingleResult()))) .isEqualTo(alpha); } - @TestOfyAndSql + @Test public void testGetSingleResult_noResults() { assertThrows( NoResultException.class, () -> - transactIfJpaTm( - () -> - tm().createQueryComposer(TestEntity.class) - .where("name", Comparator.EQ, "ziggy") - .getSingleResult())); + tm().transact( + () -> + tm().createQueryComposer(TestEntity.class) + .where("name", Comparator.EQ, "ziggy") + .getSingleResult())); } - @TestOfyAndSql + @Test public void testGetSingleResult_nonUniqueResult() { assertThrows( NonUniqueResultException.class, () -> - transactIfJpaTm( - () -> - tm().createQueryComposer(TestEntity.class) - .where("name", Comparator.GT, "alpha") - .getSingleResult())); + tm().transact( + () -> + tm().createQueryComposer(TestEntity.class) + .where("name", Comparator.GT, "alpha") + .getSingleResult())); } - @TestOfyAndSql + @Test public void testStreamQueries() { assertThat( - transactIfJpaTm( - () -> - tm() - .createQueryComposer(TestEntity.class) - .where("name", Comparator.EQ, "alpha") - .stream() - .collect(toImmutableList()))) + tm().transact( + () -> + tm() + .createQueryComposer(TestEntity.class) + .where("name", Comparator.EQ, "alpha") + .stream() + .collect(toImmutableList()))) .containsExactly(alpha); assertThat( - transactIfJpaTm( - () -> - tm() - .createQueryComposer(TestEntity.class) - .where("name", Comparator.GT, "alpha") - .stream() - .map(QueryComposerTest::assertDetachedIfJpa) - .collect(toImmutableList()))) + tm().transact( + () -> + tm() + .createQueryComposer(TestEntity.class) + .where("name", Comparator.GT, "alpha") + .stream() + .map(QueryComposerTest::assertDetachedIfJpa) + .collect(toImmutableList()))) .containsExactly(bravo, charlie); assertThat( - transactIfJpaTm( - () -> - tm() - .createQueryComposer(TestEntity.class) - .where("name", Comparator.GTE, "bravo") - .stream() - .map(QueryComposerTest::assertDetachedIfJpa) - .collect(toImmutableList()))) + tm().transact( + () -> + tm() + .createQueryComposer(TestEntity.class) + .where("name", Comparator.GTE, "bravo") + .stream() + .map(QueryComposerTest::assertDetachedIfJpa) + .collect(toImmutableList()))) .containsExactly(bravo, charlie); assertThat( - transactIfJpaTm( - () -> - tm() - .createQueryComposer(TestEntity.class) - .where("name", Comparator.LT, "charlie") - .stream() - .map(QueryComposerTest::assertDetachedIfJpa) - .collect(toImmutableList()))) + tm().transact( + () -> + tm() + .createQueryComposer(TestEntity.class) + .where("name", Comparator.LT, "charlie") + .stream() + .map(QueryComposerTest::assertDetachedIfJpa) + .collect(toImmutableList()))) .containsExactly(alpha, bravo); assertThat( - transactIfJpaTm( - () -> - tm() - .createQueryComposer(TestEntity.class) - .where("name", Comparator.LTE, "bravo") - .stream() - .map(QueryComposerTest::assertDetachedIfJpa) - .collect(toImmutableList()))) + tm().transact( + () -> + tm() + .createQueryComposer(TestEntity.class) + .where("name", Comparator.LTE, "bravo") + .stream() + .map(QueryComposerTest::assertDetachedIfJpa) + .collect(toImmutableList()))) .containsExactly(alpha, bravo); } - @TestOfyAndSql + @Test public void testListQueries() { assertThat( - transactIfJpaTm( - () -> - tm().createQueryComposer(TestEntity.class) - .where("name", Comparator.GT, "alpha") - .list())) + tm().transact( + () -> + tm().createQueryComposer(TestEntity.class) + .where("name", Comparator.GT, "alpha") + .list())) .containsExactly(bravo, charlie); } - @TestOfyAndSql + @Test public void testNonPrimaryKey() { assertThat( - transactIfJpaTm( - () -> - tm().createQueryComposer(TestEntity.class) - .where("val", Comparator.EQ, 2) - .first() - .map(QueryComposerTest::assertDetachedIfJpa) - .get())) + tm().transact( + () -> + tm().createQueryComposer(TestEntity.class) + .where("val", Comparator.EQ, 2) + .first() + .map(QueryComposerTest::assertDetachedIfJpa) + .get())) .isEqualTo(bravo); } - @TestOfyAndSql + @Test public void testOrderBy() { assertThat( - transactIfJpaTm( - () -> - tm() - .createQueryComposer(TestEntity.class) - .where("val", Comparator.GT, 1) - .orderBy("val") - .stream() - .map(QueryComposerTest::assertDetachedIfJpa) - .collect(toImmutableList()))) + tm().transact( + () -> + tm() + .createQueryComposer(TestEntity.class) + .where("val", Comparator.GT, 1) + .orderBy("val") + .stream() + .map(QueryComposerTest::assertDetachedIfJpa) + .collect(toImmutableList()))) .containsExactly(bravo, alpha); } - @TestOfyAndSql + @Test public void testEmptyQueries() { assertThat( - transactIfJpaTm( - () -> - tm().createQueryComposer(TestEntity.class) - .where("name", Comparator.GT, "foxtrot") - .first())) + tm().transact( + () -> + tm().createQueryComposer(TestEntity.class) + .where("name", Comparator.GT, "foxtrot") + .first())) .isEqualTo(Optional.empty()); assertThat( - transactIfJpaTm( - () -> - tm() - .createQueryComposer(TestEntity.class) - .where("name", Comparator.GT, "foxtrot") - .stream() - .collect(toImmutableList()))) + tm().transact( + () -> + tm() + .createQueryComposer(TestEntity.class) + .where("name", Comparator.GT, "foxtrot") + .stream() + .collect(toImmutableList()))) .isEmpty(); } - @TestOfyOnly - void testMultipleInequalities_failsDatastore() { - assertThat( - assertThrows( - IllegalArgumentException.class, - () -> - tm().createQueryComposer(TestEntity.class) - .where("val", Comparator.GT, 1) - .where("name", Comparator.LT, "b") - .list())) - .hasMessageThat() - .isEqualTo( - "Datastore cannot handle inequality queries on multiple fields, we found 2 fields."); - } - - @TestSqlOnly + @Test void testMultipleInequalities_succeedsSql() { assertThat( - transactIfJpaTm( - () -> - tm().createQueryComposer(TestEntity.class) - .where("val", Comparator.GT, 1) - .where("name", Comparator.LT, "b") - .list())) + tm().transact( + () -> + tm().createQueryComposer(TestEntity.class) + .where("val", Comparator.GT, 1) + .where("name", Comparator.LT, "b") + .list())) .containsExactly(alpha); } - @TestSqlOnly + @Test public void testLikeQueries() { assertThat( - transactIfJpaTm( - () -> - tm() - .createQueryComposer(TestEntity.class) - .where("name", Comparator.LIKE, "%harl%") - .stream() - .collect(toImmutableList()))) + tm().transact( + () -> + tm() + .createQueryComposer(TestEntity.class) + .where("name", Comparator.LIKE, "%harl%") + .stream() + .collect(toImmutableList()))) .containsExactly(charlie); // Verify that full matches work. assertThat( - transactIfJpaTm( - () -> - tm() - .createQueryComposer(TestEntity.class) - .where("name", Comparator.LIKE, "alpha") - .stream() - .collect(toImmutableList()))) + tm().transact( + () -> + tm() + .createQueryComposer(TestEntity.class) + .where("name", Comparator.LIKE, "alpha") + .stream() + .collect(toImmutableList()))) .containsExactly(alpha); // verify that we don't do partial matches. assertThat( - transactIfJpaTm( - () -> - tm() - .createQueryComposer(TestEntity.class) - .where("name", Comparator.LIKE, "%harl") - .stream() - .collect(toImmutableList()))) + tm().transact( + () -> + tm() + .createQueryComposer(TestEntity.class) + .where("name", Comparator.LIKE, "%harl") + .stream() + .collect(toImmutableList()))) .isEmpty(); assertThat( - transactIfJpaTm( - () -> - tm() - .createQueryComposer(TestEntity.class) - .where("name", Comparator.LIKE, "harl%") - .stream() - .collect(toImmutableList()))) + tm().transact( + () -> + tm() + .createQueryComposer(TestEntity.class) + .where("name", Comparator.LIKE, "harl%") + .stream() + .collect(toImmutableList()))) .isEmpty(); } - @TestOfyOnly - public void testLikeQueries_failsOnOfy() { - UnsupportedOperationException thrown = - assertThrows( - UnsupportedOperationException.class, - () -> - tm() - .createQueryComposer(TestEntity.class) - .where("name", Comparator.LIKE, "%") - .stream()); - assertThat(thrown) - .hasMessageThat() - .contains("The LIKE operation is not supported on Datastore."); - } - private static T assertDetachedIfJpa(T entity) { if (!tm().isOfy()) { return DatabaseHelper.assertDetachedFromEntityManager(entity); diff --git a/core/src/test/java/google/registry/persistence/transaction/TransactionManagerTest.java b/core/src/test/java/google/registry/persistence/transaction/TransactionManagerTest.java index a654e0852..9d6cf8203 100644 --- a/core/src/test/java/google/registry/persistence/transaction/TransactionManagerTest.java +++ b/core/src/test/java/google/registry/persistence/transaction/TransactionManagerTest.java @@ -17,26 +17,21 @@ package google.registry.persistence.transaction; import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.common.collect.ImmutableSet.toImmutableSet; import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.Truth8.assertThat; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import static org.junit.jupiter.api.Assertions.assertThrows; import com.google.common.collect.ImmutableList; import com.google.common.collect.Maps; +import com.google.common.truth.Truth8; import com.googlecode.objectify.Key; import com.googlecode.objectify.annotation.Entity; import com.googlecode.objectify.annotation.Id; import google.registry.model.ImmutableObject; -import google.registry.model.ofy.DatastoreTransactionManager; import google.registry.model.ofy.Ofy; import google.registry.persistence.VKey; import google.registry.testing.AppEngineExtension; -import google.registry.testing.DualDatabaseTest; import google.registry.testing.FakeClock; import google.registry.testing.InjectExtension; -import google.registry.testing.TestOfyAndSql; -import google.registry.testing.TestOfyOnly; import java.util.List; import java.util.NoSuchElementException; import java.util.Set; @@ -44,13 +39,10 @@ import java.util.stream.Stream; import javax.persistence.Embeddable; import javax.persistence.MappedSuperclass; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; -/** - * Unit tests for common APIs in {@link DatastoreTransactionManager} and {@link - * JpaTransactionManagerImpl}. - */ -@DualDatabaseTest +/** Unit tests for APIs in {@link JpaTransactionManagerImpl}. */ public class TransactionManagerTest { private final FakeClock fakeClock = new FakeClock(); @@ -68,7 +60,7 @@ public class TransactionManagerTest { public final AppEngineExtension appEngine = AppEngineExtension.builder() .withClock(fakeClock) - .withDatastoreAndCloudSql() + .withCloudSql() .withOfyTestEntities(TestEntity.class) .withJpaUnitTestEntities(TestEntity.class, TestEntityBase.class) .build(); @@ -81,21 +73,21 @@ public class TransactionManagerTest { fakeClock.setAutoIncrementByOneMilli(); } - @TestOfyAndSql + @Test void inTransaction_returnsCorrespondingResult() { assertThat(tm().inTransaction()).isFalse(); tm().transact(() -> assertThat(tm().inTransaction()).isTrue()); assertThat(tm().inTransaction()).isFalse(); } - @TestOfyAndSql + @Test void assertInTransaction_throwsExceptionWhenNotInTransaction() { assertThrows(IllegalStateException.class, () -> tm().assertInTransaction()); tm().transact(() -> tm().assertInTransaction()); assertThrows(IllegalStateException.class, () -> tm().assertInTransaction()); } - @TestOfyAndSql + @Test void getTransactionTime_throwsExceptionWhenNotInTransaction() { assertThrows(IllegalStateException.class, () -> tm().getTransactionTime()); fakeClock.disableAutoIncrement(); @@ -103,7 +95,7 @@ public class TransactionManagerTest { assertThrows(IllegalStateException.class, () -> tm().getTransactionTime()); } - @TestOfyAndSql + @Test void transact_hasNoEffectWithPartialSuccess() { assertEntityNotExist(theEntity); assertThrows( @@ -117,21 +109,21 @@ public class TransactionManagerTest { assertEntityNotExist(theEntity); } - @TestOfyAndSql + @Test void transact_reusesExistingTransaction() { assertEntityNotExist(theEntity); tm().transact(() -> tm().transact(() -> tm().insert(theEntity))); assertEntityExists(theEntity); } - @TestOfyAndSql + @Test void transactNew_succeeds() { assertEntityNotExist(theEntity); tm().transactNew(() -> tm().insert(theEntity)); assertEntityExists(theEntity); } - @TestOfyAndSql + @Test void transactNewReadOnly_succeeds() { assertEntityNotExist(theEntity); tm().transact(() -> tm().insert(theEntity)); @@ -140,15 +132,7 @@ public class TransactionManagerTest { assertThat(persisted).isEqualTo(theEntity); } - @TestOfyOnly // read-only not implemented in SQL yet - void transactNewReadOnly_throwsWhenWritingEntity() { - assertEntityNotExist(theEntity); - assertThrows( - RuntimeException.class, () -> tm().transactNewReadOnly(() -> tm().insert(theEntity))); - assertEntityNotExist(theEntity); - } - - @TestOfyAndSql + @Test void saveNew_succeeds() { assertEntityNotExist(theEntity); tm().transact(() -> tm().insert(theEntity)); @@ -156,14 +140,14 @@ public class TransactionManagerTest { assertThat(tm().transact(() -> tm().loadByKey(theEntity.key()))).isEqualTo(theEntity); } - @TestOfyAndSql + @Test void saveAllNew_succeeds() { assertAllEntitiesNotExist(moreEntities); tm().transact(() -> tm().insertAll(moreEntities)); assertAllEntitiesExist(moreEntities); } - @TestOfyAndSql + @Test void saveNewOrUpdate_persistsNewEntity() { assertEntityNotExist(theEntity); tm().transact(() -> tm().put(theEntity)); @@ -171,7 +155,7 @@ public class TransactionManagerTest { assertThat(tm().transact(() -> tm().loadByKey(theEntity.key()))).isEqualTo(theEntity); } - @TestOfyAndSql + @Test void saveNewOrUpdate_updatesExistingEntity() { tm().transact(() -> tm().insert(theEntity)); TestEntity persisted = tm().transact(() -> tm().loadByKey(theEntity.key())); @@ -182,14 +166,14 @@ public class TransactionManagerTest { assertThat(persisted.data).isEqualTo("bar"); } - @TestOfyAndSql + @Test void saveNewOrUpdateAll_succeeds() { assertAllEntitiesNotExist(moreEntities); tm().transact(() -> tm().putAll(moreEntities)); assertAllEntitiesExist(moreEntities); } - @TestOfyAndSql + @Test void update_succeeds() { tm().transact(() -> tm().insert(theEntity)); TestEntity persisted = @@ -204,7 +188,7 @@ public class TransactionManagerTest { assertThat(persisted.data).isEqualTo("bar"); } - @TestOfyAndSql + @Test void load_succeeds() { assertEntityNotExist(theEntity); tm().transact(() -> tm().insert(theEntity)); @@ -213,14 +197,14 @@ public class TransactionManagerTest { assertThat(persisted.data).isEqualTo("foo"); } - @TestOfyAndSql + @Test void load_throwsOnMissingElement() { assertEntityNotExist(theEntity); assertThrows( NoSuchElementException.class, () -> tm().transact(() -> tm().loadByKey(theEntity.key()))); } - @TestOfyAndSql + @Test void maybeLoad_succeeds() { assertEntityNotExist(theEntity); tm().transact(() -> tm().insert(theEntity)); @@ -229,13 +213,13 @@ public class TransactionManagerTest { assertThat(persisted.data).isEqualTo("foo"); } - @TestOfyAndSql + @Test void maybeLoad_nonExistentObject() { assertEntityNotExist(theEntity); assertThat(tm().transact(() -> tm().loadByKeyIfPresent(theEntity.key())).isPresent()).isFalse(); } - @TestOfyAndSql + @Test void delete_succeeds() { tm().transact(() -> tm().insert(theEntity)); assertEntityExists(theEntity); @@ -243,14 +227,14 @@ public class TransactionManagerTest { assertEntityNotExist(theEntity); } - @TestOfyAndSql + @Test void delete_doNothingWhenEntityNotExist() { assertEntityNotExist(theEntity); tm().transact(() -> tm().delete(theEntity.key())); assertEntityNotExist(theEntity); } - @TestOfyAndSql + @Test void delete_succeedsForEntitySet() { assertAllEntitiesNotExist(moreEntities); tm().transact(() -> tm().insertAll(moreEntities)); @@ -261,7 +245,7 @@ public class TransactionManagerTest { assertAllEntitiesNotExist(moreEntities); } - @TestOfyAndSql + @Test void delete_ignoreNonExistentEntity() { assertAllEntitiesNotExist(moreEntities); tm().transact(() -> tm().insertAll(moreEntities)); @@ -274,7 +258,7 @@ public class TransactionManagerTest { assertAllEntitiesNotExist(moreEntities); } - @TestOfyAndSql + @Test void delete_deletesTheGivenEntity() { tm().transact(() -> tm().insert(theEntity)); assertEntityExists(theEntity); @@ -282,7 +266,7 @@ public class TransactionManagerTest { assertEntityNotExist(theEntity); } - @TestOfyAndSql + @Test void load_multi() { assertAllEntitiesNotExist(moreEntities); tm().transact(() -> tm().insertAll(moreEntities)); @@ -292,7 +276,7 @@ public class TransactionManagerTest { .isEqualTo(Maps.uniqueIndex(moreEntities, TestEntity::key)); } - @TestOfyAndSql + @Test void load_multiWithDuplicateKeys() { assertAllEntitiesNotExist(moreEntities); tm().transact(() -> tm().insertAll(moreEntities)); @@ -304,7 +288,7 @@ public class TransactionManagerTest { .isEqualTo(Maps.uniqueIndex(moreEntities, TestEntity::key)); } - @TestOfyAndSql + @Test void load_multiMissingKeys() { assertAllEntitiesNotExist(moreEntities); tm().transact(() -> tm().insertAll(moreEntities)); @@ -319,7 +303,7 @@ public class TransactionManagerTest { .contains("dark"); } - @TestOfyAndSql + @Test void loadExisting_missingKeys() { assertAllEntitiesNotExist(moreEntities); tm().transact(() -> tm().insertAll(moreEntities)); @@ -331,14 +315,14 @@ public class TransactionManagerTest { .isEqualTo(Maps.uniqueIndex(moreEntities, TestEntity::key)); } - @TestOfyAndSql + @Test void loadAll_success() { tm().transact(() -> tm().insertAll(moreEntities)); assertThat(tm().transact(() -> tm().loadByEntities(moreEntities))) .containsExactlyElementsIn(moreEntities); } - @TestOfyAndSql + @Test void loadAll_missingKeys() { assertAllEntitiesNotExist(moreEntities); tm().transact(() -> tm().insertAll(moreEntities)); @@ -351,7 +335,7 @@ public class TransactionManagerTest { .contains("dark"); } - @TestOfyAndSql + @Test void loadAllExisting_missingKeys() { tm().transact(() -> tm().insertAll(moreEntities)); tm().transact(() -> tm().delete(new TestEntity("entity1", "foo"))); @@ -365,37 +349,29 @@ public class TransactionManagerTest { .containsExactly("entity2", "entity3"); } - @TestOfyOnly - void loadAllForOfyTm_throwsExceptionInTransaction() { - assertAllEntitiesNotExist(moreEntities); - tm().transact(() -> tm().insertAll(moreEntities)); - assertThrows( - IllegalArgumentException.class, - () -> tm().transact(() -> tm().loadAllOf(TestEntity.class))); - } - - @TestOfyAndSql + @Test void loadSingleton_returnsValue_orEmpty() { assertEntityNotExist(theEntity); - assertThat(transactIfJpaTm(() -> tm().loadSingleton(TestEntity.class))).isEmpty(); + Truth8.assertThat(tm().transact(() -> tm().loadSingleton(TestEntity.class))).isEmpty(); tm().transact(() -> tm().insert(theEntity)); - assertThat(transactIfJpaTm(() -> tm().loadSingleton(TestEntity.class))).hasValue(theEntity); + Truth8.assertThat(tm().transact(() -> tm().loadSingleton(TestEntity.class))) + .hasValue(theEntity); } - @TestOfyAndSql + @Test void loadSingleton_exceptionOnMultiple() { assertAllEntitiesNotExist(moreEntities); tm().transact(() -> tm().insertAll(moreEntities)); assertThat( assertThrows( IllegalArgumentException.class, - () -> transactIfJpaTm(() -> tm().loadSingleton(TestEntity.class)))) + () -> tm().transact(() -> tm().loadSingleton(TestEntity.class)))) .hasMessageThat() .isEqualTo("Expected at most one entity of type TestEntity, found at least two"); } - @TestOfyAndSql + @Test void mutatedObjectNotPersisted() { tm().transact(() -> tm().insert(theEntity)); tm().transact( diff --git a/core/src/test/java/google/registry/pricing/PricingEngineProxyTest.java b/core/src/test/java/google/registry/pricing/PricingEngineProxyTest.java index 6fa74cdd6..bf7345f31 100644 --- a/core/src/test/java/google/registry/pricing/PricingEngineProxyTest.java +++ b/core/src/test/java/google/registry/pricing/PricingEngineProxyTest.java @@ -41,8 +41,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; public class PricingEngineProxyTest { @RegisterExtension - public final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().build(); + public final AppEngineExtension appEngine = AppEngineExtension.builder().withCloudSql().build(); private Clock clock; diff --git a/core/src/test/java/google/registry/rdap/RdapActionBaseTestCase.java b/core/src/test/java/google/registry/rdap/RdapActionBaseTestCase.java index c2cd26dca..c0d632461 100644 --- a/core/src/test/java/google/registry/rdap/RdapActionBaseTestCase.java +++ b/core/src/test/java/google/registry/rdap/RdapActionBaseTestCase.java @@ -46,8 +46,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; abstract class RdapActionBaseTestCase { @RegisterExtension - public final AppEngineExtension appEngine = - AppEngineExtension.builder().withDatastoreAndCloudSql().build(); + public final AppEngineExtension appEngine = AppEngineExtension.builder().withCloudSql().build(); @RegisterExtension public final InjectExtension inject = new InjectExtension(); diff --git a/core/src/test/java/google/registry/rdap/RdapDomainActionTest.java b/core/src/test/java/google/registry/rdap/RdapDomainActionTest.java index 5f3b104be..d6b402853 100644 --- a/core/src/test/java/google/registry/rdap/RdapDomainActionTest.java +++ b/core/src/test/java/google/registry/rdap/RdapDomainActionTest.java @@ -40,11 +40,10 @@ import google.registry.rdap.RdapMetrics.SearchType; import google.registry.rdap.RdapMetrics.WildcardType; import google.registry.rdap.RdapSearchResults.IncompletenessWarningType; import google.registry.request.Action; -import google.registry.testing.DualDatabaseTest; -import google.registry.testing.TestOfyAndSql; import java.util.Optional; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; /** * Unit tests for {@link RdapDomainAction}. @@ -52,7 +51,6 @@ import org.junit.jupiter.api.Disabled; *

TODO(b/26872828): The next time we do any work on RDAP, consider adding the APNIC RDAP * conformance checker to the unit test suite. */ -@DualDatabaseTest class RdapDomainActionTest extends RdapActionBaseTestCase { RdapDomainActionTest() { @@ -249,7 +247,7 @@ class RdapDomainActionTest extends RdapActionBaseTestCase { assertThat(response.getStatus()).isEqualTo(200); } - @TestOfyAndSql + @Test void testInvalidDomain_returns400() { assertThat(generateActualJson("invalid/domain/name")) .isEqualTo( @@ -260,7 +258,7 @@ class RdapDomainActionTest extends RdapActionBaseTestCase { assertThat(response.getStatus()).isEqualTo(400); } - @TestOfyAndSql + @Test void testUnknownDomain_returns400() { assertThat(generateActualJson("missingdomain.com")) .isEqualTo( @@ -271,45 +269,45 @@ class RdapDomainActionTest extends RdapActionBaseTestCase { assertThat(response.getStatus()).isEqualTo(400); } - @TestOfyAndSql + @Test void testValidDomain_works() { login("evilregistrar"); assertProperResponseForCatLol("cat.lol", "rdap_domain.json"); } - @TestOfyAndSql + @Test void testValidDomain_asAdministrator_works() { loginAsAdmin(); assertProperResponseForCatLol("cat.lol", "rdap_domain.json"); } - @TestOfyAndSql + @Test void testValidDomain_notLoggedIn_noContacts() { assertProperResponseForCatLol("cat.lol", "rdap_domain_no_contacts_with_remark.json"); } - @TestOfyAndSql + @Test void testValidDomain_loggedInAsOtherRegistrar_noContacts() { login("idnregistrar"); assertProperResponseForCatLol("cat.lol", "rdap_domain_no_contacts_with_remark.json"); } - @TestOfyAndSql + @Test void testUpperCase_ignored() { assertProperResponseForCatLol("CaT.lOl", "rdap_domain_no_contacts_with_remark.json"); } - @TestOfyAndSql + @Test void testTrailingDot_ignored() { assertProperResponseForCatLol("cat.lol.", "rdap_domain_no_contacts_with_remark.json"); } - @TestOfyAndSql + @Test void testQueryParameter_ignored() { assertProperResponseForCatLol("cat.lol?key=value", "rdap_domain_no_contacts_with_remark.json"); } - @TestOfyAndSql + @Test void testIdnDomain_works() { login("idnregistrar"); assertThat(generateActualJson("cat.みんな")) @@ -327,7 +325,7 @@ class RdapDomainActionTest extends RdapActionBaseTestCase { assertThat(response.getStatus()).isEqualTo(200); } - @TestOfyAndSql + @Test void testIdnDomainWithPercentEncoding_works() { login("idnregistrar"); assertThat(generateActualJson("cat.%E3%81%BF%E3%82%93%E3%81%AA")) @@ -345,7 +343,7 @@ class RdapDomainActionTest extends RdapActionBaseTestCase { assertThat(response.getStatus()).isEqualTo(200); } - @TestOfyAndSql + @Test void testPunycodeDomain_works() { login("idnregistrar"); assertThat(generateActualJson("cat.xn--q9jyb4c")) @@ -363,7 +361,7 @@ class RdapDomainActionTest extends RdapActionBaseTestCase { assertThat(response.getStatus()).isEqualTo(200); } - @TestOfyAndSql + @Test void testMultilevelDomain_works() { login("1tldregistrar"); assertThat(generateActualJson("cat.1.tld")) @@ -383,35 +381,35 @@ class RdapDomainActionTest extends RdapActionBaseTestCase { // todo (b/27378695): reenable or delete this test @Disabled - @TestOfyAndSql + @Test void testDomainInTestTld_notFound() { persistResource(Registry.get("lol").asBuilder().setTldType(Registry.TldType.TEST).build()); generateActualJson("cat.lol"); assertThat(response.getStatus()).isEqualTo(404); } - @TestOfyAndSql + @Test void testDeletedDomain_notFound() { assertThat(generateActualJson("dodo.lol")) .isEqualTo(generateExpectedJsonError("dodo.lol not found", 404)); assertThat(response.getStatus()).isEqualTo(404); } - @TestOfyAndSql + @Test void testDeletedDomain_notFound_includeDeletedSetFalse() { action.includeDeletedParam = Optional.of(true); generateActualJson("dodo.lol"); assertThat(response.getStatus()).isEqualTo(404); } - @TestOfyAndSql + @Test void testDeletedDomain_notFound_notLoggedIn() { action.includeDeletedParam = Optional.of(true); generateActualJson("dodo.lol"); assertThat(response.getStatus()).isEqualTo(404); } - @TestOfyAndSql + @Test void testDeletedDomain_notFound_loggedInAsDifferentRegistrar() { login("1tldregistrar"); action.includeDeletedParam = Optional.of(true); @@ -419,7 +417,7 @@ class RdapDomainActionTest extends RdapActionBaseTestCase { assertThat(response.getStatus()).isEqualTo(404); } - @TestOfyAndSql + @Test void testDeletedDomain_works_loggedInAsCorrectRegistrar() { login("evilregistrar"); action.includeDeletedParam = Optional.of(true); @@ -438,7 +436,7 @@ class RdapDomainActionTest extends RdapActionBaseTestCase { assertThat(response.getStatus()).isEqualTo(200); } - @TestOfyAndSql + @Test void testDeletedDomain_works_loggedInAsAdmin() { loginAsAdmin(); action.includeDeletedParam = Optional.of(true); @@ -457,7 +455,7 @@ class RdapDomainActionTest extends RdapActionBaseTestCase { assertThat(response.getStatus()).isEqualTo(200); } - @TestOfyAndSql + @Test void testMetrics() { generateActualJson("cat.lol"); verify(rdapMetrics) diff --git a/core/src/test/java/google/registry/rdap/RdapDomainSearchActionTest.java b/core/src/test/java/google/registry/rdap/RdapDomainSearchActionTest.java index 84a9bd154..c19eb738e 100644 --- a/core/src/test/java/google/registry/rdap/RdapDomainSearchActionTest.java +++ b/core/src/test/java/google/registry/rdap/RdapDomainSearchActionTest.java @@ -49,19 +49,15 @@ import google.registry.rdap.RdapMetrics.EndpointType; import google.registry.rdap.RdapMetrics.SearchType; import google.registry.rdap.RdapMetrics.WildcardType; import google.registry.rdap.RdapSearchResults.IncompletenessWarningType; -import google.registry.testing.DualDatabaseTest; import google.registry.testing.FakeResponse; -import google.registry.testing.TestOfyAndSql; -import google.registry.testing.TestOfyOnly; -import google.registry.testing.TestSqlOnly; import java.net.URLDecoder; import java.util.HashMap; import java.util.Optional; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; /** Unit tests for {@link RdapDomainSearchAction}. */ -@DualDatabaseTest class RdapDomainSearchActionTest extends RdapSearchActionTestCase { RdapDomainSearchActionTest() { @@ -383,13 +379,6 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase { RdapEntityActionTest() { @@ -189,35 +187,35 @@ class RdapEntityActionTest extends RdapActionBaseTestCase { assertThat(response.getStatus()).isEqualTo(404); } - @TestOfyAndSql + @Test void testUnknownEntity_RoidPattern_notFound() { runNotFoundTest("_MISSING-ENTITY_"); } - @TestOfyAndSql + @Test void testUnknownEntity_IanaPattern_notFound() { runNotFoundTest("123"); } - @TestOfyAndSql + @Test void testUnknownEntity_notRoidNotIana_notFound() { // Since we allow search by registrar name, every string is a possible name runNotFoundTest("some,random,string"); } - @TestOfyAndSql + @Test void testValidRegistrantContact_works() { login("evilregistrar"); runSuccessfulHandleTest(registrant.getRepoId(), "rdap_associated_contact.json"); } - @TestOfyAndSql + @Test void testValidRegistrantContact_found_asAdministrator() { loginAsAdmin(); runSuccessfulHandleTest(registrant.getRepoId(), "rdap_associated_contact.json"); } - @TestOfyAndSql + @Test void testValidRegistrantContact_found_notLoggedIn() { runSuccessfulHandleTest( registrant.getRepoId(), @@ -227,7 +225,7 @@ class RdapEntityActionTest extends RdapActionBaseTestCase { "rdap_associated_contact_no_personal_data.json"); } - @TestOfyAndSql + @Test void testValidRegistrantContact_found_loggedInAsOtherRegistrar() { login("otherregistrar"); runSuccessfulHandleTest( @@ -238,49 +236,49 @@ class RdapEntityActionTest extends RdapActionBaseTestCase { "rdap_associated_contact_no_personal_data.json"); } - @TestOfyAndSql + @Test void testValidAdminContact_works() { login("evilregistrar"); runSuccessfulHandleTest(adminContact.getRepoId(), "rdap_associated_contact.json"); } - @TestOfyAndSql + @Test void testValidTechContact_works() { login("evilregistrar"); runSuccessfulHandleTest(techContact.getRepoId(), "rdap_associated_contact.json"); } - @TestOfyAndSql + @Test void testValidDisconnectedContact_works() { login("evilregistrar"); runSuccessfulHandleTest(disconnectedContact.getRepoId(), "rdap_contact.json"); } - @TestOfyAndSql + @Test void testDeletedContact_notFound() { runNotFoundTest(deletedContact.getRepoId()); } - @TestOfyAndSql + @Test void testDeletedContact_notFound_includeDeletedSetFalse() { action.includeDeletedParam = Optional.of(false); runNotFoundTest(deletedContact.getRepoId()); } - @TestOfyAndSql + @Test void testDeletedContact_notFound_notLoggedIn() { action.includeDeletedParam = Optional.of(true); runNotFoundTest(deletedContact.getRepoId()); } - @TestOfyAndSql + @Test void testDeletedContact_notFound_loggedInAsDifferentRegistrar() { login("idnregistrar"); action.includeDeletedParam = Optional.of(true); runNotFoundTest(deletedContact.getRepoId()); } - @TestOfyAndSql + @Test void testDeletedContact_found_loggedInAsCorrectRegistrar() { login("evilregistrar"); action.includeDeletedParam = Optional.of(true); @@ -292,7 +290,7 @@ class RdapEntityActionTest extends RdapActionBaseTestCase { "rdap_contact_deleted.json"); } - @TestOfyAndSql + @Test void testDeletedContact_found_loggedInAsAdmin() { loginAsAdmin(); action.includeDeletedParam = Optional.of(true); @@ -304,12 +302,12 @@ class RdapEntityActionTest extends RdapActionBaseTestCase { "rdap_contact_deleted.json"); } - @TestOfyAndSql + @Test void testRegistrar_found() { runSuccessfulHandleTest("101", "Yes Virginia