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

@ -16,12 +16,12 @@ package google.registry.tools;
import static com.google.common.io.BaseEncoding.base16;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.flows.EppXmlTransformer.unmarshal;
import static google.registry.flows.picker.FlowPicker.getFlowClass;
import static google.registry.model.domain.DesignatedContact.Type.ADMIN;
import static google.registry.model.domain.DesignatedContact.Type.BILLING;
import static google.registry.model.domain.DesignatedContact.Type.TECH;
import static google.registry.model.domain.launch.ApplicationStatus.VALIDATED;
import static google.registry.model.eppcommon.EppXmlTransformer.unmarshal;
import static google.registry.model.registry.Registry.TldState.QUIET_PERIOD;
import static google.registry.testing.DatastoreHelper.createTld;
import static google.registry.testing.DatastoreHelper.newDomainApplication;

View file

@ -0,0 +1,143 @@
// Copyright 2019 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.tools;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.security.JsonHttp.JSON_SAFETY_PREFIX;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.mockito.Mockito.when;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.LowLevelHttpRequest;
import com.google.api.client.http.LowLevelHttpResponse;
import com.google.common.collect.ImmutableMap;
import com.google.common.net.MediaType;
import google.registry.testing.MockitoJUnitRule;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.HashMap;
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;
@RunWith(JUnit4.class)
public final class AppEngineConnectionTest {
@Rule public final MockitoJUnitRule mocks = MockitoJUnitRule.create();
AppEngineConnection connection;
TestHttpTransport httpTransport;
TestLowLevelHttpRequest lowLevelHttpRequest;
@Mock LowLevelHttpResponse lowLevelHttpResponse;
private final class TestHttpTransport extends HttpTransport {
String method = null;
String url = null;
@Override
protected LowLevelHttpRequest buildRequest(String method, String url) {
// Make sure we only visit once
assertThat(this.method).isNull();
this.method = method;
this.url = url;
return lowLevelHttpRequest;
}
}
private final class TestLowLevelHttpRequest extends LowLevelHttpRequest {
final HashMap<String, String> headers = new HashMap<>();
@Override
public void addHeader(String name, String value) {
headers.put(name, value);
}
@Override
public LowLevelHttpResponse execute() {
return lowLevelHttpResponse;
}
String getContentString() throws Exception {
ByteArrayOutputStream output = new ByteArrayOutputStream();
getStreamingContent().writeTo(output);
output.close();
return new String(output.toByteArray(), UTF_8);
}
}
@Before
public void setUp() throws Exception {
lowLevelHttpRequest = new TestLowLevelHttpRequest();
when(lowLevelHttpResponse.getContent())
.thenReturn(new ByteArrayInputStream("MyContent".getBytes(UTF_8)));
when(lowLevelHttpResponse.getStatusCode()).thenReturn(200);
connection = new AppEngineConnection();
httpTransport = new TestHttpTransport();
connection.requestFactory = httpTransport.createRequestFactory();
}
@Test
public void testSendGetRequest() throws Exception {
assertThat(
connection.sendGetRequest(
"/my/path?query", ImmutableMap.of("key1", "value1", "key2", "value2")))
.isEqualTo("MyContent");
assertThat(httpTransport.method).isEqualTo("GET");
assertThat(httpTransport.url)
.isEqualTo("https://localhost/my/path?query&key1=value1&key2=value2");
assertThat(lowLevelHttpRequest.headers).containsEntry("Cache-Control", "no-cache");
assertThat(lowLevelHttpRequest.headers).containsEntry("x-requested-with", "RegistryTool");
}
@Test
public void testSendPostRequest() throws Exception {
assertThat(
connection.sendPostRequest(
"/my/path?query",
ImmutableMap.of("key1", "value1", "key2", "value2"),
MediaType.PLAIN_TEXT_UTF_8,
"some data".getBytes(UTF_8)))
.isEqualTo("MyContent");
assertThat(httpTransport.method).isEqualTo("POST");
assertThat(httpTransport.url)
.isEqualTo("https://localhost/my/path?query&key1=value1&key2=value2");
assertThat(lowLevelHttpRequest.getContentType()).isEqualTo("text/plain; charset=utf-8");
assertThat(lowLevelHttpRequest.getContentString()).isEqualTo("some data");
assertThat(lowLevelHttpRequest.headers).containsEntry("Cache-Control", "no-cache");
assertThat(lowLevelHttpRequest.headers).containsEntry("x-requested-with", "RegistryTool");
}
@Test
public void testSendJsonRequest() throws Exception {
when(lowLevelHttpResponse.getContent())
.thenReturn(
new ByteArrayInputStream((JSON_SAFETY_PREFIX + "{\"key\":\"value\"}").getBytes(UTF_8)));
assertThat(
connection.sendJson(
"/my/path?query", ImmutableMap.of("string", "value1", "bool", true)))
.containsExactly("key", "value");
assertThat(httpTransport.method).isEqualTo("POST");
assertThat(httpTransport.url).isEqualTo("https://localhost/my/path?query");
assertThat(lowLevelHttpRequest.getContentType()).isEqualTo("application/json; charset=utf-8");
assertThat(lowLevelHttpRequest.getContentString())
.isEqualTo("{\"string\":\"value1\",\"bool\":true}");
assertThat(lowLevelHttpRequest.headers).containsEntry("Cache-Control", "no-cache");
assertThat(lowLevelHttpRequest.headers).containsEntry("x-requested-with", "RegistryTool");
}
}

View file

@ -16,37 +16,66 @@ package google.registry.tools;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.testing.JUnitBackports.assertThrows;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import com.google.api.client.auth.oauth2.ClientParametersAuthentication;
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.auth.oauth2.StoredCredential;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.store.AbstractDataStoreFactory;
import com.google.api.client.util.store.DataStore;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableList;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.nio.file.Files;
import java.util.Map;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/** Unit tests for {@link AuthModule}. */
@RunWith(JUnit4.class)
public class AuthModuleTest {
private static final String TEST_CLIENT_SECRET_FILENAME =
"/google/registry/tools/resources/client_secret_UNITTEST.json";
private static final Credential FAKE_CREDENTIAL = new Credential(
new Credential.AccessMethod() {
@Override
public void intercept(HttpRequest request, String accessToken) {}
private static final String CLIENT_ID = "UNITTEST-CLIENT-ID";
private static final String CLIENT_SECRET = "UNITTEST-CLIENT-SECRET";
private static final String ACCESS_TOKEN = "FakeAccessToken";
private static final String REFRESH_TOKEN = "FakeReFreshToken";
@Override
public String getAccessTokenFromRequest(HttpRequest request) {
return "MockAccessToken";
}
});
@Rule
public final TemporaryFolder folder = new TemporaryFolder();
private final Credential fakeCredential =
new Credential.Builder(
new Credential.AccessMethod() {
@Override
public void intercept(HttpRequest request, String accessToken) {}
@Override
public String getAccessTokenFromRequest(HttpRequest request) {
return ACCESS_TOKEN;
}
})
// We need to set the following fields because they are checked when
// Credential#setRefreshToken is called. However they are not actually persisted in the
// DataStore and not actually used in tests.
.setJsonFactory(new JacksonFactory())
.setTransport(new NetHttpTransport())
.setTokenServerUrl(new GenericUrl("https://accounts.google.com/o/oauth2/token"))
.setClientAuthentication(new ClientParametersAuthentication(CLIENT_ID, CLIENT_SECRET))
.build();
@SuppressWarnings("unchecked")
DataStore<StoredCredential> dataStore = mock(DataStore.class);
@ -59,11 +88,17 @@ public class AuthModuleTest {
return result;
}
}
@Before
public void setUp() throws Exception {
fakeCredential.setRefreshToken(REFRESH_TOKEN);
when(dataStore.get(CLIENT_ID + " scope1")).thenReturn(new StoredCredential(fakeCredential));
}
@Test
public void test_clientScopeQualifier() {
AuthModule authModule = new AuthModule();
String simpleQualifier =
authModule.provideClientScopeQualifier("client-id", ImmutableSet.of("foo", "bar"));
AuthModule.provideClientScopeQualifier("client-id", ImmutableList.of("foo", "bar"));
// If we change the way we encode client id and scopes, this assertion will break. That's
// probably ok and you can just change the text. The things you have to be aware of are:
@ -73,59 +108,92 @@ public class AuthModuleTest {
assertThat(simpleQualifier).isEqualTo("client-id bar foo");
// Verify order independence.
assertThat(simpleQualifier).isEqualTo(
authModule.provideClientScopeQualifier("client-id", ImmutableSet.of("bar", "foo")));
assertThat(simpleQualifier)
.isEqualTo(
AuthModule.provideClientScopeQualifier("client-id", ImmutableList.of("bar", "foo")));
// Verify changing client id produces a different value.
assertThat(simpleQualifier).isNotEqualTo(
authModule.provideClientScopeQualifier("new-client", ImmutableSet.of("bar", "foo")));
assertThat(simpleQualifier)
.isNotEqualTo(
AuthModule.provideClientScopeQualifier("new-client", ImmutableList.of("bar", "foo")));
// Verify that adding/deleting/modifying scopes produces a different value.
assertThat(simpleQualifier).isNotEqualTo(
authModule.provideClientScopeQualifier("client id", ImmutableSet.of("bar", "foo", "baz")));
assertThat(simpleQualifier).isNotEqualTo(
authModule.provideClientScopeQualifier("client id", ImmutableSet.of("barx", "foo")));
assertThat(simpleQualifier).isNotEqualTo(
authModule.provideClientScopeQualifier("client id", ImmutableSet.of("bar", "foox")));
assertThat(simpleQualifier).isNotEqualTo(
authModule.provideClientScopeQualifier("client id", ImmutableSet.of("bar")));
assertThat(simpleQualifier)
.isNotEqualTo(
AuthModule.provideClientScopeQualifier(
"client id", ImmutableList.of("bar", "foo", "baz")));
assertThat(simpleQualifier)
.isNotEqualTo(
AuthModule.provideClientScopeQualifier("client id", ImmutableList.of("barx", "foo")));
assertThat(simpleQualifier)
.isNotEqualTo(
AuthModule.provideClientScopeQualifier("client id", ImmutableList.of("bar", "foox")));
assertThat(simpleQualifier)
.isNotEqualTo(AuthModule.provideClientScopeQualifier("client id", ImmutableList.of("bar")));
// Verify that delimiting works.
assertThat(simpleQualifier).isNotEqualTo(
authModule.provideClientScopeQualifier("client-id", ImmutableSet.of("barf", "oo")));
assertThat(simpleQualifier).isNotEqualTo(
authModule.provideClientScopeQualifier("client-idb", ImmutableSet.of("ar", "foo")));
assertThat(simpleQualifier)
.isNotEqualTo(
AuthModule.provideClientScopeQualifier("client-id", ImmutableList.of("barf", "oo")));
assertThat(simpleQualifier)
.isNotEqualTo(
AuthModule.provideClientScopeQualifier("client-idb", ImmutableList.of("ar", "foo")));
}
private Credential getCredential() {
// Reconstruct the entire dependency graph, injecting FakeDatastoreFactory and credential
// parameters.
AuthModule authModule = new AuthModule();
JacksonFactory jsonFactory = new JacksonFactory();
GoogleClientSecrets clientSecrets =
authModule.provideClientSecrets(TEST_CLIENT_SECRET_FILENAME, jsonFactory);
ImmutableSet<String> scopes = ImmutableSet.of("scope1");
return authModule.provideCredential(
authModule.provideAuthorizationCodeFlow(
GoogleClientSecrets clientSecrets = getSecrets();
ImmutableList<String> scopes = ImmutableList.of("scope1");
return AuthModule.provideCredential(
AuthModule.provideAuthorizationCodeFlow(
jsonFactory, clientSecrets, scopes, new FakeDataStoreFactory()),
authModule.provideClientScopeQualifier(authModule.provideClientId(clientSecrets), scopes));
AuthModule.provideClientScopeQualifier(AuthModule.provideClientId(clientSecrets), scopes));
}
private GoogleClientSecrets getSecrets() {
return new GoogleClientSecrets()
.setInstalled(
AuthModule.provideDefaultInstalledDetails()
.setClientId(CLIENT_ID)
.setClientSecret(CLIENT_SECRET));
}
@Test
public void test_provideCredential() throws Exception {
when(dataStore.get("UNITTEST-CLIENT-ID scope1")).thenReturn(
new StoredCredential(FAKE_CREDENTIAL));
public void test_provideLocalCredentialJson() {
String credentialJson =
AuthModule.provideLocalCredentialJson(this::getSecrets, this::getCredential, null);
Map<String, String> jsonMap =
new Gson().fromJson(credentialJson, new TypeToken<Map<String, String>>() {}.getType());
assertThat(jsonMap.get("type")).isEqualTo("authorized_user");
assertThat(jsonMap.get("client_secret")).isEqualTo(CLIENT_SECRET);
assertThat(jsonMap.get("client_id")).isEqualTo(CLIENT_ID);
assertThat(jsonMap.get("refresh_token")).isEqualTo(REFRESH_TOKEN);
}
@Test
public void test_provideExternalCredentialJson() throws Exception {
File credentialFile = folder.newFile("credential.json");
Files.write(credentialFile.toPath(), "{some_field: some_value}".getBytes(UTF_8));
String credentialJson =
AuthModule.provideLocalCredentialJson(
this::getSecrets, this::getCredential, credentialFile.getCanonicalPath());
assertThat(credentialJson).isEqualTo("{some_field: some_value}");
}
@Test
public void test_provideCredential() {
Credential cred = getCredential();
assertThat(cred.getAccessToken()).isEqualTo(FAKE_CREDENTIAL.getAccessToken());
assertThat(cred.getRefreshToken()).isEqualTo(FAKE_CREDENTIAL.getRefreshToken());
assertThat(cred.getExpirationTimeMilliseconds()).isEqualTo(
FAKE_CREDENTIAL.getExpirationTimeMilliseconds());
assertThat(cred.getAccessToken()).isEqualTo(fakeCredential.getAccessToken());
assertThat(cred.getRefreshToken()).isEqualTo(fakeCredential.getRefreshToken());
assertThat(cred.getExpirationTimeMilliseconds())
.isEqualTo(fakeCredential.getExpirationTimeMilliseconds());
}
@Test
public void test_provideCredential_notStored() {
// Doing this without the mock setup should cause us to throw an exception because the
// credential has not been stored.
public void test_provideCredential_notStored() throws IOException {
when(dataStore.get(CLIENT_ID + " scope1")).thenReturn(null);
assertThrows(AuthModule.LoginRequiredException.class, this::getCredential);
}
}

View file

@ -24,12 +24,14 @@ java_library(
"//java/google/registry/model",
"//java/google/registry/rde",
"//java/google/registry/request",
"//java/google/registry/security",
"//java/google/registry/tmch",
"//java/google/registry/tools",
"//java/google/registry/tools/params",
"//java/google/registry/tools/server",
"//java/google/registry/util",
"//java/google/registry/xml",
"//javatests/google/registry/flows",
"//javatests/google/registry/rde",
"//javatests/google/registry/testing",
"//javatests/google/registry/tmch",
@ -39,11 +41,13 @@ java_library(
"//third_party/objectify:objectify-v4_1",
"@com_beust_jcommander",
"@com_google_api_client",
"@com_google_apis_google_api_services_appengine",
"@com_google_apis_google_api_services_dns",
"@com_google_appengine_api_1_0_sdk",
"@com_google_appengine_remote_api",
"@com_google_auto_value",
"@com_google_code_findbugs_jsr305",
"@com_google_code_gson",
"@com_google_guava",
"@com_google_http_client",
"@com_google_http_client_jackson2",

View file

@ -32,6 +32,7 @@ import google.registry.model.poll.PollMessage;
import google.registry.testing.AppEngineRule;
import google.registry.testing.CertificateSamples;
import google.registry.testing.MockitoJUnitRule;
import google.registry.testing.SystemPropertyRule;
import google.registry.tools.params.ParameterFactory;
import java.io.ByteArrayOutputStream;
import java.io.File;
@ -61,6 +62,8 @@ public abstract class CommandTestCase<C extends Command> {
public final AppEngineRule appEngine =
AppEngineRule.builder().withDatastore().withTaskQueue().build();
@Rule public final SystemPropertyRule systemPropertyRule = new SystemPropertyRule();
@Rule public final MockitoJUnitRule mocks = MockitoJUnitRule.create();
@Rule
@ -69,14 +72,14 @@ public abstract class CommandTestCase<C extends Command> {
@Before
public final void beforeCommandTestCase() {
// Ensure the UNITTEST environment has been set before constructing a new command instance.
RegistryToolEnvironment.UNITTEST.setup();
RegistryToolEnvironment.UNITTEST.setup(systemPropertyRule);
command = newCommandInstance();
System.setOut(new PrintStream(stdout));
System.setErr(new PrintStream(stderr));
}
void runCommandInEnvironment(RegistryToolEnvironment env, String... args) throws Exception {
env.setup();
env.setup(systemPropertyRule);
try {
JCommander jcommander = new JCommander(command);
jcommander.addConverterFactory(new ParameterFactory());
@ -87,7 +90,7 @@ public abstract class CommandTestCase<C extends Command> {
// This primarily matters for AutoTimestamp fields, which otherwise won't have updated values.
ofy().clearSessionCache();
// Reset back to UNITTEST environment.
RegistryToolEnvironment.UNITTEST.setup();
RegistryToolEnvironment.UNITTEST.setup(systemPropertyRule);
}
}
@ -188,6 +191,10 @@ public abstract class CommandTestCase<C extends Command> {
assertThat(getStdoutAsString()).doesNotContain(expected);
}
protected void assertNotInStderr(String expected) {
assertThat(getStderrAsString()).doesNotContain(expected);
}
protected String getStdoutAsString() {
return new String(stdout.toByteArray(), UTF_8);
}

View file

@ -82,7 +82,7 @@ public final class ComparableEntityTest {
EntityProto proto1 = EntityTranslator.convertToPb(entity);
entity.setProperty("moe!", 400);
entity.setProperty("tiger!", 400);
EntityProto proto2 = EntityTranslator.convertToPb(entity);
// Construct entity objects from the two protos.

View file

@ -79,6 +79,37 @@ public class CurlCommandTest extends CommandTestCase<CurlCommand> {
eq("some data".getBytes(UTF_8)));
}
@Test
public void testPostInvocation_withContentType() throws Exception {
runCommand(
"--path=/foo/bar?a=1&b=2",
"--data=some data",
"--service=DEFAULT",
"--content-type=application/json");
verify(connection).withService(DEFAULT);
verifyNoMoreInteractions(connection);
verify(connectionForService)
.sendPostRequest(
eq("/foo/bar?a=1&b=2"),
eq(ImmutableMap.<String, String>of()),
eq(MediaType.JSON_UTF_8),
eq("some data".getBytes(UTF_8)));
}
@Test
public void testPostInvocation_badContentType() throws Exception {
assertThrows(
IllegalArgumentException.class,
() ->
runCommand(
"--path=/foo/bar?a=1&b=2",
"--data=some data",
"--service=DEFAULT",
"--content-type=bad"));
verifyNoMoreInteractions(connection);
verifyNoMoreInteractions(connectionForService);
}
@Test
public void testMultiDataPost() throws Exception {
runCommand(
@ -93,6 +124,20 @@ public class CurlCommandTest extends CommandTestCase<CurlCommand> {
eq("first=100&second=200".getBytes(UTF_8)));
}
@Test
public void testDataDoesntSplit() throws Exception {
runCommand(
"--path=/foo/bar?a=1&b=2", "--data=one,two", "--service=PUBAPI");
verify(connection).withService(PUBAPI);
verifyNoMoreInteractions(connection);
verify(connectionForService)
.sendPostRequest(
eq("/foo/bar?a=1&b=2"),
eq(ImmutableMap.<String, String>of()),
eq(MediaType.PLAIN_TEXT_UTF_8),
eq("one,two".getBytes(UTF_8)));
}
@Test
public void testExplicitPostInvocation() throws Exception {
runCommand("--path=/foo/bar?a=1&b=2", "--request=POST", "--service=TOOLS");

View file

@ -1,67 +0,0 @@
// Copyright 2017 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.tools;
import static com.google.common.truth.Truth.assertThat;
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestFactory;
import com.google.api.client.http.HttpRequestInitializer;
import google.registry.config.RegistryConfig;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@RunWith(JUnit4.class)
public class DefaultRequestFactoryModuleTest {
private static final Credential FAKE_CREDENTIAL = new Credential(
new Credential.AccessMethod() {
@Override
public void intercept(HttpRequest request, String accessToken) {}
@Override
public String getAccessTokenFromRequest(HttpRequest request) {
return "MockAccessToken";
}
});
DefaultRequestFactoryModule module = new DefaultRequestFactoryModule();
@Before
public void setUp() {
RegistryToolEnvironment.UNITTEST.setup();
}
@Test
public void test_provideHttpRequestFactory_localhost() {
// Make sure that localhost creates a request factory with an initializer.
RegistryConfig.CONFIG_SETTINGS.get().appEngine.isLocal = true;
HttpRequestFactory factory = module.provideHttpRequestFactory(() -> FAKE_CREDENTIAL);
HttpRequestInitializer initializer = factory.getInitializer();
assertThat(initializer).isNotNull();
assertThat(initializer).isNotSameAs(FAKE_CREDENTIAL);
}
@Test
public void test_provideHttpRequestFactory_remote() {
// Make sure that example.com creates a request factory with the UNITTEST client id but no
RegistryConfig.CONFIG_SETTINGS.get().appEngine.isLocal = false;
HttpRequestFactory factory = module.provideHttpRequestFactory(() -> FAKE_CREDENTIAL);
assertThat(factory.getInitializer()).isSameAs(FAKE_CREDENTIAL);
}
}

View file

@ -54,6 +54,7 @@ public class DeleteAllocationTokensCommandTest
runCommandForced("--prefix", "");
assertThat(reloadTokens(preNot1, preNot2, othrNot)).isEmpty();
assertThat(reloadTokens(preRed1, preRed2, othrRed)).containsExactly(preRed1, preRed2, othrRed);
assertInStdout("Deleted tokens: asdgfho7HASDS, prefix2978204, prefix8ZZZhs8");
}
@Test
@ -84,6 +85,7 @@ public class DeleteAllocationTokensCommandTest
runCommandForced("--prefix", "", "--dry_run");
assertThat(reloadTokens(preRed1, preRed2, preNot1, preNot2, othrRed, othrNot))
.containsExactly(preRed1, preRed2, preNot1, preNot2, othrRed, othrNot);
assertInStdout("Would delete tokens: asdgfho7HASDS, prefix2978204, prefix8ZZZhs8");
}
@Test

View file

@ -0,0 +1,194 @@
// 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.tools;
import static google.registry.model.EppResourceUtils.loadByForeignKey;
import static google.registry.testing.DatastoreHelper.assertBillingEventsForResource;
import static google.registry.testing.DatastoreHelper.createTlds;
import static google.registry.testing.DatastoreHelper.getOnlyHistoryEntryOfType;
import static google.registry.util.DateTimeUtils.END_OF_TIME;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import google.registry.flows.EppTestCase;
import google.registry.model.billing.BillingEvent;
import google.registry.model.billing.BillingEvent.Reason;
import google.registry.model.domain.DomainResource;
import google.registry.model.reporting.HistoryEntry.Type;
import google.registry.testing.AppEngineRule;
import google.registry.util.Clock;
import java.util.List;
import org.joda.money.Money;
import org.joda.time.DateTime;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/** Tests for tools that affect EPP lifecycle. */
@RunWith(JUnit4.class)
public class EppLifecycleToolsTest extends EppTestCase {
@Rule
public final AppEngineRule appEngine =
AppEngineRule.builder().withDatastore().withTaskQueue().build();
@Before
public void initTld() {
createTlds("example", "tld");
}
@Test
public void test_renewDomainThenUnrenew() throws Exception {
assertThatLoginSucceeds("NewRegistrar", "foo-BAR2");
createContacts(DateTime.parse("2000-06-01T00:00:00Z"));
// Create the domain for 2 years.
assertThatCommand(
"domain_create_no_hosts_or_dsdata.xml", ImmutableMap.of("DOMAIN", "example.tld"))
.atTime("2000-06-01T00:02:00Z")
.hasResponse(
"domain_create_response.xml",
ImmutableMap.of(
"DOMAIN", "example.tld",
"CRDATE", "2000-06-01T00:02:00Z",
"EXDATE", "2002-06-01T00:02:00Z"));
// Explicitly renew it for 4 more years.
assertThatCommand(
"domain_renew.xml",
ImmutableMap.of("DOMAIN", "example.tld", "EXPDATE", "2002-06-01", "YEARS", "4"))
.atTime("2000-06-07T00:00:00Z")
.hasResponse(
"domain_renew_response.xml",
ImmutableMap.of("DOMAIN", "example.tld", "EXDATE", "2006-06-01T00:02:00Z"));
// Run an info command and verify its registration term is 6 years in total.
assertThatCommand("domain_info.xml", ImmutableMap.of("DOMAIN", "example.tld"))
.atTime("2000-08-07T00:01:00Z")
.hasResponse(
"domain_info_response_inactive.xml",
ImmutableMap.of(
"DOMAIN", "example.tld",
"UPDATE", "2000-06-12T00:00:00Z",
"EXDATE", "2006-06-01T00:02:00Z"));
assertThatCommand("poll.xml")
.atTime("2001-01-01T00:01:00Z")
.hasResponse("poll_response_empty.xml");
// Run the nomulus unrenew_domain command to take 3 years off the registration.
clock.setTo(DateTime.parse("2001-06-07T00:00:00.0Z"));
UnrenewDomainCommand unrenewCmd =
new ForcedUnrenewDomainCommand(ImmutableList.of("example.tld"), 3, clock);
unrenewCmd.run();
// Run an info command and verify that the registration term is now 3 years in total.
assertThatCommand("domain_info.xml", ImmutableMap.of("DOMAIN", "example.tld"))
.atTime("2001-06-07T00:01:00.0Z")
.hasResponse(
"domain_info_response_inactive.xml",
ImmutableMap.of(
"DOMAIN", "example.tld",
"UPDATE", "2001-06-07T00:00:00Z",
"EXDATE", "2003-06-01T00:02:00Z"));
// Verify that the correct one-time poll message for the unrenew was sent.
assertThatCommand("poll.xml")
.atTime("2001-06-08T00:00:00Z")
.hasResponse("poll_response_unrenew.xml");
assertThatCommand("poll_ack.xml", ImmutableMap.of("ID", "1-8-TLD-17-18-2001"))
.atTime("2001-06-08T00:00:01Z")
.hasResponse("poll_ack_response_empty.xml");
// Run an info command after the 3 years to verify that the domain successfully autorenewed.
assertThatCommand("domain_info.xml", ImmutableMap.of("DOMAIN", "example.tld"))
.atTime("2003-06-02T00:00:00.0Z")
.hasResponse(
"domain_info_response_inactive_grace_period.xml",
ImmutableMap.of(
"DOMAIN", "example.tld",
"UPDATE", "2003-06-01T00:02:00Z",
"EXDATE", "2004-06-01T00:02:00Z",
"RGPSTATUS", "autoRenewPeriod"));
// And verify that the autorenew poll message worked as well.
assertThatCommand("poll.xml")
.atTime("2003-06-02T00:01:00Z")
.hasResponse(
"poll_response_autorenew.xml",
ImmutableMap.of(
"ID", "1-8-TLD-17-20-2003",
"QDATE", "2003-06-01T00:02:00Z",
"DOMAIN", "example.tld",
"EXDATE", "2004-06-01T00:02:00Z"));
// Assert about billing events.
DateTime createTime = DateTime.parse("2000-06-01T00:02:00Z");
DomainResource domain =
loadByForeignKey(
DomainResource.class, "example.tld", DateTime.parse("2003-06-02T00:02:00Z"))
.get();
BillingEvent.OneTime renewBillingEvent =
new BillingEvent.OneTime.Builder()
.setReason(Reason.RENEW)
.setTargetId(domain.getFullyQualifiedDomainName())
.setClientId(domain.getCurrentSponsorClientId())
.setCost(Money.parse("USD 44.00"))
.setPeriodYears(4)
.setEventTime(DateTime.parse("2000-06-07T00:00:00Z"))
.setBillingTime(DateTime.parse("2000-06-12T00:00:00Z"))
.setParent(getOnlyHistoryEntryOfType(domain, Type.DOMAIN_RENEW))
.build();
assertBillingEventsForResource(
domain,
makeOneTimeCreateBillingEvent(domain, createTime),
renewBillingEvent,
// The initial autorenew billing event, which was closed at the time of the explicit renew.
makeRecurringCreateBillingEvent(
domain,
getOnlyHistoryEntryOfType(domain, Type.DOMAIN_CREATE),
createTime.plusYears(2),
DateTime.parse("2000-06-07T00:00:00.000Z")),
// The renew's autorenew billing event, which was closed at the time of the unrenew.
makeRecurringCreateBillingEvent(
domain,
getOnlyHistoryEntryOfType(domain, Type.DOMAIN_RENEW),
DateTime.parse("2006-06-01T00:02:00.000Z"),
DateTime.parse("2001-06-07T00:00:00.000Z")),
// The remaining active autorenew billing event which was created by the unrenew.
makeRecurringCreateBillingEvent(
domain,
getOnlyHistoryEntryOfType(domain, Type.SYNTHETIC),
DateTime.parse("2003-06-01T00:02:00.000Z"),
END_OF_TIME));
assertThatLogoutSucceeds();
}
static class ForcedUnrenewDomainCommand extends UnrenewDomainCommand {
ForcedUnrenewDomainCommand(List<String> domainNames, int period, Clock clock) {
super();
this.clock = clock;
this.force = true;
this.mainParameters = domainNames;
this.period = period;
}
}
}

View file

@ -196,7 +196,7 @@ public class GenerateDnsReportCommandTest extends CommandTestCase<GenerateDnsRep
@Test
public void testSuccess_skipDomainsWithoutNameservers() throws Exception {
persistResource(domain1.asBuilder().setNameservers(null).build());
persistResource(domain1.asBuilder().setNameservers(ImmutableSet.of()).build());
runCommand("--output=" + output, "--tld=xn--q9jyb4c");
assertThat(getOutputAsJson())
.isEqualTo(ImmutableList.of(DOMAIN2_OUTPUT, NAMESERVER1_OUTPUT, NAMESERVER2_OUTPUT));

View file

@ -22,9 +22,12 @@ import google.registry.rde.Ghostryde;
import google.registry.testing.BouncyCastleProviderRule;
import google.registry.testing.FakeKeyringModule;
import google.registry.testing.InjectRule;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@ -58,12 +61,19 @@ public class GhostrydeCommandTest extends CommandTestCase<GhostrydeCommand> {
public final BouncyCastleProviderRule bouncy = new BouncyCastleProviderRule();
private Keyring keyring;
private PrintStream orgStdout;
@Before
public void before() {
keyring = new FakeKeyringModule().get();
command.rdeStagingDecryptionKey = keyring::getRdeStagingDecryptionKey;
command.rdeStagingEncryptionKey = keyring::getRdeStagingEncryptionKey;
orgStdout = System.out;
}
@After
public void after() {
System.setOut(orgStdout);
}
@Test
@ -112,4 +122,15 @@ public class GhostrydeCommandTest extends CommandTestCase<GhostrydeCommand> {
Path outFile = outDir.resolve("atrain.ghostryde.decrypt");
assertThat(Files.readAllBytes(outFile)).isEqualTo(SONG_BY_CHRISTINA_ROSSETTI);
}
@Test
public void testDecrypt_outputIsStdOut() throws Exception {
Path inFile = Paths.get(tmpDir.newFolder().toString()).resolve("atrain.ghostryde");
Files.write(
inFile, Ghostryde.encode(SONG_BY_CHRISTINA_ROSSETTI, keyring.getRdeStagingEncryptionKey()));
ByteArrayOutputStream out = new ByteArrayOutputStream();
System.setOut(new PrintStream(out));
runCommand("--decrypt", "--input=" + inFile);
assertThat(out.toByteArray()).isEqualTo(SONG_BY_CHRISTINA_ROSSETTI);
}
}

View file

@ -17,7 +17,9 @@ package google.registry.tools;
import static com.google.common.truth.Truth.assertThat;
import com.google.common.collect.Sets;
import google.registry.testing.SystemPropertyRule;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@ -26,9 +28,11 @@ import org.junit.runners.JUnit4;
@RunWith(JUnit4.class)
public class GtechToolTest {
@Rule public final SystemPropertyRule systemPropertyRule = new SystemPropertyRule();
@Before
public void init() {
RegistryToolEnvironment.UNITTEST.setup();
RegistryToolEnvironment.UNITTEST.setup(systemPropertyRule);
}
@Test

View file

@ -82,7 +82,7 @@ public class LockDomainCommandTest extends EppToolCommandTestCase<LockDomainComm
assertThrows(
IllegalArgumentException.class,
() -> runCommandForced("--client=NewRegistrar", "missing.tld"));
assertThat(e).hasMessageThat().isEqualTo("Domain 'missing.tld' does not exist");
assertThat(e).hasMessageThat().isEqualTo("Domain 'missing.tld' does not exist or is deleted");
}
@Test

View file

@ -17,6 +17,8 @@ package google.registry.tools;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.testing.JUnitBackports.assertThrows;
import google.registry.testing.SystemPropertyRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@ -25,17 +27,20 @@ import org.junit.runners.JUnit4;
@RunWith(JUnit4.class)
public class RegistryToolEnvironmentTest {
@Rule public final SystemPropertyRule systemPropertyRule = new SystemPropertyRule();
@Test
public void testGet_withoutSetup_throws() {
RegistryToolEnvironment.reset();
assertThrows(IllegalStateException.class, RegistryToolEnvironment::get);
}
@Test
public void testSetup_changesEnvironmentReturnedByGet() {
RegistryToolEnvironment.UNITTEST.setup();
RegistryToolEnvironment.UNITTEST.setup(systemPropertyRule);
assertThat(RegistryToolEnvironment.get()).isEqualTo(RegistryToolEnvironment.UNITTEST);
RegistryToolEnvironment.ALPHA.setup();
RegistryToolEnvironment.ALPHA.setup(systemPropertyRule);
assertThat(RegistryToolEnvironment.get()).isEqualTo(RegistryToolEnvironment.ALPHA);
}

View file

@ -25,6 +25,7 @@ import com.google.common.collect.Sets;
import com.google.common.reflect.ClassPath;
import com.google.common.reflect.ClassPath.ClassInfo;
import com.google.common.truth.Expect;
import google.registry.testing.SystemPropertyRule;
import java.io.IOException;
import java.lang.reflect.Modifier;
import java.util.Map;
@ -41,9 +42,11 @@ public class RegistryToolTest {
@Rule
public final Expect expect = Expect.create();
@Rule public final SystemPropertyRule systemPropertyRule = new SystemPropertyRule();
@Before
public void init() {
RegistryToolEnvironment.UNITTEST.setup();
RegistryToolEnvironment.UNITTEST.setup(systemPropertyRule);
}
@Test

View file

@ -0,0 +1,75 @@
// Copyright 2017 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.tools;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.tools.RequestFactoryModule.REQUEST_TIMEOUT_MS;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
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.HttpRequestFactory;
import com.google.api.client.http.HttpRequestInitializer;
import google.registry.config.RegistryConfig;
import google.registry.testing.SystemPropertyRule;
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 class RequestFactoryModuleTest {
private final GoogleCredential googleCredential = mock(GoogleCredential.class);
@Rule public final SystemPropertyRule systemPropertyRule = new SystemPropertyRule();
@Before
public void setUp() {
RegistryToolEnvironment.UNITTEST.setup(systemPropertyRule);
}
@Test
public void test_provideHttpRequestFactory_localhost() throws Exception {
// Make sure that localhost creates a request factory with an initializer.
RegistryConfig.CONFIG_SETTINGS.get().appEngine.isLocal = true;
HttpRequestFactory factory = RequestFactoryModule.provideHttpRequestFactory(googleCredential);
HttpRequestInitializer initializer = factory.getInitializer();
assertThat(initializer).isNotNull();
HttpRequest request = factory.buildGetRequest(new GenericUrl("http://localhost"));
initializer.initialize(request);
verifyZeroInteractions(googleCredential);
}
@Test
public void test_provideHttpRequestFactory_remote() throws Exception {
// Make sure that example.com creates a request factory with the UNITTEST client id but no
RegistryConfig.CONFIG_SETTINGS.get().appEngine.isLocal = false;
HttpRequestFactory factory = RequestFactoryModule.provideHttpRequestFactory(googleCredential);
HttpRequestInitializer initializer = factory.getInitializer();
assertThat(initializer).isNotNull();
// HttpRequestFactory#buildGetRequest() calls initialize() once.
HttpRequest request = factory.buildGetRequest(new GenericUrl("http://localhost"));
verify(googleCredential).initialize(request);
assertThat(request.getConnectTimeout()).isEqualTo(REQUEST_TIMEOUT_MS);
assertThat(request.getReadTimeout()).isEqualTo(REQUEST_TIMEOUT_MS);
verifyNoMoreInteractions(googleCredential);
}
}

View file

@ -0,0 +1,217 @@
// 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.tools;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.testing.JUnitBackports.assertThrows;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import com.beust.jcommander.ParameterException;
import com.google.common.collect.ImmutableMultimap;
import google.registry.testing.AppEngineAdminApiHelper;
import google.registry.testing.InjectRule;
import google.registry.util.AppEngineServiceUtils;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mock;
/** Unit tests for {@link SetNumInstancesCommand}. */
public class SetNumInstancesCommandTest extends CommandTestCase<SetNumInstancesCommand> {
@Rule public final InjectRule inject = new InjectRule();
@Mock AppEngineServiceUtils appEngineServiceUtils;
private final String projectId = "domain-registry-test";
@Before
public void before() {
command = new SetNumInstancesCommand();
command.appEngineServiceUtils = appEngineServiceUtils;
command.projectId = projectId;
}
@Test
public void test_missingService_throwsException() {
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() -> runCommand("--versions=version", "--num_instances=5"));
assertThat(thrown).hasMessageThat().contains("Service must be specified");
}
@Test
public void test_emptyService_throwsException() {
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() -> runCommand("--services=", "--versions=version", "--num_instances=5"));
assertThat(thrown).hasMessageThat().contains("Invalid service(s): []");
}
@Test
public void test_invalidService_throwsException() {
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() ->
runCommand(
"--services=INVALID,DEFAULT", "--versions=version", "--num_instances=5"));
assertThat(thrown).hasMessageThat().contains("Invalid service(s): [INVALID]");
}
@Test
public void test_missingVersion_throwsException() {
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() -> runCommand("--services=DEFAULT", "--num_instances=5"));
assertThat(thrown).hasMessageThat().contains("Version must be specified");
}
@Test
public void test_emptyVersion_throwsException() {
ParameterException thrown =
assertThrows(
ParameterException.class,
() -> runCommand("--services=DEFAULT", "--num_instances=5", "--versions"));
assertThat(thrown).hasMessageThat().contains("Expected a value after parameter --versions");
}
@Test
public void test_missingNumInstances_throwsException() {
ParameterException thrown =
assertThrows(
ParameterException.class, () -> runCommand("--services=DEFAULT", "--versions=version"));
assertThat(thrown)
.hasMessageThat()
.contains("The following option is required: --num_instances");
}
@Test
public void test_invalidNumInstances_throwsException() {
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() -> runCommand("--services=DEFAULT", "--versions=version", "--num_instances=-5"));
assertThat(thrown).hasMessageThat().contains("Number of instances must be greater than zero");
}
@Test
public void test_versionNotNullWhenSettingAllNonLiveVersions_throwsException() {
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() -> runCommand("--services=DEFAULT", "--versions=version", "--num_instances=-5"));
assertThat(thrown).hasMessageThat().contains("Number of instances must be greater than zero");
}
@Test
public void test_settingNonManualScalingVersions_throwsException() {
command.appengine =
new AppEngineAdminApiHelper.Builder()
.setAppId(projectId)
.setManualScalingVersionsMap(ImmutableMultimap.of("default", "version1"))
.build()
.getAppengine();
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() ->
runCommand(
"--non_live_versions=true",
"--services=DEFAULT",
"--versions=version",
"--num_instances=10"));
assertThat(thrown)
.hasMessageThat()
.contains("--versions cannot be set if --non_live_versions is set");
}
@Test
public void test_validParameters_succeeds() throws Exception {
command.appengine =
new AppEngineAdminApiHelper.Builder()
.setAppId(projectId)
.setManualScalingVersionsMap(ImmutableMultimap.of("default", "version"))
.build()
.getAppengine();
runCommand("--services=DEFAULT", "--versions=version", "--num_instances=10");
verify(appEngineServiceUtils, times(1)).setNumInstances("default", "version", 10L);
}
@Test
public void test_settingMultipleServicesAndVersions_succeeds() throws Exception {
command.appengine =
new AppEngineAdminApiHelper.Builder()
.setAppId(projectId)
.setManualScalingVersionsMap(
ImmutableMultimap.of(
"default", "version1",
"default", "version2",
"backend", "version1",
"backend", "version2"))
.build()
.getAppengine();
runCommand("--services=DEFAULT,BACKEND", "--versions=version1,version2", "--num_instances=10");
verify(appEngineServiceUtils, times(1)).setNumInstances("default", "version1", 10L);
verify(appEngineServiceUtils, times(1)).setNumInstances("default", "version2", 10L);
verify(appEngineServiceUtils, times(1)).setNumInstances("backend", "version1", 10L);
verify(appEngineServiceUtils, times(1)).setNumInstances("backend", "version2", 10L);
}
@Test
public void test_settingAllNonLiveVersions_succeeds() throws Exception {
command.appengine =
new AppEngineAdminApiHelper.Builder()
.setAppId(projectId)
.setManualScalingVersionsMap(
ImmutableMultimap.of(
"default", "version1", "default", "version2", "default", "version3"))
.setLiveVersionsMap(ImmutableMultimap.of("default", "version2"))
.build()
.getAppengine();
runCommand("--non_live_versions=true", "--services=DEFAULT", "--num_instances=10");
verify(appEngineServiceUtils, times(1)).setNumInstances("default", "version1", 10L);
verify(appEngineServiceUtils, times(0)).setNumInstances("default", "version2", 10L);
verify(appEngineServiceUtils, times(1)).setNumInstances("default", "version3", 10L);
}
@Test
public void test_noNonLiveVersions_succeeds() throws Exception {
command.appengine =
new AppEngineAdminApiHelper.Builder()
.setAppId(projectId)
.setManualScalingVersionsMap(
ImmutableMultimap.of(
"default", "version1", "default", "version2", "default", "version3"))
.setLiveVersionsMap(
ImmutableMultimap.of(
"default", "version1", "default", "version2", "default", "version3"))
.build()
.getAppengine();
runCommand("--non_live_versions=true", "--services=DEFAULT", "--num_instances=10");
verify(appEngineServiceUtils, times(0)).setNumInstances("default", "version1", 10L);
verify(appEngineServiceUtils, times(0)).setNumInstances("default", "version2", 10L);
verify(appEngineServiceUtils, times(0)).setNumInstances("default", "version3", 10L);
}
}

View file

@ -34,6 +34,7 @@ import google.registry.model.registrar.RegistrarContact;
import google.registry.model.registry.Registry;
import google.registry.model.registry.Registry.TldState;
import google.registry.testing.DeterministicStringGenerator;
import google.registry.testing.FakeClock;
import google.registry.util.CidrAddressBlock;
import java.security.cert.CertificateParsingException;
import org.joda.money.CurrencyUnit;
@ -46,23 +47,16 @@ import org.junit.Test;
/** Unit tests for {@link SetupOteCommand}. */
public class SetupOteCommandTest extends CommandTestCase<SetupOteCommand> {
ImmutableList<String> passwords =
ImmutableList.of(
"abcdefghijklmnop",
"qrstuvwxyzabcdef",
"ghijklmnopqrstuv",
"wxyzabcdefghijkl",
"mnopqrstuvwxyzab");
static final String PASSWORD = "abcdefghijklmnop";
DeterministicStringGenerator passwordGenerator =
new DeterministicStringGenerator("abcdefghijklmnopqrstuvwxyz");
@Before
public void init() {
SetupOteCommand.interactive = false;
command.validDnsWriterNames = ImmutableSet.of("FooDnsWriter", "BarDnsWriter", "VoidDnsWriter");
command.passwordGenerator = passwordGenerator;
command.clock = new FakeClock(DateTime.parse("2018-07-07TZ"));
persistPremiumList("default_sandbox_list", "sandbox,USD 1000");
persistPremiumList("alternate_list", "rich,USD 3000");
}
/** Verify TLD creation. */
@ -70,8 +64,6 @@ public class SetupOteCommandTest extends CommandTestCase<SetupOteCommand> {
String tldName,
String roidSuffix,
TldState tldState,
String dnsWriter,
String premiumList,
Duration addGracePeriodLength,
Duration redemptionGracePeriodLength,
Duration pendingDeleteLength,
@ -80,9 +72,9 @@ public class SetupOteCommandTest extends CommandTestCase<SetupOteCommand> {
assertThat(registry).isNotNull();
assertThat(registry.getRoidSuffix()).isEqualTo(roidSuffix);
assertThat(registry.getTldState(DateTime.now(UTC))).isEqualTo(tldState);
assertThat(registry.getDnsWriters()).containsExactly(dnsWriter);
assertThat(registry.getDnsWriters()).containsExactly("VoidDnsWriter");
assertThat(registry.getPremiumList()).isNotNull();
assertThat(registry.getPremiumList().getName()).isEqualTo(premiumList);
assertThat(registry.getPremiumList().getName()).isEqualTo("default_sandbox_list");
assertThat(registry.getAddGracePeriodLength()).isEqualTo(addGracePeriodLength);
assertThat(registry.getRedemptionGracePeriodLength()).isEqualTo(redemptionGracePeriodLength);
assertThat(registry.getPendingDeleteLength()).isEqualTo(pendingDeleteLength);
@ -98,20 +90,18 @@ public class SetupOteCommandTest extends CommandTestCase<SetupOteCommand> {
Money.of(CurrencyUnit.USD, 0),
DateTime.parse("2018-03-01T00:00:00Z"),
Money.of(CurrencyUnit.USD, 100),
DateTime.parse("2022-03-01T00:00:00Z"),
DateTime.parse("2030-03-01T00:00:00Z"),
Money.of(CurrencyUnit.USD, 0)));
}
}
/** Verify TLD creation with registry default durations. */
private void verifyTldCreation(
String tldName, String roidSuffix, TldState tldState, String dnsWriter, String premiumList) {
String tldName, String roidSuffix, TldState tldState) {
verifyTldCreation(
tldName,
roidSuffix,
tldState,
dnsWriter,
premiumList,
Registry.DEFAULT_ADD_GRACE_PERIOD,
Registry.DEFAULT_REDEMPTION_GRACE_PERIOD,
Registry.DEFAULT_PENDING_DELETE_LENGTH,
@ -162,23 +152,14 @@ public class SetupOteCommandTest extends CommandTestCase<SetupOteCommand> {
"--ip_whitelist=1.1.1.1",
"--registrar=blobio",
"--email=contact@email.com",
"--dns_writers=VoidDnsWriter",
"--certfile=" + getCertFilename());
verifyTldCreation(
"blobio-sunrise",
"BLOBIOS0",
TldState.START_DATE_SUNRISE,
"VoidDnsWriter",
"default_sandbox_list");
verifyTldCreation(
"blobio-landrush", "BLOBIOL1", TldState.LANDRUSH, "VoidDnsWriter", "default_sandbox_list");
verifyTldCreation("blobio-sunrise", "BLOBIOS0", TldState.START_DATE_SUNRISE);
verifyTldCreation("blobio-landrush", "BLOBIOL1", TldState.LANDRUSH);
verifyTldCreation(
"blobio-ga",
"BLOBIOG2",
TldState.GENERAL_AVAILABILITY,
"VoidDnsWriter",
"default_sandbox_list",
Duration.standardMinutes(60),
Duration.standardMinutes(10),
Duration.standardMinutes(5),
@ -187,8 +168,6 @@ public class SetupOteCommandTest extends CommandTestCase<SetupOteCommand> {
"blobio-eap",
"BLOBIOE3",
TldState.GENERAL_AVAILABILITY,
"VoidDnsWriter",
"default_sandbox_list",
Duration.standardMinutes(60),
Duration.standardMinutes(10),
Duration.standardMinutes(5),
@ -197,11 +176,11 @@ public class SetupOteCommandTest extends CommandTestCase<SetupOteCommand> {
ImmutableList<CidrAddressBlock> ipAddress = ImmutableList.of(
CidrAddressBlock.create("1.1.1.1"));
verifyRegistrarCreation("blobio-1", "blobio-sunrise", passwords.get(0), ipAddress);
verifyRegistrarCreation("blobio-2", "blobio-landrush", passwords.get(1), ipAddress);
verifyRegistrarCreation("blobio-3", "blobio-ga", passwords.get(2), ipAddress);
verifyRegistrarCreation("blobio-4", "blobio-ga", passwords.get(3), ipAddress);
verifyRegistrarCreation("blobio-5", "blobio-eap", passwords.get(4), ipAddress);
verifyRegistrarCreation("blobio-1", "blobio-sunrise", PASSWORD, ipAddress);
verifyRegistrarCreation("blobio-2", "blobio-landrush", PASSWORD, ipAddress);
verifyRegistrarCreation("blobio-3", "blobio-ga", PASSWORD, ipAddress);
verifyRegistrarCreation("blobio-4", "blobio-ga", PASSWORD, ipAddress);
verifyRegistrarCreation("blobio-5", "blobio-eap", PASSWORD, ipAddress);
verifyRegistrarContactCreation("blobio-1", "contact@email.com");
verifyRegistrarContactCreation("blobio-2", "contact@email.com");
@ -216,23 +195,14 @@ public class SetupOteCommandTest extends CommandTestCase<SetupOteCommand> {
"--ip_whitelist=1.1.1.1",
"--registrar=abc",
"--email=abc@email.com",
"--dns_writers=VoidDnsWriter",
"--certfile=" + getCertFilename());
verifyTldCreation(
"abc-sunrise",
"ABCSUNR0",
TldState.START_DATE_SUNRISE,
"VoidDnsWriter",
"default_sandbox_list");
verifyTldCreation(
"abc-landrush", "ABCLAND1", TldState.LANDRUSH, "VoidDnsWriter", "default_sandbox_list");
verifyTldCreation("abc-sunrise", "ABCSUNR0", TldState.START_DATE_SUNRISE);
verifyTldCreation("abc-landrush", "ABCLAND1", TldState.LANDRUSH);
verifyTldCreation(
"abc-ga",
"ABCGA2",
TldState.GENERAL_AVAILABILITY,
"VoidDnsWriter",
"default_sandbox_list",
Duration.standardMinutes(60),
Duration.standardMinutes(10),
Duration.standardMinutes(5),
@ -241,8 +211,6 @@ public class SetupOteCommandTest extends CommandTestCase<SetupOteCommand> {
"abc-eap",
"ABCEAP3",
TldState.GENERAL_AVAILABILITY,
"VoidDnsWriter",
"default_sandbox_list",
Duration.standardMinutes(60),
Duration.standardMinutes(10),
Duration.standardMinutes(5),
@ -251,11 +219,11 @@ public class SetupOteCommandTest extends CommandTestCase<SetupOteCommand> {
ImmutableList<CidrAddressBlock> ipAddress =
ImmutableList.of(CidrAddressBlock.create("1.1.1.1"));
verifyRegistrarCreation("abc-1", "abc-sunrise", passwords.get(0), ipAddress);
verifyRegistrarCreation("abc-2", "abc-landrush", passwords.get(1), ipAddress);
verifyRegistrarCreation("abc-3", "abc-ga", passwords.get(2), ipAddress);
verifyRegistrarCreation("abc-4", "abc-ga", passwords.get(3), ipAddress);
verifyRegistrarCreation("abc-5", "abc-eap", passwords.get(4), ipAddress);
verifyRegistrarCreation("abc-1", "abc-sunrise", PASSWORD, ipAddress);
verifyRegistrarCreation("abc-2", "abc-landrush", PASSWORD, ipAddress);
verifyRegistrarCreation("abc-3", "abc-ga", PASSWORD, ipAddress);
verifyRegistrarCreation("abc-4", "abc-ga", PASSWORD, ipAddress);
verifyRegistrarCreation("abc-5", "abc-eap", PASSWORD, ipAddress);
verifyRegistrarContactCreation("abc-1", "abc@email.com");
verifyRegistrarContactCreation("abc-2", "abc@email.com");
@ -267,19 +235,15 @@ public class SetupOteCommandTest extends CommandTestCase<SetupOteCommand> {
@Test
public void testSuccess_certificateHash() throws Exception {
runCommandForced(
"--eap_only",
"--ip_whitelist=1.1.1.1",
"--registrar=blobio",
"--email=contact@email.com",
"--dns_writers=VoidDnsWriter",
"--certhash=" + SAMPLE_CERT_HASH);
verifyTldCreation(
"blobio-eap",
"BLOBIOE3",
TldState.GENERAL_AVAILABILITY,
"VoidDnsWriter",
"default_sandbox_list",
Duration.standardMinutes(60),
Duration.standardMinutes(10),
Duration.standardMinutes(5),
@ -288,36 +252,7 @@ public class SetupOteCommandTest extends CommandTestCase<SetupOteCommand> {
ImmutableList<CidrAddressBlock> ipAddress =
ImmutableList.of(CidrAddressBlock.create("1.1.1.1"));
verifyRegistrarCreation("blobio-5", "blobio-eap", passwords.get(0), ipAddress, true);
verifyRegistrarContactCreation("blobio-5", "contact@email.com");
}
@Test
public void testSuccess_eapOnly() throws Exception {
runCommandForced(
"--eap_only",
"--ip_whitelist=1.1.1.1",
"--registrar=blobio",
"--email=contact@email.com",
"--dns_writers=VoidDnsWriter",
"--certfile=" + getCertFilename());
verifyTldCreation(
"blobio-eap",
"BLOBIOE3",
TldState.GENERAL_AVAILABILITY,
"VoidDnsWriter",
"default_sandbox_list",
Duration.standardMinutes(60),
Duration.standardMinutes(10),
Duration.standardMinutes(5),
true);
ImmutableList<CidrAddressBlock> ipAddress = ImmutableList.of(
CidrAddressBlock.create("1.1.1.1"));
verifyRegistrarCreation("blobio-5", "blobio-eap", passwords.get(0), ipAddress);
verifyRegistrarCreation("blobio-5", "blobio-eap", PASSWORD, ipAddress, true);
verifyRegistrarContactCreation("blobio-5", "contact@email.com");
}
@ -328,23 +263,14 @@ public class SetupOteCommandTest extends CommandTestCase<SetupOteCommand> {
"--ip_whitelist=1.1.1.1,2.2.2.2",
"--registrar=blobio",
"--email=contact@email.com",
"--dns_writers=FooDnsWriter",
"--certfile=" + getCertFilename());
verifyTldCreation(
"blobio-sunrise",
"BLOBIOS0",
TldState.START_DATE_SUNRISE,
"FooDnsWriter",
"default_sandbox_list");
verifyTldCreation(
"blobio-landrush", "BLOBIOL1", TldState.LANDRUSH, "FooDnsWriter", "default_sandbox_list");
verifyTldCreation("blobio-sunrise", "BLOBIOS0", TldState.START_DATE_SUNRISE);
verifyTldCreation("blobio-landrush", "BLOBIOL1", TldState.LANDRUSH);
verifyTldCreation(
"blobio-ga",
"BLOBIOG2",
TldState.GENERAL_AVAILABILITY,
"FooDnsWriter",
"default_sandbox_list",
Duration.standardMinutes(60),
Duration.standardMinutes(10),
Duration.standardMinutes(5),
@ -353,8 +279,6 @@ public class SetupOteCommandTest extends CommandTestCase<SetupOteCommand> {
"blobio-eap",
"BLOBIOE3",
TldState.GENERAL_AVAILABILITY,
"FooDnsWriter",
"default_sandbox_list",
Duration.standardMinutes(60),
Duration.standardMinutes(10),
Duration.standardMinutes(5),
@ -364,66 +288,11 @@ public class SetupOteCommandTest extends CommandTestCase<SetupOteCommand> {
CidrAddressBlock.create("1.1.1.1"),
CidrAddressBlock.create("2.2.2.2"));
verifyRegistrarCreation("blobio-1", "blobio-sunrise", passwords.get(0), ipAddresses);
verifyRegistrarCreation("blobio-2", "blobio-landrush", passwords.get(1), ipAddresses);
verifyRegistrarCreation("blobio-3", "blobio-ga", passwords.get(2), ipAddresses);
verifyRegistrarCreation("blobio-4", "blobio-ga", passwords.get(3), ipAddresses);
verifyRegistrarCreation("blobio-5", "blobio-eap", passwords.get(4), ipAddresses);
verifyRegistrarContactCreation("blobio-1", "contact@email.com");
verifyRegistrarContactCreation("blobio-2", "contact@email.com");
verifyRegistrarContactCreation("blobio-3", "contact@email.com");
verifyRegistrarContactCreation("blobio-4", "contact@email.com");
verifyRegistrarContactCreation("blobio-5", "contact@email.com");
}
@Test
public void testSuccess_alternatePremiumList() throws Exception {
runCommandForced(
"--ip_whitelist=1.1.1.1",
"--registrar=blobio",
"--email=contact@email.com",
"--certfile=" + getCertFilename(),
"--dns_writers=BarDnsWriter",
"--premium_list=alternate_list");
verifyTldCreation(
"blobio-sunrise",
"BLOBIOS0",
TldState.START_DATE_SUNRISE,
"BarDnsWriter",
"alternate_list");
verifyTldCreation(
"blobio-landrush", "BLOBIOL1", TldState.LANDRUSH, "BarDnsWriter", "alternate_list");
verifyTldCreation(
"blobio-ga",
"BLOBIOG2",
TldState.GENERAL_AVAILABILITY,
"BarDnsWriter",
"alternate_list",
Duration.standardMinutes(60),
Duration.standardMinutes(10),
Duration.standardMinutes(5),
false);
verifyTldCreation(
"blobio-eap",
"BLOBIOE3",
TldState.GENERAL_AVAILABILITY,
"BarDnsWriter",
"alternate_list",
Duration.standardMinutes(60),
Duration.standardMinutes(10),
Duration.standardMinutes(5),
true);
ImmutableList<CidrAddressBlock> ipAddress = ImmutableList.of(
CidrAddressBlock.create("1.1.1.1"));
verifyRegistrarCreation("blobio-1", "blobio-sunrise", passwords.get(0), ipAddress);
verifyRegistrarCreation("blobio-2", "blobio-landrush", passwords.get(1), ipAddress);
verifyRegistrarCreation("blobio-3", "blobio-ga", passwords.get(2), ipAddress);
verifyRegistrarCreation("blobio-4", "blobio-ga", passwords.get(3), ipAddress);
verifyRegistrarCreation("blobio-5", "blobio-eap", passwords.get(4), ipAddress);
verifyRegistrarCreation("blobio-1", "blobio-sunrise", PASSWORD, ipAddresses);
verifyRegistrarCreation("blobio-2", "blobio-landrush", PASSWORD, ipAddresses);
verifyRegistrarCreation("blobio-3", "blobio-ga", PASSWORD, ipAddresses);
verifyRegistrarCreation("blobio-4", "blobio-ga", PASSWORD, ipAddresses);
verifyRegistrarCreation("blobio-5", "blobio-eap", PASSWORD, ipAddresses);
verifyRegistrarContactCreation("blobio-1", "contact@email.com");
verifyRegistrarContactCreation("blobio-2", "contact@email.com");
@ -441,7 +310,6 @@ public class SetupOteCommandTest extends CommandTestCase<SetupOteCommand> {
runCommandForced(
"--registrar=blobio",
"--email=contact@email.com",
"--dns_writers=VoidDnsWriter",
"--certfile=" + getCertFilename()));
assertThat(thrown).hasMessageThat().contains("option is required: -w, --ip_whitelist");
}
@ -455,7 +323,6 @@ public class SetupOteCommandTest extends CommandTestCase<SetupOteCommand> {
runCommandForced(
"--ip_whitelist=1.1.1.1",
"--email=contact@email.com",
"--dns_writers=VoidDnsWriter",
"--certfile=" + getCertFilename()));
assertThat(thrown).hasMessageThat().contains("option is required: -r, --registrar");
}
@ -469,7 +336,6 @@ public class SetupOteCommandTest extends CommandTestCase<SetupOteCommand> {
runCommandForced(
"--ip_whitelist=1.1.1.1",
"--email=contact@email.com",
"--dns_writers=VoidDnsWriter",
"--registrar=blobio"));
assertThat(thrown)
.hasMessageThat()
@ -486,7 +352,6 @@ public class SetupOteCommandTest extends CommandTestCase<SetupOteCommand> {
runCommandForced(
"--ip_whitelist=1.1.1.1",
"--email=contact@email.com",
"--dns_writers=VoidDnsWriter",
"--registrar=blobio",
"--certfile=" + getCertFilename(),
"--certhash=" + SAMPLE_CERT_HASH));
@ -496,20 +361,6 @@ public class SetupOteCommandTest extends CommandTestCase<SetupOteCommand> {
"Must specify exactly one of client certificate file or client certificate hash.");
}
@Test
public void testFailure_missingDnsWriter() {
ParameterException thrown =
assertThrows(
ParameterException.class,
() ->
runCommandForced(
"--ip_whitelist=1.1.1.1",
"--email=contact@email.com",
"--certfile=" + getCertFilename(),
"--registrar=blobio"));
assertThat(thrown).hasMessageThat().contains("option is required: --dns_writers");
}
@Test
public void testFailure_missingEmail() {
ParameterException thrown =
@ -518,7 +369,6 @@ public class SetupOteCommandTest extends CommandTestCase<SetupOteCommand> {
() ->
runCommandForced(
"--ip_whitelist=1.1.1.1",
"--dns_writers=VoidDnsWriter",
"--certfile=" + getCertFilename(),
"--registrar=blobio"));
assertThat(thrown).hasMessageThat().contains("option is required: --email");
@ -534,7 +384,6 @@ public class SetupOteCommandTest extends CommandTestCase<SetupOteCommand> {
"--ip_whitelist=1.1.1.1",
"--registrar=blobio",
"--email=contact@email.com",
"--dns_writers=VoidDnsWriter",
"--certfile=/dev/null"));
assertThat(thrown).hasMessageThat().contains("No X509Certificate found");
}
@ -549,26 +398,8 @@ public class SetupOteCommandTest extends CommandTestCase<SetupOteCommand> {
"--ip_whitelist=1.1.1.1",
"--registrar=3blobio",
"--email=contact@email.com",
"--dns_writers=VoidDnsWriter",
"--certfile=" + getCertFilename()));
assertThat(thrown).hasMessageThat().contains("Registrar name is invalid");
}
@Test
public void testFailure_invalidDnsWriter() {
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() ->
runCommandForced(
"--ip_whitelist=1.1.1.1",
"--registrar=blobio",
"--email=contact@email.com",
"--dns_writers=InvalidDnsWriter",
"--certfile=" + getCertFilename()));
assertThat(thrown)
.hasMessageThat()
.contains("Invalid DNS writer name(s) specified: [InvalidDnsWriter]");
assertThat(thrown).hasMessageThat().contains("Invalid registrar name: 3blobio");
}
@Test
@ -581,9 +412,8 @@ public class SetupOteCommandTest extends CommandTestCase<SetupOteCommand> {
"--ip_whitelist=1.1.1.1",
"--registrar=bl",
"--email=contact@email.com",
"--dns_writers=VoidDnsWriter",
"--certfile=" + getCertFilename()));
assertThat(thrown).hasMessageThat().contains("Registrar name is invalid");
assertThat(thrown).hasMessageThat().contains("Invalid registrar name: bl");
}
@Test
@ -596,9 +426,8 @@ public class SetupOteCommandTest extends CommandTestCase<SetupOteCommand> {
"--ip_whitelist=1.1.1.1",
"--registrar=blobiotoooolong",
"--email=contact@email.com",
"--dns_writers=VoidDnsWriter",
"--certfile=" + getCertFilename()));
assertThat(thrown).hasMessageThat().contains("Registrar name is invalid");
assertThat(thrown).hasMessageThat().contains("Invalid registrar name: blobiotoooolong");
}
@Test
@ -611,25 +440,8 @@ public class SetupOteCommandTest extends CommandTestCase<SetupOteCommand> {
"--ip_whitelist=1.1.1.1",
"--registrar=blo#bio",
"--email=contact@email.com",
"--dns_writers=VoidDnsWriter",
"--certfile=" + getCertFilename()));
assertThat(thrown).hasMessageThat().contains("Registrar name is invalid");
}
@Test
public void testFailure_invalidPremiumList() {
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() ->
runCommandForced(
"--ip_whitelist=1.1.1.1",
"--registrar=blobio",
"--email=contact@email.com",
"--dns_writers=VoidDnsWriter",
"--certfile=" + getCertFilename(),
"--premium_list=foo"));
assertThat(thrown).hasMessageThat().contains("The premium list 'foo' doesn't exist");
assertThat(thrown).hasMessageThat().contains("Invalid registrar name: blo#bio");
}
@Test
@ -643,9 +455,23 @@ public class SetupOteCommandTest extends CommandTestCase<SetupOteCommand> {
"--ip_whitelist=1.1.1.1",
"--registrar=blobio",
"--email=contact@email.com",
"--dns_writers=VoidDnsWriter",
"--certfile=" + getCertFilename()));
assertThat(thrown).hasMessageThat().contains("TLD 'blobio-sunrise' already exists");
assertThat(thrown).hasMessageThat().contains("Registry(\"blobio-sunrise\")");
}
@Test
public void testSuccess_tldExists_replaceExisting() throws Exception {
createTld("blobio-sunrise");
runCommandForced(
"--overwrite",
"--ip_whitelist=1.1.1.1",
"--registrar=blobio",
"--email=contact@email.com",
"--certfile=" + getCertFilename());
verifyTldCreation("blobio-sunrise", "BLOBIOS0", TldState.START_DATE_SUNRISE);
verifyTldCreation("blobio-landrush", "BLOBIOL1", TldState.LANDRUSH);
}
@Test
@ -663,8 +489,29 @@ public class SetupOteCommandTest extends CommandTestCase<SetupOteCommand> {
"--ip_whitelist=1.1.1.1",
"--registrar=blobio",
"--email=contact@email.com",
"--dns_writers=VoidDnsWriter",
"--certfile=" + getCertFilename()));
assertThat(thrown).hasMessageThat().contains("Registrar blobio-1 already exists");
assertThat(thrown).hasMessageThat().contains("Registrar(\"blobio-1\")");
}
@Test
public void testSuccess_registrarExists_replaceExisting() throws Exception {
Registrar registrar = loadRegistrar("TheRegistrar").asBuilder()
.setClientId("blobio-1")
.setRegistrarName("blobio-1")
.build();
persistResource(registrar);
runCommandForced(
"--overwrite",
"--ip_whitelist=1.1.1.1",
"--registrar=blobio",
"--email=contact@email.com",
"--certfile=" + getCertFilename());
ImmutableList<CidrAddressBlock> ipAddress = ImmutableList.of(
CidrAddressBlock.create("1.1.1.1"));
verifyRegistrarCreation("blobio-1", "blobio-sunrise", PASSWORD, ipAddress);
verifyRegistrarCreation("blobio-2", "blobio-landrush", PASSWORD, ipAddress);
}
}

View file

@ -27,6 +27,7 @@ import com.beust.jcommander.Parameters;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import google.registry.testing.FakeClock;
import google.registry.testing.SystemPropertyRule;
import google.registry.tools.ShellCommand.JCommanderCompletor;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
@ -40,6 +41,7 @@ import org.joda.time.DateTime;
import org.joda.time.Duration;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@ -47,6 +49,8 @@ import org.junit.runners.JUnit4;
@RunWith(JUnit4.class)
public class ShellCommandTest {
@Rule public final SystemPropertyRule systemPropertyRule = new SystemPropertyRule();
CommandRunner cli = mock(CommandRunner.class);
FakeClock clock = new FakeClock(DateTime.parse("2000-01-01TZ"));
@ -107,7 +111,7 @@ public class ShellCommandTest {
@Test
public void testNoIdleWhenInAlpha() throws Exception {
RegistryToolEnvironment.ALPHA.setup();
RegistryToolEnvironment.ALPHA.setup(systemPropertyRule);
MockCli cli = new MockCli();
ShellCommand shellCommand =
createShellCommand(cli, Duration.standardDays(1), "test1 foo bar", "test2 foo bar");
@ -116,7 +120,7 @@ public class ShellCommandTest {
@Test
public void testNoIdleWhenInSandbox() throws Exception {
RegistryToolEnvironment.SANDBOX.setup();
RegistryToolEnvironment.SANDBOX.setup(systemPropertyRule);
MockCli cli = new MockCli();
ShellCommand shellCommand =
createShellCommand(cli, Duration.standardDays(1), "test1 foo bar", "test2 foo bar");
@ -125,7 +129,7 @@ public class ShellCommandTest {
@Test
public void testIdleWhenOverHourInProduction() throws Exception {
RegistryToolEnvironment.PRODUCTION.setup();
RegistryToolEnvironment.PRODUCTION.setup(systemPropertyRule);
MockCli cli = new MockCli();
ShellCommand shellCommand =
createShellCommand(cli, Duration.standardMinutes(61), "test1 foo bar", "test2 foo bar");
@ -135,7 +139,7 @@ public class ShellCommandTest {
@Test
public void testNoIdleWhenUnderHourInProduction() throws Exception {
RegistryToolEnvironment.PRODUCTION.setup();
RegistryToolEnvironment.PRODUCTION.setup(systemPropertyRule);
MockCli cli = new MockCli();
ShellCommand shellCommand =
createShellCommand(cli, Duration.standardMinutes(59), "test1 foo bar", "test2 foo bar");
@ -155,7 +159,7 @@ public class ShellCommandTest {
public void testMultipleCommandInvocations() throws Exception {
try (RegistryCli cli =
new RegistryCli("unittest", ImmutableMap.of("test_command", TestCommand.class))) {
RegistryToolEnvironment.UNITTEST.setup();
RegistryToolEnvironment.UNITTEST.setup(systemPropertyRule);
cli.setEnvironment(RegistryToolEnvironment.UNITTEST);
cli.run(new String[] {"test_command", "-x", "xval", "arg1", "arg2"});
cli.run(new String[] {"test_command", "-x", "otherxval", "arg3"});
@ -253,10 +257,11 @@ public class ShellCommandTest {
@Test
public void testEncapsulatedOutputStream_basicFuncionality() {
ByteArrayOutputStream backing = new ByteArrayOutputStream();
PrintStream out = new PrintStream(new ShellCommand.EncapsulatingOutputStream(backing, "out: "));
out.println("first line");
out.print("second line\ntrailing data");
out.flush();
try (PrintStream out =
new PrintStream(new ShellCommand.EncapsulatingOutputStream(backing, "out: "))) {
out.println("first line");
out.print("second line\ntrailing data");
}
assertThat(backing.toString())
.isEqualTo("out: first line\nout: second line\nout: trailing data\n");
}
@ -264,14 +269,14 @@ public class ShellCommandTest {
@Test
public void testEncapsulatedOutputStream_emptyStream() {
ByteArrayOutputStream backing = new ByteArrayOutputStream();
PrintStream out = new PrintStream(new ShellCommand.EncapsulatingOutputStream(backing, "out: "));
out.flush();
try (PrintStream out =
new PrintStream(new ShellCommand.EncapsulatingOutputStream(backing, "out: "))) {}
assertThat(backing.toString()).isEqualTo("");
}
@Test
public void testEncapsulatedOutput_command() throws Exception {
RegistryToolEnvironment.ALPHA.setup();
RegistryToolEnvironment.ALPHA.setup(systemPropertyRule);
captureOutput();
ShellCommand shellCommand =
new ShellCommand(
@ -288,10 +293,31 @@ public class ShellCommandTest {
assertThat(stderr.toString()).isEmpty();
assertThat(stdout.toString())
.isEqualTo(
"out: first line\nerr: second line\nerr: surprise!\nout: fragmented line\n"
"RUNNING \"command1\"\n"
+ "out: first line\nerr: second line\nerr: surprise!\nout: fragmented line\n"
+ "SUCCESS\n");
}
@Test
public void testEncapsulatedOutput_throws() throws Exception {
RegistryToolEnvironment.ALPHA.setup(systemPropertyRule);
captureOutput();
ShellCommand shellCommand =
new ShellCommand(
args -> {
System.out.println("first line");
throw new Exception("some error!");
});
shellCommand.encapsulateOutput = true;
shellCommand.run();
assertThat(stderr.toString()).isEmpty();
assertThat(stdout.toString())
.isEqualTo(
"RUNNING \"command1\"\n"
+ "out: first line\n"
+ "FAILURE java.lang.Exception some error!\n");
}
@Test
public void testEncapsulatedOutput_noCommand() throws Exception {
captureOutput();
@ -307,7 +333,7 @@ public class ShellCommandTest {
shellCommand.run();
assertThat(stderr.toString()).isEmpty();
assertThat(stdout.toString())
.isEqualTo("out: first line\nSUCCESS\n");
.isEqualTo("RUNNING \"do\" \"something\"\nout: first line\nSUCCESS\n");
}
void captureOutput() {

View file

@ -94,7 +94,7 @@ public class UnlockDomainCommandTest extends EppToolCommandTestCase<UnlockDomain
assertThrows(
IllegalArgumentException.class,
() -> runCommandForced("--client=NewRegistrar", "missing.tld"));
assertThat(e).hasMessageThat().isEqualTo("Domain 'missing.tld' does not exist");
assertThat(e).hasMessageThat().isEqualTo("Domain 'missing.tld' does not exist or is deleted");
}
@Test

View file

@ -0,0 +1,219 @@
// 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.tools;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.model.EppResourceUtils.loadByForeignKey;
import static google.registry.model.eppcommon.StatusValue.PENDING_DELETE;
import static google.registry.model.eppcommon.StatusValue.PENDING_TRANSFER;
import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.model.reporting.HistoryEntry.Type.SYNTHETIC;
import static google.registry.testing.DatastoreHelper.assertBillingEventsEqual;
import static google.registry.testing.DatastoreHelper.assertPollMessagesEqual;
import static google.registry.testing.DatastoreHelper.createTld;
import static google.registry.testing.DatastoreHelper.getOnlyHistoryEntryOfType;
import static google.registry.testing.DatastoreHelper.newDomainResource;
import static google.registry.testing.DatastoreHelper.persistActiveContact;
import static google.registry.testing.DatastoreHelper.persistActiveDomain;
import static google.registry.testing.DatastoreHelper.persistDeletedDomain;
import static google.registry.testing.DatastoreHelper.persistDomainWithDependentResources;
import static google.registry.testing.DatastoreHelper.persistResource;
import static google.registry.testing.HistoryEntrySubject.assertAboutHistoryEntries;
import static google.registry.testing.JUnitBackports.assertThrows;
import com.google.common.collect.ImmutableSet;
import com.googlecode.objectify.Key;
import google.registry.model.billing.BillingEvent;
import google.registry.model.billing.BillingEvent.Flag;
import google.registry.model.billing.BillingEvent.Reason;
import google.registry.model.contact.ContactResource;
import google.registry.model.domain.DomainResource;
import google.registry.model.eppcommon.StatusValue;
import google.registry.model.ofy.Ofy;
import google.registry.model.poll.PollMessage;
import google.registry.model.reporting.HistoryEntry;
import google.registry.testing.FakeClock;
import google.registry.testing.InjectRule;
import org.joda.time.DateTime;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
/** Unit tests for {@link UnrenewDomainCommand}. */
public class UnrenewDomainCommandTest extends CommandTestCase<UnrenewDomainCommand> {
@Rule public final InjectRule inject = new InjectRule();
private final FakeClock clock = new FakeClock(DateTime.parse("2016-12-06T13:55:01Z"));
@Before
public void before() {
createTld("tld");
inject.setStaticField(Ofy.class, "clock", clock);
command.clock = clock;
}
@Test
public void test_unrenewTwoDomains_worksSuccessfully() throws Exception {
ContactResource contact = persistActiveContact("jd1234");
clock.advanceOneMilli();
persistDomainWithDependentResources(
"foo", "tld", contact, clock.nowUtc(), clock.nowUtc(), clock.nowUtc().plusYears(5));
clock.advanceOneMilli();
persistDomainWithDependentResources(
"bar", "tld", contact, clock.nowUtc(), clock.nowUtc(), clock.nowUtc().plusYears(4));
clock.advanceOneMilli();
runCommandForced("-p", "2", "foo.tld", "bar.tld");
clock.advanceOneMilli();
assertThat(
loadByForeignKey(DomainResource.class, "foo.tld", clock.nowUtc())
.get()
.getRegistrationExpirationTime())
.isEqualTo(DateTime.parse("2019-12-06T13:55:01.001Z"));
assertThat(
loadByForeignKey(DomainResource.class, "bar.tld", clock.nowUtc())
.get()
.getRegistrationExpirationTime())
.isEqualTo(DateTime.parse("2018-12-06T13:55:01.002Z"));
assertInStdout("Successfully unrenewed all domains.");
}
@Test
public void test_unrenewDomain_savesDependentEntitiesCorrectly() throws Exception {
ContactResource contact = persistActiveContact("jd1234");
clock.advanceOneMilli();
persistDomainWithDependentResources(
"foo", "tld", contact, clock.nowUtc(), clock.nowUtc(), clock.nowUtc().plusYears(5));
DateTime newExpirationTime = clock.nowUtc().plusYears(3);
clock.advanceOneMilli();
runCommandForced("-p", "2", "foo.tld");
DateTime unrenewTime = clock.nowUtc();
clock.advanceOneMilli();
DomainResource domain = loadByForeignKey(DomainResource.class, "foo.tld", clock.nowUtc()).get();
assertAboutHistoryEntries()
.that(getOnlyHistoryEntryOfType(domain, SYNTHETIC))
.hasModificationTime(unrenewTime)
.and()
.hasMetadataReason("Domain unrenewal")
.and()
.hasPeriodYears(2)
.and()
.hasClientId("TheRegistrar")
.and()
.bySuperuser(true)
.and()
.hasMetadataRequestedByRegistrar(false);
HistoryEntry synthetic = getOnlyHistoryEntryOfType(domain, SYNTHETIC);
assertBillingEventsEqual(
ofy().load().key(domain.getAutorenewBillingEvent()).now(),
new BillingEvent.Recurring.Builder()
.setParent(synthetic)
.setReason(Reason.RENEW)
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
.setTargetId(domain.getFullyQualifiedDomainName())
.setClientId("TheRegistrar")
.setEventTime(newExpirationTime)
.build());
assertPollMessagesEqual(
ofy().load().type(PollMessage.class).ancestor(synthetic).list(),
ImmutableSet.of(
new PollMessage.OneTime.Builder()
.setParent(synthetic)
.setClientId("TheRegistrar")
.setMsg(
"Domain foo.tld was unrenewed by 2 years; "
+ "now expires at 2019-12-06T13:55:01.001Z.")
.setEventTime(unrenewTime)
.build(),
new PollMessage.Autorenew.Builder()
.setParent(synthetic)
.setTargetId("foo.tld")
.setClientId("TheRegistrar")
.setEventTime(newExpirationTime)
.setMsg("Domain was auto-renewed.")
.build()));
// Check that fields on domain were updated correctly.
assertThat(domain.getAutorenewPollMessage().getParent()).isEqualTo(Key.create(synthetic));
assertThat(domain.getRegistrationExpirationTime()).isEqualTo(newExpirationTime);
assertThat(domain.getLastEppUpdateTime()).isEqualTo(unrenewTime);
assertThat(domain.getLastEppUpdateClientId()).isEqualTo("TheRegistrar");
}
@Test
public void test_periodTooLow_fails() {
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class, () -> runCommandForced("--period", "0", "domain.tld"));
assertThat(thrown).hasMessageThat().isEqualTo("Period must be in the range 1-9");
}
@Test
public void test_periodTooHigh_fails() {
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class, () -> runCommandForced("--period", "10", "domain.tld"));
assertThat(thrown).hasMessageThat().isEqualTo("Period must be in the range 1-9");
}
@Test
public void test_varietyOfInvalidDomains_displaysErrors() {
DateTime now = clock.nowUtc();
persistResource(
newDomainResource("deleting.tld")
.asBuilder()
.setDeletionTime(now.plusHours(1))
.setStatusValues(ImmutableSet.of(PENDING_DELETE))
.build());
persistDeletedDomain("deleted.tld", now.minusHours(1));
persistResource(
newDomainResource("transferring.tld")
.asBuilder()
.setStatusValues(ImmutableSet.of(PENDING_TRANSFER))
.build());
persistResource(
newDomainResource("locked.tld")
.asBuilder()
.setStatusValues(ImmutableSet.of(StatusValue.SERVER_UPDATE_PROHIBITED))
.build());
persistActiveDomain("expiring.tld", now.minusDays(4), now.plusMonths(11));
persistActiveDomain("valid.tld", now.minusDays(4), now.plusYears(3));
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() ->
runCommandForced(
"nonexistent.tld",
"deleting.tld",
"deleted.tld",
"transferring.tld",
"locked.tld",
"expiring.tld",
"valid.tld"));
assertThat(thrown)
.hasMessageThat()
.isEqualTo("Aborting because some domains cannot be unrewed");
assertInStderr(
"Found domains that cannot be unrenewed for the following reasons:",
"Domains that don't exist: [nonexistent.tld]",
"Domains that are deleted or pending delete: [deleting.tld, deleted.tld]",
"Domains with disallowed statuses: "
+ "{transferring.tld=[PENDING_TRANSFER], locked.tld=[SERVER_UPDATE_PROHIBITED]}",
"Domains expiring too soon: {expiring.tld=2017-11-06T13:55:01.000Z}");
assertNotInStderr("valid.tld");
}
}

View file

@ -134,7 +134,7 @@ public class UpdateRegistrarCommandTest extends CommandTestCase<UpdateRegistrarC
}
@Test
public void testSuccess_clearIpWhitelist() throws Exception {
public void testSuccess_clearIpWhitelist_useNull() throws Exception {
persistResource(
loadRegistrar("NewRegistrar")
.asBuilder()
@ -148,6 +148,21 @@ public class UpdateRegistrarCommandTest extends CommandTestCase<UpdateRegistrarC
assertThat(loadRegistrar("NewRegistrar").getIpAddressWhitelist()).isEmpty();
}
@Test
public void testSuccess_clearIpWhitelist_useEmpty() throws Exception {
persistResource(
loadRegistrar("NewRegistrar")
.asBuilder()
.setIpAddressWhitelist(
ImmutableList.of(
CidrAddressBlock.create("192.168.1.1"),
CidrAddressBlock.create("192.168.0.2/16")))
.build());
assertThat(loadRegistrar("NewRegistrar").getIpAddressWhitelist()).isNotEmpty();
runCommand("--ip_whitelist=", "--force", "NewRegistrar");
assertThat(loadRegistrar("NewRegistrar").getIpAddressWhitelist()).isEmpty();
}
@Test
public void testSuccess_certFile() throws Exception {
Registrar registrar = loadRegistrar("NewRegistrar");

View file

@ -18,6 +18,7 @@ java_library(
"//java/google/registry/request",
"//java/google/registry/tools/server",
"//java/google/registry/util",
"//javatests/google/registry/model",
"//javatests/google/registry/testing",
"//javatests/google/registry/testing/mapreduce",
"//third_party/objectify:objectify-v4_1",

View file

@ -0,0 +1,94 @@
// Copyright 2019 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.tools.server;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.testing.DatastoreHelper.createTlds;
import static google.registry.testing.DatastoreHelper.persistActiveContact;
import static google.registry.testing.DatastoreHelper.persistActiveDomain;
import static google.registry.testing.DatastoreHelper.persistActiveDomainApplication;
import static google.registry.testing.DatastoreHelper.persistActiveHost;
import static google.registry.testing.DatastoreHelper.persistResource;
import com.googlecode.objectify.Key;
import google.registry.model.contact.ContactResource;
import google.registry.model.domain.DomainApplication;
import google.registry.model.domain.DomainResource;
import google.registry.model.host.HostResource;
import google.registry.model.index.DomainApplicationIndex;
import google.registry.model.index.EppResourceIndex;
import google.registry.model.index.ForeignKeyIndex;
import google.registry.model.reporting.HistoryEntry;
import google.registry.testing.FakeResponse;
import google.registry.testing.mapreduce.MapreduceTestCase;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/** Tests for {@link KillAllDomainApplicationsAction}. */
@RunWith(JUnit4.class)
public class KillAllDomainApplicationsActionTest
extends MapreduceTestCase<KillAllDomainApplicationsAction> {
private void runMapreduce() throws Exception {
action = new KillAllDomainApplicationsAction();
action.mrRunner = makeDefaultRunner();
action.response = new FakeResponse();
action.run();
executeTasksUntilEmpty("mapreduce");
}
@Test
public void test_deletesOnlyApplicationsAndAssociatedEntities() throws Exception {
createTlds("tld1", "tld2");
DomainResource domain = persistActiveDomain("foo1.tld1");
EppResourceIndex domainEri =
ofy().load().entity(EppResourceIndex.create(Key.create(domain))).now();
ForeignKeyIndex<DomainResource> domainFki =
ofy().load().key(ForeignKeyIndex.createKey(domain)).now();
HistoryEntry domainHistoryEntry =
persistResource(new HistoryEntry.Builder().setParent(domain).build());
DomainApplication application = persistActiveDomainApplication("foo2.tld1");
EppResourceIndex applicationEri =
ofy().load().entity(EppResourceIndex.create(Key.create(application))).now();
DomainApplicationIndex applicationDai =
ofy().load().key(DomainApplicationIndex.createKey(application)).now();
HistoryEntry applicationHistoryEntry =
persistResource(new HistoryEntry.Builder().setParent(application).build());
ContactResource contact = persistActiveContact("foo");
HostResource host = persistActiveHost("ns.foo.tld1");
runMapreduce();
ofy().clearSessionCache();
// Check that none of the domain, contact, and host entities were deleted.
assertThat(
ofy()
.load()
.entities(domain, domainEri, domainFki, domainHistoryEntry, contact, host)
.values())
.containsExactly(domain, domainEri, domainFki, domainHistoryEntry, contact, host);
// Check that all of the domain application entities were deleted.
assertThat(
ofy()
.load()
.entities(application, applicationEri, applicationDai, applicationHistoryEntry))
.isEmpty();
}
}

View file

@ -15,16 +15,12 @@
package google.registry.tools.server;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.testing.DatastoreHelper.deleteResource;
import static google.registry.testing.DatastoreHelper.persistResource;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import google.registry.model.reporting.HistoryEntry;
import google.registry.model.reporting.HistoryEntry.Type;
import google.registry.model.OteStatsTestHelper;
import google.registry.testing.AppEngineRule;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Pattern;
import org.junit.Before;
import org.junit.Rule;
@ -40,207 +36,94 @@ public class VerifyOteActionTest {
private final VerifyOteAction action = new VerifyOteAction();
HistoryEntry hostDeleteHistoryEntry;
HistoryEntry domainCreateHistoryEntry;
HistoryEntry domainRestoreHistoryEntry;
@Before
public void init() throws Exception {
persistResource(
new HistoryEntry.Builder()
.setClientId("blobio-1")
.setType(Type.DOMAIN_CREATE)
.setXmlBytes(ToolsTestData.loadBytes("domain_create_sunrise.xml").read())
.build());
domainCreateHistoryEntry = persistResource(
new HistoryEntry.Builder()
.setClientId("blobio-1")
.setType(Type.DOMAIN_CREATE)
.setXmlBytes(ToolsTestData.loadBytes("domain_create_idn.xml").read())
.build());
persistResource(
new HistoryEntry.Builder()
.setClientId("blobio-1")
.setType(Type.DOMAIN_CREATE)
.setXmlBytes(ToolsTestData.loadBytes("domain_create_claim_notice.xml").read())
.build());
persistResource(
new HistoryEntry.Builder()
.setClientId("blobio-1")
.setType(Type.DOMAIN_CREATE)
.setXmlBytes(ToolsTestData.loadBytes("domain_create_anchor_tenant_fee_standard.xml").read())
.build());
persistResource(
new HistoryEntry.Builder()
.setClientId("blobio-1")
.setType(Type.DOMAIN_CREATE)
.setXmlBytes(ToolsTestData.loadBytes("domain_create_dsdata.xml").read())
.build());
persistResource(
new HistoryEntry.Builder()
.setClientId("blobio-1")
.setType(Type.DOMAIN_DELETE)
.setXmlBytes(ToolsTestData.loadBytes("domain_delete.xml").read())
.build());
persistResource(
new HistoryEntry.Builder()
.setClientId("blobio-2")
.setType(Type.DOMAIN_DELETE)
.setXmlBytes(ToolsTestData.loadBytes("domain_delete.xml").read())
.build());
domainRestoreHistoryEntry = persistResource(
new HistoryEntry.Builder()
.setClientId("blobio-1")
.setType(Type.DOMAIN_RESTORE)
.setXmlBytes(ToolsTestData.loadBytes("domain_restore.xml").read())
.build());
persistResource(
new HistoryEntry.Builder()
.setClientId("blobio-1")
.setType(Type.DOMAIN_TRANSFER_APPROVE)
.setXmlBytes(ToolsTestData.loadBytes("domain_transfer_approve.xml").read())
.build());
persistResource(
new HistoryEntry.Builder()
.setClientId("blobio-1")
.setType(Type.DOMAIN_TRANSFER_CANCEL)
.setXmlBytes(ToolsTestData.loadBytes("domain_transfer_cancel.xml").read())
.build());
persistResource(
new HistoryEntry.Builder()
.setClientId("blobio-1")
.setType(Type.DOMAIN_TRANSFER_REJECT)
.setXmlBytes(ToolsTestData.loadBytes("domain_transfer_reject.xml").read())
.build());
persistResource(
new HistoryEntry.Builder()
.setClientId("blobio-1")
.setType(Type.DOMAIN_TRANSFER_REQUEST)
.setXmlBytes(ToolsTestData.loadBytes("domain_transfer_request.xml").read())
.build());
persistResource(
new HistoryEntry.Builder()
.setClientId("blobio-1")
.setType(Type.DOMAIN_UPDATE)
.setXmlBytes(ToolsTestData.loadBytes("domain_update_with_secdns.xml").read())
.build());
persistResource(
new HistoryEntry.Builder()
.setClientId("blobio-1")
.setType(Type.HOST_CREATE)
.setXmlBytes(ToolsTestData.loadBytes("host_create_complete.xml").read())
.build());
hostDeleteHistoryEntry =
persistResource(
new HistoryEntry.Builder()
.setClientId("blobio-1")
.setType(Type.HOST_DELETE)
.setXmlBytes(ToolsTestData.loadBytes("host_delete.xml").read())
.build());
persistResource(
new HistoryEntry.Builder()
.setClientId("blobio-1")
.setType(Type.HOST_UPDATE)
.setXmlBytes(ToolsTestData.loadBytes("host_update.xml").read())
.build());
OteStatsTestHelper.setupHistoryEntries();
}
@Test
public void testSuccess_summarize_allPass() {
Map<String, Object> response =
action.handleJsonRequest(
ImmutableMap.of("summarize", "true", "registrars", ImmutableList.of("blobio")));
assertThat(response)
.containsExactly(
"blobio", "# actions: 31 - Reqs: [----------------] 16/16 - Overall: PASS");
assertThat(getResponse(true))
.isEqualTo("# actions: 31 - Reqs: [----------------] 16/16 - Overall: PASS");
}
@Test
public void testSuccess_summarize_someFailures() {
deleteResource(hostDeleteHistoryEntry);
deleteResource(domainCreateHistoryEntry);
deleteResource(domainRestoreHistoryEntry);
Map<String, Object> response =
action.handleJsonRequest(
ImmutableMap.of("summarize", "true", "registrars", ImmutableList.of("blobio")));
assertThat(response)
.containsExactly(
"blobio", "# actions: 26 - Reqs: [-.-----.------.-] 13/16 - Overall: FAIL");
public void testFailure_summarize_someFailures() {
OteStatsTestHelper.deleteDomainCreateHistoryEntry();
OteStatsTestHelper.deleteDomainRestoreHistoryEntry();
OteStatsTestHelper.deleteHostDeleteHistoryEntry();
assertThat(getResponse(true))
.isEqualTo("# actions: 35 - Reqs: [-.-----.------.-] 13/16 - Overall: FAIL");
}
@Test
public void testSuccess_passNotSummarized() {
Map<String, Object> response =
action.handleJsonRequest(
ImmutableMap.of("summarize", "false", "registrars", ImmutableList.of("blobio")));
for (Entry<String, Object> registrar : response.entrySet()) {
assertThat(registrar.getKey()).matches("blobio");
String expectedOteStatus =
"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 deletes: 2\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 with sec dns: 1\n"
+ ".*"
+ "host creates subordinate: 1\n"
+ "host deletes: 1\n"
+ "host updates: 1\n"
+ ".*"
+ "Requirements passed: 16/16\n"
+ "Overall OT&E status: PASS\n";
Pattern expectedOteStatusPattern = Pattern.compile(expectedOteStatus, Pattern.DOTALL);
assertThat(registrar.getValue().toString()).containsMatch(expectedOteStatusPattern);
}
String expectedOteStatus =
"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 deletes: 2\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 with sec dns: 1\n"
+ ".*"
+ "host creates subordinate: 1\n"
+ "host deletes: 1\n"
+ "host updates: 1\n"
+ ".*"
+ "Requirements passed: 16/16\n"
+ "Overall OT&E status: PASS\n";
Pattern expectedOteStatusPattern = Pattern.compile(expectedOteStatus, Pattern.DOTALL);
assertThat(getResponse(false)).containsMatch(expectedOteStatusPattern);
}
@Test
public void testFailure_missingHostDelete() {
deleteResource(hostDeleteHistoryEntry);
OteStatsTestHelper.deleteHostDeleteHistoryEntry();
String expectedOteStatus =
"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 deletes: 2\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 with sec dns: 1\n"
+ ".*"
+ "host creates subordinate: 1\n"
+ "host deletes: 0\n"
+ "host updates: 10\n"
+ ".*"
+ "Requirements passed: 15/16\n"
+ "Overall OT&E status: FAIL\n";
Pattern expectedOteStatusPattern = Pattern.compile(expectedOteStatus, Pattern.DOTALL);
assertThat(getResponse(false)).containsMatch(expectedOteStatusPattern);
}
private String getResponse(boolean summarize) {
Map<String, Object> response =
action.handleJsonRequest(
ImmutableMap.of("summarize", "false", "registrars", ImmutableList.of("blobio")));
for (Entry<String, Object> registrar : response.entrySet()) {
assertThat(registrar.getKey()).matches("blobio");
String oteStatus = registrar.getValue().toString();
String expectedOteStatus =
"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 deletes: 2\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 with sec dns: 1\n"
+ ".*"
+ "host creates subordinate: 1\n"
+ "host deletes: 0\n"
+ "host updates: 1\n"
+ ".*"
+ "Requirements passed: 15/16\n"
+ "Overall OT&E status: FAIL\n";
Pattern expectedOteStatusPattern = Pattern.compile(expectedOteStatus, Pattern.DOTALL);
assertThat(oteStatus).containsMatch(expectedOteStatusPattern);
}
ImmutableMap.of(
"summarize",
Boolean.toString(summarize),
"registrars",
ImmutableList.of("blobio")));
assertThat(response).containsKey("blobio");
return response.get("blobio").toString();
}
}

View file

@ -1,33 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<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-one.tld</domain:name>
<domain:period unit="y">2</domain:period>
<domain:ns>
<domain:hostObj>ns1.example.net</domain:hostObj>
<domain:hostObj>ns2.example.net</domain:hostObj>
</domain:ns>
<domain:registrant>jd1234</domain:registrant>
<domain:contact type="admin">sh8013</domain:contact>
<domain:contact type="tech">sh8013</domain:contact>
<domain:authInfo>
<domain:pw>2fooBAR</domain:pw>
</domain:authInfo>
</domain:create>
</create>
<extension>
<launch:create xmlns:launch="urn:ietf:params:xml:ns:launch-1.0" type="registration">
<launch:phase>claims</launch:phase>
<launch:notice>
<launch:noticeID>370d0b7c9223372036854775807</launch:noticeID>
<launch:notAfter>2010-08-16T09:00:00.0Z</launch:notAfter>
<launch:acceptedDate>2009-08-16T09:00:00.0Z</launch:acceptedDate>
</launch:notice>
</launch:create>
</extension>
<clTRID>ABC-12345</clTRID>
</command>
</epp>

View file

@ -1,36 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<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:ns>
<domain:hostObj>ns1.example.net</domain:hostObj>
<domain:hostObj>ns2.example.net</domain:hostObj>
</domain:ns>
<domain:registrant>jd1234</domain:registrant>
<domain:contact type="admin">sh8013</domain:contact>
<domain:contact type="tech">sh8013</domain:contact>
<domain:authInfo>
<domain:pw>2fooBAR</domain:pw>
</domain:authInfo>
</domain:create>
</create>
<extension>
<secDNS:create
xmlns:secDNS="urn:ietf:params:xml:ns:secDNS-1.1">
<secDNS:maxSigLife>604800</secDNS:maxSigLife>
<secDNS:dsData>
<secDNS:keyTag>12345</secDNS:keyTag>
<secDNS:alg>3</secDNS:alg>
<secDNS:digestType>1</secDNS:digestType>
<secDNS:digest>49FD46E6C4B45C55D4AC</secDNS:digest>
</secDNS:dsData>
</secDNS:create>
</extension>
<clTRID>ABC-12345</clTRID>
</command>
</epp>

View file

@ -1,22 +0,0 @@
<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>xn--abc-873b2e7eb1k8a4lpjvv.tld</domain:name>
<domain:period unit="y">2</domain:period>
<domain:ns>
<domain:hostObj>ns1.example.net</domain:hostObj>
<domain:hostObj>ns2.example.net</domain:hostObj>
</domain:ns>
<domain:registrant>jd1234</domain:registrant>
<domain:contact type="admin">sh8013</domain:contact>
<domain:contact type="tech">sh8013</domain:contact>
<domain:authInfo>
<domain:pw>2fooBAR</domain:pw>
</domain:authInfo>
</domain:create>
</create>
<clTRID>ABC-12345</clTRID>
</command>
</epp>

View file

@ -1,136 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<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>exampleone.tld</domain:name>
<domain:ns>
<domain:hostObj>ns1.example.net</domain:hostObj>
<domain:hostObj>ns2.example.net</domain:hostObj>
</domain:ns>
<domain:registrant>jd1234</domain:registrant>
<domain:contact type="admin">sh8013</domain:contact>
<domain:contact type="tech">sh8013</domain:contact>
<domain:authInfo>
<domain:pw>2fooBAR</domain:pw>
</domain:authInfo>
</domain:create>
</create>
<extension>
<launch:create
xmlns:launch="urn:ietf:params:xml:ns:launch-1.0">
<launch:phase>sunrise</launch:phase>
<smd:signedMark xmlns:smd="urn:ietf:params:xml:ns:signedMark-1.0" id="signedMark">
<smd:id>1-2</smd:id>
<smd:issuerInfo issuerID="2">
<smd:org>Example Inc.</smd:org>
<smd:email>support@example.tld</smd:email>
<smd:url>http://www.example.tld</smd:url>
<smd:voice x="1234">+1.7035555555</smd:voice>
</smd:issuerInfo>
<smd:notBefore>2009-08-16T09:00:00.0Z</smd:notBefore>
<smd:notAfter>2010-08-16T09:00:00.0Z</smd:notAfter>
<mark:mark xmlns:mark="urn:ietf:params:xml:ns:mark-1.0">
<mark:trademark>
<mark:id>1234-2</mark:id>
<mark:markName>Example One</mark:markName>
<mark:holder entitlement="owner">
<mark:org>Example Inc.</mark:org>
<mark:addr>
<mark:street>123 Example Dr.</mark:street>
<mark:street>Suite 100</mark:street>
<mark:city>Reston</mark:city>
<mark:sp>VA</mark:sp>
<mark:pc>20190</mark:pc>
<mark:cc>US</mark:cc>
</mark:addr>
</mark:holder>
<mark:jurisdiction>US</mark:jurisdiction>
<mark:class>35</mark:class>
<mark:class>36</mark:class>
<mark:label>example-one</mark:label>
<mark:label>exampleone</mark:label>
<mark:goodsAndServices>Dirigendas et eiusmodi featuring infringo in airfare et cartam servicia.</mark:goodsAndServices>
<mark:regNum>234235</mark:regNum>
<mark:regDate>2009-08-16T09:00:00.0Z</mark:regDate>
<mark:exDate>2015-08-16T09:00:00.0Z</mark:exDate>
</mark:trademark>
</mark:mark>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod
Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<SignatureMethod
Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
<Reference URI="#signedMark">
<Transforms>
<Transform
Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
</Transforms>
<DigestMethod
Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<DigestValue>
miF4M2aTd1Y3tKOzJtiyl2VpzAnVPnV1Hq7Zax+yzrA=
</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>
MELpHTWEVfG1JcsG1/a//o54OnlJ5A864+X5JwfqgGBBeZSzGHNzwzTKFzIyyyfn
lGxVwNMoBV5aSvkF7oEKMNVzfcl/P0czNQZ/LJ83p3Ol27/iUNsqgCaGf9Zupw+M
XT4Q2lOrIw+qSx5g7q9T83siMLvkD5uEYlU5dPqgsObLTW8/doTQrA14RcxgY4kG
a4+t5B1cT+5VaghTOPb8uUSEDKjnOsGdy8p24wgyK9n8h0CTSS2ZQ6Zq/RmQeT7D
sbceUHheQ+mkQWIljpMQqsiBjw5XXh4jkEgfAzrb6gkYEF+X8ReuPZuOYC4QjIET
yx8ifN4KE3GIbMXeF4LDsA==
</SignatureValue>
<KeyInfo>
<KeyValue>
<RSAKeyValue>
<Modulus>
o/cwvXhbVYl0RDWWvoyeZpETVZVVcMCovUVNg/swWinuMgEWgVQFrz0xA04pEhXC
FVv4evbUpekJ5buqU1gmQyOsCKQlhOHTdPjvkC5upDqa51Flk0TMaMkIQjs7aUKC
mA4RG4tTTGK/EjR1ix8/D0gHYVRldy1YPrMP+ou75bOVnIos+HifrAtrIv4qEqwL
L4FTZAUpaCa2BmgXfy2CSRQbxD5Or1gcSa3vurh5sPMCNxqaXmIXmQipS+DuEBqM
M8tldaN7RYojUEKrGVsNk5i9y2/7sjn1zyyUPf7vL4GgDYqhJYWV61DnXgx/Jd6C
WxvsnDF6scscQzUTEl+hyw==
</Modulus>
<Exponent>
AQAB
</Exponent>
</RSAKeyValue>
</KeyValue>
<X509Data>
<X509Certificate>
MIIESTCCAzGgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBiMQswCQYDVQQGEwJVUzEL
MAkGA1UECBMCQ0ExFDASBgNVBAcTC0xvcyBBbmdlbGVzMRMwEQYDVQQKEwpJQ0FO
TiBUTUNIMRswGQYDVQQDExJJQ0FOTiBUTUNIIFRFU1QgQ0EwHhcNMTMwMjA4MDAw
MDAwWhcNMTgwMjA3MjM1OTU5WjBsMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0Ex
FDASBgNVBAcTC0xvcyBBbmdlbGVzMRcwFQYDVQQKEw5WYWxpZGF0b3IgVE1DSDEh
MB8GA1UEAxMYVmFsaWRhdG9yIFRNQ0ggVEVTVCBDRVJUMIIBIjANBgkqhkiG9w0B
AQEFAAOCAQ8AMIIBCgKCAQEAo/cwvXhbVYl0RDWWvoyeZpETVZVVcMCovUVNg/sw
WinuMgEWgVQFrz0xA04pEhXCFVv4evbUpekJ5buqU1gmQyOsCKQlhOHTdPjvkC5u
pDqa51Flk0TMaMkIQjs7aUKCmA4RG4tTTGK/EjR1ix8/D0gHYVRldy1YPrMP+ou7
5bOVnIos+HifrAtrIv4qEqwLL4FTZAUpaCa2BmgXfy2CSRQbxD5Or1gcSa3vurh5
sPMCNxqaXmIXmQipS+DuEBqMM8tldaN7RYojUEKrGVsNk5i9y2/7sjn1zyyUPf7v
L4GgDYqhJYWV61DnXgx/Jd6CWxvsnDF6scscQzUTEl+hywIDAQABo4H/MIH8MAwG
A1UdEwEB/wQCMAAwHQYDVR0OBBYEFPZEcIQcD/Bj2IFz/LERuo2ADJviMIGMBgNV
HSMEgYQwgYGAFO0/7kEh3FuEKS+Q/kYHaD/W6wihoWakZDBiMQswCQYDVQQGEwJV
UzELMAkGA1UECBMCQ0ExFDASBgNVBAcTC0xvcyBBbmdlbGVzMRMwEQYDVQQKEwpJ
Q0FOTiBUTUNIMRswGQYDVQQDExJJQ0FOTiBUTUNIIFRFU1QgQ0GCAQEwDgYDVR0P
AQH/BAQDAgeAMC4GA1UdHwQnMCUwI6AhoB+GHWh0dHA6Ly9jcmwuaWNhbm4ub3Jn
L3RtY2guY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQB2qSy7ui+43cebKUKwWPrzz9y/
IkrMeJGKjo40n+9uekaw3DJ5EqiOf/qZ4pjBD++oR6BJCb6NQuQKwnoAz5lE4Ssu
y5+i93oT3HfyVc4gNMIoHm1PS19l7DBKrbwbzAea/0jKWVzrvmV7TBfjxD3AQo1R
bU5dBr6IjbdLFlnO5x0G0mrG7x5OUPuurihyiURpFDpwH8KAH1wMcCpXGXFRtGKk
wydgyVYAty7otkl/z3bZkCVT34gPvF70sR6+QxUy8u0LzF5A/beYaZpxSYG31amL
AdXitTWFipaIGea9lEGFM0L9+Bg7XzNn4nVLXokyEB3bgS4scG6QznX23FGk
</X509Certificate>
</X509Data>
</KeyInfo>
</Signature>
</smd:signedMark>
</launch:create>
</extension>
<clTRID>ABC-12345</clTRID>
</command>
</epp>

View file

@ -1,17 +0,0 @@
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
<command>
<update>
<domain:update
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
<domain:name>example.tld</domain:name>
<domain:chg/>
</domain:update>
</update>
<extension>
<rgp:update xmlns:rgp="urn:ietf:params:xml:ns:rgp-1.0">
<rgp:restore op="request"/>
</rgp:update>
</extension>
<clTRID>ABC-12345</clTRID>
</command>
</epp>

View file

@ -1,11 +0,0 @@
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
<command>
<transfer op="approve">
<domain:transfer
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
<domain:name>example.tld</domain:name>
</domain:transfer>
</transfer>
<clTRID>ABC-12345</clTRID>
</command>
</epp>

View file

@ -1,11 +0,0 @@
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
<command>
<transfer op="cancel">
<domain:transfer
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
<domain:name>example.tld</domain:name>
</domain:transfer>
</transfer>
<clTRID>ABC-12345</clTRID>
</command>
</epp>

View file

@ -1,11 +0,0 @@
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
<command>
<transfer op="reject">
<domain:transfer
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
<domain:name>example.tld</domain:name>
</domain:transfer>
</transfer>
<clTRID>ABC-12345</clTRID>
</command>
</epp>

View file

@ -1,15 +0,0 @@
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
<command>
<transfer op="request">
<domain:transfer
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
<domain:name>example.tld</domain:name>
<domain:period unit="y">1</domain:period>
<domain:authInfo>
<domain:pw roid="JD1234-REP">2fooBAR</domain:pw>
</domain:authInfo>
</domain:transfer>
</transfer>
<clTRID>ABC-12345</clTRID>
</command>
</epp>

View file

@ -1,28 +0,0 @@
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
<command>
<update>
<domain:update
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
<domain:name>example.tld</domain:name>
<domain:chg/>
</domain:update>
</update>
<extension>
<rgp:update xmlns:rgp="urn:ietf:params:xml:ns:rgp-1.0">
<rgp:restore op="request"/>
</rgp:update>
<secDNS:update
xmlns:secDNS="urn:ietf:params:xml:ns:secDNS-1.1">
<secDNS:add>
<secDNS:dsData>
<secDNS:keyTag>12346</secDNS:keyTag>
<secDNS:alg>3</secDNS:alg>
<secDNS:digestType>1</secDNS:digestType>
<secDNS:digest>38EC35D5B3A34B44C39B</secDNS:digest>
</secDNS:dsData>
</secDNS:add>
</secDNS:update>
</extension>
<clTRID>ABC-12345</clTRID>
</command>
</epp>

View file

@ -1,14 +0,0 @@
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
<command>
<update>
<host:update
xmlns:host="urn:ietf:params:xml:ns:host-1.0">
<host:name>example.tld</host:name>
<host:chg>
<host:name>example2.tld</host:name>
</host:chg>
</host:update>
</update>
<clTRID>ABC-12345</clTRID>
</command>
</epp>