Merge ../nom.deleteme

This commit is contained in:
Michael Muller 2019-01-09 11:06:35 -05:00
commit 7920a05bf8
464 changed files with 14044 additions and 4321 deletions

View file

@ -193,14 +193,14 @@ public class DeleteContactsAndHostsActionTest
false);
runMapreduce();
ContactResource contactUpdated =
loadByForeignKey(ContactResource.class, "blah8221", clock.nowUtc());
loadByForeignKey(ContactResource.class, "blah8221", clock.nowUtc()).get();
assertAboutContacts()
.that(contactUpdated)
.doesNotHaveStatusValue(PENDING_DELETE)
.and()
.hasDeletionTime(END_OF_TIME);
DomainResource domainReloaded =
loadByForeignKey(DomainResource.class, "example.tld", clock.nowUtc());
loadByForeignKey(DomainResource.class, "example.tld", clock.nowUtc()).get();
assertThat(domainReloaded.getReferencedContacts()).contains(Key.create(contactUpdated));
HistoryEntry historyEntry =
getOnlyHistoryEntryOfType(contactUpdated, HistoryEntry.Type.CONTACT_DELETE_FAILURE);
@ -268,7 +268,7 @@ public class DeleteContactsAndHostsActionTest
Trid.create(clientTrid.orElse(null), "fakeServerTrid"),
false);
runMapreduce();
assertThat(loadByForeignKey(ContactResource.class, "jim919", clock.nowUtc())).isNull();
assertThat(loadByForeignKey(ContactResource.class, "jim919", clock.nowUtc())).isEmpty();
ContactResource contactAfterDeletion = ofy().load().entity(contact).now();
assertAboutContacts()
.that(contactAfterDeletion)
@ -332,10 +332,10 @@ public class DeleteContactsAndHostsActionTest
false);
runMapreduce();
// Check that the contact is deleted as of now.
assertThat(loadByForeignKey(ContactResource.class, "sh8013", clock.nowUtc())).isNull();
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));
loadByForeignKey(ContactResource.class, "sh8013", clock.nowUtc().minusDays(1)).get();
assertAboutContacts()
.that(softDeletedContact)
.hasOneHistoryEntryEachOfTypes(CONTACT_TRANSFER_REQUEST, CONTACT_DELETE);
@ -393,9 +393,9 @@ public class DeleteContactsAndHostsActionTest
Trid.create("fakeClientTrid", "fakeServerTrid"),
false);
runMapreduce();
assertThat(loadByForeignKey(ContactResource.class, "blah1234", clock.nowUtc())).isNull();
assertThat(loadByForeignKey(ContactResource.class, "blah1234", clock.nowUtc())).isEmpty();
ContactResource contactBeforeDeletion =
loadByForeignKey(ContactResource.class, "blah1234", clock.nowUtc().minusDays(1));
loadByForeignKey(ContactResource.class, "blah1234", clock.nowUtc().minusDays(1)).get();
assertAboutContacts()
.that(contactBeforeDeletion)
.isNotActiveAt(clock.nowUtc())
@ -428,7 +428,7 @@ public class DeleteContactsAndHostsActionTest
false);
runMapreduce();
ContactResource contactAfter =
loadByForeignKey(ContactResource.class, "jane0991", clock.nowUtc());
loadByForeignKey(ContactResource.class, "jane0991", clock.nowUtc()).get();
assertAboutContacts()
.that(contactAfter)
.doesNotHaveStatusValue(PENDING_DELETE)
@ -455,7 +455,7 @@ public class DeleteContactsAndHostsActionTest
Trid.create("fakeClientTrid", "fakeServerTrid"),
true);
runMapreduce();
assertThat(loadByForeignKey(ContactResource.class, "nate007", clock.nowUtc())).isNull();
assertThat(loadByForeignKey(ContactResource.class, "nate007", clock.nowUtc())).isEmpty();
ContactResource contactAfterDeletion = ofy().load().entity(contact).now();
assertAboutContacts()
.that(contactAfterDeletion)
@ -561,9 +561,9 @@ public class DeleteContactsAndHostsActionTest
false);
enqueueMapreduceOnly();
assertThat(loadByForeignKey(ContactResource.class, "blah2222", clock.nowUtc()))
.isEqualTo(contact);
.hasValue(contact);
assertThat(loadByForeignKey(HostResource.class, "rustles.your.jimmies", clock.nowUtc()))
.isEqualTo(host);
.hasValue(host);
assertNoTasksEnqueued(QUEUE_ASYNC_DELETE);
verify(action.asyncFlowMetrics).recordContactHostDeletionBatchSize(2L);
verify(action.asyncFlowMetrics)
@ -610,13 +610,14 @@ public class DeleteContactsAndHostsActionTest
false);
runMapreduce();
HostResource hostAfter =
loadByForeignKey(HostResource.class, "ns1.example.tld", clock.nowUtc());
loadByForeignKey(HostResource.class, "ns1.example.tld", clock.nowUtc()).get();
assertAboutHosts()
.that(hostAfter)
.doesNotHaveStatusValue(PENDING_DELETE)
.and()
.hasDeletionTime(END_OF_TIME);
DomainResource domain = loadByForeignKey(DomainResource.class, "example.tld", clock.nowUtc());
DomainResource domain =
loadByForeignKey(DomainResource.class, "example.tld", clock.nowUtc()).get();
assertThat(domain.getNameservers()).contains(Key.create(hostAfter));
HistoryEntry historyEntry = getOnlyHistoryEntryOfType(hostAfter, HOST_DELETE_FAILURE);
assertPollMessageFor(
@ -653,9 +654,9 @@ public class DeleteContactsAndHostsActionTest
Trid.create(clientTrid.orElse(null), "fakeServerTrid"),
false);
runMapreduce();
assertThat(loadByForeignKey(HostResource.class, "ns2.example.tld", clock.nowUtc())).isNull();
assertThat(loadByForeignKey(HostResource.class, "ns2.example.tld", clock.nowUtc())).isEmpty();
HostResource hostBeforeDeletion =
loadByForeignKey(HostResource.class, "ns2.example.tld", clock.nowUtc().minusDays(1));
loadByForeignKey(HostResource.class, "ns2.example.tld", clock.nowUtc().minusDays(1)).get();
assertAboutHosts()
.that(hostBeforeDeletion)
.isNotActiveAt(clock.nowUtc())
@ -697,9 +698,9 @@ public class DeleteContactsAndHostsActionTest
Trid.create("fakeClientTrid", "fakeServerTrid"),
false);
runMapreduce();
assertThat(loadByForeignKey(HostResource.class, "ns1.example.tld", clock.nowUtc())).isNull();
assertThat(loadByForeignKey(HostResource.class, "ns1.example.tld", clock.nowUtc())).isEmpty();
HostResource hostBeforeDeletion =
loadByForeignKey(HostResource.class, "ns1.example.tld", clock.nowUtc().minusDays(1));
loadByForeignKey(HostResource.class, "ns1.example.tld", clock.nowUtc().minusDays(1)).get();
assertAboutHosts()
.that(hostBeforeDeletion)
.isNotActiveAt(clock.nowUtc())
@ -743,15 +744,16 @@ public class DeleteContactsAndHostsActionTest
false);
runMapreduce();
// Check that the host is deleted as of now.
assertThat(loadByForeignKey(HostResource.class, "ns2.example.tld", clock.nowUtc())).isNull();
assertThat(loadByForeignKey(HostResource.class, "ns2.example.tld", clock.nowUtc())).isEmpty();
assertNoBillingEvents();
assertThat(
loadByForeignKey(DomainResource.class, "example.tld", clock.nowUtc())
.get()
.getSubordinateHosts())
.isEmpty();
assertDnsTasksEnqueued("ns2.example.tld");
HostResource hostBeforeDeletion =
loadByForeignKey(HostResource.class, "ns2.example.tld", clock.nowUtc().minusDays(1));
loadByForeignKey(HostResource.class, "ns2.example.tld", clock.nowUtc().minusDays(1)).get();
assertAboutHosts()
.that(hostBeforeDeletion)
.isNotActiveAt(clock.nowUtc())
@ -782,7 +784,7 @@ public class DeleteContactsAndHostsActionTest
false);
runMapreduce();
HostResource hostAfter =
loadByForeignKey(HostResource.class, "ns2.example.tld", clock.nowUtc());
loadByForeignKey(HostResource.class, "ns2.example.tld", clock.nowUtc()).get();
assertAboutHosts()
.that(hostAfter)
.doesNotHaveStatusValue(PENDING_DELETE)
@ -809,9 +811,9 @@ public class DeleteContactsAndHostsActionTest
Trid.create("fakeClientTrid", "fakeServerTrid"),
true);
runMapreduce();
assertThat(loadByForeignKey(HostResource.class, "ns66.example.tld", clock.nowUtc())).isNull();
assertThat(loadByForeignKey(HostResource.class, "ns66.example.tld", clock.nowUtc())).isEmpty();
HostResource hostBeforeDeletion =
loadByForeignKey(HostResource.class, "ns66.example.tld", clock.nowUtc().minusDays(1));
loadByForeignKey(HostResource.class, "ns66.example.tld", clock.nowUtc().minusDays(1)).get();
assertAboutHosts()
.that(hostBeforeDeletion)
.isNotActiveAt(clock.nowUtc())

View file

@ -15,6 +15,7 @@
package google.registry.batch;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;
import static google.registry.model.EppResourceUtils.loadByForeignKey;
import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.testing.DatastoreHelper.createTld;
@ -46,6 +47,7 @@ import google.registry.model.registry.Registry.TldType;
import google.registry.model.reporting.HistoryEntry;
import google.registry.testing.FakeResponse;
import google.registry.testing.mapreduce.MapreduceTestCase;
import java.util.Optional;
import java.util.Set;
import org.joda.money.Money;
import org.joda.time.DateTime;
@ -190,7 +192,7 @@ public class DeleteProberDataActionTest extends MapreduceTestCase<DeleteProberDa
runMapreduce();
DateTime timeAfterDeletion = DateTime.now(UTC);
assertThat(loadByForeignKey(DomainResource.class, "blah.ib-any.test", timeAfterDeletion))
.isNull();
.isEmpty();
assertThat(ofy().load().entity(domain).now().getDeletionTime()).isLessThan(timeAfterDeletion);
assertDnsTasksEnqueued("blah.ib-any.test");
}
@ -207,7 +209,7 @@ public class DeleteProberDataActionTest extends MapreduceTestCase<DeleteProberDa
resetAction();
runMapreduce();
assertThat(loadByForeignKey(DomainResource.class, "blah.ib-any.test", timeAfterDeletion))
.isNull();
.isEmpty();
assertThat(ofy().load().entity(domain).now().getDeletionTime()).isLessThan(timeAfterDeletion);
assertDnsTasksEnqueued("blah.ib-any.test");
}
@ -220,10 +222,10 @@ public class DeleteProberDataActionTest extends MapreduceTestCase<DeleteProberDa
.setCreationTimeForTest(DateTime.now(UTC).minusSeconds(1))
.build());
runMapreduce();
DomainResource domain =
Optional<DomainResource> domain =
loadByForeignKey(DomainResource.class, "blah.ib-any.test", DateTime.now(UTC));
assertThat(domain).isNotNull();
assertThat(domain.getDeletionTime()).isEqualTo(END_OF_TIME);
assertThat(domain).isPresent();
assertThat(domain.get().getDeletionTime()).isEqualTo(END_OF_TIME);
}
@Test

View file

@ -62,6 +62,7 @@ public class InvoicingPipelineTest {
invoicingPipeline.projectId = "test-project";
File beamTempFolder = tempFolder.newFolder();
invoicingPipeline.beamBucketUrl = beamTempFolder.getAbsolutePath();
invoicingPipeline.invoiceFilePrefix = "REG-INV";
invoicingPipeline.beamStagingUrl = beamTempFolder.getAbsolutePath() + "/staging";
invoicingPipeline.invoiceTemplateUrl =
beamTempFolder.getAbsolutePath() + "/templates/invoicing";
@ -196,7 +197,7 @@ public class InvoicingPipelineTest {
.containsExactlyElementsIn(entry.getValue());
}
ImmutableList<String> overallInvoice = resultFileContents("CRR-INV-2017-10.csv");
ImmutableList<String> overallInvoice = resultFileContents("REG-INV-2017-10.csv");
assertThat(overallInvoice.get(0))
.isEqualTo(
"StartDate,EndDate,ProductAccountKey,Amount,AmountCurrency,BillingProductCode,"

View file

@ -132,7 +132,7 @@ public class Spec11PipelineTest {
// Apply input and evaluation transforms
PCollection<Subdomain> input = p.apply(Create.of(inputRows));
spec11Pipeline.evaluateUrlHealth(input, evalFn, StaticValueProvider.of("2018-06"));
spec11Pipeline.evaluateUrlHealth(input, evalFn, StaticValueProvider.of("2018-06-01"));
p.run();
// Verify header and 3 threat matches for 2 registrars are found
@ -277,7 +277,7 @@ public class Spec11PipelineTest {
File resultFile =
new File(
String.format(
"%s/icann/spec11/2018-06/SPEC11_MONTHLY_REPORT",
"%s/icann/spec11/2018-06/SPEC11_MONTHLY_REPORT_2018-06-01",
tempFolder.getRoot().getAbsolutePath()));
return ImmutableList.copyOf(
ResourceUtils.readResourceUtf8(resultFile.toURI().toURL()).split("\n"));

View file

@ -12,6 +12,7 @@ java_library(
srcs = glob(["*.java"]),
deps = [
"//java/google/registry/config",
"//javatests/google/registry/testing",
"@com_google_auto_value",
"@com_google_guava",
"@com_google_truth",

View file

@ -25,13 +25,6 @@ import org.junit.runners.JUnit4;
@RunWith(JUnit4.class)
public class RegistryConfigTest {
@Test
public void test_clientSecretFilename() {
// Verify that we're pulling this from the default.
assertThat(RegistryConfig.getClientSecretFilename()).isEqualTo(
"/google/registry/tools/resources/client_secret.json");
}
@Test
public void test_reservedTermsExportDisclaimer_isPrependedWithOctothorpes() {
assertThat(provideReservedTermsExportDisclaimer(CONFIG_SETTINGS.get()))

View file

@ -250,7 +250,7 @@ public class DnsUpdateWriterTest {
newDomainResource("example.tld")
.asBuilder()
.addSubordinateHost("ns1.example.tld")
.addNameservers(ImmutableSet.of(Key.create(host)))
.addNameserver(Key.create(host))
.build());
writer.publishHost("ns1.example.tld");
@ -358,7 +358,7 @@ public class DnsUpdateWriterTest {
.asBuilder()
.addSubordinateHost("ns1.example.tld")
.addSubordinateHost("foo.example.tld")
.addNameservers(ImmutableSet.of(Key.create(inBailiwickNameserver)))
.addNameserver(Key.create(inBailiwickNameserver))
.build());
writer.publishDomain("example.tld");

View file

@ -10,13 +10,16 @@ load("//java/com/google/testing/builddefs:GenTestRules.bzl", "GenTestRules")
java_library(
name = "export",
srcs = glob(["*.java"]),
resources = [
resources = glob([
"testdata/*.json",
"backup_kinds.txt",
"reporting_kinds.txt",
],
]),
deps = [
"//java/google/registry/bigquery",
"//java/google/registry/config",
"//java/google/registry/export",
"//java/google/registry/export/datastore",
"//java/google/registry/groups",
"//java/google/registry/model",
"//java/google/registry/request",
@ -25,6 +28,7 @@ java_library(
"//javatests/google/registry/testing",
"//javatests/google/registry/testing/mapreduce",
"//third_party/objectify:objectify-v4_1",
"@com_google_api_client",
"@com_google_apis_google_api_services_bigquery",
"@com_google_apis_google_api_services_drive",
"@com_google_appengine_api_1_0_sdk",
@ -35,6 +39,7 @@ java_library(
"@com_google_flogger_system_backend",
"@com_google_guava",
"@com_google_http_client",
"@com_google_http_client_jackson2",
"@com_google_re2j",
"@com_google_truth",
"@com_google_truth_extensions_truth_java8_extension",

View file

@ -0,0 +1,85 @@
// Copyright 2018 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.export;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.export.CheckBackupAction.CHECK_BACKUP_KINDS_TO_LOAD_PARAM;
import static google.registry.export.CheckBackupAction.CHECK_BACKUP_NAME_PARAM;
import static google.registry.testing.TaskQueueHelper.assertTasksEnqueued;
import static org.mockito.Mockito.when;
import com.google.common.base.Joiner;
import google.registry.export.datastore.DatastoreAdmin;
import google.registry.export.datastore.DatastoreAdmin.Export;
import google.registry.export.datastore.Operation;
import google.registry.testing.AppEngineRule;
import google.registry.testing.FakeResponse;
import google.registry.testing.MockitoJUnitRule;
import google.registry.testing.TaskQueueHelper.TaskMatcher;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.Mock;
/** Unit tests for {@link BackupDatastoreAction}. */
@RunWith(JUnit4.class)
public class BackupDatastoreActionTest {
@Rule public final AppEngineRule appEngine = AppEngineRule.builder().withTaskQueue().build();
@Rule public final MockitoJUnitRule mocks = MockitoJUnitRule.create();
@Mock private DatastoreAdmin datastoreAdmin;
@Mock private Export exportRequest;
@Mock private Operation backupOperation;
private final FakeResponse response = new FakeResponse();
private final BackupDatastoreAction action = new BackupDatastoreAction();
@Before
public void before() throws Exception {
action.datastoreAdmin = datastoreAdmin;
action.response = response;
when(datastoreAdmin.export(
"gs://registry-project-id-datastore-backups", ExportConstants.getBackupKinds()))
.thenReturn(exportRequest);
when(exportRequest.execute()).thenReturn(backupOperation);
when(backupOperation.getName())
.thenReturn("projects/registry-project-id/operations/ASA1ODYwNjc");
when(backupOperation.getExportFolderUrl())
.thenReturn("gs://registry-project-id-datastore-backups/some-id");
}
@Test
public void testBackup_enqueuesPollTask() {
action.run();
assertTasksEnqueued(
CheckBackupAction.QUEUE,
new TaskMatcher()
.url(CheckBackupAction.PATH)
.param(CHECK_BACKUP_NAME_PARAM, "projects/registry-project-id/operations/ASA1ODYwNjc")
.param(
CHECK_BACKUP_KINDS_TO_LOAD_PARAM,
Joiner.on(",").join(ExportConstants.getReportingKinds()))
.method("POST"));
assertThat(response.getPayload())
.isEqualTo(
"Datastore backup started with name: "
+ "projects/registry-project-id/operations/ASA1ODYwNjc\n"
+ "Saving to gs://registry-project-id-datastore-backups/some-id");
}
}

View file

@ -0,0 +1,222 @@
// Copyright 2018 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.export;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.export.CheckBackupAction.CHECK_BACKUP_KINDS_TO_LOAD_PARAM;
import static google.registry.export.CheckBackupAction.CHECK_BACKUP_NAME_PARAM;
import static google.registry.testing.JUnitBackports.assertThrows;
import static google.registry.testing.TaskQueueHelper.assertNoTasksEnqueued;
import static google.registry.testing.TaskQueueHelper.assertTasksEnqueued;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.when;
import com.google.api.client.googleapis.json.GoogleJsonResponseException;
import com.google.api.client.http.HttpHeaders;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.common.collect.ImmutableSet;
import google.registry.export.datastore.DatastoreAdmin;
import google.registry.export.datastore.DatastoreAdmin.Get;
import google.registry.export.datastore.Operation;
import google.registry.request.Action.Method;
import google.registry.request.HttpException.BadRequestException;
import google.registry.request.HttpException.NoContentException;
import google.registry.request.HttpException.NotModifiedException;
import google.registry.testing.AppEngineRule;
import google.registry.testing.FakeClock;
import google.registry.testing.FakeResponse;
import google.registry.testing.MockitoJUnitRule;
import google.registry.testing.TaskQueueHelper.TaskMatcher;
import google.registry.testing.TestDataHelper;
import org.joda.time.DateTime;
import org.joda.time.Duration;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.Mock;
/** Unit tests for {@link CheckBackupAction}. */
@RunWith(JUnit4.class)
public class CheckBackupActionTest {
static final DateTime START_TIME = DateTime.parse("2014-08-01T01:02:03Z");
static final DateTime COMPLETE_TIME = START_TIME.plus(Duration.standardMinutes(30));
static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
@Rule public final AppEngineRule appEngine = AppEngineRule.builder().withTaskQueue().build();
@Rule public final MockitoJUnitRule mocks = MockitoJUnitRule.create();
@Mock private DatastoreAdmin datastoreAdmin;
@Mock private Get getNotFoundBackupProgressRequest;
@Mock private Get getBackupProgressRequest;
private Operation backupOperation;
private final FakeResponse response = new FakeResponse();
private final FakeClock clock = new FakeClock(COMPLETE_TIME.plusMillis(1000));
private final CheckBackupAction action = new CheckBackupAction();
@Before
public void before() throws Exception {
action.requestMethod = Method.POST;
action.datastoreAdmin = datastoreAdmin;
action.clock = clock;
action.backupName = "some_backup";
action.kindsToLoadParam = "one,two";
action.response = response;
when(datastoreAdmin.get(anyString())).thenReturn(getBackupProgressRequest);
when(getBackupProgressRequest.execute()).thenAnswer(arg -> backupOperation);
}
private void setPendingBackup() throws Exception {
backupOperation =
JSON_FACTORY.fromString(
TestDataHelper.loadFile(
CheckBackupActionTest.class, "backup_operation_in_progress.json"),
Operation.class);
}
private void setCompleteBackup() throws Exception {
backupOperation =
JSON_FACTORY.fromString(
TestDataHelper.loadFile(CheckBackupActionTest.class, "backup_operation_success.json"),
Operation.class);
}
private void setBackupNotFound() throws Exception {
when(datastoreAdmin.get(anyString())).thenReturn(getNotFoundBackupProgressRequest);
when(getNotFoundBackupProgressRequest.execute())
.thenThrow(
new GoogleJsonResponseException(
new GoogleJsonResponseException.Builder(404, "NOT_FOUND", new HttpHeaders())
.setMessage("No backup found"),
null));
}
private static void assertLoadTaskEnqueued(String id, String folder, String kinds) {
assertTasksEnqueued(
"export-snapshot",
new TaskMatcher()
.url("/_dr/task/uploadDatastoreBackup")
.method("POST")
.param("id", id)
.param("folder", folder)
.param("kinds", kinds));
}
@Test
public void testSuccess_enqueuePollTask() {
CheckBackupAction.enqueuePollTask("some_backup_name", ImmutableSet.of("one", "two", "three"));
assertTasksEnqueued(
CheckBackupAction.QUEUE,
new TaskMatcher()
.url(CheckBackupAction.PATH)
.param(CHECK_BACKUP_NAME_PARAM, "some_backup_name")
.param(CHECK_BACKUP_KINDS_TO_LOAD_PARAM, "one,two,three")
.method("POST"));
}
@Test
public void testPost_forPendingBackup_returnsNotModified() throws Exception {
setPendingBackup();
NotModifiedException thrown = assertThrows(NotModifiedException.class, action::run);
assertThat(thrown)
.hasMessageThat()
.contains("Datastore backup some_backup still in progress: Progress: N/A");
}
@Test
public void testPost_forStalePendingBackupBackup_returnsNoContent() throws Exception {
setPendingBackup();
clock.setTo(
START_TIME
.plus(Duration.standardHours(20))
.plus(Duration.standardMinutes(3))
.plus(Duration.millis(1234)));
NoContentException thrown = assertThrows(NoContentException.class, action::run);
assertThat(thrown)
.hasMessageThat()
.contains(
"Datastore backup some_backup abandoned - "
+ "not complete after 20 hours, 3 minutes and 1 second. Progress: Progress: N/A");
}
@Test
public void testPost_forCompleteBackup_enqueuesLoadTask() throws Exception {
setCompleteBackup();
action.run();
assertLoadTaskEnqueued(
"2014-08-01T01:02:03_99364",
"gs://registry-project-id-datastore-export-test/2014-08-01T01:02:03_99364",
"one,two");
}
@Test
public void testPost_forCompleteBackup_withExtraKindsToLoad_enqueuesLoadTask() throws Exception {
setCompleteBackup();
action.kindsToLoadParam = "one,foo";
action.run();
assertLoadTaskEnqueued(
"2014-08-01T01:02:03_99364",
"gs://registry-project-id-datastore-export-test/2014-08-01T01:02:03_99364",
"one");
}
@Test
public void testPost_forCompleteBackup_withEmptyKindsToLoad_skipsLoadTask() throws Exception {
setCompleteBackup();
action.kindsToLoadParam = "";
action.run();
assertNoTasksEnqueued("export-snapshot");
}
@Test
public void testPost_forBadBackup_returnsBadRequest() throws Exception {
setBackupNotFound();
BadRequestException thrown = assertThrows(BadRequestException.class, action::run);
assertThat(thrown).hasMessageThat().contains("Bad backup name some_backup: No backup found");
}
@Test
public void testGet_returnsInformation() throws Exception {
setCompleteBackup();
action.requestMethod = Method.GET;
action.run();
assertThat(response.getPayload())
.isEqualTo(
TestDataHelper.loadFile(
CheckBackupActionTest.class, "pretty_printed_success_backup_operation.json")
.trim());
}
@Test
public void testGet_forBadBackup_returnsError() throws Exception {
setBackupNotFound();
action.requestMethod = Method.GET;
BadRequestException thrown = assertThrows(BadRequestException.class, action::run);
assertThat(thrown).hasMessageThat().contains("Bad backup name some_backup: No backup found");
}
}

View file

@ -16,6 +16,7 @@ package google.registry.export;
import static com.google.common.collect.Iterables.transform;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.export.LoadSnapshotAction.LATEST_SNAPSHOT_VIEW_NAME;
import static google.registry.export.LoadSnapshotAction.LOAD_SNAPSHOT_FILE_PARAM;
import static google.registry.export.LoadSnapshotAction.LOAD_SNAPSHOT_ID_PARAM;
import static google.registry.export.LoadSnapshotAction.LOAD_SNAPSHOT_KINDS_PARAM;
@ -159,24 +160,30 @@ public class LoadSnapshotActionTest {
verify(bigqueryJobsInsert, times(3)).execute();
// Check that the poll tasks for each load job were enqueued.
verify(bigqueryPollEnqueuer).enqueuePollTask(
new JobReference()
.setProjectId("Project-Id")
.setJobId("load-snapshot-id12345-one-1391096117045"),
UpdateSnapshotViewAction.createViewUpdateTask("snapshots", "id12345_one", "one"),
QueueFactory.getQueue(UpdateSnapshotViewAction.QUEUE));
verify(bigqueryPollEnqueuer).enqueuePollTask(
new JobReference()
.setProjectId("Project-Id")
.setJobId("load-snapshot-id12345-two-1391096117045"),
UpdateSnapshotViewAction.createViewUpdateTask("snapshots", "id12345_two", "two"),
QueueFactory.getQueue(UpdateSnapshotViewAction.QUEUE));
verify(bigqueryPollEnqueuer).enqueuePollTask(
new JobReference()
.setProjectId("Project-Id")
.setJobId("load-snapshot-id12345-three-1391096117045"),
UpdateSnapshotViewAction.createViewUpdateTask("snapshots", "id12345_three", "three"),
QueueFactory.getQueue(UpdateSnapshotViewAction.QUEUE));
verify(bigqueryPollEnqueuer)
.enqueuePollTask(
new JobReference()
.setProjectId("Project-Id")
.setJobId("load-snapshot-id12345-one-1391096117045"),
UpdateSnapshotViewAction.createViewUpdateTask(
"snapshots", "id12345_one", "one", LATEST_SNAPSHOT_VIEW_NAME),
QueueFactory.getQueue(UpdateSnapshotViewAction.QUEUE));
verify(bigqueryPollEnqueuer)
.enqueuePollTask(
new JobReference()
.setProjectId("Project-Id")
.setJobId("load-snapshot-id12345-two-1391096117045"),
UpdateSnapshotViewAction.createViewUpdateTask(
"snapshots", "id12345_two", "two", LATEST_SNAPSHOT_VIEW_NAME),
QueueFactory.getQueue(UpdateSnapshotViewAction.QUEUE));
verify(bigqueryPollEnqueuer)
.enqueuePollTask(
new JobReference()
.setProjectId("Project-Id")
.setJobId("load-snapshot-id12345-three-1391096117045"),
UpdateSnapshotViewAction.createViewUpdateTask(
"snapshots", "id12345_three", "three", LATEST_SNAPSHOT_VIEW_NAME),
QueueFactory.getQueue(UpdateSnapshotViewAction.QUEUE));
}
@Test

View file

@ -20,6 +20,7 @@ import static google.registry.export.UpdateSnapshotViewAction.QUEUE;
import static google.registry.export.UpdateSnapshotViewAction.UPDATE_SNAPSHOT_DATASET_ID_PARAM;
import static google.registry.export.UpdateSnapshotViewAction.UPDATE_SNAPSHOT_KIND_PARAM;
import static google.registry.export.UpdateSnapshotViewAction.UPDATE_SNAPSHOT_TABLE_ID_PARAM;
import static google.registry.export.UpdateSnapshotViewAction.UPDATE_SNAPSHOT_VIEWNAME_PARAM;
import static google.registry.export.UpdateSnapshotViewAction.createViewUpdateTask;
import static google.registry.testing.JUnitBackports.assertThrows;
import static google.registry.testing.TaskQueueHelper.assertTasksEnqueued;
@ -79,20 +80,26 @@ public class UpdateSnapshotViewActionTest {
action.checkedBigquery = checkedBigquery;
action.datasetId = "some_dataset";
action.kindName = "fookind";
action.viewName = "latest_datastore_export";
action.projectId = "myproject";
action.tableId = "12345_fookind";
}
@Test
public void testSuccess_createViewUpdateTask() {
getQueue(QUEUE).add(createViewUpdateTask("some_dataset", "12345_fookind", "fookind"));
assertTasksEnqueued(QUEUE,
getQueue(QUEUE)
.add(
createViewUpdateTask(
"some_dataset", "12345_fookind", "fookind", "latest_datastore_export"));
assertTasksEnqueued(
QUEUE,
new TaskMatcher()
.url(UpdateSnapshotViewAction.PATH)
.method("POST")
.param(UPDATE_SNAPSHOT_DATASET_ID_PARAM, "some_dataset")
.param(UPDATE_SNAPSHOT_TABLE_ID_PARAM, "12345_fookind")
.param(UPDATE_SNAPSHOT_KIND_PARAM, "fookind"));
.param(UPDATE_SNAPSHOT_KIND_PARAM, "fookind")
.param(UPDATE_SNAPSHOT_VIEWNAME_PARAM, "latest_datastore_export"));
}
@Test

View file

@ -0,0 +1,209 @@
// Copyright 2017 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.export;
import static com.google.common.collect.Iterables.transform;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.export.UploadDatastoreBackupAction.BACKUP_DATASET;
import static google.registry.export.UploadDatastoreBackupAction.LATEST_BACKUP_VIEW_NAME;
import static google.registry.export.UploadDatastoreBackupAction.PATH;
import static google.registry.export.UploadDatastoreBackupAction.QUEUE;
import static google.registry.export.UploadDatastoreBackupAction.UPLOAD_BACKUP_FOLDER_PARAM;
import static google.registry.export.UploadDatastoreBackupAction.UPLOAD_BACKUP_ID_PARAM;
import static google.registry.export.UploadDatastoreBackupAction.UPLOAD_BACKUP_KINDS_PARAM;
import static google.registry.export.UploadDatastoreBackupAction.enqueueUploadBackupTask;
import static google.registry.export.UploadDatastoreBackupAction.getBackupInfoFileForKind;
import static google.registry.testing.JUnitBackports.assertThrows;
import static google.registry.testing.TaskQueueHelper.assertTasksEnqueued;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import com.google.api.services.bigquery.Bigquery;
import com.google.api.services.bigquery.model.Dataset;
import com.google.api.services.bigquery.model.Job;
import com.google.api.services.bigquery.model.JobConfigurationLoad;
import com.google.api.services.bigquery.model.JobReference;
import com.google.appengine.api.taskqueue.QueueFactory;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import google.registry.bigquery.CheckedBigquery;
import google.registry.export.BigqueryPollJobAction.BigqueryPollJobEnqueuer;
import google.registry.request.HttpException.InternalServerErrorException;
import google.registry.testing.AppEngineRule;
import google.registry.testing.TaskQueueHelper.TaskMatcher;
import java.io.IOException;
import java.util.List;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.ArgumentCaptor;
/** Unit tests for {@link UploadDatastoreBackupAction}. */
@RunWith(JUnit4.class)
public class UploadDatastoreBackupActionTest {
@Rule
public final AppEngineRule appEngine = AppEngineRule.builder()
.withTaskQueue()
.build();
private final CheckedBigquery checkedBigquery = mock(CheckedBigquery.class);
private final Bigquery bigquery = mock(Bigquery.class);
private final Bigquery.Jobs bigqueryJobs = mock(Bigquery.Jobs.class);
private final Bigquery.Jobs.Insert bigqueryJobsInsert = mock(Bigquery.Jobs.Insert.class);
private final Bigquery.Datasets bigqueryDatasets = mock(Bigquery.Datasets.class);
private final Bigquery.Datasets.Insert bigqueryDatasetsInsert =
mock(Bigquery.Datasets.Insert.class);
private final BigqueryPollJobEnqueuer bigqueryPollEnqueuer = mock(BigqueryPollJobEnqueuer.class);
private UploadDatastoreBackupAction action;
@Before
public void before() throws Exception {
when(checkedBigquery.ensureDataSetExists("Project-Id", BACKUP_DATASET)).thenReturn(bigquery);
when(bigquery.jobs()).thenReturn(bigqueryJobs);
when(bigqueryJobs.insert(eq("Project-Id"), any(Job.class))).thenReturn(bigqueryJobsInsert);
when(bigquery.datasets()).thenReturn(bigqueryDatasets);
when(bigqueryDatasets.insert(eq("Project-Id"), any(Dataset.class)))
.thenReturn(bigqueryDatasetsInsert);
action = new UploadDatastoreBackupAction();
action.checkedBigquery = checkedBigquery;
action.bigqueryPollEnqueuer = bigqueryPollEnqueuer;
action.projectId = "Project-Id";
action.backupFolderUrl = "gs://bucket/path";
action.backupId = "2018-12-05T17:46:39_92612";
action.backupKinds = "one,two,three";
}
@Test
public void testSuccess_enqueueLoadTask() {
enqueueUploadBackupTask("id12345", "gs://bucket/path", ImmutableSet.of("one", "two", "three"));
assertTasksEnqueued(
QUEUE,
new TaskMatcher()
.url(PATH)
.method("POST")
.param(UPLOAD_BACKUP_ID_PARAM, "id12345")
.param(UPLOAD_BACKUP_FOLDER_PARAM, "gs://bucket/path")
.param(UPLOAD_BACKUP_KINDS_PARAM, "one,two,three"));
}
@Test
public void testSuccess_doPost() throws Exception {
action.run();
// Verify that checkedBigquery was called in a way that would create the dataset if it didn't
// already exist.
verify(checkedBigquery).ensureDataSetExists("Project-Id", BACKUP_DATASET);
// Capture the load jobs we inserted to do additional checking on them.
ArgumentCaptor<Job> jobArgument = ArgumentCaptor.forClass(Job.class);
verify(bigqueryJobs, times(3)).insert(eq("Project-Id"), jobArgument.capture());
List<Job> jobs = jobArgument.getAllValues();
assertThat(jobs).hasSize(3);
// Check properties that should be common to all load jobs.
for (Job job : jobs) {
assertThat(job.getJobReference().getProjectId()).isEqualTo("Project-Id");
JobConfigurationLoad config = job.getConfiguration().getLoad();
assertThat(config.getSourceFormat()).isEqualTo("DATASTORE_BACKUP");
assertThat(config.getDestinationTable().getProjectId()).isEqualTo("Project-Id");
assertThat(config.getDestinationTable().getDatasetId()).isEqualTo(BACKUP_DATASET);
}
// Check the job IDs for each load job.
assertThat(transform(jobs, job -> job.getJobReference().getJobId()))
.containsExactly(
"load-backup-2018_12_05T17_46_39_92612-one",
"load-backup-2018_12_05T17_46_39_92612-two",
"load-backup-2018_12_05T17_46_39_92612-three");
// Check the source URI for each load job.
assertThat(
transform(
jobs,
job -> Iterables.getOnlyElement(job.getConfiguration().getLoad().getSourceUris())))
.containsExactly(
"gs://bucket/path/all_namespaces/kind_one/all_namespaces_kind_one.export_metadata",
"gs://bucket/path/all_namespaces/kind_two/all_namespaces_kind_two.export_metadata",
"gs://bucket/path/all_namespaces/kind_three/all_namespaces_kind_three.export_metadata");
// Check the destination table ID for each load job.
assertThat(
transform(
jobs, job -> job.getConfiguration().getLoad().getDestinationTable().getTableId()))
.containsExactly(
"2018_12_05T17_46_39_92612_one",
"2018_12_05T17_46_39_92612_two",
"2018_12_05T17_46_39_92612_three");
// Check that we executed the inserted jobs.
verify(bigqueryJobsInsert, times(3)).execute();
// Check that the poll tasks for each load job were enqueued.
verify(bigqueryPollEnqueuer)
.enqueuePollTask(
new JobReference()
.setProjectId("Project-Id")
.setJobId("load-backup-2018_12_05T17_46_39_92612-one"),
UpdateSnapshotViewAction.createViewUpdateTask(
BACKUP_DATASET, "2018_12_05T17_46_39_92612_one", "one", LATEST_BACKUP_VIEW_NAME),
QueueFactory.getQueue(UpdateSnapshotViewAction.QUEUE));
verify(bigqueryPollEnqueuer)
.enqueuePollTask(
new JobReference()
.setProjectId("Project-Id")
.setJobId("load-backup-2018_12_05T17_46_39_92612-two"),
UpdateSnapshotViewAction.createViewUpdateTask(
BACKUP_DATASET, "2018_12_05T17_46_39_92612_two", "two", LATEST_BACKUP_VIEW_NAME),
QueueFactory.getQueue(UpdateSnapshotViewAction.QUEUE));
verify(bigqueryPollEnqueuer)
.enqueuePollTask(
new JobReference()
.setProjectId("Project-Id")
.setJobId("load-backup-2018_12_05T17_46_39_92612-three"),
UpdateSnapshotViewAction.createViewUpdateTask(
BACKUP_DATASET,
"2018_12_05T17_46_39_92612_three",
"three",
LATEST_BACKUP_VIEW_NAME),
QueueFactory.getQueue(UpdateSnapshotViewAction.QUEUE));
}
@Test
public void testFailure_doPost_bigqueryThrowsException() throws Exception {
when(bigqueryJobsInsert.execute()).thenThrow(new IOException("The Internet has gone missing"));
InternalServerErrorException thrown =
assertThrows(InternalServerErrorException.class, action::run);
assertThat(thrown)
.hasMessageThat()
.contains("Error loading backup: The Internet has gone missing");
}
@Test
public void testgetBackupInfoFileForKind() {
assertThat(
getBackupInfoFileForKind(
"gs://BucketName/2018-11-11T00:00:00_12345", "AllocationToken"))
.isEqualTo(
"gs://BucketName/2018-11-11T00:00:00_12345/"
+ "all_namespaces/kind_AllocationToken/"
+ "all_namespaces_kind_AllocationToken.export_metadata");
}
}

View file

@ -0,0 +1,34 @@
package(
default_testonly = 1,
default_visibility = ["//java/google/registry:registry_project"],
)
licenses(["notice"]) # Apache 2.0
load("//java/com/google/testing/builddefs:GenTestRules.bzl", "GenTestRules")
java_library(
name = "datastore",
srcs = glob(["*.java"]),
resources = glob(["**/testdata/*.json"]),
deps = [
"//java/google/registry/export/datastore",
"//java/google/registry/util",
"//javatests/google/registry/testing",
"@com_google_api_client",
"@com_google_guava",
"@com_google_http_client",
"@com_google_http_client_jackson2",
"@com_google_truth",
"@com_google_truth_extensions_truth_java8_extension",
"@joda_time",
"@junit",
"@org_mockito_all",
],
)
GenTestRules(
name = "GeneratedTestRules",
test_files = glob(["*Test.java"]),
deps = [":datastore"],
)

View file

@ -0,0 +1,178 @@
// Copyright 2018 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.export.datastore;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.common.collect.ImmutableList;
import google.registry.testing.MockitoJUnitRule;
import google.registry.testing.TestDataHelper;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Optional;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/** Unit tests for {@link DatastoreAdmin}. */
@RunWith(JUnit4.class)
public class DatastoreAdminTest {
private static final String AUTH_HEADER_PREFIX = "Bearer ";
private static final String ACCESS_TOKEN = "MyAccessToken";
private static final ImmutableList<String> KINDS =
ImmutableList.of("Registry", "Registrar", "DomainBase");
@Rule public final MockitoJUnitRule mocks = MockitoJUnitRule.create();
private HttpTransport httpTransport;
private GoogleCredential googleCredential;
private DatastoreAdmin datastoreAdmin;
@Before
public void setup() {
httpTransport = new NetHttpTransport();
googleCredential =
new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(JacksonFactory.getDefaultInstance())
.setClock(() -> 0)
.build();
googleCredential.setAccessToken(ACCESS_TOKEN);
googleCredential.setExpiresInSeconds(1_000L);
datastoreAdmin =
new DatastoreAdmin.Builder(
googleCredential.getTransport(),
googleCredential.getJsonFactory(),
googleCredential)
.setApplicationName("MyApplication")
.setProjectId("MyCloudProject")
.build();
}
@Test
public void testExport() throws IOException {
DatastoreAdmin.Export export = datastoreAdmin.export("gs://mybucket/path", KINDS);
HttpRequest httpRequest = export.buildHttpRequest();
assertThat(httpRequest.getUrl().toString())
.isEqualTo("https://datastore.googleapis.com/v1/projects/MyCloudProject:export");
assertThat(httpRequest.getRequestMethod()).isEqualTo("POST");
assertThat(getRequestContent(httpRequest))
.hasValue(
TestDataHelper.loadFile(getClass(), "export_request_content.json")
.replaceAll("[\\s\\n]+", ""));
simulateSendRequest(httpRequest);
assertThat(getAccessToken(httpRequest)).hasValue(ACCESS_TOKEN);
}
@Test
public void testGetOperation() throws IOException {
DatastoreAdmin.Get get =
datastoreAdmin.get("projects/MyCloudProject/operations/ASAzNjMwOTEyNjUJ");
HttpRequest httpRequest = get.buildHttpRequest();
assertThat(httpRequest.getUrl().toString())
.isEqualTo(
"https://datastore.googleapis.com/v1/projects/MyCloudProject/operations/ASAzNjMwOTEyNjUJ");
assertThat(httpRequest.getRequestMethod()).isEqualTo("GET");
assertThat(httpRequest.getContent()).isNull();
simulateSendRequest(httpRequest);
assertThat(getAccessToken(httpRequest)).hasValue(ACCESS_TOKEN);
}
@Test
public void testListOperations_all() throws IOException {
DatastoreAdmin.ListOperations listOperations = datastoreAdmin.listAll();
HttpRequest httpRequest = listOperations.buildHttpRequest();
assertThat(httpRequest.getUrl().toString())
.isEqualTo("https://datastore.googleapis.com/v1/projects/MyCloudProject/operations");
assertThat(httpRequest.getRequestMethod()).isEqualTo("GET");
assertThat(httpRequest.getContent()).isNull();
simulateSendRequest(httpRequest);
assertThat(getAccessToken(httpRequest)).hasValue(ACCESS_TOKEN);
}
@Test
public void testListOperations_filterByStartTime() throws IOException {
DatastoreAdmin.ListOperations listOperations =
datastoreAdmin.list("metadata.common.startTime>\"2018-10-31T00:00:00.0Z\"");
HttpRequest httpRequest = listOperations.buildHttpRequest();
assertThat(httpRequest.getUrl().toString())
.isEqualTo(
"https://datastore.googleapis.com/v1/projects/MyCloudProject/operations"
+ "?filter=metadata.common.startTime%3E%222018-10-31T00:00:00.0Z%22");
assertThat(httpRequest.getRequestMethod()).isEqualTo("GET");
assertThat(httpRequest.getContent()).isNull();
simulateSendRequest(httpRequest);
assertThat(getAccessToken(httpRequest)).hasValue(ACCESS_TOKEN);
}
@Test
public void testListOperations_filterByState() throws IOException {
// TODO(weiminyu): consider adding a method to DatastoreAdmin to support query by state.
DatastoreAdmin.ListOperations listOperations =
datastoreAdmin.list("metadata.common.state=PROCESSING");
HttpRequest httpRequest = listOperations.buildHttpRequest();
assertThat(httpRequest.getUrl().toString())
.isEqualTo(
"https://datastore.googleapis.com/v1/projects/MyCloudProject/operations"
+ "?filter=metadata.common.state%3DPROCESSING");
assertThat(httpRequest.getRequestMethod()).isEqualTo("GET");
assertThat(httpRequest.getContent()).isNull();
simulateSendRequest(httpRequest);
assertThat(getAccessToken(httpRequest)).hasValue(ACCESS_TOKEN);
}
private static HttpRequest simulateSendRequest(HttpRequest httpRequest) {
try {
httpRequest.setUrl(new GenericUrl("https://localhost:65537")).execute();
} catch (Exception expected) {
}
return httpRequest;
}
private static Optional<String> getAccessToken(HttpRequest httpRequest) {
return httpRequest.getHeaders().getAuthorizationAsList().stream()
.filter(header -> header.startsWith(AUTH_HEADER_PREFIX))
.map(header -> header.substring(AUTH_HEADER_PREFIX.length()))
.findAny();
}
private static Optional<String> getRequestContent(HttpRequest httpRequest) throws IOException {
if (httpRequest.getContent() == null) {
return Optional.empty();
}
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
httpRequest.getContent().writeTo(outputStream);
outputStream.close();
return Optional.of(outputStream.toString(StandardCharsets.UTF_8.name()));
}
}

View file

@ -0,0 +1,80 @@
// Copyright 2018 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.export.datastore;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.testing.JUnitBackports.assertThrows;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.common.collect.ImmutableList;
import google.registry.testing.TestDataHelper;
import java.io.IOException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/** Unit tests for the instantiation, marshalling and unmarshalling of {@link EntityFilter}. */
@RunWith(JUnit4.class)
public class EntityFilterTest {
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
@Test
public void testEntityFilter_create_nullKinds() {
assertThrows(NullPointerException.class, () -> new EntityFilter(null));
}
@Test
public void testEntityFilter_create_emptyKinds() {
assertThrows(IllegalArgumentException.class, () -> new EntityFilter(ImmutableList.of()));
}
@Test
public void testEntityFilter_marshall() throws IOException {
EntityFilter entityFilter =
new EntityFilter(ImmutableList.of("Registry", "Registrar", "DomainBase"));
assertThat(JSON_FACTORY.toString(entityFilter))
.isEqualTo(loadJsonString("entity_filter.json").replaceAll("[\\s\\n]+", ""));
}
@Test
public void testEntityFilter_unmarshall() throws IOException {
EntityFilter entityFilter = loadJson("entity_filter.json", EntityFilter.class);
assertThat(entityFilter.getKinds())
.containsExactly("Registry", "Registrar", "DomainBase")
.inOrder();
}
@Test
public void testEntityFilter_unmarshall_noKinds() throws IOException {
EntityFilter entityFilter = JSON_FACTORY.fromString("{}", EntityFilter.class);
assertThat(entityFilter.getKinds()).isEmpty();
}
@Test
public void testEntityFilter_unmarshall_emptyKinds() throws IOException {
EntityFilter entityFilter = JSON_FACTORY.fromString("{ \"kinds\" : [] }", EntityFilter.class);
assertThat(entityFilter.getKinds()).isEmpty();
}
private static <T> T loadJson(String fileName, Class<T> type) throws IOException {
return JSON_FACTORY.fromString(loadJsonString(fileName), type);
}
private static String loadJsonString(String fileName) {
return TestDataHelper.loadFile(EntityFilterTest.class, fileName);
}
}

View file

@ -0,0 +1,109 @@
// Copyright 2018 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.export.datastore;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import google.registry.export.datastore.Operation.CommonMetadata;
import google.registry.export.datastore.Operation.Metadata;
import google.registry.export.datastore.Operation.Progress;
import google.registry.testing.FakeClock;
import google.registry.testing.TestDataHelper;
import google.registry.util.Clock;
import java.io.IOException;
import org.joda.time.DateTime;
import org.joda.time.Duration;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/** Unit tests for unmarshalling {@link Operation} and its member types. */
@RunWith(JUnit4.class)
public class OperationTest {
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
@Test
public void testCommonMetadata_unmarshall() throws IOException {
CommonMetadata commonMetadata = loadJson("common_metadata.json", CommonMetadata.class);
assertThat(commonMetadata.getState()).isEqualTo("SUCCESSFUL");
assertThat(commonMetadata.getOperationType()).isEqualTo("EXPORT_ENTITIES");
assertThat(commonMetadata.getStartTime())
.isEqualTo(DateTime.parse("2018-10-29T16:01:04.645299Z"));
assertThat(commonMetadata.getEndTime()).isEmpty();
}
@Test
public void testProgress_unmarshall() throws IOException {
Progress progress = loadJson("progress.json", Progress.class);
assertThat(progress.getWorkCompleted()).isEqualTo(51797);
assertThat(progress.getWorkEstimated()).isEqualTo(54513);
}
@Test
public void testMetadata_unmarshall() throws IOException {
Metadata metadata = loadJson("metadata.json", Metadata.class);
assertThat(metadata.getCommonMetadata().getOperationType()).isEqualTo("EXPORT_ENTITIES");
assertThat(metadata.getCommonMetadata().getState()).isEqualTo("SUCCESSFUL");
assertThat(metadata.getCommonMetadata().getStartTime())
.isEqualTo(DateTime.parse("2018-10-29T16:01:04.645299Z"));
assertThat(metadata.getCommonMetadata().getEndTime())
.hasValue(DateTime.parse("2018-10-29T16:02:19.009859Z"));
assertThat(metadata.getOutputUrlPrefix())
.isEqualTo("gs://domain-registry-alpha-datastore-export-test/2018-10-29T16:01:04_99364");
}
@Test
public void testOperation_unmarshall() throws IOException {
Operation operation = loadJson("operation.json", Operation.class);
assertThat(operation.getName())
.startsWith("projects/domain-registry-alpha/operations/ASAzNjMwOTEyNjUJ");
assertThat(operation.isProcessing()).isTrue();
assertThat(operation.isSuccessful()).isFalse();
assertThat(operation.isDone()).isFalse();
assertThat(operation.getStartTime()).isEqualTo(DateTime.parse("2018-10-29T16:01:04.645299Z"));
assertThat(operation.getExportFolderUrl())
.isEqualTo("gs://domain-registry-alpha-datastore-export-test/2018-10-29T16:01:04_99364");
assertThat(operation.getExportId()).isEqualTo("2018-10-29T16:01:04_99364");
assertThat(operation.getKinds()).containsExactly("Registry", "Registrar", "DomainBase");
assertThat(operation.toPrettyString())
.isEqualTo(
TestDataHelper.loadFile(OperationTest.class, "prettyprinted_operation.json").trim());
assertThat(operation.getProgress()).isEqualTo("Progress: N/A");
}
@Test
public void testOperationList_unmarshall() throws IOException {
Operation.OperationList operationList =
loadJson("operation_list.json", Operation.OperationList.class);
assertThat(operationList.toList()).hasSize(2);
Clock clock = new FakeClock(DateTime.parse("2018-10-29T16:01:04.645299Z"));
((FakeClock) clock).advanceOneMilli();
assertThat(operationList.toList().get(0).getRunningTime(clock)).isEqualTo(Duration.millis(1));
assertThat(operationList.toList().get(0).getProgress())
.isEqualTo("Progress: [51797/54513 entities]");
assertThat(operationList.toList().get(1).getRunningTime(clock))
.isEqualTo(Duration.standardMinutes(1));
// Work completed may exceed work estimated
assertThat(operationList.toList().get(1).getProgress())
.isEqualTo("Progress: [96908367/73773755 bytes] [51797/54513 entities]");
}
private static <T> T loadJson(String fileName, Class<T> type) throws IOException {
return JSON_FACTORY.fromString(TestDataHelper.loadFile(OperationTest.class, fileName), type);
}
}

View file

@ -0,0 +1,5 @@
{
"startTime": "2018-10-29T16:01:04.645299Z",
"operationType": "EXPORT_ENTITIES",
"state": "SUCCESSFUL"
}

View file

@ -0,0 +1,7 @@
{
"kinds": [
"Registry",
"Registrar",
"DomainBase"
]
}

View file

@ -0,0 +1,6 @@
{
"entityFilter": {
"kinds": ["Registry", "Registrar", "DomainBase"]
},
"outputUrlPrefix": "gs://mybucket/path"
}

View file

@ -0,0 +1,25 @@
{
"@type": "type.googleapis.com/google.datastore.admin.v1.ExportEntitiesMetadata",
"common": {
"startTime": "2018-10-29T16:01:04.645299Z",
"endTime": "2018-10-29T16:02:19.009859Z",
"operationType": "EXPORT_ENTITIES",
"state": "SUCCESSFUL"
},
"progressEntities": {
"workCompleted": "51797",
"workEstimated": "54513"
},
"progressBytes": {
"workCompleted": "96908367",
"workEstimated": "73773755"
},
"entityFilter": {
"kinds": [
"Registry",
"Registrar",
"DomainBase"
]
},
"outputUrlPrefix": "gs://domain-registry-alpha-datastore-export-test/2018-10-29T16:01:04_99364"
}

View file

@ -0,0 +1,19 @@
{
"name": "projects/domain-registry-alpha/operations/ASAzNjMwOTEyNjUJ",
"metadata": {
"@type": "type.googleapis.com/google.datastore.admin.v1.ExportEntitiesMetadata",
"common": {
"startTime": "2018-10-29T16:01:04.645299Z",
"operationType": "EXPORT_ENTITIES",
"state": "PROCESSING"
},
"entityFilter": {
"kinds": [
"Registry",
"Registrar",
"DomainBase"
]
},
"outputUrlPrefix": "gs://domain-registry-alpha-datastore-export-test/2018-10-29T16:01:04_99364"
}
}

View file

@ -0,0 +1,55 @@
{
"operations": [
{
"name": "projects/domain-registry-alpha/operations/ASAzNjMwOTEyNjUJ",
"metadata": {
"@type": "type.googleapis.com/google.datastore.admin.v1.ExportEntitiesMetadata",
"common": {
"startTime": "2018-10-29T16:01:04.645299Z",
"operationType": "EXPORT_ENTITIES",
"state": "PROCESSING"
},
"progressEntities": {
"workCompleted": "51797",
"workEstimated": "54513"
},
"entityFilter": {
"kinds": [
"Registry",
"Registrar",
"DomainBase"
]
},
"outputUrlPrefix": "gs://domain-registry-alpha-datastore-export-test/2018-10-29T16:01:04_99364"
}
},
{
"name": "projects/domain-registry-alpha/operations/ASAzNjMwOTEyNjUJ",
"metadata": {
"@type": "type.googleapis.com/google.datastore.admin.v1.ExportEntitiesMetadata",
"common": {
"startTime": "2018-10-29T16:01:04.645299Z",
"endTime": "2018-10-29T16:02:04.645299Z",
"operationType": "EXPORT_ENTITIES",
"state": "PROCESSING"
},
"progressEntities": {
"workCompleted": "51797",
"workEstimated": "54513"
},
"progressBytes": {
"workCompleted": "96908367",
"workEstimated": "73773755"
},
"entityFilter": {
"kinds": [
"Registry",
"Registrar",
"DomainBase"
]
},
"outputUrlPrefix": "gs://domain-registry-alpha-datastore-export-test/2018-10-29T16:01:04_99364"
}
}
]
}

View file

@ -0,0 +1,16 @@
{
"done" : false,
"metadata" : {
"common" : {
"operationType" : "EXPORT_ENTITIES",
"startTime" : "2018-10-29T16:01:04.645299Z",
"state" : "PROCESSING"
},
"entityFilter" : {
"kinds" : [ "Registry", "Registrar", "DomainBase" ]
},
"outputUrlPrefix" : "gs://domain-registry-alpha-datastore-export-test/2018-10-29T16:01:04_99364",
"@type" : "type.googleapis.com/google.datastore.admin.v1.ExportEntitiesMetadata"
},
"name" : "projects/domain-registry-alpha/operations/ASAzNjMwOTEyNjUJ"
}

View file

@ -0,0 +1,4 @@
{
"workCompleted": "51797",
"workEstimated": "54513"
}

View file

@ -0,0 +1,18 @@
{
"name": "projects/registry-project-id/operations/ASAzNjMwOTEyNjUJ",
"metadata": {
"@type": "type.googleapis.com/google.datastore.admin.v1.ExportEntitiesMetadata",
"common": {
"startTime": "2014-08-01T01:02:03Z",
"operationType": "EXPORT_ENTITIES",
"state": "PROCESSING"
},
"entityFilter": {
"kinds": [
"one",
"two"
]
},
"outputUrlPrefix": "gs://registry-project-id-datastore-export-test/2014-08-01T01:02:03_99364"
}
}

View file

@ -0,0 +1,20 @@
{
"name": "projects/registry-project-id/operations/ASAzNjMwOTEyNjUJ",
"metadata": {
"@type": "type.googleapis.com/google.datastore.admin.v1.ExportEntitiesMetadata",
"common": {
"startTime": "2014-08-01T01:02:03Z",
"endTime": "2014-08-01T01:32:03Z",
"operationType": "EXPORT_ENTITIES",
"state": "SUCCESSFUL"
},
"entityFilter": {
"kinds": [
"one",
"two"
]
},
"outputUrlPrefix": "gs://registry-project-id-datastore-export-test/2014-08-01T01:02:03_99364"
},
"done": true
}

View file

@ -0,0 +1,17 @@
{
"done" : true,
"metadata" : {
"common" : {
"endTime" : "2014-08-01T01:32:03Z",
"operationType" : "EXPORT_ENTITIES",
"startTime" : "2014-08-01T01:02:03Z",
"state" : "SUCCESSFUL"
},
"entityFilter" : {
"kinds" : [ "one", "two" ]
},
"outputUrlPrefix" : "gs://registry-project-id-datastore-export-test/2014-08-01T01:02:03_99364",
"@type" : "type.googleapis.com/google.datastore.admin.v1.ExportEntitiesMetadata"
},
"name" : "projects/registry-project-id/operations/ASAzNjMwOTEyNjUJ"
}

View file

@ -31,6 +31,7 @@ java_library(
"//java/google/registry/monitoring/whitebox",
"//java/google/registry/pricing",
"//java/google/registry/request",
"//java/google/registry/request/auth",
"//java/google/registry/request/lock",
"//java/google/registry/tmch",
"//java/google/registry/util",

View file

@ -22,6 +22,8 @@ import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import com.google.common.collect.ImmutableSetMultimap;
import google.registry.request.auth.AuthenticatedRegistrarAccessor;
import google.registry.testing.AppEngineRule;
import google.registry.testing.FakeHttpSession;
import google.registry.testing.ShardableTestCase;
@ -48,9 +50,11 @@ public class EppConsoleActionTest extends ShardableTestCase {
EppConsoleAction action = new EppConsoleAction();
action.inputXmlBytes = INPUT_XML_BYTES;
action.session = new FakeHttpSession();
action.session.setAttribute("CLIENT_ID", "ClientIdentifier");
action.clientId = "ClientIdentifier";
action.eppRequestHandler = mock(EppRequestHandler.class);
action.userService = getUserService();
action.registrarAccessor =
AuthenticatedRegistrarAccessor.createForTesting(ImmutableSetMultimap.of());
action.run();
ArgumentCaptor<TransportCredentials> credentialsCaptor =
ArgumentCaptor.forClass(TransportCredentials.class);
@ -62,8 +66,8 @@ public class EppConsoleActionTest extends ShardableTestCase {
eq(false),
eq(false),
eq(INPUT_XML_BYTES));
assertThat(((GaeUserCredentials) credentialsCaptor.getValue()).getUser().getEmail())
.isEqualTo("person@example.com");
assertThat(((GaeUserCredentials) credentialsCaptor.getValue()).toString())
.contains("user=TestUserId");
assertThat(metadataCaptor.getValue().getClientId()).isEqualTo("ClientIdentifier");
}
}

View file

@ -16,7 +16,7 @@ package google.registry.flows;
import static com.google.common.io.BaseEncoding.base64;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.flows.EppXmlTransformer.marshal;
import static google.registry.model.eppcommon.EppXmlTransformer.marshal;
import static google.registry.testing.DatastoreHelper.createTld;
import static google.registry.testing.LogsSubject.assertAboutLogs;
import static google.registry.testing.TestDataHelper.loadFile;

View file

@ -47,31 +47,6 @@ public class EppLifecycleDomainApplicationTest extends EppTestCase {
START_OF_GA, TldState.GENERAL_AVAILABILITY));
}
/** Create the two administrative contacts and two hosts. */
void createContactsAndHosts() throws Exception {
DateTime startTime = DateTime.parse("2000-06-01T00:00:00Z");
assertThatCommand("contact_create_sh8013.xml")
.atTime(startTime)
.hasResponse(
"contact_create_response_sh8013.xml",
ImmutableMap.of("CRDATE", "2000-06-01T00:00:00Z"));
assertThatCommand("contact_create_jd1234.xml")
.atTime(startTime.plusMinutes(1))
.hasResponse("contact_create_response_jd1234.xml");
assertThatCommand("host_create.xml", ImmutableMap.of("HOSTNAME", "ns1.example.external"))
.atTime(startTime.plusMinutes(2))
.hasResponse(
"host_create_response.xml",
ImmutableMap.of(
"HOSTNAME", "ns1.example.external", "CRDATE", startTime.plusMinutes(2).toString()));
assertThatCommand("host_create.xml", ImmutableMap.of("HOSTNAME", "ns2.example.external"))
.atTime(startTime.plusMinutes(3))
.hasResponse(
"host_create_response.xml",
ImmutableMap.of(
"HOSTNAME", "ns2.example.external", "CRDATE", startTime.plusMinutes(3).toString()));
}
@Test
public void testApplicationDuringSunrise_doesntCreateDomainWithoutAllocation() throws Exception {
assertThatLoginSucceeds("NewRegistrar", "foo-BAR2");

View file

@ -14,30 +14,24 @@
package google.registry.flows;
import static com.google.common.truth.Truth8.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_AND_CLOSE;
import static google.registry.model.eppoutput.Result.Code.SUCCESS_WITH_ACTION_PENDING;
import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.testing.DatastoreHelper.assertBillingEventsForResource;
import static google.registry.testing.DatastoreHelper.createTld;
import static google.registry.testing.DatastoreHelper.createTlds;
import static google.registry.testing.DatastoreHelper.getOnlyHistoryEntryOfType;
import static google.registry.testing.DatastoreHelper.persistResource;
import static google.registry.testing.DatastoreHelper.stripBillingEventId;
import static google.registry.testing.EppMetricSubject.assertThat;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import static org.joda.money.CurrencyUnit.USD;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedMap;
import com.google.re2j.Matcher;
import com.google.re2j.Pattern;
import com.googlecode.objectify.Key;
import google.registry.model.billing.BillingEvent;
import google.registry.model.billing.BillingEvent.Flag;
import google.registry.model.billing.BillingEvent.OneTime;
import google.registry.model.billing.BillingEvent.Reason;
import google.registry.model.domain.DomainResource;
@ -45,8 +39,6 @@ import google.registry.model.registry.Registry;
import google.registry.model.registry.Registry.TldState;
import google.registry.model.reporting.HistoryEntry.Type;
import google.registry.testing.AppEngineRule;
import java.util.Objects;
import java.util.Optional;
import org.joda.money.Money;
import org.joda.time.DateTime;
import org.junit.Before;
@ -68,74 +60,6 @@ public class EppLifecycleDomainTest extends EppTestCase {
createTlds("example", "tld");
}
/** Create the two administrative contacts and two hosts. */
void createContactsAndHosts() throws Exception {
DateTime createTime = DateTime.parse("2000-06-01T00:00:00Z");
createContacts(createTime);
assertThatCommand("host_create.xml", ImmutableMap.of("HOSTNAME", "ns1.example.external"))
.atTime(createTime.plusMinutes(2))
.hasResponse(
"host_create_response.xml",
ImmutableMap.of(
"HOSTNAME", "ns1.example.external",
"CRDATE", createTime.plusMinutes(2).toString()));
assertThatCommand("host_create.xml", ImmutableMap.of("HOSTNAME", "ns2.example.external"))
.atTime(createTime.plusMinutes(3))
.hasResponse(
"host_create_response.xml",
ImmutableMap.of(
"HOSTNAME", "ns2.example.external",
"CRDATE", createTime.plusMinutes(3).toString()));
}
private void createContacts(DateTime createTime) throws Exception {
assertThatCommand("contact_create_sh8013.xml")
.atTime(createTime)
.hasResponse(
"contact_create_response_sh8013.xml", ImmutableMap.of("CRDATE", createTime.toString()));
assertThatCommand("contact_create_jd1234.xml")
.atTime(createTime.plusMinutes(1))
.hasResponse(
"contact_create_response_jd1234.xml",
ImmutableMap.of("CRDATE", createTime.plusMinutes(1).toString()));
}
/** Creates the domain fakesite.example with two nameservers on it. */
void createFakesite() throws Exception {
createContactsAndHosts();
assertThatCommand("domain_create_fakesite.xml")
.atTime("2000-06-01T00:04:00Z")
.hasResponse(
"domain_create_response.xml",
ImmutableMap.of(
"DOMAIN", "fakesite.example",
"CRDATE", "2000-06-01T00:04:00.0Z",
"EXDATE", "2002-06-01T00:04:00.0Z"));
assertThatCommand("domain_info_fakesite.xml")
.atTime("2000-06-06T00:00:00Z")
.hasResponse("domain_info_response_fakesite_ok.xml");
}
/** Creates ns3.fakesite.example as a host, then adds it to fakesite. */
void createSubordinateHost() throws Exception {
// Add the fakesite nameserver (requires that domain is already created).
assertThatCommand("host_create_fakesite.xml")
.atTime("2000-06-06T00:01:00Z")
.hasResponse("host_create_response_fakesite.xml");
// Add new nameserver to domain.
assertThatCommand("domain_update_add_nameserver_fakesite.xml")
.atTime("2000-06-08T00:00:00Z")
.hasResponse("generic_success_response.xml");
// Verify new nameserver was added.
assertThatCommand("domain_info_fakesite.xml")
.atTime("2000-06-08T00:01:00Z")
.hasResponse("domain_info_response_fakesite_3_nameservers.xml");
// Verify that nameserver's data was set correctly.
assertThatCommand("host_info_fakesite.xml")
.atTime("2000-06-08T00:02:00Z")
.hasResponse("host_info_response_fakesite_linked.xml");
}
@Test
public void testDomainDeleteRestore() throws Exception {
assertThatLoginSucceeds("NewRegistrar", "foo-BAR2");
@ -183,7 +107,7 @@ public class EppLifecycleDomainTest extends EppTestCase {
"EXDATE", "2002-06-01T00:02:00.0Z"));
DomainResource domain =
loadByForeignKey(DomainResource.class, "example.tld", createTime.plusHours(1));
loadByForeignKey(DomainResource.class, "example.tld", createTime.plusHours(1)).get();
// Delete domain example.tld within the add grace period.
DateTime deleteTime = createTime.plusDays(1);
@ -206,7 +130,7 @@ public class EppLifecycleDomainTest extends EppTestCase {
domain,
// Check the existence of the expected create one-time billing event.
oneTimeCreateBillingEvent,
makeRecurringCreateBillingEvent(domain, createTime, deleteTime),
makeRecurringCreateBillingEvent(domain, createTime.plusYears(2), deleteTime),
// Check for the existence of a cancellation for the given one-time billing event.
makeCancellationBillingEventFor(
domain, oneTimeCreateBillingEvent, createTime, deleteTime));
@ -247,7 +171,8 @@ public class EppLifecycleDomainTest extends EppTestCase {
assertThatCommand("domain_info.xml", ImmutableMap.of("DOMAIN", "example.tld"))
.atTime("2000-08-08T00:00:00Z")
.hasResponse(
"domain_info_response_wildcard.xml", ImmutableMap.of("STATUS", "pendingDelete"));
"domain_info_response_wildcard_after_redemption.xml",
ImmutableMap.of("STATUS", "pendingDelete"));
// Verify that the domain is non-existent (available for registration) later.
assertThatCommand("domain_info.xml", ImmutableMap.of("DOMAIN", "example.tld"))
@ -259,12 +184,13 @@ public class EppLifecycleDomainTest extends EppTestCase {
DomainResource domain =
loadByForeignKey(
DomainResource.class, "example.tld", DateTime.parse("2000-08-01T00:02:00Z"));
DomainResource.class, "example.tld", DateTime.parse("2000-08-01T00:02:00Z"))
.get();
// Verify that the autorenew was ended and that the one-time billing event is not canceled.
assertBillingEventsForResource(
domain,
makeOneTimeCreateBillingEvent(domain, createTime),
makeRecurringCreateBillingEvent(domain, createTime, deleteTime));
makeRecurringCreateBillingEvent(domain, createTime.plusYears(2), deleteTime));
assertThatLogoutSucceeds();
}
@ -293,7 +219,8 @@ public class EppLifecycleDomainTest extends EppTestCase {
DomainResource domain =
loadByForeignKey(
DomainResource.class, "example.tld", DateTime.parse("2000-06-01T00:03:00Z"));
DomainResource.class, "example.tld", DateTime.parse("2000-06-01T00:03:00Z"))
.get();
// Delete domain example.tld within the add grade period.
DateTime deleteTime = createTime.plusDays(1);
@ -323,7 +250,7 @@ public class EppLifecycleDomainTest extends EppTestCase {
expectedOneTimeCreateBillingEvent,
// ... and the expected one-time EAP fee billing event ...
expectedCreateEapBillingEvent,
makeRecurringCreateBillingEvent(domain, createTime, deleteTime),
makeRecurringCreateBillingEvent(domain, createTime.plusYears(2), deleteTime),
// ... and verify that the create one-time billing event was canceled ...
makeCancellationBillingEventFor(
domain, expectedOneTimeCreateBillingEvent, createTime, deleteTime));
@ -333,77 +260,6 @@ public class EppLifecycleDomainTest extends EppTestCase {
assertThatLogoutSucceeds();
}
/** Makes a one-time billing event corresponding to the given domain's creation. */
private static BillingEvent.OneTime makeOneTimeCreateBillingEvent(
DomainResource domain, DateTime createTime) {
return new BillingEvent.OneTime.Builder()
.setReason(Reason.CREATE)
.setTargetId(domain.getFullyQualifiedDomainName())
.setClientId(domain.getCurrentSponsorClientId())
.setCost(Money.parse("USD 26.00"))
.setPeriodYears(2)
.setEventTime(createTime)
.setBillingTime(createTime.plus(Registry.get(domain.getTld()).getRenewGracePeriodLength()))
.setParent(getOnlyHistoryEntryOfType(domain, Type.DOMAIN_CREATE))
.build();
}
/** Makes a recurring billing event corresponding to the given domain's creation. */
private static BillingEvent.Recurring makeRecurringCreateBillingEvent(
DomainResource domain, DateTime createTime, DateTime endTime) {
return new BillingEvent.Recurring.Builder()
.setReason(Reason.RENEW)
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
.setTargetId(domain.getFullyQualifiedDomainName())
.setClientId(domain.getCurrentSponsorClientId())
.setEventTime(createTime.plusYears(2))
.setRecurrenceEndTime(endTime)
.setParent(getOnlyHistoryEntryOfType(domain, Type.DOMAIN_CREATE))
.build();
}
/** Makes a cancellation billing event cancelling out the given domain create billing event. */
private static BillingEvent.Cancellation makeCancellationBillingEventFor(
DomainResource domain,
OneTime billingEventToCancel,
DateTime createTime,
DateTime deleteTime) {
return new BillingEvent.Cancellation.Builder()
.setTargetId(domain.getFullyQualifiedDomainName())
.setClientId(domain.getCurrentSponsorClientId())
.setEventTime(deleteTime)
.setOneTimeEventKey(findKeyToActualOneTimeBillingEvent(billingEventToCancel))
.setBillingTime(createTime.plus(Registry.get(domain.getTld()).getRenewGracePeriodLength()))
.setReason(Reason.CREATE)
.setParent(getOnlyHistoryEntryOfType(domain, Type.DOMAIN_DELETE))
.build();
}
/**
* Finds the Key to the actual one-time create billing event associated with a domain's creation.
*
* <p>This is used in the situation where we have created an expected billing event associated
* with the domain's creation (which is passed as the parameter here), then need to locate the key
* to the actual billing event in Datastore that would be seen on a Cancellation billing event.
* This is necessary because the ID will be different even though all the rest of the fields are
* the same.
*/
private static Key<OneTime> findKeyToActualOneTimeBillingEvent(OneTime expectedBillingEvent) {
Optional<OneTime> actualCreateBillingEvent =
ofy()
.load()
.type(BillingEvent.OneTime.class)
.list()
.stream()
.filter(
b ->
Objects.equals(
stripBillingEventId(b), stripBillingEventId(expectedBillingEvent)))
.findFirst();
assertThat(actualCreateBillingEvent).isPresent();
return Key.create(actualCreateBillingEvent.get());
}
@Test
public void testDomainDeletionWithSubordinateHost_fails() throws Exception {
assertThatLoginSucceeds("NewRegistrar", "foo-BAR2");

View file

@ -218,9 +218,9 @@ public class EppLifecycleHostTest extends EppTestCase {
DateTime timeAfterCreates = DateTime.parse("2000-06-01T00:06:00Z");
HostResource exampleBarFooTldHost =
loadByForeignKey(HostResource.class, "ns1.example.bar.foo.tld", timeAfterCreates);
loadByForeignKey(HostResource.class, "ns1.example.bar.foo.tld", timeAfterCreates).get();
DomainResource exampleBarFooTldDomain =
loadByForeignKey(DomainResource.class, "example.bar.foo.tld", timeAfterCreates);
loadByForeignKey(DomainResource.class, "example.bar.foo.tld", timeAfterCreates).get();
assertAboutHosts()
.that(exampleBarFooTldHost)
.hasSuperordinateDomain(Key.create(exampleBarFooTldDomain));
@ -228,18 +228,18 @@ public class EppLifecycleHostTest extends EppTestCase {
.containsExactly("ns1.example.bar.foo.tld");
HostResource exampleFooTldHost =
loadByForeignKey(HostResource.class, "ns1.example.foo.tld", timeAfterCreates);
loadByForeignKey(HostResource.class, "ns1.example.foo.tld", timeAfterCreates).get();
DomainResource exampleFooTldDomain =
loadByForeignKey(DomainResource.class, "example.foo.tld", timeAfterCreates);
loadByForeignKey(DomainResource.class, "example.foo.tld", timeAfterCreates).get();
assertAboutHosts()
.that(exampleFooTldHost)
.hasSuperordinateDomain(Key.create(exampleFooTldDomain));
assertThat(exampleFooTldDomain.getSubordinateHosts()).containsExactly("ns1.example.foo.tld");
HostResource exampleTldHost =
loadByForeignKey(HostResource.class, "ns1.example.tld", timeAfterCreates);
loadByForeignKey(HostResource.class, "ns1.example.tld", timeAfterCreates).get();
DomainResource exampleTldDomain =
loadByForeignKey(DomainResource.class, "example.tld", timeAfterCreates);
loadByForeignKey(DomainResource.class, "example.tld", timeAfterCreates).get();
assertAboutHosts().that(exampleTldHost).hasSuperordinateDomain(Key.create(exampleTldDomain));
assertThat(exampleTldDomain.getSubordinateHosts()).containsExactly("ns1.example.tld");

View file

@ -14,10 +14,9 @@
package google.registry.flows;
import static com.google.appengine.api.users.UserServiceFactory.getUserService;
import com.google.common.collect.ImmutableSetMultimap;
import google.registry.request.auth.AuthenticatedRegistrarAccessor;
import google.registry.testing.AppEngineRule;
import google.registry.testing.UserInfo;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@ -31,18 +30,16 @@ public class EppLoginAdminUserTest extends EppTestCase {
@Rule
public final AppEngineRule appEngine = AppEngineRule.builder()
.withDatastore()
.withUserService(UserInfo.createAdmin("someone@example.com", "12345"))
.build();
@Before
public void initTransportCredentials() {
setTransportCredentials(GaeUserCredentials.forCurrentUser(getUserService()));
}
@Test
public void testNonAuthedLogin_succeedsAsAdmin() throws Exception {
// Login succeeds even though this user isn't listed on the registrar.
assertThatLoginSucceeds("TheRegistrar", "password2");
setTransportCredentials(
new GaeUserCredentials(
AuthenticatedRegistrarAccessor.createForTesting(
ImmutableSetMultimap.of(
"TheRegistrar", AuthenticatedRegistrarAccessor.Role.ADMIN,
"NewRegistrar", AuthenticatedRegistrarAccessor.Role.ADMIN))));
}
@Test

View file

@ -33,15 +33,11 @@ import org.junit.runners.JUnit4;
@RunWith(JUnit4.class)
public class EppLoginTlsTest extends EppTestCase {
@Rule
public final AppEngineRule appEngine = AppEngineRule.builder()
.withDatastore()
.build();
@Rule public final AppEngineRule appEngine = AppEngineRule.builder().withDatastore().build();
void setClientCertificateHash(String clientCertificateHash) {
setTransportCredentials(
new TlsCredentials(clientCertificateHash, Optional.of("192.168.1.100:54321")));
new TlsCredentials(true, clientCertificateHash, Optional.of("192.168.1.100:54321")));
}
@Before
@ -160,7 +156,7 @@ public class EppLoginTlsTest extends EppTestCase {
}
@Test
public void testRegistrarHasNoCertificatesOnFile_disablesCertChecking() throws Exception {
public void testRegistrarHasNoCertificatesOnFile_fails() throws Exception {
setClientCertificateHash("laffo");
DateTime now = DateTime.now(UTC);
persistResource(
@ -169,6 +165,9 @@ public class EppLoginTlsTest extends EppTestCase {
.setClientCertificate(null, now)
.setFailoverClientCertificate(null, now)
.build());
assertThatLoginSucceeds("NewRegistrar", "foo-BAR2");
assertThatLogin("NewRegistrar", "foo-BAR2")
.hasResponse(
"response_error.xml",
ImmutableMap.of("CODE", "2200", "MSG", "Registrar certificate is not configured"));
}
}

View file

@ -14,16 +14,10 @@
package google.registry.flows;
import static com.google.appengine.api.users.UserServiceFactory.getUserService;
import static google.registry.testing.DatastoreHelper.loadRegistrar;
import static google.registry.testing.DatastoreHelper.persistResource;
import com.google.appengine.api.users.User;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import google.registry.model.registrar.RegistrarContact;
import com.google.common.collect.ImmutableSetMultimap;
import google.registry.request.auth.AuthenticatedRegistrarAccessor;
import google.registry.testing.AppEngineRule;
import google.registry.testing.UserInfo;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@ -37,20 +31,15 @@ public class EppLoginUserTest extends EppTestCase {
@Rule
public final AppEngineRule appEngine = AppEngineRule.builder()
.withDatastore()
.withUserService(UserInfo.create("user@example.com", "12345"))
.build();
@Before
public void initTest() {
User user = getUserService().getCurrentUser();
persistResource(
new RegistrarContact.Builder()
.setParent(loadRegistrar("NewRegistrar"))
.setEmailAddress(user.getEmail())
.setGaeUserId(user.getUserId())
.setTypes(ImmutableSet.of(RegistrarContact.Type.ADMIN))
.build());
setTransportCredentials(GaeUserCredentials.forCurrentUser(getUserService()));
setTransportCredentials(
new GaeUserCredentials(
AuthenticatedRegistrarAccessor.createForTesting(
ImmutableSetMultimap.of(
"NewRegistrar", AuthenticatedRegistrarAccessor.Role.OWNER))));
}
@Test
@ -66,7 +55,7 @@ public class EppLoginUserTest extends EppTestCase {
"response_error.xml",
ImmutableMap.of(
"CODE", "2200",
"MSG", "User id is not allowed to login as requested registrar: user@example.com"));
"MSG", "TestUserId doesn't have access to registrar TheRegistrar"));
}
@Test
@ -80,7 +69,7 @@ public class EppLoginUserTest extends EppTestCase {
"response_error.xml",
ImmutableMap.of(
"CODE", "2200",
"MSG", "User id is not allowed to login as requested registrar: user@example.com"));
"MSG", "TestUserId doesn't have access to registrar TheRegistrar"));
}
@Test

View file

@ -16,6 +16,8 @@ package google.registry.flows;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.testing.DatastoreHelper.getOnlyHistoryEntryOfType;
import static google.registry.testing.DatastoreHelper.stripBillingEventId;
import static google.registry.testing.TestDataHelper.loadFile;
import static google.registry.xml.XmlTestUtils.assertXmlEqualsWithMessage;
import static java.nio.charset.StandardCharsets.UTF_8;
@ -23,9 +25,21 @@ import static javax.servlet.http.HttpServletResponse.SC_OK;
import static org.joda.time.DateTimeZone.UTC;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.net.MediaType;
import com.google.common.truth.Truth8;
import com.googlecode.objectify.Key;
import google.registry.flows.EppTestComponent.FakesAndMocksModule;
import google.registry.model.billing.BillingEvent;
import google.registry.model.billing.BillingEvent.Flag;
import google.registry.model.billing.BillingEvent.OneTime;
import google.registry.model.billing.BillingEvent.Reason;
import google.registry.model.domain.DomainResource;
import google.registry.model.eppcommon.EppXmlTransformer;
import google.registry.model.ofy.Ofy;
import google.registry.model.registry.Registry;
import google.registry.model.reporting.HistoryEntry;
import google.registry.model.reporting.HistoryEntry.Type;
import google.registry.monitoring.whitebox.EppMetric;
import google.registry.testing.FakeClock;
import google.registry.testing.FakeHttpSession;
@ -33,7 +47,10 @@ import google.registry.testing.FakeResponse;
import google.registry.testing.InjectRule;
import google.registry.testing.ShardableTestCase;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import javax.annotation.Nullable;
import org.joda.money.Money;
import org.joda.time.DateTime;
import org.junit.Before;
import org.junit.Rule;
@ -46,7 +63,7 @@ public class EppTestCase extends ShardableTestCase {
@Rule
public final InjectRule inject = new InjectRule();
private final FakeClock clock = new FakeClock();
protected final FakeClock clock = new FakeClock();
private SessionMetadata sessionMetadata;
private TransportCredentials credentials = new PasswordOnlyTransportCredentials();
@ -75,7 +92,7 @@ public class EppTestCase extends ShardableTestCase {
this.isSuperuser = isSuperuser;
}
class CommandAsserter {
public class CommandAsserter {
private final String inputFilename;
private @Nullable final Map<String, String> inputSubstitutions;
private DateTime now;
@ -87,44 +104,44 @@ public class EppTestCase extends ShardableTestCase {
this.now = DateTime.now(UTC);
}
CommandAsserter atTime(DateTime now) {
public CommandAsserter atTime(DateTime now) {
this.now = now;
return this;
}
CommandAsserter atTime(String now) {
public CommandAsserter atTime(String now) {
return atTime(DateTime.parse(now));
}
String hasResponse(String outputFilename) throws Exception {
public String hasResponse(String outputFilename) throws Exception {
return hasResponse(outputFilename, null);
}
String hasResponse(String outputFilename, @Nullable Map<String, String> outputSubstitutions)
throws Exception {
public String hasResponse(
String outputFilename, @Nullable Map<String, String> outputSubstitutions) throws Exception {
return assertCommandAndResponse(
inputFilename, inputSubstitutions, outputFilename, outputSubstitutions, now);
}
}
CommandAsserter assertThatCommand(String inputFilename) {
protected CommandAsserter assertThatCommand(String inputFilename) {
return assertThatCommand(inputFilename, null);
}
CommandAsserter assertThatCommand(
protected CommandAsserter assertThatCommand(
String inputFilename, @Nullable Map<String, String> inputSubstitutions) {
return new CommandAsserter(inputFilename, inputSubstitutions);
}
CommandAsserter assertThatLogin(String clientId, String password) {
protected CommandAsserter assertThatLogin(String clientId, String password) {
return assertThatCommand("login.xml", ImmutableMap.of("CLID", clientId, "PW", password));
}
void assertThatLoginSucceeds(String clientId, String password) throws Exception {
protected void assertThatLoginSucceeds(String clientId, String password) throws Exception {
assertThatLogin(clientId, password).hasResponse("generic_success_response.xml");
}
void assertThatLogoutSucceeds() throws Exception {
protected void assertThatLogoutSucceeds() throws Exception {
assertThatCommand("logout.xml").hasResponse("logout_response.xml");
}
@ -136,8 +153,8 @@ public class EppTestCase extends ShardableTestCase {
DateTime now)
throws Exception {
clock.setTo(now);
String input = loadFile(getClass(), inputFilename, inputSubstitutions);
String expectedOutput = loadFile(getClass(), outputFilename, outputSubstitutions);
String input = loadFile(EppTestCase.class, inputFilename, inputSubstitutions);
String expectedOutput = loadFile(EppTestCase.class, outputFilename, outputSubstitutions);
if (sessionMetadata == null) {
sessionMetadata =
new HttpSessionMetadata(new FakeHttpSession()) {
@ -188,4 +205,150 @@ public class EppTestCase extends ShardableTestCase {
protected EppMetric getRecordedEppMetric() {
return eppMetricBuilder.build();
}
/** Create the two administrative contacts and two hosts. */
protected void createContactsAndHosts() throws Exception {
DateTime createTime = DateTime.parse("2000-06-01T00:00:00Z");
createContacts(createTime);
assertThatCommand("host_create.xml", ImmutableMap.of("HOSTNAME", "ns1.example.external"))
.atTime(createTime.plusMinutes(2))
.hasResponse(
"host_create_response.xml",
ImmutableMap.of(
"HOSTNAME", "ns1.example.external",
"CRDATE", createTime.plusMinutes(2).toString()));
assertThatCommand("host_create.xml", ImmutableMap.of("HOSTNAME", "ns2.example.external"))
.atTime(createTime.plusMinutes(3))
.hasResponse(
"host_create_response.xml",
ImmutableMap.of(
"HOSTNAME", "ns2.example.external",
"CRDATE", createTime.plusMinutes(3).toString()));
}
protected void createContacts(DateTime createTime) throws Exception {
assertThatCommand("contact_create_sh8013.xml")
.atTime(createTime)
.hasResponse(
"contact_create_response_sh8013.xml", ImmutableMap.of("CRDATE", createTime.toString()));
assertThatCommand("contact_create_jd1234.xml")
.atTime(createTime.plusMinutes(1))
.hasResponse(
"contact_create_response_jd1234.xml",
ImmutableMap.of("CRDATE", createTime.plusMinutes(1).toString()));
}
/** Creates the domain fakesite.example with two nameservers on it. */
protected void createFakesite() throws Exception {
createContactsAndHosts();
assertThatCommand("domain_create_fakesite.xml")
.atTime("2000-06-01T00:04:00Z")
.hasResponse(
"domain_create_response.xml",
ImmutableMap.of(
"DOMAIN", "fakesite.example",
"CRDATE", "2000-06-01T00:04:00.0Z",
"EXDATE", "2002-06-01T00:04:00.0Z"));
assertThatCommand("domain_info_fakesite.xml")
.atTime("2000-06-06T00:00:00Z")
.hasResponse("domain_info_response_fakesite_ok.xml");
}
/** Creates ns3.fakesite.example as a host, then adds it to fakesite. */
protected void createSubordinateHost() throws Exception {
// Add the fakesite nameserver (requires that domain is already created).
assertThatCommand("host_create_fakesite.xml")
.atTime("2000-06-06T00:01:00Z")
.hasResponse("host_create_response_fakesite.xml");
// Add new nameserver to domain.
assertThatCommand("domain_update_add_nameserver_fakesite.xml")
.atTime("2000-06-08T00:00:00Z")
.hasResponse("generic_success_response.xml");
// Verify new nameserver was added.
assertThatCommand("domain_info_fakesite.xml")
.atTime("2000-06-08T00:01:00Z")
.hasResponse("domain_info_response_fakesite_3_nameservers.xml");
// Verify that nameserver's data was set correctly.
assertThatCommand("host_info_fakesite.xml")
.atTime("2000-06-08T00:02:00Z")
.hasResponse("host_info_response_fakesite_linked.xml");
}
/** Makes a one-time billing event corresponding to the given domain's creation. */
protected static BillingEvent.OneTime makeOneTimeCreateBillingEvent(
DomainResource domain, DateTime createTime) {
return new BillingEvent.OneTime.Builder()
.setReason(Reason.CREATE)
.setTargetId(domain.getFullyQualifiedDomainName())
.setClientId(domain.getCurrentSponsorClientId())
.setCost(Money.parse("USD 26.00"))
.setPeriodYears(2)
.setEventTime(createTime)
.setBillingTime(createTime.plus(Registry.get(domain.getTld()).getRenewGracePeriodLength()))
.setParent(getOnlyHistoryEntryOfType(domain, Type.DOMAIN_CREATE))
.build();
}
/** Makes a recurring billing event corresponding to the given domain's creation. */
protected static BillingEvent.Recurring makeRecurringCreateBillingEvent(
DomainResource domain, DateTime eventTime, DateTime endTime) {
return makeRecurringCreateBillingEvent(
domain, getOnlyHistoryEntryOfType(domain, Type.DOMAIN_CREATE), eventTime, endTime);
}
/** Makes a recurring billing event corresponding to the given history entry. */
protected static BillingEvent.Recurring makeRecurringCreateBillingEvent(
DomainResource domain, HistoryEntry historyEntry, DateTime eventTime, DateTime endTime) {
return new BillingEvent.Recurring.Builder()
.setReason(Reason.RENEW)
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
.setTargetId(domain.getFullyQualifiedDomainName())
.setClientId(domain.getCurrentSponsorClientId())
.setEventTime(eventTime)
.setRecurrenceEndTime(endTime)
.setParent(historyEntry)
.build();
}
/** Makes a cancellation billing event cancelling out the given domain create billing event. */
protected static BillingEvent.Cancellation makeCancellationBillingEventFor(
DomainResource domain,
OneTime billingEventToCancel,
DateTime createTime,
DateTime deleteTime) {
return new BillingEvent.Cancellation.Builder()
.setTargetId(domain.getFullyQualifiedDomainName())
.setClientId(domain.getCurrentSponsorClientId())
.setEventTime(deleteTime)
.setOneTimeEventKey(findKeyToActualOneTimeBillingEvent(billingEventToCancel))
.setBillingTime(createTime.plus(Registry.get(domain.getTld()).getRenewGracePeriodLength()))
.setReason(Reason.CREATE)
.setParent(getOnlyHistoryEntryOfType(domain, Type.DOMAIN_DELETE))
.build();
}
/**
* Finds the Key to the actual one-time create billing event associated with a domain's creation.
*
* <p>This is used in the situation where we have created an expected billing event associated
* with the domain's creation (which is passed as the parameter here), then need to locate the key
* to the actual billing event in Datastore that would be seen on a Cancellation billing event.
* This is necessary because the ID will be different even though all the rest of the fields are
* the same.
*/
protected static Key<OneTime> findKeyToActualOneTimeBillingEvent(OneTime expectedBillingEvent) {
Optional<OneTime> actualCreateBillingEvent =
ofy()
.load()
.type(BillingEvent.OneTime.class)
.list()
.stream()
.filter(
b ->
Objects.equals(
stripBillingEventId(b), stripBillingEventId(expectedBillingEvent)))
.findFirst();
Truth8.assertThat(actualCreateBillingEvent).isPresent();
return Key.create(actualCreateBillingEvent.get());
}
}

View file

@ -21,10 +21,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/**
* Tests for XXE attacks.
*
*/
/** Tests for <a href="https://en.wikipedia.org/wiki/XML_external_entity_attack">XXE</a> attacks. */
@RunWith(JUnit4.class)
public class EppXxeAttackTest extends EppTestCase {

View file

@ -23,16 +23,17 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import com.google.appengine.api.users.User;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.flogger.LoggerConfig;
import com.google.common.testing.TestLogHandler;
import google.registry.model.eppcommon.Trid;
import google.registry.model.eppoutput.EppOutput.ResponseOrGreeting;
import google.registry.model.eppoutput.EppResponse;
import google.registry.monitoring.whitebox.EppMetric;
import google.registry.request.auth.AuthenticatedRegistrarAccessor;
import google.registry.testing.AppEngineRule;
import google.registry.testing.FakeClock;
import google.registry.testing.FakeHttpSession;
@ -142,15 +143,16 @@ public class FlowRunnerTest extends ShardableTestCase {
@Test
public void testRun_loggingStatement_gaeUserCredentials() throws Exception {
flowRunner.credentials =
GaeUserCredentials.forTestingUser(new User("user@example.com", "authDomain"), false);
new GaeUserCredentials(AuthenticatedRegistrarAccessor.createForTesting(
ImmutableSetMultimap.of()));
flowRunner.run(eppMetricBuilder);
assertThat(Splitter.on("\n\t").split(findFirstLogMessageByPrefix(handler, "EPP Command\n\t")))
.contains("GaeUserCredentials{gaeUser=user@example.com, isAdmin=false}");
assertThat(findFirstLogMessageByPrefix(handler, "EPP Command\n\t"))
.contains("user=TestUserId");
}
@Test
public void testRun_loggingStatement_tlsCredentials() throws Exception {
flowRunner.credentials = new TlsCredentials("abc123def", Optional.of("127.0.0.1"));
flowRunner.credentials = new TlsCredentials(true, "abc123def", Optional.of("127.0.0.1"));
flowRunner.run(eppMetricBuilder);
assertThat(Splitter.on("\n\t").split(findFirstLogMessageByPrefix(handler, "EPP Command\n\t")))
.contains("TlsCredentials{clientCertificateHash=abc123def, clientAddress=/127.0.0.1}");

View file

@ -19,7 +19,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.collect.Sets.difference;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.flows.EppXmlTransformer.marshal;
import static google.registry.model.eppcommon.EppXmlTransformer.marshal;
import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.testing.DatastoreHelper.POLL_MESSAGE_ID_STRIPPER;
import static google.registry.testing.DatastoreHelper.getPollMessages;

View file

@ -17,6 +17,7 @@ package google.registry.flows;
import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.model.EppResourceUtils.loadByForeignKey;
import static google.registry.model.EppResourceUtils.loadDomainApplication;
import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.model.tmch.ClaimsListShardTest.createTestClaimsListShard;
import static google.registry.testing.EppExceptionSubject.assertAboutEppExceptions;
@ -32,7 +33,6 @@ import com.google.common.testing.TestLogHandler;
import com.googlecode.objectify.Key;
import google.registry.flows.FlowUtils.NotLoggedInException;
import google.registry.model.EppResource;
import google.registry.model.EppResourceUtils;
import google.registry.model.domain.DomainApplication;
import google.registry.model.domain.launch.ApplicationIdTargetExtension;
import google.registry.model.eppcommon.Trid;
@ -46,6 +46,7 @@ import google.registry.testing.TaskQueueHelper.TaskMatcher;
import google.registry.util.TypeUtils.TypeInstantiator;
import java.util.Optional;
import java.util.logging.Level;
import javax.annotation.Nullable;
import org.joda.time.DateTime;
import org.joda.time.Duration;
import org.json.simple.JSONValue;
@ -71,20 +72,22 @@ public abstract class ResourceFlowTestCase<F extends Flow, R extends EppResource
LoggerConfig.getConfig("").addHandler(logHandler);
}
@Nullable
protected R reloadResourceByForeignKey(DateTime now) throws Exception {
// Force the session to be cleared so that when we read it back, we read from Datastore and not
// from the transaction's session cache.
ofy().clearSessionCache();
return loadByForeignKey(getResourceClass(), getUniqueIdFromCommand(), now);
return loadByForeignKey(getResourceClass(), getUniqueIdFromCommand(), now).orElse(null);
}
@Nullable
protected R reloadResourceByForeignKey() throws Exception {
return reloadResourceByForeignKey(clock.nowUtc());
}
protected DomainApplication reloadDomainApplication() throws Exception {
ofy().clearSessionCache();
return EppResourceUtils.loadDomainApplication(getUniqueIdFromCommand(), clock.nowUtc());
return loadDomainApplication(getUniqueIdFromCommand(), clock.nowUtc()).get();
}
protected <T extends EppResource> T reloadResourceAndCloneAtTime(T resource, DateTime now) {

View file

@ -15,19 +15,31 @@
package google.registry.flows;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.testing.DatastoreHelper.loadRegistrar;
import static google.registry.testing.DatastoreHelper.persistResource;
import static google.registry.testing.JUnitBackports.assertThrows;
import static org.joda.time.DateTimeZone.UTC;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import google.registry.model.registrar.Registrar;
import google.registry.request.HttpException.BadRequestException;
import google.registry.testing.AppEngineRule;
import google.registry.testing.ShardableTestCase;
import java.util.Optional;
import javax.servlet.http.HttpServletRequest;
import org.joda.time.DateTime;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/** Unit tests for {@link TlsCredentials}. */
@RunWith(JUnit4.class)
public final class TlsCredentialsTest {
public final class TlsCredentialsTest extends ShardableTestCase {
@Rule public final AppEngineRule appEngine = AppEngineRule.builder().withDatastore().build();
@Test
public void testProvideClientCertificateHash() {
HttpServletRequest req = mock(HttpServletRequest.class);
@ -46,8 +58,15 @@ public final class TlsCredentialsTest {
}
@Test
public void testNothing1() {}
@Test
public void testNothing2() {}
public void test_validateCertificate_canBeConfiguredToBypassCertHashes() throws Exception {
TlsCredentials tls = new TlsCredentials(false, "certHash", Optional.of("192.168.1.1"));
persistResource(
loadRegistrar("TheRegistrar")
.asBuilder()
.setClientCertificate(null, DateTime.now(UTC))
.setFailoverClientCertificate(null, DateTime.now(UTC))
.build());
// This would throw a RegistrarCertificateNotConfiguredException if cert hashes wren't bypassed.
tls.validateCertificate(Registrar.loadByClientId("TheRegistrar").get());
}
}

View file

@ -150,7 +150,7 @@ public class DomainAllocateFlowTest
boolean sunrushAddGracePeriod = (nameservers == 0);
// The application should be marked as allocated, with a new history entry.
DomainApplication application = loadDomainApplication(applicationId, clock.nowUtc());
DomainApplication application = loadDomainApplication(applicationId, clock.nowUtc()).get();
assertAboutApplications().that(application)
.hasApplicationStatus(ApplicationStatus.ALLOCATED).and()
.hasHistoryEntryAtIndex(0)

View file

@ -100,7 +100,7 @@ import google.registry.flows.domain.DomainFlowUtils.NameserversNotSpecifiedForTl
import google.registry.flows.domain.DomainFlowUtils.NotAuthorizedForTldException;
import google.registry.flows.domain.DomainFlowUtils.PremiumNameBlockedException;
import google.registry.flows.domain.DomainFlowUtils.RegistrantNotAllowedException;
import google.registry.flows.domain.DomainFlowUtils.RegistrarMustBeActiveToCreateDomainsException;
import google.registry.flows.domain.DomainFlowUtils.RegistrarMustBeActiveForThisOperationException;
import google.registry.flows.domain.DomainFlowUtils.TldDoesNotExistException;
import google.registry.flows.domain.DomainFlowUtils.TooManyDsRecordsException;
import google.registry.flows.domain.DomainFlowUtils.TooManyNameserversException;
@ -771,7 +771,24 @@ public class DomainApplicationCreateFlowTest
.build());
clock.advanceOneMilli();
EppException thrown =
assertThrows(RegistrarMustBeActiveToCreateDomainsException.class, this::runFlow);
assertThrows(RegistrarMustBeActiveForThisOperationException.class, this::runFlow);
assertAboutEppExceptions().that(thrown).marshalsToXml();
}
@Test
public void testFailure_pendingRegistrarCantCreateDomainApplication() {
setEppInput("domain_create_sunrise_encoded_signed_mark.xml");
persistContactsAndHosts();
clock.advanceOneMilli();
persistResource(
Registrar.loadByClientId("TheRegistrar")
.get()
.asBuilder()
.setState(State.PENDING)
.build());
clock.advanceOneMilli();
EppException thrown =
assertThrows(RegistrarMustBeActiveForThisOperationException.class, this::runFlow);
assertAboutEppExceptions().that(thrown).marshalsToXml();
}

View file

@ -15,8 +15,10 @@
package google.registry.flows.domain;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;
import static google.registry.model.EppResourceUtils.isLinked;
import static google.registry.model.EppResourceUtils.loadByForeignKey;
import static google.registry.model.EppResourceUtils.loadDomainApplication;
import static google.registry.model.index.ForeignKeyIndex.loadAndGetKey;
import static google.registry.testing.DatastoreHelper.assertNoBillingEvents;
import static google.registry.testing.DatastoreHelper.createTld;
@ -72,7 +74,7 @@ public class DomainApplicationDeleteFlowTest
clock.advanceOneMilli();
runFlowAssertResponse(loadFile("generic_success_response.xml"));
// Check that the domain is fully deleted.
assertThat(reloadDomainApplication()).isNull();
assertThat(loadDomainApplication(getUniqueIdFromCommand(), clock.nowUtc())).isEmpty();
assertNoBillingEvents();
}
@ -93,11 +95,10 @@ public class DomainApplicationDeleteFlowTest
.asBuilder()
.setRepoId("1-TLD")
.setRegistrant(
Key.create(loadByForeignKey(ContactResource.class, "sh8013", clock.nowUtc())))
Key.create(loadByForeignKey(ContactResource.class, "sh8013", clock.nowUtc()).get()))
.setNameservers(
ImmutableSet.of(
Key.create(
loadByForeignKey(HostResource.class, "ns1.example.net", clock.nowUtc()))))
Key.create(
loadByForeignKey(HostResource.class, "ns1.example.net", clock.nowUtc()).get()))
.build());
doSuccessfulTest();
for (Key<? extends EppResource> key :

View file

@ -112,16 +112,15 @@ public class DomainApplicationUpdateFlowTest
}
private DomainApplication persistApplication() {
HostResource host =
loadByForeignKey(HostResource.class, "ns1.example.tld", clock.nowUtc()).get();
return persistResource(
newApplicationBuilder()
.setContacts(
ImmutableSet.of(
DesignatedContact.create(Type.TECH, Key.create(sh8013Contact)),
DesignatedContact.create(Type.ADMIN, Key.create(unusedContact))))
.setNameservers(
ImmutableSet.of(
Key.create(
loadByForeignKey(HostResource.class, "ns1.example.tld", clock.nowUtc()))))
.setNameservers(ImmutableSet.of(Key.create(host)))
.build());
}
@ -184,7 +183,8 @@ public class DomainApplicationUpdateFlowTest
public void testSuccess_registrantMovedToTechContact() throws Exception {
setEppInput("domain_update_sunrise_registrant_to_tech.xml");
persistReferencedEntities();
ContactResource sh8013 = loadByForeignKey(ContactResource.class, "sh8013", clock.nowUtc());
ContactResource sh8013 =
loadByForeignKey(ContactResource.class, "sh8013", clock.nowUtc()).get();
persistResource(newApplicationBuilder().setRegistrant(Key.create(sh8013)).build());
clock.advanceOneMilli();
runFlowAssertResponse(loadFile("generic_success_response.xml"));
@ -194,7 +194,8 @@ public class DomainApplicationUpdateFlowTest
public void testSuccess_multipleReferencesToSameContactRemoved() throws Exception {
setEppInput("domain_update_sunrise_remove_multiple_contacts.xml");
persistReferencedEntities();
ContactResource sh8013 = loadByForeignKey(ContactResource.class, "sh8013", clock.nowUtc());
ContactResource sh8013 =
loadByForeignKey(ContactResource.class, "sh8013", clock.nowUtc()).get();
Key<ContactResource> sh8013Key = Key.create(sh8013);
persistResource(
newApplicationBuilder()
@ -411,7 +412,8 @@ public class DomainApplicationUpdateFlowTest
nameservers.add(
Key.create(
loadByForeignKey(
HostResource.class, String.format("ns%d.example.tld", i), clock.nowUtc())));
HostResource.class, String.format("ns%d.example.tld", i), clock.nowUtc())
.get()));
}
}
persistResource(
@ -546,7 +548,7 @@ public class DomainApplicationUpdateFlowTest
DesignatedContact.create(
Type.TECH,
Key.create(
loadByForeignKey(ContactResource.class, "foo", clock.nowUtc())))))
loadByForeignKey(ContactResource.class, "foo", clock.nowUtc()).get()))))
.build());
EppException thrown = assertThrows(DuplicateContactForRoleException.class, this::runFlow);
assertAboutEppExceptions().that(thrown).marshalsToXml();
@ -639,7 +641,8 @@ public class DomainApplicationUpdateFlowTest
.setNameservers(
ImmutableSet.of(
Key.create(
loadByForeignKey(HostResource.class, "ns1.example.tld", clock.nowUtc()))))
loadByForeignKey(HostResource.class, "ns1.example.tld", clock.nowUtc())
.get())))
.build());
EppException thrown = assertThrows(AddRemoveSameValueException.class, this::runFlow);
assertAboutEppExceptions().that(thrown).marshalsToXml();
@ -656,7 +659,8 @@ public class DomainApplicationUpdateFlowTest
DesignatedContact.create(
Type.TECH,
Key.create(
loadByForeignKey(ContactResource.class, "sh8013", clock.nowUtc())))))
loadByForeignKey(ContactResource.class, "sh8013", clock.nowUtc())
.get()))))
.build());
EppException thrown = assertThrows(AddRemoveSameValueException.class, this::runFlow);
assertAboutEppExceptions().that(thrown).marshalsToXml();
@ -759,10 +763,9 @@ public class DomainApplicationUpdateFlowTest
persistResource(
reloadDomainApplication()
.asBuilder()
.addNameservers(
ImmutableSet.of(
Key.create(
loadByForeignKey(HostResource.class, "ns2.example.tld", clock.nowUtc()))))
.addNameserver(
Key.create(
loadByForeignKey(HostResource.class, "ns2.example.tld", clock.nowUtc()).get()))
.build());
persistResource(
Registry.get("tld")
@ -833,10 +836,9 @@ public class DomainApplicationUpdateFlowTest
persistResource(
reloadDomainApplication()
.asBuilder()
.addNameservers(
ImmutableSet.of(
Key.create(
loadByForeignKey(HostResource.class, "ns2.example.tld", clock.nowUtc()))))
.addNameserver(
Key.create(
loadByForeignKey(HostResource.class, "ns2.example.tld", clock.nowUtc()).get()))
.build());
persistResource(
Registry.get("tld")

View file

@ -121,7 +121,7 @@ import google.registry.flows.domain.DomainFlowUtils.NameserversNotSpecifiedForTl
import google.registry.flows.domain.DomainFlowUtils.NotAuthorizedForTldException;
import google.registry.flows.domain.DomainFlowUtils.PremiumNameBlockedException;
import google.registry.flows.domain.DomainFlowUtils.RegistrantNotAllowedException;
import google.registry.flows.domain.DomainFlowUtils.RegistrarMustBeActiveToCreateDomainsException;
import google.registry.flows.domain.DomainFlowUtils.RegistrarMustBeActiveForThisOperationException;
import google.registry.flows.domain.DomainFlowUtils.TldDoesNotExistException;
import google.registry.flows.domain.DomainFlowUtils.TooManyDsRecordsException;
import google.registry.flows.domain.DomainFlowUtils.TooManyNameserversException;
@ -1618,7 +1618,21 @@ public class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow,
.setState(State.SUSPENDED)
.build());
EppException thrown =
assertThrows(RegistrarMustBeActiveToCreateDomainsException.class, this::runFlow);
assertThrows(RegistrarMustBeActiveForThisOperationException.class, this::runFlow);
assertAboutEppExceptions().that(thrown).marshalsToXml();
}
@Test
public void testFailure_pendingRegistrarCantCreateDomain() {
persistContactsAndHosts();
persistResource(
Registrar.loadByClientId("TheRegistrar")
.get()
.asBuilder()
.setState(State.PENDING)
.build());
EppException thrown =
assertThrows(RegistrarMustBeActiveForThisOperationException.class, this::runFlow);
assertAboutEppExceptions().that(thrown).marshalsToXml();
}

View file

@ -327,6 +327,30 @@ public class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow,
assertThat(getPollMessages("TheRegistrar", A_MONTH_FROM_NOW)).isEmpty();
}
@Test
public void testSuccess_updatedEppUpdateTimeAfterPendingRedemption() throws Exception {
persistResource(
Registry.get("tld")
.asBuilder()
.setRedemptionGracePeriodLength(standardDays(3))
.setPendingDeleteLength(standardDays(2))
.build());
setClientIdForFlow("TheRegistrar");
setUpSuccessfulTest();
clock.advanceOneMilli();
runFlowAssertResponse(loadFile("domain_delete_response_pending.xml"));
DomainResource domain = reloadResourceByForeignKey();
DateTime redemptionEndTime = domain.getLastEppUpdateTime().plusDays(3);
DomainResource domainAtRedemptionTime = domain.cloneProjectedAtTime(redemptionEndTime);
assertAboutDomains()
.that(domainAtRedemptionTime)
.hasLastEppUpdateClientId("TheRegistrar")
.and()
.hasLastEppUpdateTime(redemptionEndTime);
}
@Test
public void testSuccess_addGracePeriodResultsInImmediateDelete() throws Exception {
sessionMetadata.setServiceExtensionUris(ImmutableSet.of());
@ -668,6 +692,7 @@ public class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow,
HostResource host = persistResource(newHostResource("ns1.example.tld"));
persistResource(
loadByForeignKey(DomainResource.class, getUniqueIdFromCommand(), clock.nowUtc())
.get()
.asBuilder()
.setNameservers(ImmutableSet.of(Key.create(host)))
.build());
@ -676,7 +701,7 @@ public class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow,
newDomainResource("example1.tld")
.asBuilder()
.setRegistrant(
Key.create(loadByForeignKey(ContactResource.class, "sh8013", clock.nowUtc())))
Key.create(loadByForeignKey(ContactResource.class, "sh8013", clock.nowUtc()).get()))
.setNameservers(ImmutableSet.of(Key.create(host)))
.setDeletionTime(START_OF_TIME)
.build());
@ -834,7 +859,11 @@ public class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow,
runFlow();
assertAboutDomains()
.that(reloadResourceByForeignKey())
.hasOneHistoryEntryEachOfTypes(DOMAIN_CREATE, DOMAIN_DELETE);
.hasOneHistoryEntryEachOfTypes(DOMAIN_CREATE, DOMAIN_DELETE)
.and()
.hasLastEppUpdateTime(clock.nowUtc())
.and()
.hasLastEppUpdateClientId("TheRegistrar");
assertAboutHistoryEntries()
.that(getOnlyHistoryEntryOfType(domain, DOMAIN_DELETE))
.hasType(DOMAIN_DELETE)

View file

@ -49,6 +49,7 @@ import google.registry.flows.domain.DomainFlowUtils.ExceedsMaxRegistrationYearsE
import google.registry.flows.domain.DomainFlowUtils.FeesMismatchException;
import google.registry.flows.domain.DomainFlowUtils.FeesRequiredForPremiumNameException;
import google.registry.flows.domain.DomainFlowUtils.NotAuthorizedForTldException;
import google.registry.flows.domain.DomainFlowUtils.RegistrarMustBeActiveForThisOperationException;
import google.registry.flows.domain.DomainFlowUtils.UnsupportedFeeAttributeException;
import google.registry.flows.domain.DomainRenewFlow.IncorrectCurrentExpirationDateException;
import google.registry.flows.exceptions.ResourceStatusProhibitsOperationException;
@ -60,6 +61,8 @@ import google.registry.model.domain.GracePeriod;
import google.registry.model.domain.rgp.GracePeriodStatus;
import google.registry.model.eppcommon.StatusValue;
import google.registry.model.poll.PollMessage;
import google.registry.model.registrar.Registrar;
import google.registry.model.registrar.Registrar.State;
import google.registry.model.registry.Registry;
import google.registry.model.reporting.DomainTransactionRecord;
import google.registry.model.reporting.DomainTransactionRecord.TransactionReportField;
@ -166,7 +169,11 @@ public class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, D
.hasRegistrationExpirationTime(newExpiration)
.and()
.hasOneHistoryEntryEachOfTypes(
HistoryEntry.Type.DOMAIN_CREATE, HistoryEntry.Type.DOMAIN_RENEW);
HistoryEntry.Type.DOMAIN_CREATE, HistoryEntry.Type.DOMAIN_RENEW)
.and()
.hasLastEppUpdateTime(clock.nowUtc())
.and()
.hasLastEppUpdateClientId("TheRegistrar");
assertAboutHistoryEntries().that(historyEntryDomainRenew).hasPeriodYears(renewalYears);
BillingEvent.OneTime renewBillingEvent =
new BillingEvent.OneTime.Builder()
@ -374,6 +381,32 @@ public class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, D
assertAboutEppExceptions().that(thrown).marshalsToXml();
}
@Test
public void testFailure_suspendedRegistrarCantRenewDomain() {
persistResource(
Registrar.loadByClientId("TheRegistrar")
.get()
.asBuilder()
.setState(State.SUSPENDED)
.build());
EppException thrown =
assertThrows(RegistrarMustBeActiveForThisOperationException.class, this::runFlow);
assertAboutEppExceptions().that(thrown).marshalsToXml();
}
@Test
public void testFailure_pendingRegistrarCantRenewDomain() {
persistResource(
Registrar.loadByClientId("TheRegistrar")
.get()
.asBuilder()
.setState(State.PENDING)
.build());
EppException thrown =
assertThrows(RegistrarMustBeActiveForThisOperationException.class, this::runFlow);
assertAboutEppExceptions().that(thrown).marshalsToXml();
}
@Test
public void testSuccess_nonDefaultRenewGracePeriod() throws Exception {
persistResource(

View file

@ -51,6 +51,7 @@ import google.registry.flows.domain.DomainFlowUtils.FeesMismatchException;
import google.registry.flows.domain.DomainFlowUtils.FeesRequiredForPremiumNameException;
import google.registry.flows.domain.DomainFlowUtils.NotAuthorizedForTldException;
import google.registry.flows.domain.DomainFlowUtils.PremiumNameBlockedException;
import google.registry.flows.domain.DomainFlowUtils.RegistrarMustBeActiveForThisOperationException;
import google.registry.flows.domain.DomainFlowUtils.UnsupportedFeeAttributeException;
import google.registry.flows.domain.DomainRestoreRequestFlow.DomainNotEligibleForRestoreException;
import google.registry.flows.domain.DomainRestoreRequestFlow.RestoreCommandIncludesChangesException;
@ -62,6 +63,8 @@ import google.registry.model.domain.GracePeriod;
import google.registry.model.domain.rgp.GracePeriodStatus;
import google.registry.model.eppcommon.StatusValue;
import google.registry.model.poll.PollMessage;
import google.registry.model.registrar.Registrar;
import google.registry.model.registrar.Registrar.State;
import google.registry.model.registry.Registry;
import google.registry.model.reporting.DomainTransactionRecord;
import google.registry.model.reporting.DomainTransactionRecord.TransactionReportField;
@ -148,7 +151,11 @@ public class DomainRestoreRequestFlowTest
.hasDeletionTime(END_OF_TIME)
.and()
.hasOneHistoryEntryEachOfTypes(
HistoryEntry.Type.DOMAIN_DELETE, HistoryEntry.Type.DOMAIN_RESTORE);
HistoryEntry.Type.DOMAIN_DELETE, HistoryEntry.Type.DOMAIN_RESTORE)
.and()
.hasLastEppUpdateTime(clock.nowUtc())
.and()
.hasLastEppUpdateClientId("TheRegistrar");
assertThat(domain.getGracePeriods()).isEmpty();
assertDnsTasksEnqueued("example.tld");
// The poll message for the delete should now be gone. The only poll message should be the new
@ -349,6 +356,33 @@ public class DomainRestoreRequestFlowTest
ResourceDoesNotExistException thrown =
assertThrows(ResourceDoesNotExistException.class, this::runFlow);
assertThat(thrown).hasMessageThat().contains(String.format("(%s)", getUniqueIdFromCommand()));
assertAboutEppExceptions().that(thrown).marshalsToXml();
}
@Test
public void testFailure_suspendedRegistrarCantRestoreDomain() {
persistResource(
Registrar.loadByClientId("TheRegistrar")
.get()
.asBuilder()
.setState(State.SUSPENDED)
.build());
EppException thrown =
assertThrows(RegistrarMustBeActiveForThisOperationException.class, this::runFlow);
assertAboutEppExceptions().that(thrown).marshalsToXml();
}
@Test
public void testFailure_pendingRegistrarCantRestoreDomain() {
persistResource(
Registrar.loadByClientId("TheRegistrar")
.get()
.asBuilder()
.setState(State.PENDING)
.build());
EppException thrown =
assertThrows(RegistrarMustBeActiveForThisOperationException.class, this::runFlow);
assertAboutEppExceptions().that(thrown).marshalsToXml();
}
@Test

View file

@ -115,7 +115,11 @@ public class DomainTransferApproveFlowTest
.and()
.hasLastTransferTime(clock.nowUtc())
.and()
.doesNotHaveStatusValue(StatusValue.PENDING_TRANSFER);
.doesNotHaveStatusValue(StatusValue.PENDING_TRANSFER)
.and()
.hasLastEppUpdateTime(clock.nowUtc())
.and()
.hasLastEppUpdateClientId("TheRegistrar");
// The domain TransferData should reflect the approved transfer as we expect, with
// all the speculative server-approve fields nulled out.
assertThat(domain.getTransferData())

View file

@ -133,7 +133,11 @@ public class DomainTransferCancelFlowTest
assertAboutDomains()
.that(domain)
.hasOneHistoryEntryEachOfTypes(
DOMAIN_CREATE, DOMAIN_TRANSFER_REQUEST, DOMAIN_TRANSFER_CANCEL);
DOMAIN_CREATE, DOMAIN_TRANSFER_REQUEST, DOMAIN_TRANSFER_CANCEL)
.and()
.hasLastEppUpdateTime(clock.nowUtc())
.and()
.hasLastEppUpdateClientId("NewRegistrar");
final HistoryEntry historyEntryTransferCancel =
getOnlyHistoryEntryOfType(domain, DOMAIN_TRANSFER_CANCEL);
assertAboutHistoryEntries()

View file

@ -102,7 +102,11 @@ public class DomainTransferRejectFlowTest
.hasLastTransferTimeNotEqualTo(clock.nowUtc())
.and()
.hasOneHistoryEntryEachOfTypes(
DOMAIN_CREATE, DOMAIN_TRANSFER_REQUEST, DOMAIN_TRANSFER_REJECT);
DOMAIN_CREATE, DOMAIN_TRANSFER_REQUEST, DOMAIN_TRANSFER_REJECT)
.and()
.hasLastEppUpdateTime(clock.nowUtc())
.and()
.hasLastEppUpdateClientId("TheRegistrar");
final HistoryEntry historyEntryTransferRejected =
getOnlyHistoryEntryOfType(domain, DOMAIN_TRANSFER_REJECT);
assertAboutHistoryEntries().that(historyEntryTransferRejected).hasOtherClientId("NewRegistrar");

View file

@ -67,6 +67,7 @@ import google.registry.flows.domain.DomainFlowUtils.FeesMismatchException;
import google.registry.flows.domain.DomainFlowUtils.FeesRequiredForPremiumNameException;
import google.registry.flows.domain.DomainFlowUtils.NotAuthorizedForTldException;
import google.registry.flows.domain.DomainFlowUtils.PremiumNameBlockedException;
import google.registry.flows.domain.DomainFlowUtils.RegistrarMustBeActiveForThisOperationException;
import google.registry.flows.domain.DomainFlowUtils.UnsupportedFeeAttributeException;
import google.registry.flows.exceptions.AlreadyPendingTransferException;
import google.registry.flows.exceptions.InvalidTransferPeriodValueException;
@ -89,6 +90,8 @@ import google.registry.model.eppcommon.StatusValue;
import google.registry.model.eppcommon.Trid;
import google.registry.model.poll.PendingActionNotificationResponse;
import google.registry.model.poll.PollMessage;
import google.registry.model.registrar.Registrar;
import google.registry.model.registrar.Registrar.State;
import google.registry.model.registry.Registry;
import google.registry.model.reporting.DomainTransactionRecord;
import google.registry.model.reporting.HistoryEntry;
@ -150,7 +153,11 @@ public class DomainTransferRequestFlowTest
.that(domain)
.hasCurrentSponsorClientId("TheRegistrar")
.and()
.hasStatusValue(StatusValue.PENDING_TRANSFER);
.hasStatusValue(StatusValue.PENDING_TRANSFER)
.and()
.hasLastEppUpdateTime(clock.nowUtc())
.and()
.hasLastEppUpdateClientId("NewRegistrar");
Trid expectedTrid =
Trid.create(
getClientTrid(),
@ -414,7 +421,11 @@ public class DomainTransferRequestFlowTest
assertTransferApproved(domainAfterAutomaticTransfer, implicitTransferTime, expectedPeriod);
assertAboutDomains()
.that(domainAfterAutomaticTransfer)
.hasRegistrationExpirationTime(expectedExpirationTime);
.hasRegistrationExpirationTime(expectedExpirationTime)
.and()
.hasLastEppUpdateTime(implicitTransferTime)
.and()
.hasLastEppUpdateClientId("NewRegistrar");
assertThat(
ofy()
.load()
@ -775,6 +786,40 @@ public class DomainTransferRequestFlowTest
assertAboutEppExceptions().that(thrown).marshalsToXml();
}
@Test
public void testFailure_suspendedRegistrarCantTransferDomain() {
setupDomain("example", "tld");
clock.advanceOneMilli();
persistResource(
Registrar.loadByClientId("NewRegistrar")
.get()
.asBuilder()
.setState(State.SUSPENDED)
.build());
EppException thrown =
assertThrows(
RegistrarMustBeActiveForThisOperationException.class,
() -> doFailingTest("domain_transfer_request.xml"));
assertAboutEppExceptions().that(thrown).marshalsToXml();
}
@Test
public void testFailure_pendingRegistrarCantTransferDomain() {
setupDomain("example", "tld");
clock.advanceOneMilli();
persistResource(
Registrar.loadByClientId("NewRegistrar")
.get()
.asBuilder()
.setState(State.PENDING)
.build());
EppException thrown =
assertThrows(
RegistrarMustBeActiveForThisOperationException.class,
() -> doFailingTest("domain_transfer_request.xml"));
assertAboutEppExceptions().that(thrown).marshalsToXml();
}
@Test
public void testSuccess_nonDefaultAutomaticTransferLength() throws Exception {
setupDomain("example", "tld");
@ -805,6 +850,19 @@ public class DomainTransferRequestFlowTest
"domain_transfer_request_missing_period.xml", "domain_transfer_request_response.xml");
}
@Test
public void testSuccess_canTransferAwayFromSuspendedRegistrar() throws Exception {
setupDomain("example", "tld");
clock.advanceOneMilli();
persistResource(
Registrar.loadByClientId("TheRegistrar")
.get()
.asBuilder()
.setState(State.SUSPENDED)
.build());
doSuccessfulTest("domain_transfer_request.xml", "domain_transfer_request_response.xml");
}
@Test
public void testFailure_multiYearPeriod() {
setupDomain("example", "tld");

View file

@ -124,7 +124,8 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
}
private DomainResource persistDomain() throws Exception {
HostResource host = loadByForeignKey(HostResource.class, "ns1.example.foo", clock.nowUtc());
HostResource host =
loadByForeignKey(HostResource.class, "ns1.example.foo", clock.nowUtc()).get();
DomainResource domain =
persistResource(
newDomainResource(getUniqueIdFromCommand())
@ -160,7 +161,11 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
.hasAuthInfoPwd("2BARfoo")
.and()
.hasOneHistoryEntryEachOfTypes(
HistoryEntry.Type.DOMAIN_CREATE, HistoryEntry.Type.DOMAIN_UPDATE);
HistoryEntry.Type.DOMAIN_CREATE, HistoryEntry.Type.DOMAIN_UPDATE)
.and()
.hasLastEppUpdateTime(clock.nowUtc())
.and()
.hasLastEppUpdateClientId("TheRegistrar");
assertNoBillingEvents();
assertDnsTasksEnqueued("example.tld");
}
@ -223,7 +228,8 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
getOnlyHistoryEntryOfType(resource, HistoryEntry.Type.DOMAIN_UPDATE);
assertThat(resource.getNameservers())
.containsExactly(
Key.create(loadByForeignKey(HostResource.class, "ns2.example.foo", clock.nowUtc())));
Key.create(
loadByForeignKey(HostResource.class, "ns2.example.foo", clock.nowUtc()).get()));
BillingEvent.OneTime regularAddBillingEvent =
new BillingEvent.OneTime.Builder()
.setReason(Reason.CREATE)
@ -279,7 +285,7 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
persistResource(
reloadResourceByForeignKey()
.asBuilder()
.setNameservers(null)
.setNameservers(ImmutableSet.of())
.addGracePeriod(
GracePeriod.forBillingEvent(GracePeriodStatus.SUNRUSH_ADD, sunrushAddBillingEvent))
.build());
@ -304,7 +310,7 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
persistResource(
reloadResourceByForeignKey()
.asBuilder()
.setNameservers(null)
.setNameservers(ImmutableSet.of())
.addGracePeriod(
GracePeriod.forBillingEvent(GracePeriodStatus.SUNRUSH_ADD, sunrushAddBillingEvent))
.build());
@ -325,9 +331,8 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
reloadResourceByForeignKey()
.asBuilder()
.setNameservers(
ImmutableSet.of(
Key.create(
loadByForeignKey(HostResource.class, "ns2.example.foo", clock.nowUtc()))))
Key.create(
loadByForeignKey(HostResource.class, "ns2.example.foo", clock.nowUtc()).get()))
.addGracePeriod(
GracePeriod.forBillingEvent(GracePeriodStatus.SUNRUSH_ADD, sunrushAddBillingEvent))
.addStatusValue(StatusValue.SERVER_HOLD)
@ -352,9 +357,8 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
reloadResourceByForeignKey()
.asBuilder()
.setNameservers(
ImmutableSet.of(
Key.create(
loadByForeignKey(HostResource.class, "ns2.example.foo", clock.nowUtc()))))
Key.create(
loadByForeignKey(HostResource.class, "ns2.example.foo", clock.nowUtc()).get()))
.addGracePeriod(
GracePeriod.forBillingEvent(GracePeriodStatus.SUNRUSH_ADD, sunrushAddBillingEvent))
.addStatusValue(StatusValue.CLIENT_HOLD)
@ -379,7 +383,7 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
persistResource(
reloadResourceByForeignKey()
.asBuilder()
.setNameservers(null)
.setNameservers(ImmutableSet.of())
.addGracePeriod(
GracePeriod.forBillingEvent(GracePeriodStatus.SUNRUSH_ADD, sunrushAddBillingEvent))
.addStatusValue(StatusValue.SERVER_HOLD)
@ -403,7 +407,8 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
nameservers.add(
Key.create(
loadByForeignKey(
HostResource.class, String.format("ns%d.example.foo", i), clock.nowUtc())));
HostResource.class, String.format("ns%d.example.foo", i), clock.nowUtc())
.get()));
}
}
persistResource(
@ -519,8 +524,8 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
.setNameservers(
ImmutableSet.of(
Key.create(
loadByForeignKey(
HostResource.class, "ns1.example.tld", clock.nowUtc()))))
loadByForeignKey(HostResource.class, "ns1.example.tld", clock.nowUtc())
.get())))
.build());
clock.advanceOneMilli();
assertTransactionalFlow(true);
@ -528,8 +533,8 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
domain = reloadResourceByForeignKey();
assertThat(domain.getNameservers()).containsExactly(Key.create(addedHost));
assertThat(domain.getSubordinateHosts()).containsExactly("ns1.example.tld", "ns2.example.tld");
existingHost = loadByForeignKey(HostResource.class, "ns1.example.tld", clock.nowUtc());
addedHost = loadByForeignKey(HostResource.class, "ns2.example.tld", clock.nowUtc());
existingHost = loadByForeignKey(HostResource.class, "ns1.example.tld", clock.nowUtc()).get();
addedHost = loadByForeignKey(HostResource.class, "ns2.example.tld", clock.nowUtc()).get();
assertThat(existingHost.getSuperordinateDomain()).isEqualTo(Key.create(domain));
assertThat(addedHost.getSuperordinateDomain()).isEqualTo(Key.create(domain));
}
@ -538,7 +543,8 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
public void testSuccess_registrantMovedToTechContact() throws Exception {
setEppInput("domain_update_registrant_to_tech.xml");
persistReferencedEntities();
ContactResource sh8013 = loadByForeignKey(ContactResource.class, "sh8013", clock.nowUtc());
ContactResource sh8013 =
loadByForeignKey(ContactResource.class, "sh8013", clock.nowUtc()).get();
persistResource(
newDomainResource(getUniqueIdFromCommand())
.asBuilder()
@ -552,7 +558,8 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
public void testSuccess_multipleReferencesToSameContactRemoved() throws Exception {
setEppInput("domain_update_remove_multiple_contacts.xml");
persistReferencedEntities();
ContactResource sh8013 = loadByForeignKey(ContactResource.class, "sh8013", clock.nowUtc());
ContactResource sh8013 =
loadByForeignKey(ContactResource.class, "sh8013", clock.nowUtc()).get();
Key<ContactResource> sh8013Key = Key.create(sh8013);
persistResource(
newDomainResource(getUniqueIdFromCommand())
@ -932,11 +939,10 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
reloadResourceByForeignKey()
.asBuilder()
.setContacts(
ImmutableSet.of(
DesignatedContact.create(
Type.TECH,
Key.create(
loadByForeignKey(ContactResource.class, "foo", clock.nowUtc())))))
DesignatedContact.create(
Type.TECH,
Key.create(
loadByForeignKey(ContactResource.class, "foo", clock.nowUtc()).get())))
.build());
EppException thrown = assertThrows(DuplicateContactForRoleException.class, this::runFlow);
assertAboutEppExceptions().that(thrown).marshalsToXml();
@ -1110,7 +1116,8 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
.setNameservers(
ImmutableSet.of(
Key.create(
loadByForeignKey(HostResource.class, "ns1.example.foo", clock.nowUtc()))))
loadByForeignKey(HostResource.class, "ns1.example.foo", clock.nowUtc())
.get())))
.build());
EppException thrown = assertThrows(AddRemoveSameValueException.class, this::runFlow);
assertAboutEppExceptions().that(thrown).marshalsToXml();
@ -1124,11 +1131,10 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
newDomainResource(getUniqueIdFromCommand())
.asBuilder()
.setContacts(
ImmutableSet.of(
DesignatedContact.create(
Type.TECH,
Key.create(
loadByForeignKey(ContactResource.class, "sh8013", clock.nowUtc())))))
DesignatedContact.create(
Type.TECH,
Key.create(
loadByForeignKey(ContactResource.class, "sh8013", clock.nowUtc()).get())))
.build());
EppException thrown = assertThrows(AddRemoveSameValueException.class, this::runFlow);
assertAboutEppExceptions().that(thrown).marshalsToXml();
@ -1175,6 +1181,7 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
persistActiveContact("sh8013");
persistResource(
loadByForeignKey(ContactResource.class, "mak21", clock.nowUtc())
.get()
.asBuilder()
.addStatusValue(StatusValue.PENDING_DELETE)
.build());
@ -1193,6 +1200,7 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
persistActiveContact("sh8013");
persistResource(
loadByForeignKey(HostResource.class, "ns2.example.foo", clock.nowUtc())
.get()
.asBuilder()
.addStatusValue(StatusValue.PENDING_DELETE)
.build());
@ -1245,11 +1253,13 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
.build());
assertThat(reloadResourceByForeignKey().getNameservers())
.doesNotContain(
Key.create(loadByForeignKey(HostResource.class, "ns2.example.foo", clock.nowUtc())));
Key.create(
loadByForeignKey(HostResource.class, "ns2.example.foo", clock.nowUtc()).get()));
runFlow();
assertThat(reloadResourceByForeignKey().getNameservers())
.contains(
Key.create(loadByForeignKey(HostResource.class, "ns2.example.foo", clock.nowUtc())));
Key.create(
loadByForeignKey(HostResource.class, "ns2.example.foo", clock.nowUtc()).get()));
}
@Test
@ -1290,10 +1300,9 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
persistResource(
reloadResourceByForeignKey()
.asBuilder()
.addNameservers(
ImmutableSet.of(
Key.create(
loadByForeignKey(HostResource.class, "ns2.example.foo", clock.nowUtc()))))
.addNameserver(
Key.create(
loadByForeignKey(HostResource.class, "ns2.example.foo", clock.nowUtc()).get()))
.build());
persistResource(
Registry.get("tld")
@ -1303,12 +1312,14 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
.build());
assertThat(reloadResourceByForeignKey().getNameservers())
.contains(
Key.create(loadByForeignKey(HostResource.class, "ns1.example.foo", clock.nowUtc())));
Key.create(
loadByForeignKey(HostResource.class, "ns1.example.foo", clock.nowUtc()).get()));
clock.advanceOneMilli();
runFlow();
assertThat(reloadResourceByForeignKey().getNameservers())
.doesNotContain(
Key.create(loadByForeignKey(HostResource.class, "ns1.example.foo", clock.nowUtc())));
Key.create(
loadByForeignKey(HostResource.class, "ns1.example.foo", clock.nowUtc()).get()));
}
@Test
@ -1383,10 +1394,9 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
persistResource(
reloadResourceByForeignKey()
.asBuilder()
.addNameservers(
ImmutableSet.of(
Key.create(
loadByForeignKey(HostResource.class, "ns2.example.foo", clock.nowUtc()))))
.addNameserver(
Key.create(
loadByForeignKey(HostResource.class, "ns2.example.foo", clock.nowUtc()).get()))
.build());
persistResource(
Registry.get("tld")
@ -1397,12 +1407,14 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
.build());
assertThat(reloadResourceByForeignKey().getNameservers())
.contains(
Key.create(loadByForeignKey(HostResource.class, "ns1.example.foo", clock.nowUtc())));
Key.create(
loadByForeignKey(HostResource.class, "ns1.example.foo", clock.nowUtc()).get()));
clock.advanceOneMilli();
runFlow();
assertThat(reloadResourceByForeignKey().getNameservers())
.doesNotContain(
Key.create(loadByForeignKey(HostResource.class, "ns1.example.foo", clock.nowUtc())));
Key.create(
loadByForeignKey(HostResource.class, "ns1.example.foo", clock.nowUtc()).get()));
}
@Test

View file

@ -35,7 +35,7 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.googlecode.objectify.Key;
import google.registry.flows.EppException;
import google.registry.flows.EppXmlTransformer.IpAddressVersionMismatchException;
import google.registry.flows.FlowUtils.IpAddressVersionMismatchException;
import google.registry.flows.ResourceFlowTestCase;
import google.registry.flows.exceptions.ResourceAlreadyExistsException;
import google.registry.flows.host.HostCreateFlow.SubordinateHostMustHaveIpException;
@ -116,7 +116,7 @@ public class HostCreateFlowTest extends ResourceFlowTestCase<HostCreateFlow, Hos
doSuccessfulInternalTest("tld");
HostResource host = reloadResourceByForeignKey();
DomainResource superordinateDomain =
loadByForeignKey(DomainResource.class, "example.tld", clock.nowUtc());
loadByForeignKey(DomainResource.class, "example.tld", clock.nowUtc()).get();
assertAboutHosts().that(host).hasSuperordinateDomain(Key.create(superordinateDomain));
assertThat(superordinateDomain.getSubordinateHosts()).containsExactly("ns1.example.tld");
assertDnsTasksEnqueued("ns1.example.tld");
@ -145,7 +145,7 @@ public class HostCreateFlowTest extends ResourceFlowTestCase<HostCreateFlow, Hos
doSuccessfulInternalTest("tld");
HostResource host = reloadResourceByForeignKey();
DomainResource superordinateDomain =
loadByForeignKey(DomainResource.class, "example.tld", clock.nowUtc());
loadByForeignKey(DomainResource.class, "example.tld", clock.nowUtc()).get();
assertAboutHosts().that(host).hasSuperordinateDomain(Key.create(superordinateDomain));
assertThat(superordinateDomain.getSubordinateHosts()).containsExactly("ns1.example.tld");
assertDnsTasksEnqueued("ns1.example.tld");

View file

@ -92,7 +92,7 @@ public class HostInfoFlowTest extends ResourceFlowTestCase<HostInfoFlow, HostRes
persistResource(
newDomainResource("example.foobar")
.asBuilder()
.addNameservers(ImmutableSet.of(Key.create(persistHostResource())))
.addNameserver(Key.create(persistHostResource()))
.build());
assertTransactionalFlow(false);
// Check that the persisted host info was returned.

View file

@ -159,7 +159,7 @@ public class HostUpdateFlowTest extends ResourceFlowTestCase<HostUpdateFlow, Hos
assertThat(reloadResourceByForeignKey()).isNull();
// However, it should load correctly if we use the new name (taken from the xml).
HostResource renamedHost =
loadByForeignKey(HostResource.class, "ns2.example.tld", clock.nowUtc());
loadByForeignKey(HostResource.class, "ns2.example.tld", clock.nowUtc()).get();
assertAboutHosts()
.that(renamedHost)
.hasOnlyOneHistoryEntryWhich()

View file

@ -45,7 +45,7 @@ public abstract class LoginFlowTestCase extends FlowTestCase<LoginFlow> {
@Before
public void initRegistrar() {
sessionMetadata.setClientId(null); // Don't implicitly log in (all other flows need to).
sessionMetadata.setClientId(null); // Don't implicitly log in (all other flows need to).
registrar = loadRegistrar("NewRegistrar");
registrarBuilder = registrar.asBuilder();
}

View file

@ -14,16 +14,11 @@
package google.registry.flows.session;
import static google.registry.testing.DatastoreHelper.loadRegistrar;
import static google.registry.testing.DatastoreHelper.persistResource;
import com.google.appengine.api.users.User;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSetMultimap;
import google.registry.flows.GaeUserCredentials;
import google.registry.flows.GaeUserCredentials.BadGaeUserIdException;
import google.registry.flows.GaeUserCredentials.UserNotLoggedInException;
import google.registry.model.registrar.Registrar;
import google.registry.model.registrar.RegistrarContact;
import google.registry.flows.GaeUserCredentials.UserForbiddenException;
import google.registry.request.auth.AuthenticatedRegistrarAccessor;
import org.junit.Test;
/**
@ -32,53 +27,32 @@ import org.junit.Test;
*/
public class LoginFlowViaConsoleTest extends LoginFlowTestCase {
private static final String GAE_USER_ID1 = "12345";
private static final String GAE_USER_ID2 = "54321";
@Test
public void testSuccess_withLoginAndLinkedAccount() throws Exception {
persistLinkedAccount("person@example.com", GAE_USER_ID1);
public void testSuccess_withAccess() throws Exception {
credentials =
GaeUserCredentials.forTestingUser(new User("person", "example.com", GAE_USER_ID1), false);
new GaeUserCredentials(
AuthenticatedRegistrarAccessor.createForTesting(
ImmutableSetMultimap.of(
"NewRegistrar", AuthenticatedRegistrarAccessor.Role.OWNER)));
doSuccessfulTest("login_valid.xml");
}
@Test
public void testFailure_withoutLoginAndLinkedAccount() {
persistLinkedAccount("person@example.com", GAE_USER_ID1);
credentials = GaeUserCredentials.forLoggedOutUser();
doFailingTest("login_valid.xml", UserNotLoggedInException.class);
}
@Test
public void testFailure_withoutLoginAndWithoutLinkedAccount() {
credentials = GaeUserCredentials.forLoggedOutUser();
doFailingTest("login_valid.xml", UserNotLoggedInException.class);
}
@Test
public void testFailure_withLoginAndWithoutLinkedAccount() {
public void testFailure_withoutAccess() {
credentials =
GaeUserCredentials.forTestingUser(new User("person", "example.com", GAE_USER_ID1), false);
doFailingTest("login_valid.xml", BadGaeUserIdException.class);
new GaeUserCredentials(
AuthenticatedRegistrarAccessor.createForTesting(
ImmutableSetMultimap.of()));
doFailingTest("login_valid.xml", UserForbiddenException.class);
}
@Test
public void testFailure_withLoginAndNoMatchingLinkedAccount() {
persistLinkedAccount("joe@example.com", GAE_USER_ID2);
public void testFailure_withAccessToDifferentRegistrar() {
credentials =
GaeUserCredentials.forTestingUser(new User("person", "example.com", GAE_USER_ID1), false);
doFailingTest("login_valid.xml", BadGaeUserIdException.class);
}
private void persistLinkedAccount(String email, String gaeUserId) {
Registrar registrar = loadRegistrar("NewRegistrar");
RegistrarContact c = new RegistrarContact.Builder()
.setParent(registrar)
.setEmailAddress(email)
.setTypes(ImmutableSet.of(RegistrarContact.Type.ADMIN))
.setGaeUserId(gaeUserId)
.build();
persistResource(c);
new GaeUserCredentials(
AuthenticatedRegistrarAccessor.createForTesting(
ImmutableSetMultimap.of(
"TheRegistrar", AuthenticatedRegistrarAccessor.Role.OWNER)));
doFailingTest("login_valid.xml", UserForbiddenException.class);
}
}

View file

@ -49,7 +49,7 @@ public class LoginFlowViaTlsTest extends LoginFlowTestCase {
@Test
public void testSuccess_withGoodCredentials() throws Exception {
persistResource(getRegistrarBuilder().build());
credentials = new TlsCredentials(GOOD_CERT, GOOD_IP);
credentials = new TlsCredentials(true, GOOD_CERT, GOOD_IP);
doSuccessfulTest("login_valid.xml");
}
@ -60,7 +60,7 @@ public class LoginFlowViaTlsTest extends LoginFlowTestCase {
.setIpAddressWhitelist(ImmutableList.of(
CidrAddressBlock.create("2001:db8:0:0:0:0:1:1/32")))
.build());
credentials = new TlsCredentials(GOOD_CERT, GOOD_IPV6);
credentials = new TlsCredentials(true, GOOD_CERT, GOOD_IPV6);
doSuccessfulTest("login_valid.xml");
}
@ -71,7 +71,7 @@ public class LoginFlowViaTlsTest extends LoginFlowTestCase {
.setIpAddressWhitelist(ImmutableList.of(
CidrAddressBlock.create("2001:db8:0:0:0:0:1:1/32")))
.build());
credentials = new TlsCredentials(GOOD_CERT, GOOD_IPV6);
credentials = new TlsCredentials(true, GOOD_CERT, GOOD_IPV6);
doSuccessfulTest("login_valid.xml");
}
@ -82,21 +82,21 @@ public class LoginFlowViaTlsTest extends LoginFlowTestCase {
.setIpAddressWhitelist(ImmutableList.of(
CidrAddressBlock.create("192.168.1.255/24")))
.build());
credentials = new TlsCredentials(GOOD_CERT, GOOD_IP);
credentials = new TlsCredentials(true, GOOD_CERT, GOOD_IP);
doSuccessfulTest("login_valid.xml");
}
@Test
public void testFailure_incorrectClientCertificateHash() {
persistResource(getRegistrarBuilder().build());
credentials = new TlsCredentials(BAD_CERT, GOOD_IP);
credentials = new TlsCredentials(true, BAD_CERT, GOOD_IP);
doFailingTest("login_valid.xml", BadRegistrarCertificateException.class);
}
@Test
public void testFailure_missingClientCertificateHash() {
persistResource(getRegistrarBuilder().build());
credentials = new TlsCredentials(null, GOOD_IP);
credentials = new TlsCredentials(true, null, GOOD_IP);
doFailingTest("login_valid.xml", MissingRegistrarCertificateException.class);
}
@ -108,7 +108,7 @@ public class LoginFlowViaTlsTest extends LoginFlowTestCase {
CidrAddressBlock.create(InetAddresses.forString("192.168.1.1"), 32),
CidrAddressBlock.create(InetAddresses.forString("2001:db8::1"), 128)))
.build());
credentials = new TlsCredentials(GOOD_CERT, Optional.empty());
credentials = new TlsCredentials(true, GOOD_CERT, Optional.empty());
doFailingTest("login_valid.xml", BadRegistrarIpAddressException.class);
}
@ -120,7 +120,7 @@ public class LoginFlowViaTlsTest extends LoginFlowTestCase {
CidrAddressBlock.create(InetAddresses.forString("192.168.1.1"), 32),
CidrAddressBlock.create(InetAddresses.forString("2001:db8::1"), 128)))
.build());
credentials = new TlsCredentials(GOOD_CERT, BAD_IP);
credentials = new TlsCredentials(true, GOOD_CERT, BAD_IP);
doFailingTest("login_valid.xml", BadRegistrarIpAddressException.class);
}
@ -132,7 +132,7 @@ public class LoginFlowViaTlsTest extends LoginFlowTestCase {
CidrAddressBlock.create(InetAddresses.forString("192.168.1.1"), 32),
CidrAddressBlock.create(InetAddresses.forString("2001:db8::1"), 128)))
.build());
credentials = new TlsCredentials(GOOD_CERT, BAD_IPV6);
credentials = new TlsCredentials(true, GOOD_CERT, BAD_IPV6);
doFailingTest("login_valid.xml", BadRegistrarIpAddressException.class);
}
}

View file

@ -21,8 +21,8 @@
<domain:clID>NewRegistrar</domain:clID>
<domain:crID>NewRegistrar</domain:crID>
<domain:crDate>2000-06-01T00:04:00Z</domain:crDate>
<domain:upID>NewRegistrar</domain:upID>
<domain:upDate>2000-06-08T00:00:00Z</domain:upDate>
<domain:upID>TheRegistrar</domain:upID>
<domain:upDate>2002-05-30T00:00:00Z</domain:upDate>
<domain:exDate>2002-06-01T00:04:00Z</domain:exDate>
<domain:authInfo>
<domain:pw>2fooBAR</domain:pw>

View file

@ -21,8 +21,8 @@
<domain:clID>TheRegistrar</domain:clID>
<domain:crID>NewRegistrar</domain:crID>
<domain:crDate>2000-06-01T00:04:00Z</domain:crDate>
<domain:upID>NewRegistrar</domain:upID>
<domain:upDate>2000-06-08T00:00:00Z</domain:upDate>
<domain:upID>TheRegistrar</domain:upID>
<domain:upDate>2002-06-09T00:00:00Z</domain:upDate>
<domain:exDate>2003-06-01T00:04:00Z</domain:exDate>
<domain:trDate>2002-06-04T00:00:00Z</domain:trDate>
<domain:authInfo>

View file

@ -20,6 +20,8 @@
<domain:clID>NewRegistrar</domain:clID>
<domain:crID>NewRegistrar</domain:crID>
<domain:crDate>2000-06-01T00:04:00Z</domain:crDate>
<domain:upID>NewRegistrar</domain:upID>
<domain:upDate>2000-06-06T00:04:00Z</domain:upDate>
<domain:exDate>2002-06-01T00:04:00Z</domain:exDate>
<domain:authInfo>
<domain:pw>2fooBAR</domain:pw>

View file

@ -19,6 +19,8 @@
<domain:clID>NewRegistrar</domain:clID>
<domain:crID>NewRegistrar</domain:crID>
<domain:crDate>2000-06-01T00:04:00Z</domain:crDate>
<domain:upID>NewRegistrar</domain:upID>
<domain:upDate>2002-05-30T01:01:00Z</domain:upDate>
<domain:exDate>2002-06-01T00:04:00Z</domain:exDate>
<domain:authInfo>
<domain:pw>2fooBAR</domain:pw>

View file

@ -19,6 +19,8 @@
<domain:clID>NewRegistrar</domain:clID>
<domain:crID>NewRegistrar</domain:crID>
<domain:crDate>2000-06-01T00:04:00Z</domain:crDate>
<domain:upID>TheRegistrar</domain:upID>
<domain:upDate>2002-05-30T00:00:00Z</domain:upDate>
<domain:exDate>2002-06-01T00:04:00Z</domain:exDate>
<domain:authInfo>
<domain:pw>2fooBAR</domain:pw>

View file

@ -19,6 +19,8 @@
<domain:clID>NewRegistrar</domain:clID>
<domain:crID>NewRegistrar</domain:crID>
<domain:crDate>2000-06-01T00:04:00Z</domain:crDate>
<domain:upID>NewRegistrar</domain:upID>
<domain:upDate>2002-06-01T00:04:00.000Z</domain:upDate>
<domain:exDate>2003-06-01T00:04:00Z</domain:exDate>
<domain:authInfo>
<domain:pw>2fooBAR</domain:pw>

View file

@ -19,6 +19,8 @@
<domain:clID>NewRegistrar</domain:clID>
<domain:crID>NewRegistrar</domain:crID>
<domain:crDate>2000-06-01T00:04:00Z</domain:crDate>
<domain:upID>NewRegistrar</domain:upID>
<domain:upDate>2002-05-30T01:03:00Z</domain:upDate>
<domain:exDate>2003-05-30T01:03:00Z</domain:exDate>
<domain:authInfo>
<domain:pw>2fooBAR</domain:pw>

View file

@ -19,6 +19,8 @@
<domain:clID>TheRegistrar</domain:clID>
<domain:crID>NewRegistrar</domain:crID>
<domain:crDate>2000-06-01T00:04:00Z</domain:crDate>
<domain:upID>TheRegistrar</domain:upID>
<domain:upDate>2002-06-09T00:00:00Z</domain:upDate>
<domain:exDate>2003-06-01T00:04:00Z</domain:exDate>
<domain:trDate>2002-06-04T00:00:00Z</domain:trDate>
<domain:authInfo>

View file

@ -19,6 +19,8 @@
<domain:clID>TheRegistrar</domain:clID>
<domain:crID>NewRegistrar</domain:crID>
<domain:crDate>2000-06-01T00:04:00Z</domain:crDate>
<domain:upID>TheRegistrar</domain:upID>
<domain:upDate>2002-06-04T00:00:00Z</domain:upDate>
<domain:exDate>2003-06-01T00:04:00Z</domain:exDate>
<domain:trDate>2002-06-04T00:00:00Z</domain:trDate>
<domain:authInfo>

View file

@ -0,0 +1,31 @@
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
<response>
<result code="1000">
<msg>Command completed successfully</msg>
</result>
<resData>
<domain:infData
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
<domain:name>%DOMAIN%</domain:name>
<domain:roid>8-TLD</domain:roid>
<domain:status s="inactive"/>
<domain:registrant>jd1234</domain:registrant>
<domain:contact type="tech">sh8013</domain:contact>
<domain:contact type="admin">sh8013</domain:contact>
<domain:clID>NewRegistrar</domain:clID>
<domain:crID>NewRegistrar</domain:crID>
<domain:crDate>2000-06-01T00:02:00Z</domain:crDate>
<domain:upID>NewRegistrar</domain:upID>
<domain:upDate>%UPDATE%</domain:upDate>
<domain:exDate>%EXDATE%</domain:exDate>
<domain:authInfo>
<domain:pw>2fooBAR</domain:pw>
</domain:authInfo>
</domain:infData>
</resData>
<trID>
<clTRID>ABC-12345</clTRID>
<svTRID>server-trid</svTRID>
</trID>
</response>
</epp>

View file

@ -0,0 +1,36 @@
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
<response>
<result code="1000">
<msg>Command completed successfully</msg>
</result>
<resData>
<domain:infData
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
<domain:name>%DOMAIN%</domain:name>
<domain:roid>8-TLD</domain:roid>
<domain:status s="inactive"/>
<domain:registrant>jd1234</domain:registrant>
<domain:contact type="tech">sh8013</domain:contact>
<domain:contact type="admin">sh8013</domain:contact>
<domain:clID>NewRegistrar</domain:clID>
<domain:crID>NewRegistrar</domain:crID>
<domain:crDate>2000-06-01T00:02:00Z</domain:crDate>
<domain:upID>NewRegistrar</domain:upID>
<domain:upDate>%UPDATE%</domain:upDate>
<domain:exDate>%EXDATE%</domain:exDate>
<domain:authInfo>
<domain:pw>2fooBAR</domain:pw>
</domain:authInfo>
</domain:infData>
</resData>
<extension>
<rgp:infData xmlns:rgp="urn:ietf:params:xml:ns:rgp-1.0">
<rgp:rgpStatus s="%RGPSTATUS%"/>
</rgp:infData>
</extension>
<trID>
<clTRID>ABC-12345</clTRID>
<svTRID>server-trid</svTRID>
</trID>
</response>
</epp>

View file

@ -17,6 +17,8 @@
<domain:clID>NewRegistrar</domain:clID>
<domain:crID>NewRegistrar</domain:crID>
<domain:crDate>2000-06-01T00:02:00.0Z</domain:crDate>
<domain:upID>NewRegistrar</domain:upID>
<domain:upDate>2000-07-07T00:02:00Z</domain:upDate>
<domain:exDate>2002-06-01T00:02:00.0Z</domain:exDate>
<domain:authInfo>
<domain:pw>2fooBAR</domain:pw>

View file

@ -0,0 +1,38 @@
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<response>
<result code="1000">
<msg>Command completed successfully</msg>
</result>
<resData>
<domain:infData
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
<domain:name>example.tld</domain:name>
<domain:roid>%ROID%</domain:roid>
<domain:status s="inactive"/>
<domain:status s="pendingDelete"/>
<domain:registrant>jd1234</domain:registrant>
<domain:contact type="admin">sh8013</domain:contact>
<domain:contact type="tech">sh8013</domain:contact>
<domain:clID>NewRegistrar</domain:clID>
<domain:crID>NewRegistrar</domain:crID>
<domain:crDate>2000-06-01T00:02:00.0Z</domain:crDate>
<domain:upID>NewRegistrar</domain:upID>
<domain:upDate>2000-08-06T00:02:00Z</domain:upDate>
<domain:exDate>2002-06-01T00:02:00.0Z</domain:exDate>
<domain:authInfo>
<domain:pw>2fooBAR</domain:pw>
</domain:authInfo>
</domain:infData>
</resData>
<extension>
<rgp:infData xmlns:rgp="urn:ietf:params:xml:ns:rgp-1.0">
<rgp:rgpStatus s="%STATUS%"/>
</rgp:infData>
</extension>
<trID>
<clTRID>ABC-12345</clTRID>
<svTRID>server-trid</svTRID>
</trID>
</response>
</epp>

View file

@ -0,0 +1,18 @@
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
<response>
<result code="1000">
<msg>Command completed successfully</msg>
</result>
<resData>
<domain:renData
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
<domain:name>%DOMAIN%</domain:name>
<domain:exDate>%EXDATE%</domain:exDate>
</domain:renData>
</resData>
<trID>
<clTRID>ABC-12345</clTRID>
<svTRID>server-trid</svTRID>
</trID>
</response>
</epp>

View file

@ -0,0 +1,15 @@
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
<response>
<result code="1301">
<msg>Command completed successfully; ack to dequeue</msg>
</result>
<msgQ count="1" id="1-8-TLD-17-18-2001">
<qDate>2001-06-07T00:00:00Z</qDate>
<msg>Domain example.tld was unrenewed by 3 years; now expires at 2003-06-01T00:02:00.000Z.</msg>
</msgQ>
<trID>
<clTRID>ABC-12345</clTRID>
<svTRID>server-trid</svTRID>
</trID>
</response>
</epp>

View file

@ -216,6 +216,45 @@ public class DirectoryGroupsConnectionTest {
assertThat(connection.getMembersOfGroup("nonexistent_group@fake.notreal")).isEmpty();
}
@Test
public void test_isMemberOfSupportGroup_userInGroup_True() throws Exception {
when(members.get("support@domain-registry.example", "user@example.com")).thenReturn(membersGet);
when(membersGet.execute()).thenReturn(new Member());
assertThat(connection.isMemberOfGroup("user@example.com", "support@domain-registry.example"))
.isTrue();
}
@Test
public void test_isMemberOfSupportGroup_userExistButNotInGroup_returnsFalse() throws Exception {
when(members.get("support@domain-registry.example", "user@example.com"))
.thenThrow(makeResponseException(0, "Resource Not Found: memberKey"));
when(membersGet.execute()).thenReturn(new Member());
assertThat(connection.isMemberOfGroup("user@example.com", "support@domain-registry.example"))
.isFalse();
}
@Test
public void test_isMemberOfSupportGroup_userDoesntExist_returnsFalse() throws Exception {
when(members.get("support@domain-registry.example", "user@example.com"))
.thenThrow(makeResponseException(0, "Missing required field: memberKey"));
when(membersGet.execute()).thenReturn(new Member());
assertThat(connection.isMemberOfGroup("user@example.com", "support@domain-registry.example"))
.isFalse();
}
@Test
public void test_isMemberOfSupportGroup_otherError_throws() throws Exception {
when(members.get("support@domain-registry.example", "user@example.com"))
.thenThrow(makeResponseException(0, "some error"));
when(membersGet.execute()).thenReturn(new Member());
RuntimeException e =
assertThrows(
RuntimeException.class,
() ->
connection.isMemberOfGroup("user@example.com", "support@domain-registry.example"));
assertThat(e).hasCauseThat().isInstanceOf(GoogleJsonResponseException.class);
}
/** Runs a full test to add a member to the group and returns the expected Member. */
private Member runAddMemberTest() throws Exception {
connection.addMemberToGroup("spam@example.com", "jim@example.com", Role.MEMBER);

View file

@ -15,6 +15,8 @@
package google.registry.model;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;
import static google.registry.model.EppResourceUtils.loadByForeignKey;
import static google.registry.testing.DatastoreHelper.persistActiveContact;
import static google.registry.testing.DatastoreHelper.persistActiveHost;
import static google.registry.testing.DatastoreHelper.persistResource;
@ -40,9 +42,8 @@ public class EppResourceTest extends EntityTestCase {
persistResource(originalContact.asBuilder().setEmailAddress("different@fake.lol").build());
assertThat(EppResource.loadCached(ImmutableList.of(Key.create(originalContact))))
.containsExactly(Key.create(originalContact), originalContact);
assertThat(
EppResourceUtils.loadByForeignKey(ContactResource.class, "contact123", clock.nowUtc()))
.isEqualTo(modifiedContact);
assertThat(loadByForeignKey(ContactResource.class, "contact123", clock.nowUtc()))
.hasValue(modifiedContact);
}
@Test
@ -56,10 +57,8 @@ public class EppResourceTest extends EntityTestCase {
originalHost.asBuilder().setLastTransferTime(clock.nowUtc().minusDays(60)).build());
assertThat(EppResource.loadCached(ImmutableList.of(Key.create(originalHost))))
.containsExactly(Key.create(originalHost), originalHost);
assertThat(
EppResourceUtils.loadByForeignKey(
HostResource.class, "ns1.example.com", clock.nowUtc()))
.isEqualTo(modifiedHost);
assertThat(loadByForeignKey(HostResource.class, "ns1.example.com", clock.nowUtc()))
.hasValue(modifiedHost);
}
private static void setNonZeroCachingInterval() {

View file

@ -0,0 +1,351 @@
// Copyright 2018 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.model;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;
import static google.registry.testing.CertificateSamples.SAMPLE_CERT;
import static google.registry.testing.CertificateSamples.SAMPLE_CERT_HASH;
import static google.registry.testing.DatastoreHelper.persistPremiumList;
import static google.registry.testing.JUnitBackports.assertThrows;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import static org.joda.money.CurrencyUnit.USD;
import com.google.common.collect.ImmutableList;
import google.registry.model.registrar.Registrar;
import google.registry.model.registrar.RegistrarContact;
import google.registry.model.registry.Registry;
import google.registry.model.registry.Registry.TldState;
import google.registry.testing.AppEngineRule;
import google.registry.testing.DatastoreHelper;
import google.registry.util.CidrAddressBlock;
import google.registry.util.SystemClock;
import org.joda.money.Money;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.Duration;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@RunWith(JUnit4.class)
public final class OteAccountBuilderTest {
@Rule public final AppEngineRule appEngine = AppEngineRule.builder().withDatastore().build();
@Test
public void testGetRegistrarToTldMap() {
assertThat(OteAccountBuilder.forClientId("myclientid").getClientIdToTldMap())
.containsExactly(
"myclientid-1", "myclientid-sunrise",
"myclientid-2", "myclientid-landrush",
"myclientid-3", "myclientid-ga",
"myclientid-4", "myclientid-ga",
"myclientid-5", "myclientid-eap");
}
@Before
public void setUp() {
persistPremiumList("default_sandbox_list", "sandbox,USD 1000");
}
private void assertTldExists(String tld, Registry.TldState tldState) {
Registry registry = Registry.get(tld);
assertThat(registry).isNotNull();
assertThat(registry.getPremiumList().getName()).isEqualTo("default_sandbox_list");
assertThat(registry.getTldStateTransitions()).containsExactly(START_OF_TIME, tldState);
assertThat(registry.getDnsWriters()).containsExactly("VoidDnsWriter");
assertThat(registry.getAddGracePeriodLength()).isEqualTo(Duration.standardDays(5));
assertThat(registry.getPendingDeleteLength()).isEqualTo(Duration.standardDays(5));
assertThat(registry.getRedemptionGracePeriodLength()).isEqualTo(Duration.standardDays(30));
assertThat(registry.getEapFeeScheduleAsMap()).containsExactly(START_OF_TIME, Money.of(USD, 0));
}
private void assertTldExistsGa(String tld, Money eapFee) {
Registry registry = Registry.get(tld);
assertThat(registry).isNotNull();
assertThat(registry.getPremiumList().getName()).isEqualTo("default_sandbox_list");
assertThat(registry.getTldStateTransitions())
.containsExactly(START_OF_TIME, TldState.GENERAL_AVAILABILITY);
assertThat(registry.getDnsWriters()).containsExactly("VoidDnsWriter");
assertThat(registry.getAddGracePeriodLength()).isEqualTo(Duration.standardHours(1));
assertThat(registry.getPendingDeleteLength()).isEqualTo(Duration.standardMinutes(5));
assertThat(registry.getRedemptionGracePeriodLength()).isEqualTo(Duration.standardMinutes(10));
assertThat(registry.getCurrency()).isEqualTo(eapFee.getCurrencyUnit());
// This uses "now" on purpose - so the test will break at 2022 when the current EapFee in OTE
// goes back to 0
assertThat(registry.getEapFeeFor(DateTime.now(DateTimeZone.UTC)).getCost())
.isEqualTo(eapFee.getAmount());
}
private void assertRegistrarExists(String clientId, String tld) {
Registrar registrar = Registrar.loadByClientId(clientId).orElse(null);
assertThat(registrar).isNotNull();
assertThat(registrar.getType()).isEqualTo(Registrar.Type.OTE);
assertThat(registrar.getState()).isEqualTo(Registrar.State.ACTIVE);
assertThat(registrar.getAllowedTlds()).containsExactly(tld);
}
private void assertContactExists(String clientId, String email) {
Registrar registrar = Registrar.loadByClientId(clientId).get();
assertThat(registrar.getContacts().stream().map(RegistrarContact::getEmailAddress))
.contains(email);
RegistrarContact contact =
registrar.getContacts().stream()
.filter(c -> email.equals(c.getEmailAddress()))
.findAny()
.get();
assertThat(contact.getEmailAddress()).isEqualTo(email);
assertThat(contact.getGaeUserId()).isNotEmpty();
}
@Test
public void testCreateOteEntities_success() {
OteAccountBuilder.forClientId("myclientid").addContact("email@example.com").buildAndPersist();
assertTldExists("myclientid-sunrise", TldState.START_DATE_SUNRISE);
assertTldExists("myclientid-landrush", TldState.LANDRUSH);
assertTldExistsGa("myclientid-ga", Money.of(USD, 0));
assertTldExistsGa("myclientid-eap", Money.of(USD, 100));
assertRegistrarExists("myclientid-1", "myclientid-sunrise");
assertRegistrarExists("myclientid-2", "myclientid-landrush");
assertRegistrarExists("myclientid-3", "myclientid-ga");
assertRegistrarExists("myclientid-4", "myclientid-ga");
assertRegistrarExists("myclientid-5", "myclientid-eap");
assertContactExists("myclientid-1", "email@example.com");
assertContactExists("myclientid-2", "email@example.com");
assertContactExists("myclientid-3", "email@example.com");
assertContactExists("myclientid-4", "email@example.com");
assertContactExists("myclientid-5", "email@example.com");
}
@Test
public void testCreateOteEntities_multipleContacts_success() {
OteAccountBuilder.forClientId("myclientid")
.addContact("email@example.com")
.addContact("other@example.com")
.addContact("someone@example.com")
.buildAndPersist();
assertTldExists("myclientid-sunrise", TldState.START_DATE_SUNRISE);
assertTldExists("myclientid-landrush", TldState.LANDRUSH);
assertTldExistsGa("myclientid-ga", Money.of(USD, 0));
assertTldExistsGa("myclientid-eap", Money.of(USD, 100));
assertRegistrarExists("myclientid-1", "myclientid-sunrise");
assertRegistrarExists("myclientid-2", "myclientid-landrush");
assertRegistrarExists("myclientid-3", "myclientid-ga");
assertRegistrarExists("myclientid-4", "myclientid-ga");
assertRegistrarExists("myclientid-5", "myclientid-eap");
assertContactExists("myclientid-1", "email@example.com");
assertContactExists("myclientid-2", "email@example.com");
assertContactExists("myclientid-3", "email@example.com");
assertContactExists("myclientid-4", "email@example.com");
assertContactExists("myclientid-5", "email@example.com");
assertContactExists("myclientid-1", "other@example.com");
assertContactExists("myclientid-2", "other@example.com");
assertContactExists("myclientid-3", "other@example.com");
assertContactExists("myclientid-4", "other@example.com");
assertContactExists("myclientid-5", "other@example.com");
assertContactExists("myclientid-1", "someone@example.com");
assertContactExists("myclientid-2", "someone@example.com");
assertContactExists("myclientid-3", "someone@example.com");
assertContactExists("myclientid-4", "someone@example.com");
assertContactExists("myclientid-5", "someone@example.com");
}
@Test
public void testCreateOteEntities_setPassword() {
OteAccountBuilder.forClientId("myclientid").setPassword("myPassword").buildAndPersist();
assertThat(Registrar.loadByClientId("myclientid-3").get().testPassword("myPassword")).isTrue();
}
@Test
public void testCreateOteEntities_setCertificateHash() {
OteAccountBuilder.forClientId("myclientid")
.setCertificateHash(SAMPLE_CERT_HASH)
.buildAndPersist();
assertThat(Registrar.loadByClientId("myclientid-3").get().getClientCertificateHash())
.isEqualTo(SAMPLE_CERT_HASH);
}
@Test
public void testCreateOteEntities_setCertificate() {
OteAccountBuilder.forClientId("myclientid")
.setCertificate(SAMPLE_CERT, new SystemClock().nowUtc())
.buildAndPersist();
assertThat(Registrar.loadByClientId("myclientid-3").get().getClientCertificateHash())
.isEqualTo(SAMPLE_CERT_HASH);
assertThat(Registrar.loadByClientId("myclientid-3").get().getClientCertificate())
.isEqualTo(SAMPLE_CERT);
}
@Test
public void testCreateOteEntities_setIpWhitelist() {
OteAccountBuilder.forClientId("myclientid")
.setIpWhitelist(ImmutableList.of("1.1.1.0/24"))
.buildAndPersist();
assertThat(Registrar.loadByClientId("myclientid-3").get().getIpAddressWhitelist())
.containsExactly(CidrAddressBlock.create("1.1.1.0/24"));
}
@Test
public void testCreateOteEntities_invalidClientId_fails() {
assertThat(
assertThrows(
IllegalArgumentException.class, () -> OteAccountBuilder.forClientId("3blobio")))
.hasMessageThat()
.isEqualTo("Invalid registrar name: 3blobio");
}
@Test
public void testCreateOteEntities_clientIdTooShort_fails() {
assertThat(
assertThrows(IllegalArgumentException.class, () -> OteAccountBuilder.forClientId("bl")))
.hasMessageThat()
.isEqualTo("Invalid registrar name: bl");
}
@Test
public void testCreateOteEntities_clientIdTooLong_fails() {
assertThat(
assertThrows(
IllegalArgumentException.class,
() -> OteAccountBuilder.forClientId("blobiotoooolong")))
.hasMessageThat()
.isEqualTo("Invalid registrar name: blobiotoooolong");
}
@Test
public void testCreateOteEntities_clientIdBadCharacter_fails() {
assertThat(
assertThrows(
IllegalArgumentException.class, () -> OteAccountBuilder.forClientId("blo#bio")))
.hasMessageThat()
.isEqualTo("Invalid registrar name: blo#bio");
}
@Test
public void testCreateOteEntities_entityExists_failsWhenNotReplaceExisting() {
DatastoreHelper.persistSimpleResource(
AppEngineRule.makeRegistrar1().asBuilder().setClientId("myclientid-1").build());
OteAccountBuilder oteSetupHelper = OteAccountBuilder.forClientId("myclientid");
assertThat(assertThrows(IllegalStateException.class, () -> oteSetupHelper.buildAndPersist()))
.hasMessageThat()
.contains("Found existing object(s) conflicting with OT&E objects");
}
@Test
public void testCreateOteEntities_entityExists_succeedsWhenReplaceExisting() {
DatastoreHelper.persistSimpleResource(
AppEngineRule.makeRegistrar1().asBuilder().setClientId("myclientid-1").build());
DatastoreHelper.createTld("myclientid-landrush", Registry.TldState.SUNRUSH);
OteAccountBuilder.forClientId("myclientid").setReplaceExisting(true).buildAndPersist();
assertTldExists("myclientid-landrush", TldState.LANDRUSH);
assertRegistrarExists("myclientid-3", "myclientid-ga");
}
@Test
public void testCreateOteEntities_doubleCreation_actuallyReplaces() {
OteAccountBuilder.forClientId("myclientid")
.setPassword("oldPassword")
.addContact("email@example.com")
.buildAndPersist();
assertThat(Registrar.loadByClientId("myclientid-3").get().testPassword("oldPassword")).isTrue();
OteAccountBuilder.forClientId("myclientid")
.setPassword("newPassword")
.addContact("email@example.com")
.setReplaceExisting(true)
.buildAndPersist();
assertThat(Registrar.loadByClientId("myclientid-3").get().testPassword("oldPassword"))
.isFalse();
assertThat(Registrar.loadByClientId("myclientid-3").get().testPassword("newPassword")).isTrue();
}
@Test
public void testCreateOteEntities_doubleCreation_keepsOldContacts() {
OteAccountBuilder.forClientId("myclientid").addContact("email@example.com").buildAndPersist();
assertContactExists("myclientid-3", "email@example.com");
OteAccountBuilder.forClientId("myclientid")
.addContact("other@example.com")
.setReplaceExisting(true)
.buildAndPersist();
assertContactExists("myclientid-3", "other@example.com");
assertContactExists("myclientid-3", "email@example.com");
}
@Test
public void testCreateClientIdToTldMap_validEntries() {
assertThat(OteAccountBuilder.createClientIdToTldMap("myclientid"))
.containsExactly(
"myclientid-1", "myclientid-sunrise",
"myclientid-2", "myclientid-landrush",
"myclientid-3", "myclientid-ga",
"myclientid-4", "myclientid-ga",
"myclientid-5", "myclientid-eap");
}
@Test
public void testCreateClientIdToTldMap_invalidId() {
IllegalArgumentException exception =
assertThrows(
IllegalArgumentException.class, () -> OteAccountBuilder.createClientIdToTldMap("a"));
assertThat(exception).hasMessageThat().isEqualTo("Invalid registrar name: a");
}
@Test
public void testGetBaseClientId_validOteId() {
assertThat(OteAccountBuilder.getBaseClientId("myclientid-4")).isEqualTo("myclientid");
}
@Test
public void testGetBaseClientId_multipleDashesValid() {
assertThat(OteAccountBuilder.getBaseClientId("two-dashes-3")).isEqualTo("two-dashes");
}
@Test
public void testGetBaseClientId_invalidInput_malformed() {
assertThat(
assertThrows(
IllegalArgumentException.class,
() -> OteAccountBuilder.getBaseClientId("myclientid")))
.hasMessageThat()
.isEqualTo("Invalid OT&E client ID: myclientid");
}
@Test
public void testGetBaseClientId_invalidInput_wrongForBase() {
assertThat(
assertThrows(
IllegalArgumentException.class,
() -> OteAccountBuilder.getBaseClientId("myclientid-7")))
.hasMessageThat()
.isEqualTo("ID myclientid-7 is not one of the OT&E client IDs for base myclientid");
}
}

View file

@ -0,0 +1,147 @@
// Copyright 2018 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.model;
import static com.google.common.truth.Truth.assertThat;
import google.registry.model.OteStats.StatType;
import google.registry.testing.AppEngineRule;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@RunWith(JUnit4.class)
public final class OteStatsTest {
@Rule public final AppEngineRule appEngine = AppEngineRule.builder().withDatastore().build();
@Before
public void init() throws Exception {
OteStatsTestHelper.setupHistoryEntries();
}
@Test
public void testSuccess_allPass() {
OteStats stats = OteStats.getFromRegistrar("blobio");
assertThat(stats.getFailures()).isEmpty();
assertThat(stats.getSize()).isEqualTo(31);
}
@Test
public void testSuccess_someFailures() {
OteStatsTestHelper.deleteHostDeleteHistoryEntry();
OteStatsTestHelper.deleteDomainCreateHistoryEntry();
OteStatsTestHelper.deleteDomainRestoreHistoryEntry();
OteStats stats = OteStats.getFromRegistrar("blobio");
assertThat(stats.getFailures())
.containsExactly(
StatType.DOMAIN_CREATES_IDN, StatType.DOMAIN_RESTORES, StatType.HOST_DELETES)
.inOrder();
assertThat(stats.getSize()).isEqualTo(35);
}
@Test
public void testSuccess_toString() {
OteStats stats = OteStats.getFromRegistrar("blobio");
String expected =
"contact creates: 0\n"
+ "contact deletes: 0\n"
+ "contact transfer approves: 0\n"
+ "contact transfer cancels: 0\n"
+ "contact transfer rejects: 0\n"
+ "contact transfer requests: 0\n"
+ "contact updates: 0\n"
+ "domain application creates: 0\n"
+ "domain application creates landrush: 0\n"
+ "domain application creates sunrise: 0\n"
+ "domain application deletes: 0\n"
+ "domain application updates: 0\n"
+ "domain autorenews: 0\n"
+ "domain creates: 5\n"
+ "domain creates ascii: 4\n"
+ "domain creates idn: 1\n"
+ "domain creates start date sunrise: 1\n"
+ "domain creates with claims notice: 1\n"
+ "domain creates with fee: 1\n"
+ "domain creates with sec dns: 1\n"
+ "domain creates without sec dns: 4\n"
+ "domain deletes: 2\n"
+ "domain renews: 0\n"
+ "domain restores: 1\n"
+ "domain transfer approves: 1\n"
+ "domain transfer cancels: 1\n"
+ "domain transfer rejects: 1\n"
+ "domain transfer requests: 1\n"
+ "domain updates: 1\n"
+ "domain updates with sec dns: 1\n"
+ "domain updates without sec dns: 0\n"
+ "host creates: 1\n"
+ "host creates external: 0\n"
+ "host creates subordinate: 1\n"
+ "host deletes: 1\n"
+ "host updates: 1\n"
+ "unclassified flows: 0\n"
+ "TOTAL: 31";
assertThat(stats.toString()).isEqualTo(expected);
}
@Test
public void testMissingHostDeletes_toString() {
OteStatsTestHelper.deleteHostDeleteHistoryEntry();
OteStats stats = OteStats.getFromRegistrar("blobio");
String expected =
"contact creates: 0\n"
+ "contact deletes: 0\n"
+ "contact transfer approves: 0\n"
+ "contact transfer cancels: 0\n"
+ "contact transfer rejects: 0\n"
+ "contact transfer requests: 0\n"
+ "contact updates: 0\n"
+ "domain application creates: 0\n"
+ "domain application creates landrush: 0\n"
+ "domain application creates sunrise: 0\n"
+ "domain application deletes: 0\n"
+ "domain application updates: 0\n"
+ "domain autorenews: 0\n"
+ "domain creates: 5\n"
+ "domain creates ascii: 4\n"
+ "domain creates idn: 1\n"
+ "domain creates start date sunrise: 1\n"
+ "domain creates with claims notice: 1\n"
+ "domain creates with fee: 1\n"
+ "domain creates with sec dns: 1\n"
+ "domain creates without sec dns: 4\n"
+ "domain deletes: 2\n"
+ "domain renews: 0\n"
+ "domain restores: 1\n"
+ "domain transfer approves: 1\n"
+ "domain transfer cancels: 1\n"
+ "domain transfer rejects: 1\n"
+ "domain transfer requests: 1\n"
+ "domain updates: 1\n"
+ "domain updates with sec dns: 1\n"
+ "domain updates without sec dns: 0\n"
+ "host creates: 1\n"
+ "host creates external: 0\n"
+ "host creates subordinate: 1\n"
+ "host deletes: 0\n"
+ "host updates: 10\n"
+ "unclassified flows: 0\n"
+ "TOTAL: 39";
assertThat(stats.toString()).isEqualTo(expected);
}
}

View file

@ -0,0 +1,159 @@
// Copyright 2017 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.model;
import static google.registry.testing.DatastoreHelper.deleteResource;
import static google.registry.testing.DatastoreHelper.persistPremiumList;
import static google.registry.testing.DatastoreHelper.persistResource;
import static google.registry.testing.TestDataHelper.loadBytes;
import static google.registry.util.DateTimeUtils.END_OF_TIME;
import google.registry.model.eppcommon.Trid;
import google.registry.model.reporting.HistoryEntry;
import google.registry.model.reporting.HistoryEntry.Type;
import java.io.IOException;
public final class OteStatsTestHelper {
private static HistoryEntry hostDeleteHistoryEntry;
private static HistoryEntry domainCreateHistoryEntry;
private static HistoryEntry domainRestoreHistoryEntry;
public static void setupHistoryEntries() throws IOException {
persistPremiumList("default_sandbox_list", "sandbox,USD 1000");
persistResource(
new HistoryEntry.Builder()
.setClientId("blobio-1")
.setType(Type.DOMAIN_CREATE)
.setXmlBytes(getBytes("domain_create_sunrise.xml"))
.build());
domainCreateHistoryEntry =
persistResource(
new HistoryEntry.Builder()
.setClientId("blobio-1")
.setType(Type.DOMAIN_CREATE)
.setXmlBytes(getBytes("domain_create_idn.xml"))
.build());
persistResource(
new HistoryEntry.Builder()
.setClientId("blobio-1")
.setType(Type.DOMAIN_CREATE)
.setXmlBytes(getBytes("domain_create_claim_notice.xml"))
.build());
persistResource(
new HistoryEntry.Builder()
.setClientId("blobio-1")
.setType(Type.DOMAIN_CREATE)
.setXmlBytes(getBytes("domain_create_anchor_tenant_fee_standard.xml"))
.build());
persistResource(
new HistoryEntry.Builder()
.setClientId("blobio-1")
.setType(Type.DOMAIN_CREATE)
.setXmlBytes(getBytes("domain_create_dsdata.xml"))
.build());
persistResource(
new HistoryEntry.Builder()
.setClientId("blobio-1")
.setType(Type.DOMAIN_DELETE)
.setXmlBytes(getBytes("domain_delete.xml"))
.build());
persistResource(
new HistoryEntry.Builder()
.setClientId("blobio-2")
.setType(Type.DOMAIN_DELETE)
.setXmlBytes(getBytes("domain_delete.xml"))
.build());
domainRestoreHistoryEntry =
persistResource(
new HistoryEntry.Builder()
.setClientId("blobio-1")
.setType(Type.DOMAIN_RESTORE)
.setXmlBytes(getBytes("domain_restore.xml"))
.build());
persistResource(
new HistoryEntry.Builder()
.setClientId("blobio-1")
.setType(Type.DOMAIN_TRANSFER_APPROVE)
.setXmlBytes(getBytes("domain_transfer_approve.xml"))
.build());
persistResource(
new HistoryEntry.Builder()
.setClientId("blobio-1")
.setType(Type.DOMAIN_TRANSFER_CANCEL)
.setXmlBytes(getBytes("domain_transfer_cancel.xml"))
.build());
persistResource(
new HistoryEntry.Builder()
.setClientId("blobio-1")
.setType(Type.DOMAIN_TRANSFER_REJECT)
.setXmlBytes(getBytes("domain_transfer_reject.xml"))
.build());
persistResource(
new HistoryEntry.Builder()
.setClientId("blobio-1")
.setType(Type.DOMAIN_TRANSFER_REQUEST)
.setXmlBytes(getBytes("domain_transfer_request.xml"))
.build());
persistResource(
new HistoryEntry.Builder()
.setClientId("blobio-1")
.setType(Type.DOMAIN_UPDATE)
.setXmlBytes(getBytes("domain_update_with_secdns.xml"))
.build());
persistResource(
new HistoryEntry.Builder()
.setClientId("blobio-1")
.setType(Type.HOST_CREATE)
.setXmlBytes(getBytes("host_create_complete.xml"))
.build());
hostDeleteHistoryEntry =
persistResource(
new HistoryEntry.Builder()
.setClientId("blobio-1")
.setType(Type.HOST_DELETE)
.setXmlBytes(getBytes("host_delete.xml"))
.build());
// Persist 10 host updates for a total of 25 history entries. Since these also sort last by
// modification time, when these cause all tests to pass, only the first will be recorded and
// the rest will be skipped.
for (int i = 0; i < 10; i++) {
persistResource(
new HistoryEntry.Builder()
.setClientId("blobio-1")
.setType(Type.HOST_UPDATE)
.setXmlBytes(getBytes("host_update.xml"))
.setTrid(Trid.create(null, String.format("blahtrid-%d", i)))
.setModificationTime(END_OF_TIME)
.build());
}
}
public static void deleteHostDeleteHistoryEntry() {
deleteResource(hostDeleteHistoryEntry);
}
public static void deleteDomainCreateHistoryEntry() {
deleteResource(domainCreateHistoryEntry);
}
public static void deleteDomainRestoreHistoryEntry() {
deleteResource(domainRestoreHistoryEntry);
}
private static byte[] getBytes(String filename) throws IOException {
return loadBytes(OteStatsTestHelper.class, filename).read();
}
}

View file

@ -14,7 +14,7 @@
package google.registry.model;
import static google.registry.flows.EppXmlTransformer.marshalInput;
import static google.registry.model.eppcommon.EppXmlTransformer.marshalInput;
import static google.registry.xml.ValidationMode.STRICT;
import static google.registry.xml.XmlTestUtils.assertXmlEquals;
import static java.nio.charset.StandardCharsets.UTF_8;

View file

@ -14,8 +14,8 @@
package google.registry.model.contact;
import static google.registry.flows.EppXmlTransformer.marshalInput;
import static google.registry.flows.EppXmlTransformer.validateInput;
import static google.registry.model.eppcommon.EppXmlTransformer.marshalInput;
import static google.registry.model.eppcommon.EppXmlTransformer.validateInput;
import static google.registry.xml.ValidationMode.LENIENT;
import static google.registry.xml.XmlTestUtils.assertXmlEquals;
import static java.nio.charset.StandardCharsets.UTF_8;

View file

@ -15,6 +15,7 @@
package google.registry.model.contact;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;
import static google.registry.model.EppResourceUtils.loadByForeignKey;
import static google.registry.testing.ContactResourceSubject.assertAboutContacts;
import static google.registry.testing.DatastoreHelper.cloneAndSetAutoTimestamps;
@ -112,7 +113,7 @@ public class ContactResourceTest extends EntityTestCase {
public void testPersistence() {
assertThat(
loadByForeignKey(ContactResource.class, contactResource.getForeignKey(), clock.nowUtc()))
.isEqualTo(contactResource);
.hasValue(contactResource);
}
@Test

View file

@ -15,6 +15,7 @@
package google.registry.model.domain;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;
import static google.registry.model.EppResourceUtils.loadDomainApplication;
import static google.registry.testing.DatastoreHelper.cloneAndSetAutoTimestamps;
import static google.registry.testing.DatastoreHelper.createTld;
@ -88,7 +89,7 @@ public class DomainApplicationTest extends EntityTestCase {
@Test
public void testPersistence() {
assertThat(loadDomainApplication(domainApplication.getForeignKey(), clock.nowUtc()))
.isEqualTo(domainApplication);
.hasValue(domainApplication);
}
@Test
@ -121,7 +122,6 @@ public class DomainApplicationTest extends EntityTestCase {
@Test
public void testEmptySetsAndArraysBecomeNull() {
assertThat(emptyBuilder().setNameservers(null).build().nsHosts).isNull();
assertThat(emptyBuilder().setNameservers(ImmutableSet.of()).build().nsHosts).isNull();
assertThat(
emptyBuilder()

View file

@ -17,6 +17,7 @@ package google.registry.model.domain;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.common.collect.Iterables.getOnlyElement;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;
import static google.registry.model.EppResourceUtils.loadByForeignKey;
import static google.registry.testing.DatastoreHelper.cloneAndSetAutoTimestamps;
import static google.registry.testing.DatastoreHelper.createTld;
@ -92,61 +93,66 @@ public class DomainResourceTest extends EntityTestCase {
Key<PollMessage.OneTime> onetimePollKey =
Key.create(historyEntryKey, PollMessage.OneTime.class, 1);
// Set up a new persisted domain entity.
domain = persistResource(cloneAndSetAutoTimestamps(
new DomainResource.Builder()
.setFullyQualifiedDomainName("example.com")
.setRepoId("4-COM")
.setCreationClientId("a registrar")
.setLastEppUpdateTime(clock.nowUtc())
.setLastEppUpdateClientId("AnotherRegistrar")
.setLastTransferTime(clock.nowUtc())
.setStatusValues(ImmutableSet.of(
StatusValue.CLIENT_DELETE_PROHIBITED,
StatusValue.SERVER_DELETE_PROHIBITED,
StatusValue.SERVER_TRANSFER_PROHIBITED,
StatusValue.SERVER_UPDATE_PROHIBITED,
StatusValue.SERVER_RENEW_PROHIBITED,
StatusValue.SERVER_HOLD))
.setRegistrant(contact1Key)
.setContacts(ImmutableSet.of(DesignatedContact.create(Type.ADMIN, contact2Key)))
.setNameservers(ImmutableSet.of(hostKey))
.setSubordinateHosts(ImmutableSet.of("ns1.example.com"))
.setPersistedCurrentSponsorClientId("ThirdRegistrar")
.setRegistrationExpirationTime(clock.nowUtc().plusYears(1))
.setAuthInfo(DomainAuthInfo.create(PasswordAuth.create("password")))
.setDsData(ImmutableSet.of(DelegationSignerData.create(1, 2, 3, new byte[] {0, 1, 2})))
.setLaunchNotice(
LaunchNotice.create("tcnid", "validatorId", START_OF_TIME, START_OF_TIME))
.setTransferData(
new TransferData.Builder()
.setGainingClientId("gaining")
.setLosingClientId("losing")
.setPendingTransferExpirationTime(clock.nowUtc())
.setServerApproveEntities(
ImmutableSet.of(oneTimeBillKey, recurringBillKey, autorenewPollKey))
.setServerApproveBillingEvent(oneTimeBillKey)
.setServerApproveAutorenewEvent(recurringBillKey)
.setServerApproveAutorenewPollMessage(autorenewPollKey)
.setTransferRequestTime(clock.nowUtc().plusDays(1))
.setTransferStatus(TransferStatus.SERVER_APPROVED)
.setTransferRequestTrid(Trid.create("client-trid", "server-trid"))
.setTransferredRegistrationExpirationTime(clock.nowUtc().plusYears(2))
.build())
.setDeletePollMessage(onetimePollKey)
.setAutorenewBillingEvent(recurringBillKey)
.setAutorenewPollMessage(autorenewPollKey)
.setSmdId("smdid")
.setApplicationTime(START_OF_TIME)
.setApplication(Key.create(DomainApplication.class, 1))
.addGracePeriod(GracePeriod.create(
GracePeriodStatus.ADD, clock.nowUtc().plusDays(1), "registrar", null))
.build()));
domain =
persistResource(
cloneAndSetAutoTimestamps(
new DomainResource.Builder()
.setFullyQualifiedDomainName("example.com")
.setRepoId("4-COM")
.setCreationClientId("a registrar")
.setLastEppUpdateTime(clock.nowUtc())
.setLastEppUpdateClientId("AnotherRegistrar")
.setLastTransferTime(clock.nowUtc())
.setStatusValues(
ImmutableSet.of(
StatusValue.CLIENT_DELETE_PROHIBITED,
StatusValue.SERVER_DELETE_PROHIBITED,
StatusValue.SERVER_TRANSFER_PROHIBITED,
StatusValue.SERVER_UPDATE_PROHIBITED,
StatusValue.SERVER_RENEW_PROHIBITED,
StatusValue.SERVER_HOLD))
.setRegistrant(contact1Key)
.setContacts(ImmutableSet.of(DesignatedContact.create(Type.ADMIN, contact2Key)))
.setNameservers(ImmutableSet.of(hostKey))
.setSubordinateHosts(ImmutableSet.of("ns1.example.com"))
.setPersistedCurrentSponsorClientId("losing")
.setRegistrationExpirationTime(clock.nowUtc().plusYears(1))
.setAuthInfo(DomainAuthInfo.create(PasswordAuth.create("password")))
.setDsData(
ImmutableSet.of(DelegationSignerData.create(1, 2, 3, new byte[] {0, 1, 2})))
.setLaunchNotice(
LaunchNotice.create("tcnid", "validatorId", START_OF_TIME, START_OF_TIME))
.setTransferData(
new TransferData.Builder()
.setGainingClientId("gaining")
.setLosingClientId("losing")
.setPendingTransferExpirationTime(clock.nowUtc())
.setServerApproveEntities(
ImmutableSet.of(oneTimeBillKey, recurringBillKey, autorenewPollKey))
.setServerApproveBillingEvent(oneTimeBillKey)
.setServerApproveAutorenewEvent(recurringBillKey)
.setServerApproveAutorenewPollMessage(autorenewPollKey)
.setTransferRequestTime(clock.nowUtc().plusDays(1))
.setTransferStatus(TransferStatus.SERVER_APPROVED)
.setTransferRequestTrid(Trid.create("client-trid", "server-trid"))
.setTransferredRegistrationExpirationTime(clock.nowUtc().plusYears(2))
.build())
.setDeletePollMessage(onetimePollKey)
.setAutorenewBillingEvent(recurringBillKey)
.setAutorenewPollMessage(autorenewPollKey)
.setSmdId("smdid")
.setApplicationTime(START_OF_TIME)
.setApplication(Key.create(DomainApplication.class, 1))
.addGracePeriod(
GracePeriod.create(
GracePeriodStatus.ADD, clock.nowUtc().plusDays(1), "registrar", null))
.build()));
}
@Test
public void testPersistence() {
assertThat(loadByForeignKey(DomainResource.class, domain.getForeignKey(), clock.nowUtc()))
.isEqualTo(domain);
.hasValue(domain);
}
@Test
@ -182,7 +188,12 @@ public class DomainResourceTest extends EntityTestCase {
@Test
public void testEmptySetsAndArraysBecomeNull() {
assertThat(newDomainResource("example.com").asBuilder().setNameservers(null).build().nsHosts)
assertThat(
newDomainResource("example.com")
.asBuilder()
.setNameservers(ImmutableSet.of())
.build()
.nsHosts)
.isNull();
assertThat(
newDomainResource("example.com")
@ -344,6 +355,89 @@ public class DomainResourceTest extends EntityTestCase {
doExpiredTransferTest(clock.nowUtc().minusDays(1));
}
private void setupPendingTransferDomain(
DateTime oldExpirationTime, DateTime transferRequestTime, DateTime transferSuccessTime) {
domain =
domain
.asBuilder()
.setRegistrationExpirationTime(oldExpirationTime)
.setTransferData(
domain
.getTransferData()
.asBuilder()
.setTransferStatus(TransferStatus.PENDING)
.setTransferRequestTime(transferRequestTime)
.setPendingTransferExpirationTime(transferSuccessTime)
.build())
.setLastEppUpdateTime(transferRequestTime)
.setLastEppUpdateClientId(domain.getTransferData().getGainingClientId())
.build();
}
@Test
public void testEppLastUpdateTimeAndClientId_autoRenewBeforeTransferSuccess() {
DateTime now = clock.nowUtc();
DateTime transferRequestDateTime = now.plusDays(1);
DateTime autorenewDateTime = now.plusDays(3);
DateTime transferSuccessDateTime = now.plusDays(5);
setupPendingTransferDomain(autorenewDateTime, transferRequestDateTime, transferSuccessDateTime);
DomainResource beforeAutoRenew = domain.cloneProjectedAtTime(autorenewDateTime.minusDays(1));
assertThat(beforeAutoRenew.getLastEppUpdateTime()).isEqualTo(transferRequestDateTime);
assertThat(beforeAutoRenew.getLastEppUpdateClientId()).isEqualTo("gaining");
// If autorenew happens before transfer succeeds(before transfer grace period starts as well),
// lastEppUpdateClientId should still be the current sponsor client id
DomainResource afterAutoRenew = domain.cloneProjectedAtTime(autorenewDateTime.plusDays(1));
assertThat(afterAutoRenew.getLastEppUpdateTime()).isEqualTo(autorenewDateTime);
assertThat(afterAutoRenew.getLastEppUpdateClientId()).isEqualTo("losing");
}
@Test
public void testEppLastUpdateTimeAndClientId_autoRenewAfterTransferSuccess() {
DateTime now = clock.nowUtc();
DateTime transferRequestDateTime = now.plusDays(1);
DateTime autorenewDateTime = now.plusDays(3);
DateTime transferSuccessDateTime = now.plusDays(5);
setupPendingTransferDomain(autorenewDateTime, transferRequestDateTime, transferSuccessDateTime);
DomainResource beforeAutoRenew = domain.cloneProjectedAtTime(autorenewDateTime.minusDays(1));
assertThat(beforeAutoRenew.getLastEppUpdateTime()).isEqualTo(transferRequestDateTime);
assertThat(beforeAutoRenew.getLastEppUpdateClientId()).isEqualTo("gaining");
DomainResource afterTransferSuccess =
domain.cloneProjectedAtTime(transferSuccessDateTime.plusDays(1));
assertThat(afterTransferSuccess.getLastEppUpdateTime()).isEqualTo(transferSuccessDateTime);
assertThat(afterTransferSuccess.getLastEppUpdateClientId()).isEqualTo("gaining");
}
private void setupUnmodifiedDomain(DateTime oldExpirationTime) {
domain =
domain
.asBuilder()
.setRegistrationExpirationTime(oldExpirationTime)
.setTransferData(TransferData.EMPTY)
.setGracePeriods(ImmutableSet.of())
.setLastEppUpdateTime(null)
.setLastEppUpdateClientId(null)
.build();
}
@Test
public void testEppLastUpdateTimeAndClientId_isSetCorrectlyWithNullPreviousValue() {
DateTime now = clock.nowUtc();
DateTime autorenewDateTime = now.plusDays(3);
setupUnmodifiedDomain(autorenewDateTime);
DomainResource beforeAutoRenew = domain.cloneProjectedAtTime(autorenewDateTime.minusDays(1));
assertThat(beforeAutoRenew.getLastEppUpdateTime()).isEqualTo(null);
assertThat(beforeAutoRenew.getLastEppUpdateClientId()).isEqualTo(null);
DomainResource afterAutoRenew = domain.cloneProjectedAtTime(autorenewDateTime.plusDays(1));
assertThat(afterAutoRenew.getLastEppUpdateTime()).isEqualTo(autorenewDateTime);
assertThat(afterAutoRenew.getLastEppUpdateClientId()).isEqualTo("losing");
}
@Test
public void testStackedGracePeriods() {
ImmutableList<GracePeriod> gracePeriods = ImmutableList.of(
@ -383,7 +477,7 @@ public class DomainResourceTest extends EntityTestCase {
domain.cloneProjectedAtTime(domain.getRegistrationExpirationTime());
assertThat(renewed.getRegistrationExpirationTime())
.isEqualTo(domain.getRegistrationExpirationTime().plusYears(1));
assertThat(renewed.getLastEppUpdateTime()).isEqualTo(clock.nowUtc());
assertThat(renewed.getLastEppUpdateTime()).isEqualTo(domain.getRegistrationExpirationTime());
assertThat(getOnlyElement(renewed.getGracePeriods()).getType())
.isEqualTo(GracePeriodStatus.AUTO_RENEW);
}
@ -428,7 +522,7 @@ public class DomainResourceTest extends EntityTestCase {
domain.cloneProjectedAtTime(oldExpirationTime.plusYears(2));
assertThat(renewedThreeTimes.getRegistrationExpirationTime())
.isEqualTo(oldExpirationTime.plusYears(3));
assertThat(renewedThreeTimes.getLastEppUpdateTime()).isEqualTo(clock.nowUtc());
assertThat(renewedThreeTimes.getLastEppUpdateTime()).isEqualTo(oldExpirationTime.plusYears(2));
assertThat(renewedThreeTimes.getGracePeriods())
.containsExactly(GracePeriod.createForRecurring(
GracePeriodStatus.AUTO_RENEW,

View file

@ -12,11 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.flows;
package google.registry.model.eppcommon;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.flows.EppXmlTransformer.unmarshal;
import static google.registry.model.eppcommon.EppXmlTransformer.unmarshal;
import static google.registry.testing.JUnitBackports.assertThrows;
import static google.registry.testing.TestDataHelper.loadBytes;
@ -41,8 +40,6 @@ public class EppXmlTransformerTest extends ShardableTestCase {
public void testUnmarshalingWrongClassThrows() {
assertThrows(
ClassCastException.class,
() ->
EppXmlTransformer.unmarshal(
EppOutput.class, loadBytes(getClass(), "contact_info.xml").read()));
() -> unmarshal(EppOutput.class, loadBytes(getClass(), "contact_info.xml").read()));
}
}

View file

@ -0,0 +1,14 @@
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
<command>
<info>
<contact:info
xmlns:contact="urn:ietf:params:xml:ns:contact-1.0">
<contact:id>sh8013</contact:id>
<contact:authInfo>
<contact:pw>2fooBAR</contact:pw>
</contact:authInfo>
</contact:info>
</info>
<clTRID>ABC-12345</clTRID>
</command>
</epp>

View file

@ -16,15 +16,15 @@ package google.registry.model.eppinput;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;
import static google.registry.flows.EppXmlTransformer.unmarshal;
import static google.registry.model.eppcommon.EppXmlTransformer.unmarshal;
import static google.registry.testing.JUnitBackports.assertThrows;
import static google.registry.testing.TestDataHelper.loadBytes;
import google.registry.flows.EppException.SyntaxErrorException;
import google.registry.model.contact.ContactResourceTest;
import google.registry.model.domain.DomainResourceTest;
import google.registry.model.eppinput.EppInput.InnerCommand;
import google.registry.model.eppinput.EppInput.Login;
import google.registry.xml.XmlException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@ -83,7 +83,7 @@ public class EppInputTest {
@Test
public void testUnmarshalling_loginTagInWrongCase_throws() {
assertThrows(
SyntaxErrorException.class,
XmlException.class,
() -> unmarshal(EppInput.class, loadBytes(getClass(), "login_wrong_case.xml").read()));
}
}

View file

@ -15,6 +15,7 @@
package google.registry.model.host;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;
import static google.registry.model.EppResourceUtils.loadByForeignKey;
import static google.registry.testing.DatastoreHelper.cloneAndSetAutoTimestamps;
import static google.registry.testing.DatastoreHelper.createTld;
@ -86,9 +87,8 @@ public class HostResourceTest extends EntityTestCase {
@Test
public void testPersistence() {
assertThat(loadByForeignKey(
HostResource.class, host.getForeignKey(), clock.nowUtc()))
.isEqualTo(host);
assertThat(loadByForeignKey(HostResource.class, host.getForeignKey(), clock.nowUtc()))
.hasValue(host);
}
@Test

View file

@ -15,6 +15,8 @@
package google.registry.model.index;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;
import static google.registry.model.EppResourceUtils.loadByForeignKey;
import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.testing.DatastoreHelper.createTld;
import static google.registry.testing.DatastoreHelper.deleteResource;
@ -29,7 +31,6 @@ import com.google.common.cache.CacheBuilder;
import com.google.common.collect.ImmutableList;
import com.googlecode.objectify.Key;
import google.registry.model.EntityTestCase;
import google.registry.model.EppResourceUtils;
import google.registry.model.contact.ContactResource;
import google.registry.model.host.HostResource;
import google.registry.model.index.ForeignKeyIndex.ForeignKeyHostIndex;
@ -180,10 +181,8 @@ public class ForeignKeyIndexTest extends EntityTestCase {
clock.advanceOneMilli();
ForeignKeyIndex<HostResource> newFki = loadHostFki("ns1.example.com");
assertThat(newFki).isNotEqualTo(originalFki);
assertThat(
EppResourceUtils.loadByForeignKey(
HostResource.class, "ns1.example.com", clock.nowUtc()))
.isEqualTo(modifiedHost);
assertThat(loadByForeignKey(HostResource.class, "ns1.example.com", clock.nowUtc()))
.hasValue(modifiedHost);
assertThat(
ForeignKeyIndex.loadCached(
HostResource.class, ImmutableList.of("ns1.example.com"), clock.nowUtc()))

View file

@ -23,6 +23,7 @@ import static google.registry.testing.CertificateSamples.SAMPLE_CERT2_HASH;
import static google.registry.testing.CertificateSamples.SAMPLE_CERT_HASH;
import static google.registry.testing.DatastoreHelper.cloneAndSetAutoTimestamps;
import static google.registry.testing.DatastoreHelper.createTld;
import static google.registry.testing.DatastoreHelper.newRegistry;
import static google.registry.testing.DatastoreHelper.persistResource;
import static google.registry.testing.DatastoreHelper.persistSimpleResource;
import static google.registry.testing.DatastoreHelper.persistSimpleResources;
@ -33,10 +34,12 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.googlecode.objectify.Key;
import google.registry.config.RegistryConfig;
import google.registry.model.EntityTestCase;
import google.registry.model.common.EntityGroupRoot;
import google.registry.model.registrar.Registrar.State;
import google.registry.model.registrar.Registrar.Type;
import google.registry.model.registry.Registries;
import google.registry.util.CidrAddressBlock;
import org.joda.money.CurrencyUnit;
import org.junit.Before;
@ -415,6 +418,84 @@ public class RegistrarTest extends EntityTestCase {
IllegalArgumentException.class, () -> new Registrar.Builder().setPhonePasscode("code1"));
}
@Test
public void testSuccess_setAllowedTlds() {
assertThat(
registrar.asBuilder()
.setAllowedTlds(ImmutableSet.of("xn--q9jyb4c"))
.build()
.getAllowedTlds())
.containsExactly("xn--q9jyb4c");
}
@Test
public void testSuccess_setAllowedTldsUncached() {
assertThat(
registrar.asBuilder()
.setAllowedTldsUncached(ImmutableSet.of("xn--q9jyb4c"))
.build()
.getAllowedTlds())
.containsExactly("xn--q9jyb4c");
}
@Test
public void testFailure_setAllowedTlds_nonexistentTld() {
assertThrows(
IllegalArgumentException.class,
() -> registrar.asBuilder().setAllowedTlds(ImmutableSet.of("bad")));
}
@Test
public void testFailure_setAllowedTldsUncached_nonexistentTld() {
assertThrows(
IllegalArgumentException.class,
() -> registrar.asBuilder().setAllowedTldsUncached(ImmutableSet.of("bad")));
}
@Test
public void testSuccess_setAllowedTldsUncached_newTldNotInCache() {
try {
// Cache duration in tests is 0. To make sure the data isn't in the cache we have to set it
// to a higher value and reset the cache.
RegistryConfig.CONFIG_SETTINGS.get().caching.singletonCacheRefreshSeconds = 600;
Registries.resetCache();
// Make sure the TLD we want to create doesn't exist yet.
// This is also important because getTlds fills out the cache when used.
assertThat(Registries.getTlds()).doesNotContain("newtld");
// We can't use createTld here because it failes when the cache is used.
persistResource(newRegistry("newtld", "NEWTLD"));
// Make sure we set up the cache correctly, so the newly created TLD isn't in the cache
assertThat(Registries.getTlds()).doesNotContain("newtld");
// Test that the uncached version works
assertThat(
registrar
.asBuilder()
.setAllowedTldsUncached(ImmutableSet.of("newtld"))
.build()
.getAllowedTlds())
.containsExactly("newtld");
// Test that the "regular" cached version fails. If this doesn't throw - then we changed how
// the cached version works:
// - either we switched to a different cache type/duration, and we haven't actually set up
// that cache in the test
// - or we stopped using the cache entirely and we should rethink if the Uncached version is
// still needed
assertThrows(
IllegalArgumentException.class,
() -> registrar.asBuilder().setAllowedTlds(ImmutableSet.of("newtld")));
// Make sure the cache hasn't expired during the test and "newtld" is still not in the cached
// TLDs
assertThat(Registries.getTlds()).doesNotContain("newtld");
} finally {
// Set the cache duration back to 0 to satisfy other tests.
RegistryConfig.CONFIG_SETTINGS.get().caching.singletonCacheRefreshSeconds = 0;
Registries.resetCache();
}
}
@Test
public void testLoadByClientIdCached_isTransactionless() {
ofy()

View file

@ -26,6 +26,7 @@ import static google.registry.model.registry.label.DomainLabelMetrics.PremiumLis
import static google.registry.model.registry.label.DomainLabelMetrics.PremiumListCheckOutcome.UNCACHED_POSITIVE;
import static google.registry.model.registry.label.DomainLabelMetrics.premiumListChecks;
import static google.registry.model.registry.label.DomainLabelMetrics.premiumListProcessingTime;
import static google.registry.model.registry.label.PremiumList.createCachePremiumLists;
import static google.registry.model.registry.label.PremiumListUtils.deletePremiumList;
import static google.registry.model.registry.label.PremiumListUtils.doesPremiumListExist;
import static google.registry.model.registry.label.PremiumListUtils.getPremiumPrice;
@ -35,7 +36,7 @@ import static google.registry.testing.DatastoreHelper.loadPremiumListEntries;
import static google.registry.testing.DatastoreHelper.persistPremiumList;
import static google.registry.testing.DatastoreHelper.persistResource;
import static google.registry.testing.JUnitBackports.assertThrows;
import static org.joda.time.Duration.standardMinutes;
import static org.joda.time.Duration.standardDays;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@ -63,9 +64,11 @@ public class PremiumListUtilsTest {
@Before
public void before() {
// createTld() overwrites the premium list, so call it first.
// Set long persist times on caches so they can be tested (cache times default to 0 in tests).
PremiumList.cachePremiumListEntries =
PremiumList.createCachePremiumListEntries(standardMinutes(1));
PremiumList.createCachePremiumListEntries(standardDays(1));
PremiumList.cachePremiumLists = createCachePremiumLists(standardDays(1));
// createTld() overwrites the premium list, so call it first.
createTld("tld");
PremiumList pl =
persistPremiumList(
@ -309,6 +312,16 @@ public class PremiumListUtilsTest {
assertThat(entriesReloaded.get("test").parent).isEqualTo(resaved.getRevisionKey());
}
@Test
public void test_savePremiumListAndEntries_clearsCache() {
assertThat(PremiumList.cachePremiumLists.getIfPresent("tld")).isNull();
PremiumList pl = PremiumList.getCached("tld").get();
assertThat(PremiumList.cachePremiumLists.getIfPresent("tld")).isEqualTo(pl);
savePremiumListAndEntries(
new PremiumList.Builder().setName("tld").build(), ImmutableList.of("test,USD 1"));
assertThat(PremiumList.cachePremiumLists.getIfPresent("tld")).isNull();
}
@Test
public void testDelete() {
persistPremiumList("gtld1", "trombone,USD 10");

View file

@ -0,0 +1,29 @@
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
<command>
<create>
<domain:create
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
<domain:name>example.tld</domain:name>
<domain:period unit="y">2</domain:period>
<domain:registrant>jd1234</domain:registrant>
<domain:contact type="admin">jd1234</domain:contact>
<domain:contact type="tech">jd1234</domain:contact>
<domain:authInfo>
<domain:pw>abcdefghijklmnop</domain:pw>
</domain:authInfo>
</domain:create>
</create>
<extension>
<metadata:metadata xmlns:metadata="urn:google:params:xml:ns:metadata-1.0">
<metadata:reason>anchor-tenant-test</metadata:reason>
<metadata:requestedByRegistrar>false</metadata:requestedByRegistrar>
<metadata:anchorTenant>true</metadata:anchorTenant>
</metadata:metadata>
<fee:create xmlns:fee="urn:ietf:params:xml:ns:fee-0.6">
<fee:currency>USD</fee:currency>
<fee:fee>26.00</fee:fee>
</fee:create>
</extension>
<clTRID>RegistryTool</clTRID>
</command>
</epp>

View file

@ -0,0 +1,17 @@
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
<command>
<delete>
<domain:delete
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
<domain:name>example.tld</domain:name>
</domain:delete>
</delete>
<extension>
<metadata:metadata xmlns:metadata="urn:google:params:xml:ns:metadata-1.0">
<metadata:reason>Deleted by registry administrator: Test</metadata:reason>
<metadata:requestedByRegistrar>false</metadata:requestedByRegistrar>
</metadata:metadata>
</extension>
<clTRID>RegistryTool</clTRID>
</command>
</epp>

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