mirror of
https://github.com/google/nomulus
synced 2026-09-01 21:57:02 +00:00
Remove Ofy code from various flow-related classes (#1653)
This included removing ofy-specific code from various tests. Also, some of the other tests (e.g. RdapDomainActionTest) had to be configured to use only SQL -- otherwise, as it currently stands, they were trying to use ofy. We also delete the CreateSyntheticHistoryEntriesAction and pipeline because they're no longer relevant, and impossible to test (the goal of the actions were to create objects in ofy which doesn't happen any more).
This commit is contained in:
@@ -1,950 +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.batch;
|
||||
|
||||
import static com.google.appengine.api.taskqueue.QueueFactory.getQueue;
|
||||
import static com.google.common.collect.MoreCollectors.onlyElement;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static com.google.common.truth.Truth8.assertThat;
|
||||
import static google.registry.batch.AsyncTaskEnqueuer.PARAM_RESOURCE_KEY;
|
||||
import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_DELETE;
|
||||
import static google.registry.batch.AsyncTaskMetrics.OperationResult.STALE;
|
||||
import static google.registry.model.EppResourceUtils.loadByForeignKey;
|
||||
import static google.registry.model.eppcommon.StatusValue.PENDING_DELETE;
|
||||
import static google.registry.model.ofy.ObjectifyService.auditedOfy;
|
||||
import static google.registry.model.reporting.HistoryEntry.Type.CONTACT_DELETE;
|
||||
import static google.registry.model.reporting.HistoryEntry.Type.CONTACT_DELETE_FAILURE;
|
||||
import static google.registry.model.reporting.HistoryEntry.Type.CONTACT_TRANSFER_REQUEST;
|
||||
import static google.registry.model.reporting.HistoryEntry.Type.HOST_DELETE;
|
||||
import static google.registry.model.reporting.HistoryEntry.Type.HOST_DELETE_FAILURE;
|
||||
import static google.registry.testing.ContactResourceSubject.assertAboutContacts;
|
||||
import static google.registry.testing.DatabaseHelper.assertNoBillingEvents;
|
||||
import static google.registry.testing.DatabaseHelper.createTld;
|
||||
import static google.registry.testing.DatabaseHelper.getOnlyHistoryEntryOfType;
|
||||
import static google.registry.testing.DatabaseHelper.getOnlyPollMessageForHistoryEntry;
|
||||
import static google.registry.testing.DatabaseHelper.getPollMessages;
|
||||
import static google.registry.testing.DatabaseHelper.newContactResource;
|
||||
import static google.registry.testing.DatabaseHelper.newDomainBase;
|
||||
import static google.registry.testing.DatabaseHelper.newHostResource;
|
||||
import static google.registry.testing.DatabaseHelper.persistActiveContact;
|
||||
import static google.registry.testing.DatabaseHelper.persistActiveHost;
|
||||
import static google.registry.testing.DatabaseHelper.persistContactWithPendingTransfer;
|
||||
import static google.registry.testing.DatabaseHelper.persistDeletedContact;
|
||||
import static google.registry.testing.DatabaseHelper.persistDeletedHost;
|
||||
import static google.registry.testing.DatabaseHelper.persistResource;
|
||||
import static google.registry.testing.HostResourceSubject.assertAboutHosts;
|
||||
import static google.registry.testing.TaskQueueHelper.assertDnsTasksEnqueued;
|
||||
import static google.registry.testing.TaskQueueHelper.assertNoTasksEnqueued;
|
||||
import static google.registry.testing.TaskQueueHelper.assertTasksEnqueued;
|
||||
import static google.registry.util.DateTimeUtils.END_OF_TIME;
|
||||
import static org.joda.time.DateTimeZone.UTC;
|
||||
import static org.joda.time.Duration.millis;
|
||||
import static org.joda.time.Duration.standardDays;
|
||||
import static org.joda.time.Duration.standardHours;
|
||||
import static org.joda.time.Duration.standardSeconds;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import com.google.appengine.api.taskqueue.TaskOptions;
|
||||
import com.google.appengine.api.taskqueue.TaskOptions.Method;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import google.registry.batch.AsyncTaskMetrics.OperationResult;
|
||||
import google.registry.batch.AsyncTaskMetrics.OperationType;
|
||||
import google.registry.batch.DeleteContactsAndHostsAction.DeleteEppResourceReducer;
|
||||
import google.registry.model.EppResource;
|
||||
import google.registry.model.contact.ContactAddress;
|
||||
import google.registry.model.contact.ContactPhoneNumber;
|
||||
import google.registry.model.contact.ContactResource;
|
||||
import google.registry.model.contact.PostalInfo;
|
||||
import google.registry.model.domain.DomainBase;
|
||||
import google.registry.model.eppcommon.StatusValue;
|
||||
import google.registry.model.eppcommon.Trid;
|
||||
import google.registry.model.eppoutput.EppResponse.ResponseData;
|
||||
import google.registry.model.host.HostResource;
|
||||
import google.registry.model.ofy.Ofy;
|
||||
import google.registry.model.poll.PendingActionNotificationResponse;
|
||||
import google.registry.model.poll.PendingActionNotificationResponse.ContactPendingActionNotificationResponse;
|
||||
import google.registry.model.poll.PendingActionNotificationResponse.HostPendingActionNotificationResponse;
|
||||
import google.registry.model.poll.PollMessage;
|
||||
import google.registry.model.poll.PollMessage.OneTime;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.model.server.Lock;
|
||||
import google.registry.model.tld.Registry;
|
||||
import google.registry.model.transfer.ContactTransferData;
|
||||
import google.registry.model.transfer.TransferData;
|
||||
import google.registry.model.transfer.TransferResponse;
|
||||
import google.registry.model.transfer.TransferStatus;
|
||||
import google.registry.testing.CloudTasksHelper;
|
||||
import google.registry.testing.FakeClock;
|
||||
import google.registry.testing.FakeResponse;
|
||||
import google.registry.testing.FakeSleeper;
|
||||
import google.registry.testing.InjectExtension;
|
||||
import google.registry.testing.TaskQueueHelper.TaskMatcher;
|
||||
import google.registry.testing.mapreduce.MapreduceTestCase;
|
||||
import google.registry.util.RequestStatusChecker;
|
||||
import google.registry.util.Retrier;
|
||||
import google.registry.util.Sleeper;
|
||||
import google.registry.util.SystemSleeper;
|
||||
import java.util.Optional;
|
||||
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;
|
||||
import org.mockito.Mock;
|
||||
|
||||
/** Unit tests for {@link DeleteContactsAndHostsAction}. */
|
||||
public class DeleteContactsAndHostsActionTest
|
||||
extends MapreduceTestCase<DeleteContactsAndHostsAction> {
|
||||
|
||||
@RegisterExtension public final InjectExtension inject = new InjectExtension();
|
||||
|
||||
private AsyncTaskEnqueuer enqueuer;
|
||||
private final FakeClock clock = new FakeClock(DateTime.parse("2015-01-15T11:22:33Z"));
|
||||
private final FakeResponse fakeResponse = new FakeResponse();
|
||||
@Mock private RequestStatusChecker requestStatusChecker;
|
||||
|
||||
private void runMapreduce() throws Exception {
|
||||
clock.advanceBy(standardSeconds(5));
|
||||
// Apologies for the hard sleeps. Without them, the tests can be flaky because the tasks aren't
|
||||
// quite fully enqueued by the time the tests attempt to lease from the queue.
|
||||
Sleeper sleeper = new SystemSleeper();
|
||||
sleeper.sleep(millis(50));
|
||||
action.run();
|
||||
sleeper.sleep(millis(50));
|
||||
executeTasksUntilEmpty("mapreduce", clock);
|
||||
sleeper.sleep(millis(50));
|
||||
clock.advanceBy(standardSeconds(5));
|
||||
auditedOfy().clearSessionCache();
|
||||
}
|
||||
|
||||
/** Kicks off, but does not run, the mapreduce tasks. Useful for testing validation/setup. */
|
||||
private void enqueueMapreduceOnly() {
|
||||
clock.advanceBy(standardSeconds(5));
|
||||
action.run();
|
||||
clock.advanceBy(standardSeconds(5));
|
||||
auditedOfy().clearSessionCache();
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() {
|
||||
inject.setStaticField(Ofy.class, "clock", clock);
|
||||
enqueuer =
|
||||
AsyncTaskEnqueuerTest.createForTesting(
|
||||
new CloudTasksHelper(clock).getTestCloudTasksUtils(), clock, Duration.ZERO);
|
||||
AsyncTaskMetrics asyncTaskMetricsMock = mock(AsyncTaskMetrics.class);
|
||||
action = new DeleteContactsAndHostsAction();
|
||||
action.asyncTaskMetrics = asyncTaskMetricsMock;
|
||||
inject.setStaticField(DeleteEppResourceReducer.class, "asyncTaskMetrics", asyncTaskMetricsMock);
|
||||
action.clock = clock;
|
||||
action.mrRunner = makeDefaultRunner();
|
||||
action.requestStatusChecker = requestStatusChecker;
|
||||
action.response = fakeResponse;
|
||||
action.retrier = new Retrier(new FakeSleeper(clock), 1);
|
||||
action.queue = getQueue(QUEUE_ASYNC_DELETE);
|
||||
when(requestStatusChecker.getLogId()).thenReturn("requestId");
|
||||
when(requestStatusChecker.isRunning(anyString()))
|
||||
.thenThrow(new AssertionError("Should not be called"));
|
||||
|
||||
createTld("tld");
|
||||
clock.advanceOneMilli();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_contact_referencedByActiveDomain_doesNotGetDeleted() throws Exception {
|
||||
ContactResource contact = persistContactPendingDelete("blah8221");
|
||||
persistResource(newDomainBase("example.tld", contact));
|
||||
DateTime timeEnqueued = clock.nowUtc();
|
||||
enqueuer.enqueueAsyncDelete(
|
||||
contact,
|
||||
timeEnqueued,
|
||||
"TheRegistrar",
|
||||
Trid.create("fakeClientTrid", "fakeServerTrid"),
|
||||
false);
|
||||
runMapreduce();
|
||||
ContactResource contactUpdated =
|
||||
loadByForeignKey(ContactResource.class, "blah8221", clock.nowUtc()).get();
|
||||
assertAboutContacts()
|
||||
.that(contactUpdated)
|
||||
.doesNotHaveStatusValue(PENDING_DELETE)
|
||||
.and()
|
||||
.hasDeletionTime(END_OF_TIME);
|
||||
DomainBase domainReloaded =
|
||||
loadByForeignKey(DomainBase.class, "example.tld", clock.nowUtc()).get();
|
||||
// We have to check for the objectify key here, specifically, as the SQL side of the key does
|
||||
// not get persisted.
|
||||
assertThat(domainReloaded.getReferencedContacts()).contains(contactUpdated.createVKey());
|
||||
HistoryEntry historyEntry =
|
||||
getOnlyHistoryEntryOfType(contactUpdated, HistoryEntry.Type.CONTACT_DELETE_FAILURE);
|
||||
assertPollMessageFor(
|
||||
historyEntry,
|
||||
"TheRegistrar",
|
||||
"Can't delete contact blah8221 because it is referenced by a domain.",
|
||||
false,
|
||||
contact,
|
||||
Optional.of("fakeClientTrid"));
|
||||
assertNoTasksEnqueued(QUEUE_ASYNC_DELETE);
|
||||
verify(action.asyncTaskMetrics).recordContactHostDeletionBatchSize(1L);
|
||||
verify(action.asyncTaskMetrics)
|
||||
.recordAsyncFlowResult(OperationType.CONTACT_DELETE, OperationResult.FAILURE, timeEnqueued);
|
||||
verifyNoMoreInteractions(action.asyncTaskMetrics);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_contact_notReferenced_getsDeleted_andPiiWipedOut() throws Exception {
|
||||
runSuccessfulContactDeletionTest(Optional.of("fakeClientTrid"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_contact_andNoClientTrid_deletesSuccessfully() throws Exception {
|
||||
runSuccessfulContactDeletionTest(Optional.empty());
|
||||
}
|
||||
|
||||
@Test
|
||||
void test_cannotAcquireLock() {
|
||||
// Make lock acquisition fail.
|
||||
acquireLock();
|
||||
enqueueMapreduceOnly();
|
||||
assertThat(fakeResponse.getPayload()).isEqualTo("Can't acquire lock; aborting.");
|
||||
}
|
||||
|
||||
@Test
|
||||
void test_mapreduceHasWorkToDo_lockIsAcquired() {
|
||||
ContactResource contact = persistContactPendingDelete("blah8221");
|
||||
persistResource(newDomainBase("example.tld", contact));
|
||||
DateTime timeEnqueued = clock.nowUtc();
|
||||
enqueuer.enqueueAsyncDelete(
|
||||
contact,
|
||||
timeEnqueued,
|
||||
"TheRegistrar",
|
||||
Trid.create("fakeClientTrid", "fakeServerTrid"),
|
||||
false);
|
||||
enqueueMapreduceOnly();
|
||||
assertThat(acquireLock()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void test_noTasksToLease_releasesLockImmediately() {
|
||||
enqueueMapreduceOnly();
|
||||
// If the Lock was correctly released, then we can acquire it now.
|
||||
assertThat(acquireLock()).isPresent();
|
||||
}
|
||||
|
||||
private void runSuccessfulContactDeletionTest(Optional<String> clientTrid) throws Exception {
|
||||
ContactResource contact = persistContactWithPii("jim919");
|
||||
DateTime timeEnqueued = clock.nowUtc();
|
||||
enqueuer.enqueueAsyncDelete(
|
||||
contact,
|
||||
timeEnqueued,
|
||||
"TheRegistrar",
|
||||
Trid.create(clientTrid.orElse(null), "fakeServerTrid"),
|
||||
false);
|
||||
runMapreduce();
|
||||
assertThat(loadByForeignKey(ContactResource.class, "jim919", clock.nowUtc())).isEmpty();
|
||||
ContactResource contactAfterDeletion = auditedOfy().load().entity(contact).now();
|
||||
assertAboutContacts()
|
||||
.that(contactAfterDeletion)
|
||||
.isNotActiveAt(clock.nowUtc())
|
||||
// Note that there will be another history entry of CONTACT_PENDING_DELETE, but this is
|
||||
// added by the flow and not the mapreduce itself.
|
||||
.and()
|
||||
.hasOnlyOneHistoryEntryWhich()
|
||||
.hasType(CONTACT_DELETE);
|
||||
assertAboutContacts()
|
||||
.that(contactAfterDeletion)
|
||||
.hasNullLocalizedPostalInfo()
|
||||
.and()
|
||||
.hasNullInternationalizedPostalInfo()
|
||||
.and()
|
||||
.hasNullEmailAddress()
|
||||
.and()
|
||||
.hasNullVoiceNumber()
|
||||
.and()
|
||||
.hasNullFaxNumber();
|
||||
HistoryEntry historyEntry = getOnlyHistoryEntryOfType(contactAfterDeletion, CONTACT_DELETE);
|
||||
assertPollMessageFor(
|
||||
historyEntry, "TheRegistrar", "Deleted contact jim919.", true, contact, clientTrid);
|
||||
assertNoTasksEnqueued(QUEUE_ASYNC_DELETE);
|
||||
verify(action.asyncTaskMetrics).recordContactHostDeletionBatchSize(1L);
|
||||
verify(action.asyncTaskMetrics)
|
||||
.recordAsyncFlowResult(OperationType.CONTACT_DELETE, OperationResult.SUCCESS, timeEnqueued);
|
||||
verifyNoMoreInteractions(action.asyncTaskMetrics);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_contactWithoutPendingTransfer_isDeletedAndHasNoTransferData() throws Exception {
|
||||
ContactResource contact = persistContactPendingDelete("blah8221");
|
||||
enqueuer.enqueueAsyncDelete(
|
||||
contact,
|
||||
clock.nowUtc(),
|
||||
"TheRegistrar",
|
||||
Trid.create("fakeClientTrid", "fakeServerTrid"),
|
||||
false);
|
||||
runMapreduce();
|
||||
ContactResource contactAfterDeletion = auditedOfy().load().entity(contact).now();
|
||||
assertThat(contactAfterDeletion.getTransferData()).isEqualTo(ContactTransferData.EMPTY);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_contactWithPendingTransfer_getsDeleted() throws Exception {
|
||||
DateTime transferRequestTime = clock.nowUtc().minusDays(3);
|
||||
ContactResource contact =
|
||||
persistContactWithPendingTransfer(
|
||||
newContactResource("sh8013").asBuilder().addStatusValue(PENDING_DELETE).build(),
|
||||
transferRequestTime,
|
||||
transferRequestTime.plus(Registry.DEFAULT_TRANSFER_GRACE_PERIOD),
|
||||
clock.nowUtc());
|
||||
enqueuer.enqueueAsyncDelete(
|
||||
contact,
|
||||
clock.nowUtc(),
|
||||
"TheRegistrar",
|
||||
Trid.create("fakeClientTrid", "fakeServerTrid"),
|
||||
false);
|
||||
runMapreduce();
|
||||
// Check that the contact is deleted as of now.
|
||||
assertThat(loadByForeignKey(ContactResource.class, "sh8013", clock.nowUtc())).isEmpty();
|
||||
// Check that it's still there (it wasn't deleted yesterday) and that it has history.
|
||||
ContactResource softDeletedContact =
|
||||
loadByForeignKey(ContactResource.class, "sh8013", clock.nowUtc().minusDays(1)).get();
|
||||
assertAboutContacts()
|
||||
.that(softDeletedContact)
|
||||
.hasOneHistoryEntryEachOfTypes(CONTACT_TRANSFER_REQUEST, CONTACT_DELETE);
|
||||
// Check that the transfer data reflects the cancelled transfer as we expect.
|
||||
TransferData oldTransferData = contact.getTransferData();
|
||||
assertThat(softDeletedContact.getTransferData())
|
||||
.isEqualTo(
|
||||
oldTransferData.copyConstantFieldsToBuilder()
|
||||
.setTransferStatus(TransferStatus.SERVER_CANCELLED)
|
||||
.setPendingTransferExpirationTime(softDeletedContact.getDeletionTime())
|
||||
.build());
|
||||
assertNoBillingEvents();
|
||||
PollMessage deletePollMessage =
|
||||
Iterables.getOnlyElement(getPollMessages("TheRegistrar", clock.nowUtc().plusMonths(1)));
|
||||
assertThat(deletePollMessage.getMsg()).isEqualTo("Deleted contact sh8013.");
|
||||
// The poll message in the future to the gaining registrar should be gone too, but there
|
||||
// should be one at the current time to the gaining registrar.
|
||||
PollMessage gainingPollMessage =
|
||||
Iterables.getOnlyElement(getPollMessages("NewRegistrar", clock.nowUtc()));
|
||||
assertThat(gainingPollMessage.getEventTime()).isLessThan(clock.nowUtc());
|
||||
assertThat(
|
||||
gainingPollMessage
|
||||
.getResponseData()
|
||||
.stream()
|
||||
.filter(TransferResponse.class::isInstance)
|
||||
.map(TransferResponse.class::cast)
|
||||
.collect(onlyElement())
|
||||
.getTransferStatus())
|
||||
.isEqualTo(TransferStatus.SERVER_CANCELLED);
|
||||
PendingActionNotificationResponse panData =
|
||||
gainingPollMessage
|
||||
.getResponseData()
|
||||
.stream()
|
||||
.filter(PendingActionNotificationResponse.class::isInstance)
|
||||
.map(PendingActionNotificationResponse.class::cast)
|
||||
.collect(onlyElement());
|
||||
assertThat(panData.getTrid())
|
||||
.isEqualTo(Trid.create("transferClient-trid", "transferServer-trid"));
|
||||
assertThat(panData.getActionResult()).isFalse();
|
||||
assertNoTasksEnqueued(QUEUE_ASYNC_DELETE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_contact_referencedByDeletedDomain_getsDeleted() throws Exception {
|
||||
ContactResource contactUsed = persistContactPendingDelete("blah1234");
|
||||
persistResource(
|
||||
newDomainBase("example.tld", contactUsed)
|
||||
.asBuilder()
|
||||
.setDeletionTime(clock.nowUtc().minusDays(3))
|
||||
.build());
|
||||
enqueuer.enqueueAsyncDelete(
|
||||
contactUsed,
|
||||
clock.nowUtc(),
|
||||
"TheRegistrar",
|
||||
Trid.create("fakeClientTrid", "fakeServerTrid"),
|
||||
false);
|
||||
runMapreduce();
|
||||
assertThat(loadByForeignKey(ContactResource.class, "blah1234", clock.nowUtc())).isEmpty();
|
||||
ContactResource contactBeforeDeletion =
|
||||
loadByForeignKey(ContactResource.class, "blah1234", clock.nowUtc().minusDays(1)).get();
|
||||
assertAboutContacts()
|
||||
.that(contactBeforeDeletion)
|
||||
.isNotActiveAt(clock.nowUtc())
|
||||
.and()
|
||||
.hasExactlyStatusValues(StatusValue.OK)
|
||||
// Note that there will be another history entry of CONTACT_PENDING_DELETE, but this is
|
||||
// added by the flow and not the mapreduce itself.
|
||||
.and()
|
||||
.hasOnlyOneHistoryEntryWhich()
|
||||
.hasType(CONTACT_DELETE);
|
||||
HistoryEntry historyEntry = getOnlyHistoryEntryOfType(contactBeforeDeletion, CONTACT_DELETE);
|
||||
assertPollMessageFor(
|
||||
historyEntry,
|
||||
"TheRegistrar",
|
||||
"Deleted contact blah1234.",
|
||||
true,
|
||||
contactUsed,
|
||||
Optional.of("fakeClientTrid"));
|
||||
assertNoTasksEnqueued(QUEUE_ASYNC_DELETE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_contact_notRequestedByOwner_doesNotGetDeleted() throws Exception {
|
||||
ContactResource contact = persistContactPendingDelete("jane0991");
|
||||
enqueuer.enqueueAsyncDelete(
|
||||
contact,
|
||||
clock.nowUtc(),
|
||||
"OtherRegistrar",
|
||||
Trid.create("fakeClientTrid", "fakeServerTrid"),
|
||||
false);
|
||||
runMapreduce();
|
||||
ContactResource contactAfter =
|
||||
loadByForeignKey(ContactResource.class, "jane0991", clock.nowUtc()).get();
|
||||
assertAboutContacts()
|
||||
.that(contactAfter)
|
||||
.doesNotHaveStatusValue(PENDING_DELETE)
|
||||
.and()
|
||||
.hasDeletionTime(END_OF_TIME);
|
||||
HistoryEntry historyEntry = getOnlyHistoryEntryOfType(contactAfter, CONTACT_DELETE_FAILURE);
|
||||
assertPollMessageFor(
|
||||
historyEntry,
|
||||
"OtherRegistrar",
|
||||
"Can't delete contact jane0991 because it was transferred prior to deletion.",
|
||||
false,
|
||||
contact,
|
||||
Optional.of("fakeClientTrid"));
|
||||
assertNoTasksEnqueued(QUEUE_ASYNC_DELETE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_contact_notRequestedByOwner_isSuperuser_getsDeleted() throws Exception {
|
||||
ContactResource contact = persistContactWithPii("nate007");
|
||||
enqueuer.enqueueAsyncDelete(
|
||||
contact,
|
||||
clock.nowUtc(),
|
||||
"OtherRegistrar",
|
||||
Trid.create("fakeClientTrid", "fakeServerTrid"),
|
||||
true);
|
||||
runMapreduce();
|
||||
assertThat(loadByForeignKey(ContactResource.class, "nate007", clock.nowUtc())).isEmpty();
|
||||
ContactResource contactAfterDeletion = auditedOfy().load().entity(contact).now();
|
||||
assertAboutContacts()
|
||||
.that(contactAfterDeletion)
|
||||
.isNotActiveAt(clock.nowUtc())
|
||||
// Note that there will be another history entry of CONTACT_PENDING_DELETE, but this is
|
||||
// added by the flow and not the mapreduce itself.
|
||||
.and()
|
||||
.hasOnlyOneHistoryEntryWhich()
|
||||
.hasType(CONTACT_DELETE);
|
||||
assertAboutContacts()
|
||||
.that(contactAfterDeletion)
|
||||
.hasNullLocalizedPostalInfo()
|
||||
.and()
|
||||
.hasNullInternationalizedPostalInfo()
|
||||
.and()
|
||||
.hasNullEmailAddress()
|
||||
.and()
|
||||
.hasNullVoiceNumber()
|
||||
.and()
|
||||
.hasNullFaxNumber();
|
||||
HistoryEntry historyEntry = getOnlyHistoryEntryOfType(contactAfterDeletion, CONTACT_DELETE);
|
||||
assertPollMessageFor(
|
||||
historyEntry,
|
||||
"OtherRegistrar",
|
||||
"Deleted contact nate007.",
|
||||
true,
|
||||
contact,
|
||||
Optional.of("fakeClientTrid"));
|
||||
assertNoTasksEnqueued(QUEUE_ASYNC_DELETE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_targetResourcesDontExist_areDelayedForADay() {
|
||||
ContactResource contactNotSaved = newContactResource("somecontact");
|
||||
HostResource hostNotSaved = newHostResource("a11.blah.foo");
|
||||
DateTime timeBeforeRun = clock.nowUtc();
|
||||
enqueuer.enqueueAsyncDelete(
|
||||
contactNotSaved,
|
||||
timeBeforeRun,
|
||||
"TheRegistrar",
|
||||
Trid.create("fakeClientTrid", "fakeServerTrid"),
|
||||
false);
|
||||
enqueuer.enqueueAsyncDelete(
|
||||
hostNotSaved,
|
||||
timeBeforeRun,
|
||||
"TheRegistrar",
|
||||
Trid.create("fakeClientTrid", "fakeServerTrid"),
|
||||
false);
|
||||
enqueueMapreduceOnly();
|
||||
assertTasksEnqueued(
|
||||
QUEUE_ASYNC_DELETE,
|
||||
new TaskMatcher()
|
||||
.etaDelta(standardHours(23), standardHours(25))
|
||||
.param(PARAM_RESOURCE_KEY, contactNotSaved.createVKey().stringify())
|
||||
.param("requestingClientId", "TheRegistrar")
|
||||
.param("clientTransactionId", "fakeClientTrid")
|
||||
.param("serverTransactionId", "fakeServerTrid")
|
||||
.param("isSuperuser", "false")
|
||||
.param("requestedTime", timeBeforeRun.toString()),
|
||||
new TaskMatcher()
|
||||
.etaDelta(standardHours(23), standardHours(25))
|
||||
.param(PARAM_RESOURCE_KEY, hostNotSaved.createVKey().stringify())
|
||||
.param("requestingClientId", "TheRegistrar")
|
||||
.param("clientTransactionId", "fakeClientTrid")
|
||||
.param("serverTransactionId", "fakeServerTrid")
|
||||
.param("isSuperuser", "false")
|
||||
.param("requestedTime", timeBeforeRun.toString()));
|
||||
assertThat(acquireLock()).isPresent();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_unparseableTasks_areDelayedForADay() {
|
||||
TaskOptions task =
|
||||
TaskOptions.Builder.withMethod(Method.PULL).param("gobbledygook", "kljhadfgsd9f7gsdfh");
|
||||
getQueue(QUEUE_ASYNC_DELETE).add(task);
|
||||
enqueueMapreduceOnly();
|
||||
assertTasksEnqueued(
|
||||
QUEUE_ASYNC_DELETE,
|
||||
new TaskMatcher()
|
||||
.payload("gobbledygook=kljhadfgsd9f7gsdfh")
|
||||
.etaDelta(standardHours(23), standardHours(25)));
|
||||
verify(action.asyncTaskMetrics).recordContactHostDeletionBatchSize(1L);
|
||||
verifyNoMoreInteractions(action.asyncTaskMetrics);
|
||||
assertThat(acquireLock()).isPresent();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_resourcesNotInPendingDelete_areSkipped() {
|
||||
ContactResource contact = persistActiveContact("blah2222");
|
||||
HostResource host = persistActiveHost("rustles.your.jimmies");
|
||||
DateTime timeEnqueued = clock.nowUtc();
|
||||
enqueuer.enqueueAsyncDelete(
|
||||
contact,
|
||||
timeEnqueued,
|
||||
"TheRegistrar",
|
||||
Trid.create("fakeClientTrid", "fakeServerTrid"),
|
||||
false);
|
||||
enqueuer.enqueueAsyncDelete(
|
||||
host,
|
||||
timeEnqueued,
|
||||
"TheRegistrar",
|
||||
Trid.create("fakeClientTrid", "fakeServerTrid"),
|
||||
false);
|
||||
enqueueMapreduceOnly();
|
||||
assertThat(loadByForeignKey(ContactResource.class, "blah2222", clock.nowUtc()))
|
||||
.hasValue(contact);
|
||||
assertThat(loadByForeignKey(HostResource.class, "rustles.your.jimmies", clock.nowUtc()))
|
||||
.hasValue(host);
|
||||
assertNoTasksEnqueued(QUEUE_ASYNC_DELETE);
|
||||
verify(action.asyncTaskMetrics).recordContactHostDeletionBatchSize(2L);
|
||||
verify(action.asyncTaskMetrics)
|
||||
.recordAsyncFlowResult(OperationType.CONTACT_DELETE, STALE, timeEnqueued);
|
||||
verify(action.asyncTaskMetrics)
|
||||
.recordAsyncFlowResult(OperationType.HOST_DELETE, STALE, timeEnqueued);
|
||||
verifyNoMoreInteractions(action.asyncTaskMetrics);
|
||||
assertThat(acquireLock()).isPresent();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_alreadyDeletedResources_areSkipped() {
|
||||
ContactResource contactDeleted = persistDeletedContact("blah1236", clock.nowUtc().minusDays(2));
|
||||
HostResource hostDeleted = persistDeletedHost("a.lim.lop", clock.nowUtc().minusDays(3));
|
||||
enqueuer.enqueueAsyncDelete(
|
||||
contactDeleted,
|
||||
clock.nowUtc(),
|
||||
"TheRegistrar",
|
||||
Trid.create("fakeClientTrid", "fakeServerTrid"),
|
||||
false);
|
||||
enqueuer.enqueueAsyncDelete(
|
||||
hostDeleted,
|
||||
clock.nowUtc(),
|
||||
"TheRegistrar",
|
||||
Trid.create("fakeClientTrid", "fakeServerTrid"),
|
||||
false);
|
||||
enqueueMapreduceOnly();
|
||||
assertThat(auditedOfy().load().entity(contactDeleted).now()).isEqualTo(contactDeleted);
|
||||
assertThat(auditedOfy().load().entity(hostDeleted).now()).isEqualTo(hostDeleted);
|
||||
assertNoTasksEnqueued(QUEUE_ASYNC_DELETE);
|
||||
assertThat(acquireLock()).isPresent();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_host_referencedByActiveDomain_doesNotGetDeleted() throws Exception {
|
||||
HostResource host = persistHostPendingDelete("ns1.example.tld");
|
||||
persistUsedDomain("example.tld", persistActiveContact("abc456"), host);
|
||||
DateTime timeEnqueued = clock.nowUtc();
|
||||
enqueuer.enqueueAsyncDelete(
|
||||
host,
|
||||
timeEnqueued,
|
||||
"TheRegistrar",
|
||||
Trid.create("fakeClientTrid", "fakeServerTrid"),
|
||||
false);
|
||||
runMapreduce();
|
||||
HostResource hostAfter =
|
||||
loadByForeignKey(HostResource.class, "ns1.example.tld", clock.nowUtc()).get();
|
||||
assertAboutHosts()
|
||||
.that(hostAfter)
|
||||
.doesNotHaveStatusValue(PENDING_DELETE)
|
||||
.and()
|
||||
.hasDeletionTime(END_OF_TIME);
|
||||
DomainBase domain =
|
||||
loadByForeignKey(DomainBase.class, "example.tld", clock.nowUtc()).get();
|
||||
assertThat(domain.getNameservers()).contains(hostAfter.createVKey());
|
||||
HistoryEntry historyEntry = getOnlyHistoryEntryOfType(hostAfter, HOST_DELETE_FAILURE);
|
||||
assertPollMessageFor(
|
||||
historyEntry,
|
||||
"TheRegistrar",
|
||||
"Can't delete host ns1.example.tld because it is referenced by a domain.",
|
||||
false,
|
||||
host,
|
||||
Optional.of("fakeClientTrid"));
|
||||
assertNoTasksEnqueued(QUEUE_ASYNC_DELETE);
|
||||
verify(action.asyncTaskMetrics).recordContactHostDeletionBatchSize(1L);
|
||||
verify(action.asyncTaskMetrics)
|
||||
.recordAsyncFlowResult(OperationType.HOST_DELETE, OperationResult.FAILURE, timeEnqueued);
|
||||
verifyNoMoreInteractions(action.asyncTaskMetrics);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_host_notReferenced_getsDeleted() throws Exception {
|
||||
runSuccessfulHostDeletionTest(Optional.of("fakeClientTrid"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_host_andNoClientTrid_deletesSuccessfully() throws Exception {
|
||||
runSuccessfulHostDeletionTest(Optional.empty());
|
||||
}
|
||||
|
||||
private void runSuccessfulHostDeletionTest(Optional<String> clientTrid) throws Exception {
|
||||
HostResource host = persistHostPendingDelete("ns2.example.tld");
|
||||
DateTime timeEnqueued = clock.nowUtc();
|
||||
enqueuer.enqueueAsyncDelete(
|
||||
host,
|
||||
timeEnqueued,
|
||||
"TheRegistrar",
|
||||
Trid.create(clientTrid.orElse(null), "fakeServerTrid"),
|
||||
false);
|
||||
runMapreduce();
|
||||
assertThat(loadByForeignKey(HostResource.class, "ns2.example.tld", clock.nowUtc())).isEmpty();
|
||||
HostResource hostBeforeDeletion =
|
||||
loadByForeignKey(HostResource.class, "ns2.example.tld", clock.nowUtc().minusDays(1)).get();
|
||||
assertAboutHosts()
|
||||
.that(hostBeforeDeletion)
|
||||
.isNotActiveAt(clock.nowUtc())
|
||||
.and()
|
||||
.hasExactlyStatusValues(StatusValue.OK)
|
||||
// Note that there will be another history entry of HOST_PENDING_DELETE, but this is
|
||||
// added by the flow and not the mapreduce itself.
|
||||
.and()
|
||||
.hasOnlyOneHistoryEntryWhich()
|
||||
.hasType(HOST_DELETE);
|
||||
HistoryEntry historyEntry = getOnlyHistoryEntryOfType(hostBeforeDeletion, HOST_DELETE);
|
||||
assertPollMessageFor(
|
||||
historyEntry,
|
||||
"TheRegistrar",
|
||||
"Deleted host ns2.example.tld.",
|
||||
true,
|
||||
host,
|
||||
clientTrid);
|
||||
assertNoTasksEnqueued(QUEUE_ASYNC_DELETE);
|
||||
verify(action.asyncTaskMetrics).recordContactHostDeletionBatchSize(1L);
|
||||
verify(action.asyncTaskMetrics)
|
||||
.recordAsyncFlowResult(OperationType.HOST_DELETE, OperationResult.SUCCESS, timeEnqueued);
|
||||
verifyNoMoreInteractions(action.asyncTaskMetrics);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_host_referencedByDeletedDomain_getsDeleted() throws Exception {
|
||||
HostResource host = persistHostPendingDelete("ns1.example.tld");
|
||||
persistResource(
|
||||
newDomainBase("example.tld")
|
||||
.asBuilder()
|
||||
.setNameservers(ImmutableSet.of(host.createVKey()))
|
||||
.setDeletionTime(clock.nowUtc().minusDays(5))
|
||||
.build());
|
||||
enqueuer.enqueueAsyncDelete(
|
||||
host,
|
||||
clock.nowUtc(),
|
||||
"TheRegistrar",
|
||||
Trid.create("fakeClientTrid", "fakeServerTrid"),
|
||||
false);
|
||||
runMapreduce();
|
||||
assertThat(loadByForeignKey(HostResource.class, "ns1.example.tld", clock.nowUtc())).isEmpty();
|
||||
HostResource hostBeforeDeletion =
|
||||
loadByForeignKey(HostResource.class, "ns1.example.tld", clock.nowUtc().minusDays(1)).get();
|
||||
assertAboutHosts()
|
||||
.that(hostBeforeDeletion)
|
||||
.isNotActiveAt(clock.nowUtc())
|
||||
.and()
|
||||
.hasExactlyStatusValues(StatusValue.OK)
|
||||
// Note that there will be another history entry of HOST_PENDING_DELETE, but this is
|
||||
// added by the flow and not the mapreduce itself.
|
||||
.and()
|
||||
.hasOnlyOneHistoryEntryWhich()
|
||||
.hasType(HOST_DELETE);
|
||||
HistoryEntry historyEntry = getOnlyHistoryEntryOfType(hostBeforeDeletion, HOST_DELETE);
|
||||
assertPollMessageFor(
|
||||
historyEntry,
|
||||
"TheRegistrar",
|
||||
"Deleted host ns1.example.tld.",
|
||||
true,
|
||||
host,
|
||||
Optional.of("fakeClientTrid"));
|
||||
assertNoTasksEnqueued(QUEUE_ASYNC_DELETE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_subordinateHost_getsDeleted() throws Exception {
|
||||
DomainBase domain =
|
||||
persistResource(
|
||||
newDomainBase("example.tld")
|
||||
.asBuilder()
|
||||
.setSubordinateHosts(ImmutableSet.of("ns2.example.tld"))
|
||||
.build());
|
||||
HostResource host =
|
||||
persistResource(
|
||||
persistHostPendingDelete("ns2.example.tld")
|
||||
.asBuilder()
|
||||
.setSuperordinateDomain(domain.createVKey())
|
||||
.build());
|
||||
enqueuer.enqueueAsyncDelete(
|
||||
host,
|
||||
clock.nowUtc(),
|
||||
"TheRegistrar",
|
||||
Trid.create("fakeClientTrid", "fakeServerTrid"),
|
||||
false);
|
||||
runMapreduce();
|
||||
// Check that the host is deleted as of now.
|
||||
assertThat(loadByForeignKey(HostResource.class, "ns2.example.tld", clock.nowUtc())).isEmpty();
|
||||
assertNoBillingEvents();
|
||||
assertThat(
|
||||
loadByForeignKey(DomainBase.class, "example.tld", clock.nowUtc())
|
||||
.get()
|
||||
.getSubordinateHosts())
|
||||
.isEmpty();
|
||||
assertDnsTasksEnqueued("ns2.example.tld");
|
||||
HostResource hostBeforeDeletion =
|
||||
loadByForeignKey(HostResource.class, "ns2.example.tld", clock.nowUtc().minusDays(1)).get();
|
||||
assertAboutHosts()
|
||||
.that(hostBeforeDeletion)
|
||||
.isNotActiveAt(clock.nowUtc())
|
||||
.and()
|
||||
.hasExactlyStatusValues(StatusValue.OK)
|
||||
.and()
|
||||
.hasOnlyOneHistoryEntryWhich()
|
||||
.hasType(HOST_DELETE);
|
||||
HistoryEntry historyEntry = getOnlyHistoryEntryOfType(hostBeforeDeletion, HOST_DELETE);
|
||||
assertPollMessageFor(
|
||||
historyEntry,
|
||||
"TheRegistrar",
|
||||
"Deleted host ns2.example.tld.",
|
||||
true,
|
||||
host,
|
||||
Optional.of("fakeClientTrid"));
|
||||
assertNoTasksEnqueued(QUEUE_ASYNC_DELETE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_host_notRequestedByOwner_doesNotGetDeleted() throws Exception {
|
||||
HostResource host = persistHostPendingDelete("ns2.example.tld");
|
||||
enqueuer.enqueueAsyncDelete(
|
||||
host,
|
||||
clock.nowUtc(),
|
||||
"OtherRegistrar",
|
||||
Trid.create("fakeClientTrid", "fakeServerTrid"),
|
||||
false);
|
||||
runMapreduce();
|
||||
HostResource hostAfter =
|
||||
loadByForeignKey(HostResource.class, "ns2.example.tld", clock.nowUtc()).get();
|
||||
assertAboutHosts()
|
||||
.that(hostAfter)
|
||||
.doesNotHaveStatusValue(PENDING_DELETE)
|
||||
.and()
|
||||
.hasDeletionTime(END_OF_TIME);
|
||||
HistoryEntry historyEntry = getOnlyHistoryEntryOfType(host, HOST_DELETE_FAILURE);
|
||||
assertPollMessageFor(
|
||||
historyEntry,
|
||||
"OtherRegistrar",
|
||||
"Can't delete host ns2.example.tld because it was transferred prior to deletion.",
|
||||
false,
|
||||
host,
|
||||
Optional.of("fakeClientTrid"));
|
||||
assertNoTasksEnqueued(QUEUE_ASYNC_DELETE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_host_notRequestedByOwner_isSuperuser_getsDeleted() throws Exception {
|
||||
HostResource host = persistHostPendingDelete("ns66.example.tld");
|
||||
enqueuer.enqueueAsyncDelete(
|
||||
host,
|
||||
clock.nowUtc(),
|
||||
"OtherRegistrar",
|
||||
Trid.create("fakeClientTrid", "fakeServerTrid"),
|
||||
true);
|
||||
runMapreduce();
|
||||
assertThat(loadByForeignKey(HostResource.class, "ns66.example.tld", clock.nowUtc())).isEmpty();
|
||||
HostResource hostBeforeDeletion =
|
||||
loadByForeignKey(HostResource.class, "ns66.example.tld", clock.nowUtc().minusDays(1)).get();
|
||||
assertAboutHosts()
|
||||
.that(hostBeforeDeletion)
|
||||
.isNotActiveAt(clock.nowUtc())
|
||||
.and()
|
||||
.hasExactlyStatusValues(StatusValue.OK)
|
||||
// Note that there will be another history entry of HOST_PENDING_DELETE, but this is
|
||||
// added by the flow and not the mapreduce itself.
|
||||
.and()
|
||||
.hasOnlyOneHistoryEntryWhich()
|
||||
.hasType(HOST_DELETE);
|
||||
HistoryEntry historyEntry = getOnlyHistoryEntryOfType(hostBeforeDeletion, HOST_DELETE);
|
||||
assertPollMessageFor(
|
||||
historyEntry,
|
||||
"OtherRegistrar",
|
||||
"Deleted host ns66.example.tld.",
|
||||
true,
|
||||
host,
|
||||
Optional.of("fakeClientTrid"));
|
||||
assertNoTasksEnqueued(QUEUE_ASYNC_DELETE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_deleteABunchOfContactsAndHosts_butNotSome() throws Exception {
|
||||
ContactResource c1 = persistContactPendingDelete("nsaid54");
|
||||
ContactResource c2 = persistContactPendingDelete("nsaid55");
|
||||
ContactResource c3 = persistContactPendingDelete("nsaid57");
|
||||
HostResource h1 = persistHostPendingDelete("nn5.example.tld");
|
||||
HostResource h2 = persistHostPendingDelete("no.foos.ball");
|
||||
HostResource h3 = persistHostPendingDelete("slime.wars.fun");
|
||||
ContactResource c4 = persistContactPendingDelete("iaminuse6");
|
||||
HostResource h4 = persistHostPendingDelete("used.host.com");
|
||||
persistUsedDomain("usescontactandhost.tld", c4, h4);
|
||||
for (EppResource resource : ImmutableList.<EppResource>of(c1, c2, c3, c4, h1, h2, h3, h4)) {
|
||||
enqueuer.enqueueAsyncDelete(
|
||||
resource,
|
||||
clock.nowUtc(),
|
||||
"TheRegistrar",
|
||||
Trid.create("fakeClientTrid", "fakeServerTrid"),
|
||||
false);
|
||||
}
|
||||
runMapreduce();
|
||||
for (EppResource resource : ImmutableList.<EppResource>of(c1, c2, c3, h1, h2, h3)) {
|
||||
EppResource loaded = auditedOfy().load().entity(resource).now();
|
||||
assertThat(loaded.getDeletionTime()).isLessThan(DateTime.now(UTC));
|
||||
assertThat(loaded.getStatusValues()).doesNotContain(PENDING_DELETE);
|
||||
}
|
||||
for (EppResource resource : ImmutableList.<EppResource>of(c4, h4)) {
|
||||
EppResource loaded = auditedOfy().load().entity(resource).now();
|
||||
assertThat(loaded.getDeletionTime()).isEqualTo(END_OF_TIME);
|
||||
assertThat(loaded.getStatusValues()).doesNotContain(PENDING_DELETE);
|
||||
}
|
||||
assertNoTasksEnqueued(QUEUE_ASYNC_DELETE);
|
||||
}
|
||||
|
||||
private static ContactResource persistContactWithPii(String contactId) {
|
||||
return persistResource(
|
||||
newContactResource(contactId)
|
||||
.asBuilder()
|
||||
.setLocalizedPostalInfo(
|
||||
new PostalInfo.Builder()
|
||||
.setType(PostalInfo.Type.LOCALIZED)
|
||||
.setAddress(
|
||||
new ContactAddress.Builder()
|
||||
.setStreet(ImmutableList.of("123 Grand Ave"))
|
||||
.build())
|
||||
.build())
|
||||
.setInternationalizedPostalInfo(
|
||||
new PostalInfo.Builder()
|
||||
.setType(PostalInfo.Type.INTERNATIONALIZED)
|
||||
.setAddress(
|
||||
new ContactAddress.Builder()
|
||||
.setStreet(ImmutableList.of("123 Avenida Grande"))
|
||||
.build())
|
||||
.build())
|
||||
.setEmailAddress("bob@bob.com")
|
||||
.setVoiceNumber(new ContactPhoneNumber.Builder().setPhoneNumber("555-1212").build())
|
||||
.setFaxNumber(new ContactPhoneNumber.Builder().setPhoneNumber("555-1212").build())
|
||||
.addStatusValue(PENDING_DELETE)
|
||||
.build());
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to check that one poll message exists with a given history entry, resource,
|
||||
* client id, and message. Also checks that the only resulting async response matches the resource
|
||||
* type, and has the appropriate actionResult, nameOrId, and Trid.
|
||||
*/
|
||||
private static void assertPollMessageFor(
|
||||
HistoryEntry historyEntry,
|
||||
String registrarId,
|
||||
String msg,
|
||||
boolean expectedActionResult,
|
||||
EppResource resource,
|
||||
Optional<String> clientTrid) {
|
||||
PollMessage.OneTime pollMessage = (OneTime) getOnlyPollMessageForHistoryEntry(historyEntry);
|
||||
assertThat(pollMessage.getMsg()).isEqualTo(msg);
|
||||
assertThat(pollMessage.getRegistrarId()).isEqualTo(registrarId);
|
||||
|
||||
ImmutableList<ResponseData> pollResponses = pollMessage.getResponseData();
|
||||
assertThat(pollResponses).hasSize(1);
|
||||
ResponseData responseData = pollMessage.getResponseData().get(0);
|
||||
|
||||
String expectedResourceName;
|
||||
if (resource instanceof HostResource) {
|
||||
assertThat(responseData).isInstanceOf(HostPendingActionNotificationResponse.class);
|
||||
expectedResourceName = ((HostResource) resource).getHostName();
|
||||
} else {
|
||||
assertThat(responseData).isInstanceOf(ContactPendingActionNotificationResponse.class);
|
||||
expectedResourceName = ((ContactResource) resource).getContactId();
|
||||
}
|
||||
PendingActionNotificationResponse pendingResponse =
|
||||
(PendingActionNotificationResponse) responseData;
|
||||
assertThat(pendingResponse.getActionResult()).isEqualTo(expectedActionResult);
|
||||
assertThat(pendingResponse.getNameAsString()).isEqualTo(expectedResourceName);
|
||||
Trid trid = pendingResponse.getTrid();
|
||||
assertThat(trid.getClientTransactionId()).isEqualTo(clientTrid);
|
||||
assertThat(trid.getServerTransactionId()).isEqualTo("fakeServerTrid");
|
||||
}
|
||||
|
||||
private static ContactResource persistContactPendingDelete(String contactId) {
|
||||
return persistResource(
|
||||
newContactResource(contactId).asBuilder().addStatusValue(PENDING_DELETE).build());
|
||||
}
|
||||
|
||||
private static HostResource persistHostPendingDelete(String hostName) {
|
||||
return persistResource(
|
||||
newHostResource(hostName).asBuilder().addStatusValue(PENDING_DELETE).build());
|
||||
}
|
||||
|
||||
private static DomainBase persistUsedDomain(
|
||||
String domainName, ContactResource contact, HostResource host) {
|
||||
return persistResource(
|
||||
newDomainBase(domainName, contact)
|
||||
.asBuilder()
|
||||
.setNameservers(ImmutableSet.of(host.createVKey()))
|
||||
.build());
|
||||
}
|
||||
|
||||
private Optional<Lock> acquireLock() {
|
||||
return Lock.acquire(
|
||||
DeleteContactsAndHostsAction.class.getSimpleName(),
|
||||
null,
|
||||
standardDays(30),
|
||||
requestStatusChecker,
|
||||
false);
|
||||
}
|
||||
}
|
||||
@@ -16,13 +16,10 @@ package google.registry.flows;
|
||||
|
||||
import static google.registry.model.eppoutput.Result.Code.SUCCESS;
|
||||
import static google.registry.model.eppoutput.Result.Code.SUCCESS_WITH_ACK_MESSAGE;
|
||||
import static google.registry.model.eppoutput.Result.Code.SUCCESS_WITH_ACTION_PENDING;
|
||||
import static google.registry.model.eppoutput.Result.Code.SUCCESS_WITH_NO_MESSAGES;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.testing.EppMetricSubject.assertThat;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import google.registry.model.eppoutput.Result;
|
||||
import google.registry.testing.AppEngineExtension;
|
||||
import google.registry.testing.DualDatabaseTest;
|
||||
import google.registry.testing.TestOfyAndSql;
|
||||
@@ -65,22 +62,14 @@ class EppLifecycleContactTest extends EppTestCase {
|
||||
.hasCommandName("ContactInfo")
|
||||
.and()
|
||||
.hasStatus(SUCCESS);
|
||||
Result.Code deleteResultCode;
|
||||
if (tm().isOfy()) {
|
||||
assertThatCommand("contact_delete_sh8013.xml")
|
||||
.hasResponse("contact_delete_response_sh8013_pending.xml");
|
||||
deleteResultCode = SUCCESS_WITH_ACTION_PENDING;
|
||||
} else {
|
||||
assertThatCommand("contact_delete_sh8013.xml")
|
||||
.hasResponse("contact_delete_response_sh8013.xml");
|
||||
deleteResultCode = SUCCESS;
|
||||
}
|
||||
assertThatCommand("contact_delete_sh8013.xml")
|
||||
.hasResponse("contact_delete_response_sh8013.xml");
|
||||
assertThat(getRecordedEppMetric())
|
||||
.hasClientId("NewRegistrar")
|
||||
.and()
|
||||
.hasCommandName("ContactDelete")
|
||||
.and()
|
||||
.hasStatus(deleteResultCode);
|
||||
.hasStatus(SUCCESS);
|
||||
assertThatLogoutSucceeds();
|
||||
}
|
||||
|
||||
|
||||
@@ -17,8 +17,6 @@ package google.registry.flows;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.model.EppResourceUtils.loadByForeignKey;
|
||||
import static google.registry.model.eppoutput.Result.Code.SUCCESS;
|
||||
import static google.registry.model.eppoutput.Result.Code.SUCCESS_WITH_ACTION_PENDING;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.testing.DatabaseHelper.createTld;
|
||||
import static google.registry.testing.DatabaseHelper.createTlds;
|
||||
import static google.registry.testing.EppMetricSubject.assertThat;
|
||||
@@ -26,7 +24,6 @@ import static google.registry.testing.HostResourceSubject.assertAboutHosts;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import google.registry.model.domain.DomainBase;
|
||||
import google.registry.model.eppoutput.Result;
|
||||
import google.registry.model.host.HostResource;
|
||||
import google.registry.testing.AppEngineExtension;
|
||||
import google.registry.testing.DualDatabaseTest;
|
||||
@@ -82,24 +79,15 @@ class EppLifecycleHostTest extends EppTestCase {
|
||||
.hasCommandName("HostInfo")
|
||||
.and()
|
||||
.hasStatus(SUCCESS);
|
||||
Result.Code deleteResultCode;
|
||||
if (tm().isOfy()) {
|
||||
assertThatCommand("host_delete.xml", ImmutableMap.of("HOSTNAME", "ns1.example.tld"))
|
||||
.atTime("2000-06-02T00:03:00Z")
|
||||
.hasResponse("generic_success_action_pending_response.xml");
|
||||
deleteResultCode = SUCCESS_WITH_ACTION_PENDING;
|
||||
} else {
|
||||
assertThatCommand("host_delete.xml", ImmutableMap.of("HOSTNAME", "ns1.example.tld"))
|
||||
.atTime("2000-06-02T00:03:00Z")
|
||||
.hasResponse("generic_success_response.xml");
|
||||
deleteResultCode = SUCCESS;
|
||||
}
|
||||
assertThatCommand("host_delete.xml", ImmutableMap.of("HOSTNAME", "ns1.example.tld"))
|
||||
.atTime("2000-06-02T00:03:00Z")
|
||||
.hasResponse("generic_success_response.xml");
|
||||
assertThat(getRecordedEppMetric())
|
||||
.hasClientId("NewRegistrar")
|
||||
.and()
|
||||
.hasCommandName("HostDelete")
|
||||
.and()
|
||||
.hasStatus(deleteResultCode);
|
||||
.hasStatus(SUCCESS);
|
||||
assertThatLogoutSucceeds();
|
||||
}
|
||||
|
||||
|
||||
@@ -148,19 +148,12 @@ class EppPointInTimeTest {
|
||||
.isEqualExceptFields(domainAfterCreate, "updateTimestamp");
|
||||
|
||||
tm().clearSessionCache();
|
||||
if (tm().isOfy()) {
|
||||
// Both updates happened on the same day. Since the revisions field has day granularity in
|
||||
// Datastore, the key to the first update should have been overwritten by the second, and its
|
||||
// timestamp rolled forward. So we have to fall back to the last revision before midnight.
|
||||
assertThat(loadAtPointInTime(latest, timeAtFirstUpdate)).isEqualTo(domainAfterCreate);
|
||||
} else {
|
||||
// In SQL, however, we are not limited by the day granularity, so when we request the object
|
||||
// at timeAtFirstUpdate we should receive the object at that first update, even though the
|
||||
// second update occurred one millisecond later.
|
||||
assertAboutImmutableObjects()
|
||||
.that(loadAtPointInTime(latest, timeAtFirstUpdate))
|
||||
.isEqualExceptFields(domainAfterFirstUpdate, "updateTimestamp");
|
||||
}
|
||||
// In SQL, we are not limited by the day granularity, so when we request the object
|
||||
// at timeAtFirstUpdate we should receive the object at that first update, even though the
|
||||
// second update occurred one millisecond later.
|
||||
assertAboutImmutableObjects()
|
||||
.that(loadAtPointInTime(latest, timeAtFirstUpdate))
|
||||
.isEqualExceptFields(domainAfterFirstUpdate, "updateTimestamp");
|
||||
|
||||
tm().clearSessionCache();
|
||||
assertAboutImmutableObjects()
|
||||
|
||||
@@ -14,12 +14,9 @@
|
||||
|
||||
package google.registry.flows;
|
||||
|
||||
import static com.google.common.collect.ImmutableList.toImmutableList;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
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.model.ofy.ObjectifyService.auditedOfy;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm;
|
||||
import static google.registry.testing.LogsSubject.assertAboutLogs;
|
||||
@@ -28,9 +25,7 @@ import static google.registry.testing.TaskQueueHelper.assertTasksEnqueued;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Streams;
|
||||
import com.google.common.testing.TestLogHandler;
|
||||
import com.googlecode.objectify.Key;
|
||||
import google.registry.model.EppResource;
|
||||
import google.registry.model.contact.ContactBase;
|
||||
import google.registry.model.contact.ContactHistory;
|
||||
@@ -41,8 +36,6 @@ import google.registry.model.eppinput.EppInput.ResourceCommandWrapper;
|
||||
import google.registry.model.eppinput.ResourceCommand;
|
||||
import google.registry.model.host.HostBase;
|
||||
import google.registry.model.host.HostHistory;
|
||||
import google.registry.model.index.EppResourceIndex;
|
||||
import google.registry.model.index.EppResourceIndexBucket;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.model.tmch.ClaimsList;
|
||||
import google.registry.model.tmch.ClaimsListDao;
|
||||
@@ -117,30 +110,6 @@ public abstract class ResourceFlowTestCase<F extends Flow, R extends EppResource
|
||||
ClaimsListDao.save(ClaimsList.create(clock.nowUtc(), labelsToKeys));
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirms that an EppResourceIndex entity exists in Datastore for a given resource.
|
||||
*/
|
||||
protected static <T extends EppResource> void assertEppResourceIndexEntityFor(final T resource) {
|
||||
if (!tm().isOfy()) {
|
||||
// Indices aren't explicitly stored as objects in SQL
|
||||
return;
|
||||
}
|
||||
ImmutableList<EppResourceIndex> indices =
|
||||
Streams.stream(
|
||||
auditedOfy()
|
||||
.load()
|
||||
.type(EppResourceIndex.class)
|
||||
.filter("kind", Key.getKind(resource.getClass())))
|
||||
.filter(
|
||||
index ->
|
||||
Key.create(resource).equals(index.getKey())
|
||||
&& auditedOfy().load().key(index.getKey()).now().equals(resource))
|
||||
.collect(toImmutableList());
|
||||
assertThat(indices).hasSize(1);
|
||||
assertThat(indices.get(0).getBucket())
|
||||
.isEqualTo(EppResourceIndexBucket.getBucketKey(Key.create(resource)));
|
||||
}
|
||||
|
||||
/** Asserts the presence of a single enqueued async contact or host deletion */
|
||||
protected <T extends EppResource> void assertAsyncDeletionTaskEnqueued(
|
||||
T resource, String requestingClientId, Trid trid, boolean isSuperuser) {
|
||||
@@ -180,26 +149,24 @@ public abstract class ResourceFlowTestCase<F extends Flow, R extends EppResource
|
||||
}
|
||||
|
||||
protected void assertLastHistoryContainsResource(EppResource resource) {
|
||||
if (!tm().isOfy()) {
|
||||
HistoryEntry historyEntry = Iterables.getLast(DatabaseHelper.getHistoryEntries(resource));
|
||||
if (resource instanceof ContactBase) {
|
||||
ContactHistory contactHistory = (ContactHistory) historyEntry;
|
||||
// Don't use direct equals comparison since one might be a subclass of the other
|
||||
assertAboutImmutableObjects()
|
||||
.that(contactHistory.getContactBase().get())
|
||||
.hasFieldsEqualTo(resource);
|
||||
} else if (resource instanceof DomainContent) {
|
||||
DomainHistory domainHistory = (DomainHistory) historyEntry;
|
||||
assertAboutImmutableObjects()
|
||||
.that(domainHistory.getDomainContent().get())
|
||||
.isEqualExceptFields(resource, "gracePeriods", "dsData", "nsHosts");
|
||||
} else if (resource instanceof HostBase) {
|
||||
HostHistory hostHistory = (HostHistory) historyEntry;
|
||||
// Don't use direct equals comparison since one might be a subclass of the other
|
||||
assertAboutImmutableObjects()
|
||||
.that(hostHistory.getHostBase().get())
|
||||
.hasFieldsEqualTo(resource);
|
||||
}
|
||||
HistoryEntry historyEntry = Iterables.getLast(DatabaseHelper.getHistoryEntries(resource));
|
||||
if (resource instanceof ContactBase) {
|
||||
ContactHistory contactHistory = (ContactHistory) historyEntry;
|
||||
// Don't use direct equals comparison since one might be a subclass of the other
|
||||
assertAboutImmutableObjects()
|
||||
.that(contactHistory.getContactBase().get())
|
||||
.hasFieldsEqualTo(resource);
|
||||
} else if (resource instanceof DomainContent) {
|
||||
DomainHistory domainHistory = (DomainHistory) historyEntry;
|
||||
assertAboutImmutableObjects()
|
||||
.that(domainHistory.getDomainContent().get())
|
||||
.isEqualExceptFields(resource, "gracePeriods", "dsData", "nsHosts");
|
||||
} else if (resource instanceof HostBase) {
|
||||
HostHistory hostHistory = (HostHistory) historyEntry;
|
||||
// Don't use direct equals comparison since one might be a subclass of the other
|
||||
assertAboutImmutableObjects()
|
||||
.that(hostHistory.getHostBase().get())
|
||||
.hasFieldsEqualTo(resource);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
package google.registry.flows.contact;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.testing.ContactResourceSubject.assertAboutContacts;
|
||||
import static google.registry.testing.DatabaseHelper.assertNoBillingEvents;
|
||||
import static google.registry.testing.DatabaseHelper.newContactResource;
|
||||
@@ -63,9 +62,6 @@ class ContactCreateFlowTest extends ResourceFlowTestCase<ContactCreateFlow, Cont
|
||||
ContactResource contact = reloadResourceByForeignKey();
|
||||
assertAboutContacts().that(contact).hasOnlyOneHistoryEntryWhich().hasNoXml();
|
||||
assertNoBillingEvents();
|
||||
if (tm().isOfy()) {
|
||||
assertEppResourceIndexEntityFor(contact);
|
||||
}
|
||||
assertLastHistoryContainsResource(contact);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@ package google.registry.flows.contact;
|
||||
import static com.google.common.collect.MoreCollectors.onlyElement;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_DELETE;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.testing.ContactResourceSubject.assertAboutContacts;
|
||||
import static google.registry.testing.DatabaseHelper.assertNoBillingEvents;
|
||||
import static google.registry.testing.DatabaseHelper.createTld;
|
||||
@@ -87,11 +86,7 @@ class ContactDeleteFlowTest extends ResourceFlowTestCase<ContactDeleteFlow, Cont
|
||||
@TestOfyAndSql
|
||||
void testDryRun() throws Exception {
|
||||
persistActiveContact(getUniqueIdFromCommand());
|
||||
if (tm().isOfy()) {
|
||||
dryRunFlowAssertResponse(loadFile("contact_delete_response_pending.xml"));
|
||||
} else {
|
||||
dryRunFlowAssertResponse(loadFile("contact_delete_response.xml"));
|
||||
}
|
||||
dryRunFlowAssertResponse(loadFile("contact_delete_response.xml"));
|
||||
}
|
||||
|
||||
@TestOfyAndSql
|
||||
@@ -99,13 +94,8 @@ class ContactDeleteFlowTest extends ResourceFlowTestCase<ContactDeleteFlow, Cont
|
||||
persistActiveContact(getUniqueIdFromCommand());
|
||||
clock.advanceOneMilli();
|
||||
assertTransactionalFlow(true);
|
||||
if (tm().isOfy()) {
|
||||
runFlowAssertResponse(loadFile("contact_delete_response_pending.xml"));
|
||||
assertOfyDeleteSuccess();
|
||||
} else {
|
||||
runFlowAssertResponse(loadFile("contact_delete_response.xml"));
|
||||
assertSqlDeleteSuccess();
|
||||
}
|
||||
runFlowAssertResponse(loadFile("contact_delete_response.xml"));
|
||||
assertSqlDeleteSuccess();
|
||||
}
|
||||
|
||||
@TestSqlOnly
|
||||
@@ -156,13 +146,8 @@ class ContactDeleteFlowTest extends ResourceFlowTestCase<ContactDeleteFlow, Cont
|
||||
persistActiveContact(getUniqueIdFromCommand());
|
||||
clock.advanceOneMilli();
|
||||
assertTransactionalFlow(true);
|
||||
if (tm().isOfy()) {
|
||||
runFlowAssertResponse(loadFile("contact_delete_response_no_cltrid_pending.xml"));
|
||||
assertOfyDeleteSuccess("TheRegistrar", null, false);
|
||||
} else {
|
||||
runFlowAssertResponse(loadFile("contact_delete_response_no_cltrid.xml"));
|
||||
assertSqlDeleteSuccess();
|
||||
}
|
||||
runFlowAssertResponse(loadFile("contact_delete_response_no_cltrid.xml"));
|
||||
assertSqlDeleteSuccess();
|
||||
}
|
||||
|
||||
@TestOfyAndSql
|
||||
@@ -225,17 +210,9 @@ class ContactDeleteFlowTest extends ResourceFlowTestCase<ContactDeleteFlow, Cont
|
||||
sessionMetadata.setRegistrarId("NewRegistrar");
|
||||
persistActiveContact(getUniqueIdFromCommand());
|
||||
clock.advanceOneMilli();
|
||||
if (tm().isOfy()) {
|
||||
runFlowAssertResponse(
|
||||
CommitMode.LIVE,
|
||||
UserPrivileges.SUPERUSER,
|
||||
loadFile("contact_delete_response_pending.xml"));
|
||||
assertOfyDeleteSuccess("NewRegistrar", "ABC-12345", true);
|
||||
} else {
|
||||
runFlowAssertResponse(
|
||||
CommitMode.LIVE, UserPrivileges.SUPERUSER, loadFile("contact_delete_response.xml"));
|
||||
assertSqlDeleteSuccess();
|
||||
}
|
||||
runFlowAssertResponse(
|
||||
CommitMode.LIVE, UserPrivileges.SUPERUSER, loadFile("contact_delete_response.xml"));
|
||||
assertSqlDeleteSuccess();
|
||||
}
|
||||
|
||||
@TestOfyAndSql
|
||||
@@ -272,25 +249,6 @@ class ContactDeleteFlowTest extends ResourceFlowTestCase<ContactDeleteFlow, Cont
|
||||
DatabaseHelper.removeDatabaseMigrationSchedule();
|
||||
}
|
||||
|
||||
private void assertOfyDeleteSuccess(String registrarId, String clientTrid, boolean isSuperuser)
|
||||
throws Exception {
|
||||
ContactResource deletedContact = reloadResourceByForeignKey();
|
||||
assertAsyncDeletionTaskEnqueued(
|
||||
deletedContact, registrarId, Trid.create(clientTrid, "server-trid"), isSuperuser);
|
||||
assertAboutContacts()
|
||||
.that(deletedContact)
|
||||
.hasStatusValue(StatusValue.PENDING_DELETE)
|
||||
.and()
|
||||
.hasOnlyOneHistoryEntryWhich()
|
||||
.hasType(Type.CONTACT_PENDING_DELETE);
|
||||
assertNoBillingEvents();
|
||||
assertLastHistoryContainsResource(deletedContact);
|
||||
}
|
||||
|
||||
private void assertOfyDeleteSuccess() throws Exception {
|
||||
assertOfyDeleteSuccess("TheRegistrar", "ABC-12345", false);
|
||||
}
|
||||
|
||||
private void assertSqlDeleteSuccess(HistoryEntry.Type... historyEntryTypes) throws Exception {
|
||||
assertThat(reloadResourceByForeignKey()).isNull();
|
||||
assertAboutContacts()
|
||||
|
||||
@@ -368,7 +368,6 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||
GracePeriodStatus.ADD, domain.getRepoId(), billingTime, "TheRegistrar", null),
|
||||
createBillingEvent));
|
||||
assertDnsTasksEnqueued(getUniqueIdFromCommand());
|
||||
assertEppResourceIndexEntityFor(domain);
|
||||
|
||||
replayExtension.expectUpdateFor(domain);
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@ package google.registry.flows.host;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.model.EppResourceUtils.loadByForeignKey;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.testing.DatabaseHelper.assertNoBillingEvents;
|
||||
import static google.registry.testing.DatabaseHelper.createTld;
|
||||
import static google.registry.testing.DatabaseHelper.createTlds;
|
||||
@@ -105,9 +104,6 @@ class HostCreateFlowTest extends ResourceFlowTestCase<HostCreateFlow, HostResour
|
||||
.hasOnlyOneHistoryEntryWhich()
|
||||
.hasType(HistoryEntry.Type.HOST_CREATE);
|
||||
assertNoBillingEvents();
|
||||
if (tm().isOfy()) {
|
||||
assertEppResourceIndexEntityFor(host);
|
||||
}
|
||||
assertLastHistoryContainsResource(host);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@ package google.registry.flows.host;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_DELETE;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.testing.DatabaseHelper.assertNoBillingEvents;
|
||||
import static google.registry.testing.DatabaseHelper.createTld;
|
||||
import static google.registry.testing.DatabaseHelper.loadByKey;
|
||||
@@ -47,7 +46,6 @@ import google.registry.flows.host.HostFlowUtils.HostNameNotNormalizedException;
|
||||
import google.registry.flows.host.HostFlowUtils.HostNameNotPunyCodedException;
|
||||
import google.registry.model.domain.DomainBase;
|
||||
import google.registry.model.eppcommon.StatusValue;
|
||||
import google.registry.model.eppcommon.Trid;
|
||||
import google.registry.model.host.HostResource;
|
||||
import google.registry.model.reporting.HistoryEntry.Type;
|
||||
import google.registry.model.tld.Registry;
|
||||
@@ -86,11 +84,7 @@ class HostDeleteFlowTest extends ResourceFlowTestCase<HostDeleteFlow, HostResour
|
||||
@TestOfyAndSql
|
||||
void testDryRun() throws Exception {
|
||||
persistActiveHost("ns1.example.tld");
|
||||
if (tm().isOfy()) {
|
||||
dryRunFlowAssertResponse(loadFile("host_delete_response_pending.xml"));
|
||||
} else {
|
||||
dryRunFlowAssertResponse(loadFile("host_delete_response.xml"));
|
||||
}
|
||||
dryRunFlowAssertResponse(loadFile("host_delete_response.xml"));
|
||||
}
|
||||
|
||||
@TestOfyAndSql
|
||||
@@ -98,13 +92,8 @@ class HostDeleteFlowTest extends ResourceFlowTestCase<HostDeleteFlow, HostResour
|
||||
persistActiveHost("ns1.example.tld");
|
||||
clock.advanceOneMilli();
|
||||
assertTransactionalFlow(true);
|
||||
if (tm().isOfy()) {
|
||||
runFlowAssertResponse(loadFile("host_delete_response_pending.xml"));
|
||||
assertOfyDeleteSuccess();
|
||||
} else {
|
||||
runFlowAssertResponse(loadFile("host_delete_response.xml"));
|
||||
assertSqlDeleteSuccess();
|
||||
}
|
||||
runFlowAssertResponse(loadFile("host_delete_response.xml"));
|
||||
assertSqlDeleteSuccess();
|
||||
}
|
||||
|
||||
@TestOfyAndSql
|
||||
@@ -113,13 +102,8 @@ class HostDeleteFlowTest extends ResourceFlowTestCase<HostDeleteFlow, HostResour
|
||||
persistActiveHost("ns1.example.tld");
|
||||
clock.advanceOneMilli();
|
||||
assertTransactionalFlow(true);
|
||||
if (tm().isOfy()) {
|
||||
runFlowAssertResponse(loadFile("host_delete_response_no_cltrid_pending.xml"));
|
||||
assertOfyDeleteSuccess("TheRegistrar", null, false);
|
||||
} else {
|
||||
runFlowAssertResponse(loadFile("host_delete_response_no_cltrid.xml"));
|
||||
assertSqlDeleteSuccess();
|
||||
}
|
||||
runFlowAssertResponse(loadFile("host_delete_response_no_cltrid.xml"));
|
||||
assertSqlDeleteSuccess();
|
||||
}
|
||||
|
||||
@TestOfyAndSql
|
||||
@@ -178,15 +162,9 @@ class HostDeleteFlowTest extends ResourceFlowTestCase<HostDeleteFlow, HostResour
|
||||
sessionMetadata.setRegistrarId("NewRegistrar");
|
||||
persistActiveHost("ns1.example.tld");
|
||||
clock.advanceOneMilli();
|
||||
if (tm().isOfy()) {
|
||||
runFlowAssertResponse(
|
||||
CommitMode.LIVE, UserPrivileges.SUPERUSER, loadFile("host_delete_response_pending.xml"));
|
||||
assertOfyDeleteSuccess("NewRegistrar", "ABC-12345", true);
|
||||
} else {
|
||||
runFlowAssertResponse(
|
||||
CommitMode.LIVE, UserPrivileges.SUPERUSER, loadFile("host_delete_response.xml"));
|
||||
assertSqlDeleteSuccess();
|
||||
}
|
||||
runFlowAssertResponse(
|
||||
CommitMode.LIVE, UserPrivileges.SUPERUSER, loadFile("host_delete_response.xml"));
|
||||
assertSqlDeleteSuccess();
|
||||
}
|
||||
|
||||
@TestOfyAndSql
|
||||
@@ -206,13 +184,8 @@ class HostDeleteFlowTest extends ResourceFlowTestCase<HostDeleteFlow, HostResour
|
||||
.setSuperordinateDomain(domain.createVKey())
|
||||
.build());
|
||||
clock.advanceOneMilli();
|
||||
if (tm().isOfy()) {
|
||||
runFlowAssertResponse(loadFile("host_delete_response_pending.xml"));
|
||||
assertOfyDeleteSuccess();
|
||||
} else {
|
||||
runFlowAssertResponse(loadFile("host_delete_response.xml"));
|
||||
assertSqlDeleteSuccess(true);
|
||||
}
|
||||
runFlowAssertResponse(loadFile("host_delete_response.xml"));
|
||||
assertSqlDeleteSuccess(true);
|
||||
}
|
||||
|
||||
@TestOfyAndSql
|
||||
@@ -265,13 +238,8 @@ class HostDeleteFlowTest extends ResourceFlowTestCase<HostDeleteFlow, HostResour
|
||||
.setSuperordinateDomain(domain.createVKey())
|
||||
.build());
|
||||
clock.advanceOneMilli();
|
||||
if (tm().isOfy()) {
|
||||
runFlowAssertResponse(loadFile("host_delete_response_pending.xml"));
|
||||
assertOfyDeleteSuccess("NewRegistrar", "ABC-12345", false);
|
||||
} else {
|
||||
runFlowAssertResponse(loadFile("host_delete_response.xml"));
|
||||
assertSqlDeleteSuccess(true);
|
||||
}
|
||||
runFlowAssertResponse(loadFile("host_delete_response.xml"));
|
||||
assertSqlDeleteSuccess(true);
|
||||
}
|
||||
|
||||
@TestOfyAndSql
|
||||
@@ -367,25 +335,6 @@ class HostDeleteFlowTest extends ResourceFlowTestCase<HostDeleteFlow, HostResour
|
||||
DatabaseHelper.removeDatabaseMigrationSchedule();
|
||||
}
|
||||
|
||||
private void assertOfyDeleteSuccess(String registrarId, String clientTrid, boolean isSuperuser)
|
||||
throws Exception {
|
||||
HostResource deletedHost = reloadResourceByForeignKey();
|
||||
assertAsyncDeletionTaskEnqueued(
|
||||
deletedHost, registrarId, Trid.create(clientTrid, "server-trid"), isSuperuser);
|
||||
assertAboutHosts()
|
||||
.that(deletedHost)
|
||||
.hasStatusValue(StatusValue.PENDING_DELETE)
|
||||
.and()
|
||||
.hasOnlyOneHistoryEntryWhich()
|
||||
.hasType(Type.HOST_PENDING_DELETE);
|
||||
assertNoBillingEvents();
|
||||
assertNoDnsTasksEnqueued();
|
||||
}
|
||||
|
||||
private void assertOfyDeleteSuccess() throws Exception {
|
||||
assertOfyDeleteSuccess("TheRegistrar", "ABC-12345", false);
|
||||
}
|
||||
|
||||
private void assertSqlDeleteSuccess(boolean isSubordinate) throws Exception {
|
||||
assertThat(reloadResourceByForeignKey()).isNull();
|
||||
HostResource deletedHost = reloadResourceByForeignKey(clock.nowUtc().minusMillis(1));
|
||||
|
||||
@@ -19,7 +19,6 @@ import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.batch.AsyncTaskEnqueuer.PARAM_HOST_KEY;
|
||||
import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_HOST_RENAME;
|
||||
import static google.registry.model.EppResourceUtils.loadByForeignKey;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.testing.DatabaseHelper.assertNoBillingEvents;
|
||||
import static google.registry.testing.DatabaseHelper.createTld;
|
||||
import static google.registry.testing.DatabaseHelper.getOnlyHistoryEntryOfType;
|
||||
@@ -198,16 +197,6 @@ class HostUpdateFlowTest extends ResourceFlowTestCase<HostUpdateFlow, HostResour
|
||||
HostResource renamedHost = doSuccessfulTest();
|
||||
assertThat(renamedHost.isSubordinate()).isTrue();
|
||||
assertDnsTasksEnqueued("ns1.example.tld", "ns2.example.tld");
|
||||
// As we don't actually store ForeignKeyIndex<HostResource> entity in SQL database(it is
|
||||
// reconstructed by reading the information from Host table), we can not reconstruct the entity
|
||||
// for the old host name because of the rename so we just skip the check for SQL database.
|
||||
if (tm().isOfy()) {
|
||||
// The old ForeignKeyIndex is invalidated at the time we did the rename.
|
||||
ForeignKeyIndex<HostResource> oldFkiBeforeRename =
|
||||
ForeignKeyIndex.load(HostResource.class, oldHostName(), clock.nowUtc().minusMillis(1));
|
||||
assertThat(oldFkiBeforeRename.getResourceKey()).isEqualTo(renamedHost.createVKey());
|
||||
assertThat(oldFkiBeforeRename.getDeletionTime()).isEqualTo(clock.nowUtc());
|
||||
}
|
||||
ForeignKeyIndex<HostResource> oldFkiAfterRename =
|
||||
ForeignKeyIndex.load(HostResource.class, oldHostName(), clock.nowUtc());
|
||||
assertThat(oldFkiAfterRename).isNull();
|
||||
|
||||
@@ -40,10 +40,11 @@ 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}.
|
||||
@@ -51,6 +52,7 @@ import org.junit.jupiter.api.Test;
|
||||
* <p>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<RdapDomainAction> {
|
||||
|
||||
RdapDomainActionTest() {
|
||||
@@ -247,7 +249,7 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testInvalidDomain_returns400() {
|
||||
assertThat(generateActualJson("invalid/domain/name"))
|
||||
.isEqualTo(
|
||||
@@ -258,7 +260,7 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
|
||||
assertThat(response.getStatus()).isEqualTo(400);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testUnknownDomain_returns400() {
|
||||
assertThat(generateActualJson("missingdomain.com"))
|
||||
.isEqualTo(
|
||||
@@ -269,45 +271,45 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
|
||||
assertThat(response.getStatus()).isEqualTo(400);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testValidDomain_works() {
|
||||
login("evilregistrar");
|
||||
assertProperResponseForCatLol("cat.lol", "rdap_domain.json");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testValidDomain_asAdministrator_works() {
|
||||
loginAsAdmin();
|
||||
assertProperResponseForCatLol("cat.lol", "rdap_domain.json");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testValidDomain_notLoggedIn_noContacts() {
|
||||
assertProperResponseForCatLol("cat.lol", "rdap_domain_no_contacts_with_remark.json");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testValidDomain_loggedInAsOtherRegistrar_noContacts() {
|
||||
login("idnregistrar");
|
||||
assertProperResponseForCatLol("cat.lol", "rdap_domain_no_contacts_with_remark.json");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testUpperCase_ignored() {
|
||||
assertProperResponseForCatLol("CaT.lOl", "rdap_domain_no_contacts_with_remark.json");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testTrailingDot_ignored() {
|
||||
assertProperResponseForCatLol("cat.lol.", "rdap_domain_no_contacts_with_remark.json");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testQueryParameter_ignored() {
|
||||
assertProperResponseForCatLol("cat.lol?key=value", "rdap_domain_no_contacts_with_remark.json");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testIdnDomain_works() {
|
||||
login("idnregistrar");
|
||||
assertThat(generateActualJson("cat.みんな"))
|
||||
@@ -325,7 +327,7 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testIdnDomainWithPercentEncoding_works() {
|
||||
login("idnregistrar");
|
||||
assertThat(generateActualJson("cat.%E3%81%BF%E3%82%93%E3%81%AA"))
|
||||
@@ -343,7 +345,7 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testPunycodeDomain_works() {
|
||||
login("idnregistrar");
|
||||
assertThat(generateActualJson("cat.xn--q9jyb4c"))
|
||||
@@ -361,7 +363,7 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testMultilevelDomain_works() {
|
||||
login("1tldregistrar");
|
||||
assertThat(generateActualJson("cat.1.tld"))
|
||||
@@ -381,35 +383,35 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
|
||||
|
||||
// todo (b/27378695): reenable or delete this test
|
||||
@Disabled
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testDomainInTestTld_notFound() {
|
||||
persistResource(Registry.get("lol").asBuilder().setTldType(Registry.TldType.TEST).build());
|
||||
generateActualJson("cat.lol");
|
||||
assertThat(response.getStatus()).isEqualTo(404);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testDeletedDomain_notFound() {
|
||||
assertThat(generateActualJson("dodo.lol"))
|
||||
.isEqualTo(generateExpectedJsonError("dodo.lol not found", 404));
|
||||
assertThat(response.getStatus()).isEqualTo(404);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testDeletedDomain_notFound_includeDeletedSetFalse() {
|
||||
action.includeDeletedParam = Optional.of(true);
|
||||
generateActualJson("dodo.lol");
|
||||
assertThat(response.getStatus()).isEqualTo(404);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testDeletedDomain_notFound_notLoggedIn() {
|
||||
action.includeDeletedParam = Optional.of(true);
|
||||
generateActualJson("dodo.lol");
|
||||
assertThat(response.getStatus()).isEqualTo(404);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testDeletedDomain_notFound_loggedInAsDifferentRegistrar() {
|
||||
login("1tldregistrar");
|
||||
action.includeDeletedParam = Optional.of(true);
|
||||
@@ -417,7 +419,7 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
|
||||
assertThat(response.getStatus()).isEqualTo(404);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testDeletedDomain_works_loggedInAsCorrectRegistrar() {
|
||||
login("evilregistrar");
|
||||
action.includeDeletedParam = Optional.of(true);
|
||||
@@ -436,7 +438,7 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testDeletedDomain_works_loggedInAsAdmin() {
|
||||
loginAsAdmin();
|
||||
action.includeDeletedParam = Optional.of(true);
|
||||
@@ -455,7 +457,7 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testMetrics() {
|
||||
generateActualJson("cat.lol");
|
||||
verify(rdapMetrics)
|
||||
|
||||
@@ -29,27 +29,33 @@ import google.registry.model.domain.DomainBase;
|
||||
import google.registry.model.domain.DomainHistory;
|
||||
import google.registry.model.reporting.HistoryEntry.Type;
|
||||
import google.registry.testing.AppEngineExtension;
|
||||
import google.registry.testing.DualDatabaseTest;
|
||||
import google.registry.testing.TestOfyAndSql;
|
||||
import google.registry.util.Clock;
|
||||
import java.util.List;
|
||||
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 tools that affect EPP lifecycle. */
|
||||
@DualDatabaseTest
|
||||
class EppLifecycleToolsTest extends EppTestCase {
|
||||
|
||||
@RegisterExtension
|
||||
final AppEngineExtension appEngine =
|
||||
AppEngineExtension.builder().withDatastoreAndCloudSql().withTaskQueue().build();
|
||||
AppEngineExtension.builder()
|
||||
.withClock(clock)
|
||||
.withDatastoreAndCloudSql()
|
||||
.withTaskQueue()
|
||||
.build();
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() {
|
||||
createTlds("example", "tld");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void test_renewDomainThenUnrenew() throws Exception {
|
||||
assertThatLoginSucceeds("NewRegistrar", "foo-BAR2");
|
||||
createContacts(DateTime.parse("2000-06-01T00:00:00Z"));
|
||||
|
||||
-152
@@ -1,152 +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.truth.Truth.assertThat;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
|
||||
import static google.registry.testing.DatabaseHelper.createTld;
|
||||
import static google.registry.testing.DatabaseHelper.loadByKey;
|
||||
import static google.registry.testing.DatabaseHelper.loadRegistrar;
|
||||
import static google.registry.testing.DatabaseHelper.persistActiveDomain;
|
||||
import static google.registry.testing.DatabaseHelper.persistActiveHost;
|
||||
import static google.registry.testing.DatabaseHelper.persistDomainAsDeleted;
|
||||
import static google.registry.testing.DatabaseHelper.persistDomainWithDependentResources;
|
||||
import static google.registry.testing.DatabaseHelper.persistResource;
|
||||
import static google.registry.util.DateTimeUtils.END_OF_TIME;
|
||||
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.googlecode.objectify.Key;
|
||||
import google.registry.model.EppResource;
|
||||
import google.registry.model.contact.ContactResource;
|
||||
import google.registry.model.domain.DomainBase;
|
||||
import google.registry.model.domain.DomainHistory;
|
||||
import google.registry.model.host.HostResource;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.model.reporting.HistoryEntryDao;
|
||||
import google.registry.model.tld.Registry;
|
||||
import google.registry.testing.FakeResponse;
|
||||
import google.registry.testing.mapreduce.MapreduceTestCase;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/** Tests for {@link CreateSyntheticHistoryEntriesAction}. */
|
||||
public class CreateSyntheticHistoryEntriesActionTest
|
||||
extends MapreduceTestCase<CreateSyntheticHistoryEntriesAction> {
|
||||
|
||||
private DomainBase domain;
|
||||
private ContactResource contact;
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() {
|
||||
action =
|
||||
new CreateSyntheticHistoryEntriesAction(
|
||||
makeDefaultRunner(), new FakeResponse(), "adminRegistrarId");
|
||||
|
||||
createTld("tld");
|
||||
domain = persistActiveDomain("example.tld");
|
||||
contact = loadByKey(domain.getAdminContact());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCreation_forAllTypes() throws Exception {
|
||||
DomainBase domain2 = persistActiveDomain("exampletwo.tld");
|
||||
ContactResource contact2 = loadByKey(domain2.getAdminContact());
|
||||
HostResource host = persistActiveHost("ns1.foobar.tld");
|
||||
HostResource host2 = persistActiveHost("ns1.baz.tld");
|
||||
|
||||
assertThat(HistoryEntryDao.loadAllHistoryObjects(START_OF_TIME, END_OF_TIME)).isEmpty();
|
||||
runMapreduce();
|
||||
|
||||
for (EppResource resource : ImmutableList.of(contact, contact2, domain, domain2, host, host2)) {
|
||||
HistoryEntry historyEntry =
|
||||
Iterables.getOnlyElement(
|
||||
HistoryEntryDao.loadHistoryObjectsForResource(resource.createVKey()));
|
||||
assertThat(historyEntry.getParent()).isEqualTo(Key.create(resource));
|
||||
assertThat(historyEntry.getType()).isEqualTo(HistoryEntry.Type.SYNTHETIC);
|
||||
}
|
||||
assertThat(HistoryEntryDao.loadAllHistoryObjects(START_OF_TIME, END_OF_TIME)).hasSize(6);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCreation_withPreviousHistoryEntry() throws Exception {
|
||||
DateTime now = DateTime.parse("1999-04-03T22:00:00.0Z");
|
||||
DomainBase withHistoryEntry =
|
||||
persistDomainWithDependentResources("foobar", "tld", contact, now, now, now.plusYears(1));
|
||||
assertThat(
|
||||
Iterables.getOnlyElement(
|
||||
HistoryEntryDao.loadHistoryObjectsForResource(withHistoryEntry.createVKey()))
|
||||
.getType())
|
||||
.isEqualTo(HistoryEntry.Type.DOMAIN_CREATE);
|
||||
|
||||
runMapreduce();
|
||||
|
||||
Iterable<? extends HistoryEntry> historyEntries =
|
||||
HistoryEntryDao.loadHistoryObjectsForResource(withHistoryEntry.createVKey());
|
||||
assertThat(historyEntries).hasSize(2);
|
||||
assertThat(Iterables.getLast(historyEntries).getType()).isEqualTo(HistoryEntry.Type.SYNTHETIC);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDoesntSave_ifAlreadyReplayed() throws Exception {
|
||||
DateTime now = DateTime.parse("1999-04-03T22:00:00.0Z");
|
||||
DomainHistory domainHistoryWithoutDomain =
|
||||
persistResource(
|
||||
new DomainHistory.Builder()
|
||||
.setType(HistoryEntry.Type.DOMAIN_CREATE)
|
||||
.setModificationTime(now)
|
||||
.setDomain(domain)
|
||||
.setRegistrarId(domain.getCreationRegistrarId())
|
||||
.build());
|
||||
DomainHistory domainHistoryWithDomain =
|
||||
domainHistoryWithoutDomain.asBuilder().setDomain(domain).build();
|
||||
// Simulate having replayed the domain and history to SQL
|
||||
jpaTm()
|
||||
.transact(
|
||||
() ->
|
||||
jpaTm()
|
||||
.putAll(
|
||||
Registry.get("tld"),
|
||||
loadRegistrar("TheRegistrar"),
|
||||
contact,
|
||||
domain,
|
||||
domainHistoryWithDomain));
|
||||
runMapreduce();
|
||||
|
||||
// Since we already had a DomainHistory with the domain in SQL, we shouldn't create a synthetic
|
||||
// history entry
|
||||
assertThat(HistoryEntryDao.loadHistoryObjectsForResource(domain.createVKey()))
|
||||
.containsExactly(domainHistoryWithoutDomain);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCreation_forDeletedResource() throws Exception {
|
||||
persistDomainAsDeleted(domain, domain.getCreationTime().plusMonths(6));
|
||||
runMapreduce();
|
||||
|
||||
assertThat(
|
||||
Iterables.getOnlyElement(
|
||||
HistoryEntryDao.loadHistoryObjectsForResource(domain.createVKey()))
|
||||
.getType())
|
||||
.isEqualTo(HistoryEntry.Type.SYNTHETIC);
|
||||
}
|
||||
|
||||
private void runMapreduce() throws Exception {
|
||||
action.run();
|
||||
executeTasksUntilEmpty("mapreduce");
|
||||
}
|
||||
}
|
||||
-115
@@ -1,115 +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.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.removeTmOverrideForTest;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.setTmOverrideForTest;
|
||||
import static google.registry.testing.DatabaseHelper.createTld;
|
||||
import static google.registry.testing.DatabaseHelper.newDomainBase;
|
||||
import static google.registry.testing.DatabaseHelper.persistActiveHost;
|
||||
import static google.registry.testing.DatabaseHelper.persistNewRegistrar;
|
||||
import static google.registry.testing.DatabaseHelper.persistSimpleResource;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import google.registry.beam.TestPipelineExtension;
|
||||
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.host.HostHistory;
|
||||
import google.registry.model.host.HostResource;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.persistence.transaction.JpaTestExtensions;
|
||||
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationTestExtension;
|
||||
import google.registry.testing.DatastoreEntityExtension;
|
||||
import google.registry.testing.FakeClock;
|
||||
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 CreateSyntheticHistoryEntriesPipeline}. */
|
||||
public class CreateSyntheticHistoryEntriesPipelineTest {
|
||||
|
||||
FakeClock clock = new FakeClock();
|
||||
|
||||
@RegisterExtension
|
||||
JpaIntegrationTestExtension jpaEextension =
|
||||
new JpaTestExtensions.Builder().withClock(clock).buildIntegrationTestExtension();
|
||||
|
||||
@RegisterExtension
|
||||
DatastoreEntityExtension datastoreEntityExtension =
|
||||
new DatastoreEntityExtension().allThreads(true);
|
||||
|
||||
@RegisterExtension TestPipelineExtension pipeline = TestPipelineExtension.create();
|
||||
|
||||
DomainBase domain;
|
||||
ContactResource contact;
|
||||
HostResource host;
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() {
|
||||
setTmOverrideForTest(jpaTm());
|
||||
persistNewRegistrar("TheRegistrar");
|
||||
persistNewRegistrar("NewRegistrar");
|
||||
createTld("tld");
|
||||
host = persistActiveHost("external.com");
|
||||
domain =
|
||||
persistSimpleResource(
|
||||
newDomainBase("example.tld").asBuilder().setNameservers(host.createVKey()).build());
|
||||
contact = jpaTm().transact(() -> jpaTm().loadByKey(domain.getRegistrant()));
|
||||
clock.advanceOneMilli();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void afterEach() {
|
||||
removeTmOverrideForTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess() {
|
||||
assertThat(jpaTm().transact(() -> jpaTm().loadAllOf(DomainHistory.class))).isEmpty();
|
||||
assertThat(jpaTm().transact(() -> jpaTm().loadAllOf(ContactHistory.class))).isEmpty();
|
||||
assertThat(jpaTm().transact(() -> jpaTm().loadAllOf(HostHistory.class))).isEmpty();
|
||||
CreateSyntheticHistoryEntriesPipeline.setup(pipeline, "NewRegistrar");
|
||||
pipeline.run().waitUntilFinish();
|
||||
validateHistoryEntry(DomainHistory.class, domain);
|
||||
validateHistoryEntry(ContactHistory.class, contact);
|
||||
validateHistoryEntry(HostHistory.class, host);
|
||||
}
|
||||
|
||||
private static <T extends EppResource> void validateHistoryEntry(
|
||||
Class<? extends HistoryEntry> historyClazz, T resource) {
|
||||
ImmutableList<? extends HistoryEntry> historyEntries =
|
||||
jpaTm().transact(() -> jpaTm().loadAllOf(historyClazz));
|
||||
assertThat(historyEntries).hasSize(1);
|
||||
HistoryEntry historyEntry = historyEntries.get(0);
|
||||
assertThat(historyEntry.getType()).isEqualTo(HistoryEntry.Type.SYNTHETIC);
|
||||
assertThat(historyEntry.getRegistrarId()).isEqualTo("NewRegistrar");
|
||||
EppResource embeddedResource;
|
||||
if (historyEntry instanceof DomainHistory) {
|
||||
embeddedResource = ((DomainHistory) historyEntry).getDomainContent().get();
|
||||
} else if (historyEntry instanceof ContactHistory) {
|
||||
embeddedResource = ((ContactHistory) historyEntry).getContactBase().get();
|
||||
} else {
|
||||
embeddedResource = ((HostHistory) historyEntry).getHostBase().get();
|
||||
}
|
||||
assertAboutImmutableObjects().that(embeddedResource).hasFieldsEqualTo(resource);
|
||||
}
|
||||
}
|
||||
@@ -20,12 +20,14 @@ import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import google.registry.model.OteStatsTestHelper;
|
||||
import google.registry.testing.AppEngineExtension;
|
||||
import google.registry.testing.DualDatabaseTest;
|
||||
import google.registry.testing.TestOfyAndSql;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
|
||||
/** Unit tests for {@link VerifyOteAction}. */
|
||||
@DualDatabaseTest
|
||||
class VerifyOteActionTest {
|
||||
|
||||
@RegisterExtension
|
||||
@@ -34,21 +36,21 @@ class VerifyOteActionTest {
|
||||
|
||||
private final VerifyOteAction action = new VerifyOteAction();
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testSuccess_summarize_allPass() throws Exception {
|
||||
OteStatsTestHelper.setupCompleteOte("blobio");
|
||||
assertThat(getResponse(true))
|
||||
.isEqualTo("# actions: 30 - Reqs: [----------------] 16/16 - Overall: PASS");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testFailure_summarize_someFailures() throws Exception {
|
||||
OteStatsTestHelper.setupIncompleteOte("blobio");
|
||||
assertThat(getResponse(true))
|
||||
.isEqualTo("# actions: 34 - Reqs: [-.-----.------.-] 13/16 - Overall: FAIL");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testSuccess_passNotSummarized() throws Exception {
|
||||
OteStatsTestHelper.setupCompleteOte("blobio");
|
||||
String expectedOteStatus =
|
||||
@@ -78,7 +80,7 @@ class VerifyOteActionTest {
|
||||
assertThat(getResponse(false)).containsMatch(expectedOteStatusPattern);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testFailure_incomplete() throws Exception {
|
||||
OteStatsTestHelper.setupIncompleteOte("blobio");
|
||||
String expectedOteStatus =
|
||||
|
||||
@@ -30,14 +30,16 @@ import google.registry.model.registrar.Registrar.Type;
|
||||
import google.registry.request.auth.AuthenticatedRegistrarAccessor;
|
||||
import google.registry.request.auth.AuthenticatedRegistrarAccessor.Role;
|
||||
import google.registry.testing.AppEngineExtension;
|
||||
import google.registry.testing.DualDatabaseTest;
|
||||
import google.registry.testing.TestOfyAndSql;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
|
||||
/** Unit tests for {@link OteStatusAction} */
|
||||
@DualDatabaseTest
|
||||
public final class OteStatusActionTest {
|
||||
|
||||
private static final String CLIENT_ID = "blobio-1";
|
||||
@@ -57,7 +59,7 @@ public final class OteStatusActionTest {
|
||||
action.registrarAccessor = AuthenticatedRegistrarAccessor.createForTesting(authValues);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
@SuppressWarnings("unchecked")
|
||||
void testSuccess_finishedOte() throws Exception {
|
||||
OteStatsTestHelper.setupCompleteOte(BASE_CLIENT_ID);
|
||||
@@ -72,7 +74,7 @@ public final class OteStatusActionTest {
|
||||
assertThat(getFailingResultDetails(results)).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
@SuppressWarnings("unchecked")
|
||||
void testSuccess_incomplete() throws Exception {
|
||||
OteStatsTestHelper.setupIncompleteOte(BASE_CLIENT_ID);
|
||||
@@ -103,7 +105,7 @@ public final class OteStatusActionTest {
|
||||
"completed", false));
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testFailure_malformedInput() {
|
||||
assertThat(action.handleJsonRequest(null))
|
||||
.containsExactlyEntriesIn(errorResultWithMessage("Malformed JSON"));
|
||||
@@ -111,14 +113,14 @@ public final class OteStatusActionTest {
|
||||
.containsExactlyEntriesIn(errorResultWithMessage("Missing key for OT&E client: clientId"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testFailure_registrarDoesntExist() {
|
||||
assertThat(action.handleJsonRequest(ImmutableMap.of("clientId", "nonexistent-3")))
|
||||
.containsExactlyEntriesIn(
|
||||
errorResultWithMessage("Registrar nonexistent-3 does not exist"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testFailure_notAuthorized() {
|
||||
persistNewRegistrar(CLIENT_ID, "blobio-1", Type.REAL, 1L);
|
||||
action.registrarAccessor =
|
||||
@@ -128,7 +130,7 @@ public final class OteStatusActionTest {
|
||||
errorResultWithMessage("TestUserId doesn't have access to registrar blobio-1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testFailure_malformedRegistrarName() {
|
||||
assertThat(action.handleJsonRequest(ImmutableMap.of("clientId", "badclient-id")))
|
||||
.containsExactlyEntriesIn(
|
||||
@@ -136,7 +138,7 @@ public final class OteStatusActionTest {
|
||||
"ID badclient-id is not one of the OT&E registrar IDs for base badclient"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testFailure_nonOteRegistrar() {
|
||||
persistNewRegistrar(CLIENT_ID, "SomeRegistrar", Type.REAL, 1L);
|
||||
assertThat(action.handleJsonRequest(ImmutableMap.of("clientId", CLIENT_ID)))
|
||||
|
||||
+19
-17
@@ -49,8 +49,10 @@ import google.registry.testing.AppEngineExtension;
|
||||
import google.registry.testing.CloudTasksHelper;
|
||||
import google.registry.testing.DatabaseHelper;
|
||||
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.StringGenerator;
|
||||
@@ -58,10 +60,10 @@ import google.registry.util.StringGenerator.Alphabets;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import org.joda.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 RegistryLockVerifyAction}. */
|
||||
@DualDatabaseTest
|
||||
final class RegistryLockVerifyActionTest {
|
||||
|
||||
private final FakeClock fakeClock = new FakeClock();
|
||||
@@ -96,7 +98,7 @@ final class RegistryLockVerifyActionTest {
|
||||
action = createAction(lockId, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testSuccess_lockDomain() {
|
||||
saveRegistryLock(createLock());
|
||||
action.run();
|
||||
@@ -112,7 +114,7 @@ final class RegistryLockVerifyActionTest {
|
||||
assertBillingEvent(historyEntry);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testSuccess_unlockDomain() {
|
||||
action = createAction(lockId, false);
|
||||
domain = persistResource(domain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
|
||||
@@ -130,7 +132,7 @@ final class RegistryLockVerifyActionTest {
|
||||
assertBillingEvent(historyEntry);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testSuccess_adminLock_createsOnlyHistoryEntry() {
|
||||
action.authResult = AuthResult.create(AuthLevel.USER, UserAuthInfo.create(user, true));
|
||||
saveRegistryLock(createLock().asBuilder().isSuperuser(true).build());
|
||||
@@ -142,7 +144,7 @@ final class RegistryLockVerifyActionTest {
|
||||
DatabaseHelper.assertNoBillingEvents();
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testFailure_badVerificationCode() {
|
||||
saveRegistryLock(
|
||||
createLock().asBuilder().setVerificationCode("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA").build());
|
||||
@@ -151,7 +153,7 @@ final class RegistryLockVerifyActionTest {
|
||||
assertNoDomainChanges();
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testFailure_alreadyVerified() {
|
||||
saveRegistryLock(createLock().asBuilder().setLockCompletionTime(fakeClock.nowUtc()).build());
|
||||
action.run();
|
||||
@@ -159,7 +161,7 @@ final class RegistryLockVerifyActionTest {
|
||||
assertNoDomainChanges();
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testFailure_expired() {
|
||||
saveRegistryLock(createLock());
|
||||
fakeClock.advanceBy(Duration.standardHours(2));
|
||||
@@ -169,7 +171,7 @@ final class RegistryLockVerifyActionTest {
|
||||
assertNoDomainChanges();
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testFailure_nonAdmin_verifyingAdminLock() {
|
||||
saveRegistryLock(createLock().asBuilder().isSuperuser(true).build());
|
||||
action.run();
|
||||
@@ -177,7 +179,7 @@ final class RegistryLockVerifyActionTest {
|
||||
assertNoDomainChanges();
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testFailure_alreadyUnlocked() {
|
||||
action = createAction(lockId, false);
|
||||
saveRegistryLock(
|
||||
@@ -192,7 +194,7 @@ final class RegistryLockVerifyActionTest {
|
||||
assertNoDomainChanges();
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testFailure_alreadyLocked() {
|
||||
saveRegistryLock(createLock());
|
||||
domain = persistResource(domain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
|
||||
@@ -201,7 +203,7 @@ final class RegistryLockVerifyActionTest {
|
||||
assertNoDomainChanges();
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testFailure_notLoggedIn() {
|
||||
action.authResult = AuthResult.NOT_AUTHENTICATED;
|
||||
action.run();
|
||||
@@ -210,7 +212,7 @@ final class RegistryLockVerifyActionTest {
|
||||
assertNoDomainChanges();
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testFailure_doesNotChangeLockObject() {
|
||||
// A failure when performing Datastore actions means that no actions should be taken in the
|
||||
// Cloud SQL RegistryLock object
|
||||
@@ -229,7 +231,7 @@ final class RegistryLockVerifyActionTest {
|
||||
assertThat(afterAction).isEqualTo(lock);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testFailure_isLockTrue_shouldBeFalse() {
|
||||
domain = persistResource(domain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
|
||||
saveRegistryLock(
|
||||
@@ -242,7 +244,7 @@ final class RegistryLockVerifyActionTest {
|
||||
assertThat(response.getPayload()).contains("Failed: Domain example.tld is already locked");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testFailure_isLockFalse_shouldBeTrue() {
|
||||
action = createAction(lockId, false);
|
||||
saveRegistryLock(createLock());
|
||||
@@ -250,7 +252,7 @@ final class RegistryLockVerifyActionTest {
|
||||
assertThat(response.getPayload()).contains("Failed: Domain example.tld is already unlocked");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testFailure_lock_unlock_lockAgain() {
|
||||
RegistryLock lock = saveRegistryLock(createLock());
|
||||
action.run();
|
||||
@@ -269,7 +271,7 @@ final class RegistryLockVerifyActionTest {
|
||||
assertThat(response.getPayload()).contains("Failed: Invalid verification code");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testFailure_lock_lockAgain() {
|
||||
saveRegistryLock(createLock());
|
||||
action.run();
|
||||
@@ -279,7 +281,7 @@ final class RegistryLockVerifyActionTest {
|
||||
assertThat(response.getPayload()).contains("Failed: Domain example.tld is already locked");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestOfyAndSql
|
||||
void testFailure_unlock_unlockAgain() {
|
||||
action = createAction(lockId, false);
|
||||
domain = persistResource(domain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
|
||||
|
||||
@@ -24,11 +24,14 @@ import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.net.HostAndPort;
|
||||
import google.registry.persistence.transaction.JpaTestExtensions;
|
||||
import google.registry.request.auth.AuthenticatedRegistrarAccessor;
|
||||
import google.registry.server.Fixture;
|
||||
import google.registry.server.Route;
|
||||
import google.registry.server.TestServer;
|
||||
import google.registry.testing.AppEngineExtension;
|
||||
import google.registry.testing.DatabaseHelper;
|
||||
import google.registry.testing.FakeClock;
|
||||
import google.registry.testing.UserInfo;
|
||||
import java.net.URL;
|
||||
import java.net.UnknownHostException;
|
||||
@@ -40,6 +43,8 @@ import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.FutureTask;
|
||||
import java.util.concurrent.LinkedBlockingDeque;
|
||||
import javax.servlet.Filter;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.DateTimeZone;
|
||||
import org.junit.jupiter.api.extension.AfterEachCallback;
|
||||
import org.junit.jupiter.api.extension.BeforeEachCallback;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
@@ -202,7 +207,15 @@ public final class TestServerExtension implements BeforeEachCallback, AfterEachC
|
||||
}
|
||||
}
|
||||
|
||||
void runInner() throws InterruptedException {
|
||||
void runInner() throws Exception {
|
||||
// Clear the SQL database and set it as primary (we have to do this out of band because the
|
||||
// AppEngineExtension can't natively do it for us yet due to remaining ofy dependencies)
|
||||
new JpaTestExtensions.Builder().buildIntegrationTestExtension().beforeEach(null);
|
||||
DatabaseHelper.setMigrationScheduleToSqlPrimary(
|
||||
new FakeClock(DateTime.now(DateTimeZone.UTC)));
|
||||
// sleep a few millis to make sure we get to SQL-primary mode
|
||||
Thread.sleep(4);
|
||||
AppEngineExtension.loadInitialData();
|
||||
for (Fixture fixture : fixtures) {
|
||||
fixture.load();
|
||||
}
|
||||
|
||||
@@ -9,8 +9,6 @@ PATH CLASS
|
||||
/_dr/task/brdaCopy BrdaCopyAction POST y INTERNAL,API APP ADMIN
|
||||
/_dr/task/checkDatastoreBackup CheckBackupAction POST,GET y INTERNAL,API APP ADMIN
|
||||
/_dr/task/copyDetailReports CopyDetailReportsAction POST n INTERNAL,API APP ADMIN
|
||||
/_dr/task/createSyntheticHistoryEntries CreateSyntheticHistoryEntriesAction GET n INTERNAL,API APP ADMIN
|
||||
/_dr/task/deleteContactsAndHosts DeleteContactsAndHostsAction GET n INTERNAL,API APP ADMIN
|
||||
/_dr/task/deleteExpiredDomains DeleteExpiredDomainsAction GET n INTERNAL,API APP ADMIN
|
||||
/_dr/task/deleteLoadTestData DeleteLoadTestDataAction POST n INTERNAL,API APP ADMIN
|
||||
/_dr/task/deleteOldCommitLogs DeleteOldCommitLogsAction GET n INTERNAL,API APP ADMIN
|
||||
|
||||
Reference in New Issue
Block a user