Change the LoadTestAction to use /_dr/epptool

The load tests used to directly build EPP, but that becomes
problematic for an upcoming CL that refactors a lot of the
EPP flow code. Instead, use the existing tool endpoint
(conveniently, LoadTestAction is already in the tools module).
This required changing the EppToolServlet to get its
xml from a param rather than from the request payload,
since task queues won't allow both a payload and request
params on the same task.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=124351878
This commit is contained in:
Corey Goldfeder 2016-06-08 07:51:02 -07:00 committed by Justine Tunney
parent 5a2f63cf58
commit 366c5a344d
19 changed files with 227 additions and 255 deletions

View file

@ -15,8 +15,7 @@
package google.registry.flows;
import static google.registry.flows.EppServletUtils.handleEppCommandAndWriteResponse;
import com.google.common.io.ByteStreams;
import static java.nio.charset.StandardCharsets.UTF_8;
import google.registry.flows.SessionMetadata.SessionSource;
import google.registry.model.eppcommon.ProtocolDefinition;
@ -42,9 +41,8 @@ public class EppToolServlet extends XsrfProtectedServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse rsp) throws IOException {
byte[] xml = ByteStreams.toByteArray(req.getInputStream());
handleEppCommandAndWriteResponse(
xml, rsp, new StatelessRequestSessionMetadata(
req.getParameter("xml").getBytes(UTF_8), rsp, new StatelessRequestSessionMetadata(
req.getParameter("clientIdentifier"),
Boolean.parseBoolean(req.getParameter("superuser")),
Boolean.parseBoolean(req.getParameter("dryRun")),

View file

@ -17,6 +17,7 @@ java_library(
deps = [
"//java/com/google/common/base",
"//java/com/google/common/collect",
"//java/com/google/common/net",
"//third_party/java/appengine:appengine-api",
"//third_party/java/dagger",
"//third_party/java/joda_time",
@ -24,8 +25,6 @@ java_library(
"//third_party/java/objectify:objectify-v4_1",
"//third_party/java/servlet/servlet_api",
"//java/google/registry/config",
"//java/google/registry/flows",
"//java/google/registry/model",
"//java/google/registry/request",
"//java/google/registry/util",
],

View file

@ -1,50 +0,0 @@
// Copyright 2016 The Domain Registry 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.loadtest;
import static com.google.cloud.sql.jdbc.internal.Charsets.UTF_8;
import static google.registry.flows.EppController.handleEppCommand;
import com.google.appengine.api.taskqueue.DeferredTask;
import google.registry.flows.SessionMetadata.SessionSource;
import google.registry.flows.StatelessRequestSessionMetadata;
import google.registry.model.eppcommon.ProtocolDefinition;
/** A task that executes a single EPP command. */
public class LoadTask implements DeferredTask {
private static final long serialVersionUID = -7541344556045675149L;
private final String clientId;
private final String xml;
LoadTask(String clientId, String xml) {
this.clientId = clientId;
this.xml = xml;
}
@Override
public void run() {
handleEppCommand(
xml.getBytes(UTF_8),
new StatelessRequestSessionMetadata(
clientId,
false,
false,
ProtocolDefinition.getVisibleServiceExtensionUris(),
SessionSource.LOADTEST));
}
}

View file

@ -16,19 +16,22 @@ package google.registry.loadtest;
import static com.google.appengine.api.taskqueue.QueueConstants.maxTasksPerAdd;
import static com.google.appengine.api.taskqueue.QueueFactory.getQueue;
import static com.google.appengine.api.taskqueue.TaskOptions.Builder.withPayload;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.collect.Lists.partition;
import static com.google.common.collect.Lists.transform;
import static google.registry.util.ResourceUtils.readResourceUtf8;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Arrays.asList;
import static org.joda.time.DateTimeZone.UTC;
import com.google.appengine.api.taskqueue.TaskOptions;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterators;
import com.google.common.net.MediaType;
import google.registry.config.RegistryEnvironment;
import google.registry.request.Action;
@ -37,6 +40,8 @@ import google.registry.util.TaskEnqueuer;
import org.joda.time.DateTime;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
@ -278,12 +283,28 @@ public class LoadTestAction implements Runnable {
for (int i = 0; i < xmls.size(); i++) {
// Space tasks evenly within across a second.
int offsetMillis = (int) (1000.0 / xmls.size() * i);
tasks.add(withPayload(new LoadTask(clientId, xmls.get(i)))
.etaMillis(start.plusMillis(offsetMillis).getMillis()));
tasks.add(TaskOptions.Builder.withUrl("/_dr/epptool")
.etaMillis(start.getMillis() + offsetMillis)
.payload(
Joiner.on('&').withKeyValueSeparator('=').join(
ImmutableMap.of(
"clientIdentifier", clientId,
"superuser", false,
"dryRun", false,
"xml", urlEncode(xmls.get(i)))),
MediaType.FORM_DATA.toString()));
}
return tasks.build();
}
private String urlEncode(String xml) {
try {
return URLEncoder.encode(xml, UTF_8.toString());
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
private void enqueue(List<TaskOptions> tasks) {
List<List<TaskOptions>> chunks = partition(tasks, maxTasksPerAdd());
// Farm out tasks to multiple queues to work around queue qps quotas.

View file

@ -20,7 +20,6 @@ import static com.google.common.base.Predicates.notNull;
import static com.google.common.base.Strings.nullToEmpty;
import static com.google.common.collect.Maps.filterValues;
import static com.google.common.io.Resources.getResource;
import static google.registry.flows.EppServletUtils.APPLICATION_EPP_XML_UTF8;
import static google.registry.model.registry.Registries.findTldForNameOrThrow;
import static google.registry.tools.CommandUtilities.addHeader;
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
@ -29,9 +28,11 @@ import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Multimap;
import com.google.common.net.InternetDomainName;
import com.google.common.net.MediaType;
import com.google.template.soy.SoyFileSet;
import com.google.template.soy.data.SoyRecord;
import com.google.template.soy.parseinfo.SoyFileInfo;
@ -42,6 +43,7 @@ import com.beust.jcommander.Parameter;
import google.registry.model.registrar.Registrar;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@ -144,11 +146,14 @@ abstract class EppToolCommand extends ConfirmingCommand implements ServerSideCom
params.put("dryRun", dryRun);
params.put("clientIdentifier", command.clientId);
params.put("superuser", superuser);
params.put("xml", URLEncoder.encode(command.xml, UTF_8.toString()));
String requestBody = Joiner.on('&').withKeyValueSeparator('=')
.join(filterValues(params, notNull()));
responses.add(nullToEmpty(connection.send(
"/_dr/epptool",
filterValues(params, notNull()),
APPLICATION_EPP_XML_UTF8,
command.xml.getBytes(UTF_8))));
ImmutableMap.<String, String>of(),
MediaType.FORM_DATA,
requestBody.getBytes(UTF_8))));
}
return responses.build();
}

View file

@ -18,7 +18,6 @@ import static com.google.common.io.BaseEncoding.base16;
import static com.google.common.io.Resources.getResource;
import static com.google.common.io.Resources.toByteArray;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.flows.EppServletUtils.APPLICATION_EPP_XML_UTF8;
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;
@ -31,14 +30,8 @@ import static google.registry.testing.DatastoreHelper.persistActiveContact;
import static google.registry.testing.DatastoreHelper.persistActiveHost;
import static google.registry.testing.DatastoreHelper.persistResource;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import static google.registry.util.ResourceUtils.readResourceUtf8;
import static google.registry.xml.XmlTestUtils.assertXmlEquals;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static google.registry.util.ResourceUtils.readResourceBytes;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.beust.jcommander.ParameterException;
@ -58,27 +51,16 @@ import google.registry.tools.ServerSideCommand.Connection;
import org.joda.time.DateTime;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import java.io.IOException;
import java.util.List;
/** Unit tests for {@link AllocateDomainCommand}. */
public class AllocateDomainCommandTest extends CommandTestCase<AllocateDomainCommand> {
private static final String EXPECTED_XML_ONE =
readResourceUtf8(AllocateDomainCommandTest.class, "testdata/allocate_domain.xml");
private static final String EXPECTED_XML_TWO =
readResourceUtf8(AllocateDomainCommandTest.class, "testdata/allocate_domain2.xml");
@Mock
Connection connection;
@Captor
ArgumentCaptor<byte[]> xml;
@Before
public void init() throws IOException {
command.setConnection(connection);
@ -119,7 +101,6 @@ public class AllocateDomainCommandTest extends CommandTestCase<AllocateDomainCom
DateTime.parse("2010-08-16T09:00:00.0Z"),
DateTime.parse("2009-08-16T09:00:00.0Z")))
.build());
persistResource(
new HistoryEntry.Builder()
.setParent(application)
@ -130,40 +111,30 @@ public class AllocateDomainCommandTest extends CommandTestCase<AllocateDomainCom
.build());
}
private void verifySent(boolean dryRun, String clientId, String... expectedXml) throws Exception {
ImmutableMap<String, ?> params = ImmutableMap.of(
"dryRun", dryRun,
"clientIdentifier", clientId,
"superuser", true);
verify(connection, times(expectedXml.length))
.send(eq("/_dr/epptool"), eq(params), eq(APPLICATION_EPP_XML_UTF8), xml.capture());
List<byte[]> allCapturedXml = xml.getAllValues();
assertThat(allCapturedXml).hasSize(expectedXml.length);
int capturedXmlIndex = 0;
for (String expected : expectedXml) {
assertXmlEquals(expected, new String(allCapturedXml.get(capturedXmlIndex++), UTF_8));
}
private EppToolVerifier eppVerifier() {
return new EppToolVerifier()
.withConnection(connection)
.withClientIdentifier("TheRegistrar")
.asSuperuser();
}
@Test
public void testSuccess() throws Exception {
runCommand("--ids=1-TLD", "--force", "--superuser");
// NB: These commands are all sent on behalf of the sponsoring registrar, in this case
// "TheRegistrar".
verifySent(false, "TheRegistrar", EXPECTED_XML_ONE);
// NB: These commands are sent as the sponsoring registrar, in this case "TheRegistrar".
eppVerifier().verifySent("allocate_domain.xml");
}
@Test
public void testSuccess_multiple() throws Exception {
runCommand("--ids=1-TLD,2-TLD", "--force", "--superuser");
verifySent(false, "TheRegistrar", EXPECTED_XML_ONE, EXPECTED_XML_TWO);
eppVerifier().verifySent("allocate_domain.xml", "allocate_domain2.xml");
}
@Test
public void testSuccess_dryRun() throws Exception {
runCommand("--ids=1-TLD", "--dry_run", "--superuser");
verifySent(true, "TheRegistrar", EXPECTED_XML_ONE);
eppVerifier().asDryRun().verifySent("allocate_domain.xml");
}
@Test
@ -187,7 +158,8 @@ public class AllocateDomainCommandTest extends CommandTestCase<AllocateDomainCom
@Test
public void testXmlInstantiatesFlow() throws Exception {
assertThat(
getFlowClass(EppXmlTransformer.<EppInput>unmarshal(EXPECTED_XML_ONE.getBytes(UTF_8))))
.isEqualTo(DomainAllocateFlow.class);
getFlowClass(EppXmlTransformer.<EppInput>unmarshal(
readResourceBytes(getClass(), "testdata/allocate_domain.xml").read())))
.isEqualTo(DomainAllocateFlow.class);
}
}

View file

@ -22,14 +22,15 @@ import com.beust.jcommander.ParameterException;
import google.registry.model.registry.Registry;
import org.junit.Before;
import org.junit.Test;
/** Unit tests for {@link CreateAnchorTenantCommand}. */
public class CreateAnchorTenantCommandTest
extends EppToolCommandTestCase<CreateAnchorTenantCommand> {
@Override
void initEppToolCommandTestCase() {
@Before
public void initCommand() {
command.passwordGenerator = new FakePasswordGenerator("abcdefghijklmnopqrstuvwxyz");
}
@ -37,35 +38,35 @@ public class CreateAnchorTenantCommandTest
public void testSuccess() throws Exception {
runCommandForced("--client=NewRegistrar", "--superuser",
"--reason=anchor-tenant-test", "--contact=jd1234", "--domain_name=example.tld");
eppVerifier().asSuperuser().verifySent("testdata/domain_create_anchor_tenant.xml");
eppVerifier().asSuperuser().verifySent("domain_create_anchor_tenant.xml");
}
@Test
public void testSuccess_suppliedPassword() throws Exception {
runCommandForced("--client=NewRegistrar", "--superuser", "--password=foo",
"--reason=anchor-tenant-test", "--contact=jd1234", "--domain_name=example.tld");
eppVerifier().asSuperuser().verifySent("testdata/domain_create_anchor_tenant_password.xml");
eppVerifier().asSuperuser().verifySent("domain_create_anchor_tenant_password.xml");
}
@Test
public void testSuccess_multipleWordReason() throws Exception {
runCommandForced("--client=NewRegistrar", "--superuser",
"--reason=\"anchor tenant test\"", "--contact=jd1234", "--domain_name=example.tld");
eppVerifier().asSuperuser().verifySent("testdata/domain_create_anchor_tenant_multiple_word_reason.xml");
eppVerifier().asSuperuser().verifySent("domain_create_anchor_tenant_multiple_word_reason.xml");
}
@Test
public void testSuccess_noReason() throws Exception {
runCommandForced("--client=NewRegistrar", "--superuser",
"--contact=jd1234", "--domain_name=example.tld");
eppVerifier().asSuperuser().verifySent("testdata/domain_create_anchor_tenant_no_reason.xml");
eppVerifier().asSuperuser().verifySent("domain_create_anchor_tenant_no_reason.xml");
}
@Test
public void testSuccess_feeStandard() throws Exception {
runCommandForced("--client=NewRegistrar", "--superuser", "--fee",
"--reason=anchor-tenant-test", "--contact=jd1234", "--domain_name=example.tld");
eppVerifier().asSuperuser().verifySent("testdata/domain_create_anchor_tenant_fee_standard.xml");
eppVerifier().asSuperuser().verifySent("domain_create_anchor_tenant_fee_standard.xml");
}
@Test
@ -78,7 +79,7 @@ public class CreateAnchorTenantCommandTest
.build());
runCommandForced("--client=NewRegistrar", "--superuser", "--fee",
"--reason=anchor-tenant-test", "--contact=jd1234", "--domain_name=premium.tld");
eppVerifier().asSuperuser().verifySent("testdata/domain_create_anchor_tenant_fee_premium.xml");
eppVerifier().asSuperuser().verifySent("domain_create_anchor_tenant_fee_premium.xml");
}
@Test

View file

@ -16,14 +16,15 @@ package google.registry.tools;
import com.beust.jcommander.ParameterException;
import org.junit.Before;
import org.junit.Test;
/** Unit tests for {@link CreateContactCommand}. */
public class CreateContactCommandTest
extends EppToolCommandTestCase<CreateContactCommand> {
@Override
void initEppToolCommandTestCase() {
@Before
public void initCommand() {
command.passwordGenerator = new FakePasswordGenerator("abcdefghijklmnopqrstuvwxyz");
}
@ -45,7 +46,7 @@ public class CreateContactCommandTest
"--fax=+1.7035555556",
"--email=jdoe@example.com",
"--password=2fooBAR");
eppVerifier().verifySent("testdata/contact_create_complete.xml");
eppVerifier().verifySent("contact_create_complete.xml");
}
@Test
@ -53,7 +54,7 @@ public class CreateContactCommandTest
// Will never be the case, but tests that each field can be omitted.
// Also tests the auto-gen password.
runCommandForced("--client=NewRegistrar");
eppVerifier().verifySent("testdata/contact_create_minimal.xml");
eppVerifier().verifySent("contact_create_minimal.xml");
}
@Test

View file

@ -25,28 +25,28 @@ public class DeleteDomainCommandTest extends EppToolCommandTestCase<DeleteDomain
public void testSuccess() throws Exception {
runCommand("--client=NewRegistrar", "--domain_name=example.tld", "--force",
"--reason=Test");
eppVerifier().verifySent("testdata/domain_delete.xml");
eppVerifier().verifySent("domain_delete.xml");
}
@Test
public void testSuccess_multipleWordReason() throws Exception {
runCommand("--client=NewRegistrar", "--domain_name=example.tld", "--force",
"--reason=\"Test test\"");
eppVerifier().verifySent("testdata/domain_delete_multiple_word_reason.xml");
eppVerifier().verifySent("domain_delete_multiple_word_reason.xml");
}
@Test
public void testSuccess_requestedByRegistrarFalse() throws Exception {
runCommand("--client=NewRegistrar", "--domain_name=example.tld", "--force",
"--reason=Test", "--registrar_request=false");
eppVerifier().verifySent("testdata/domain_delete.xml");
eppVerifier().verifySent("domain_delete.xml");
}
@Test
public void testSuccess_requestedByRegistrarTrue() throws Exception {
runCommand("--client=NewRegistrar", "--domain_name=example.tld", "--force",
"--reason=Test", "--registrar_request=true");
eppVerifier().verifySent("testdata/domain_delete_by_registrar.xml");
eppVerifier().verifySent("domain_delete_by_registrar.xml");
}
@Test

View file

@ -26,7 +26,7 @@ public class DomainApplicationInfoCommandTest
public void testSuccess() throws Exception {
runCommandForced("--client=NewRegistrar", "--domain_name=example.tld",
"--phase=landrush", "--id=123");
eppVerifier().verifySent("testdata/domain_info_landrush.xml");
eppVerifier().verifySent("domain_info_landrush.xml");
}
@Test
@ -34,7 +34,7 @@ public class DomainApplicationInfoCommandTest
// Sunrush: phase=sunrise, subphase=landrush
runCommandForced("--client=NewRegistrar", "--domain_name=example.tld",
"--phase=sunrush", "--id=123");
eppVerifier().verifySent("testdata/domain_info_sunrush.xml");
eppVerifier().verifySent("domain_info_sunrush.xml");
}
@Test

View file

@ -24,15 +24,15 @@ public class DomainCheckClaimsCommandTest extends EppToolCommandTestCase<DomainC
@Test
public void testSuccess() throws Exception {
runCommandForced("--client=NewRegistrar", "example.tld");
eppVerifier().verifySent("testdata/domain_check_claims.xml");
eppVerifier().verifySent("domain_check_claims.xml");
}
@Test
public void testSuccess_multipleTlds() throws Exception {
runCommandForced("--client=NewRegistrar", "example.tld", "example.tld2");
eppVerifier().verifySent(
"testdata/domain_check_claims.xml",
"testdata/domain_check_claims_second_tld.xml");
"domain_check_claims.xml",
"domain_check_claims_second_tld.xml");
}
@Test
@ -42,7 +42,7 @@ public class DomainCheckClaimsCommandTest extends EppToolCommandTestCase<DomainC
"example.tld",
"example2.tld",
"example3.tld");
eppVerifier().verifySent("testdata/domain_check_claims_multiple.xml");
eppVerifier().verifySent("domain_check_claims_multiple.xml");
}
@Test
@ -54,8 +54,8 @@ public class DomainCheckClaimsCommandTest extends EppToolCommandTestCase<DomainC
"example3.tld",
"example.tld2");
eppVerifier().verifySent(
"testdata/domain_check_claims_multiple.xml",
"testdata/domain_check_claims_second_tld.xml");
"domain_check_claims_multiple.xml",
"domain_check_claims_second_tld.xml");
}
@Test

View file

@ -24,15 +24,15 @@ public class DomainCheckCommandTest extends EppToolCommandTestCase<DomainCheckCo
@Test
public void testSuccess() throws Exception {
runCommandForced("--client=NewRegistrar", "example.tld");
eppVerifier().verifySent("testdata/domain_check.xml");
eppVerifier().verifySent("domain_check.xml");
}
@Test
public void testSuccess_multipleTlds() throws Exception {
runCommandForced("--client=NewRegistrar", "example.tld", "example.tld2");
eppVerifier().verifySent(
"testdata/domain_check.xml",
"testdata/domain_check_second_tld.xml");
"domain_check.xml",
"domain_check_second_tld.xml");
}
@Test
@ -42,7 +42,7 @@ public class DomainCheckCommandTest extends EppToolCommandTestCase<DomainCheckCo
"example.tld",
"example2.tld",
"example3.tld");
eppVerifier().verifySent("testdata/domain_check_multiple.xml");
eppVerifier().verifySent("domain_check_multiple.xml");
}
@Test
@ -54,8 +54,8 @@ public class DomainCheckCommandTest extends EppToolCommandTestCase<DomainCheckCo
"example3.tld",
"example.tld2");
eppVerifier().verifySent(
"testdata/domain_check_multiple.xml",
"testdata/domain_check_second_tld.xml");
"domain_check_multiple.xml",
"domain_check_second_tld.xml");
}
@Test

View file

@ -24,15 +24,15 @@ public class DomainCheckFeeCommandTest extends EppToolCommandTestCase<DomainChec
@Test
public void testSuccess() throws Exception {
runCommandForced("--client=NewRegistrar", "example.tld");
eppVerifier().verifySent("testdata/domain_check_fee.xml");
eppVerifier().verifySent("domain_check_fee.xml");
}
@Test
public void testSuccess_multipleTlds() throws Exception {
runCommandForced("--client=NewRegistrar", "example.tld", "example.tld2");
eppVerifier().verifySent(
"testdata/domain_check_fee.xml",
"testdata/domain_check_fee_second_tld.xml");
"domain_check_fee.xml",
"domain_check_fee_second_tld.xml");
}
@Test
@ -42,7 +42,7 @@ public class DomainCheckFeeCommandTest extends EppToolCommandTestCase<DomainChec
"example.tld",
"example2.tld",
"example3.tld");
eppVerifier().verifySent("testdata/domain_check_fee_multiple.xml");
eppVerifier().verifySent("domain_check_fee_multiple.xml");
}
@Test
@ -54,8 +54,8 @@ public class DomainCheckFeeCommandTest extends EppToolCommandTestCase<DomainChec
"example3.tld",
"example.tld2");
eppVerifier().verifySent(
"testdata/domain_check_fee_multiple.xml",
"testdata/domain_check_fee_second_tld.xml");
"domain_check_fee_multiple.xml",
"domain_check_fee_second_tld.xml");
}
@Test

View file

@ -14,11 +14,7 @@
package google.registry.tools;
import static google.registry.flows.EppServletUtils.APPLICATION_EPP_XML_UTF8;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.verify;
import com.google.common.collect.ImmutableMap;
import static google.registry.util.ResourceUtils.readResourceUtf8;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
@ -55,28 +51,22 @@ public class EppToolCommandTest extends EppToolCommandTestCase<EppToolCommand> {
@Test
public void testSuccess_singleXmlCommand() throws Exception {
runCommandForced("--client=NewRegistrar", "xml");
ImmutableMap<String, Object> params = ImmutableMap.<String, Object>of(
"clientIdentifier", "NewRegistrar",
"superuser", false,
"dryRun", false);
verify(connection)
.send(eq("/_dr/epptool"), eq(params), eq(APPLICATION_EPP_XML_UTF8), eq("xml".getBytes()));
// The choice of xml file is arbitrary.
runCommandForced(
"--client=NewRegistrar",
readResourceUtf8(getClass(), "testdata/contact_create.xml"));
eppVerifier().verifySent("contact_create.xml");
}
@Test
public void testSuccess_multipleXmlCommands() throws Exception {
runCommandForced("--client=NewRegistrar", "one", "two", "three");
ImmutableMap<String, Object> params = ImmutableMap.<String, Object>of(
"clientIdentifier", "NewRegistrar",
"superuser", false,
"dryRun", false);
verify(connection)
.send(eq("/_dr/epptool"), eq(params), eq(APPLICATION_EPP_XML_UTF8), eq("one".getBytes()));
verify(connection)
.send(eq("/_dr/epptool"), eq(params), eq(APPLICATION_EPP_XML_UTF8), eq("two".getBytes()));
verify(connection)
.send(eq("/_dr/epptool"), eq(params), eq(APPLICATION_EPP_XML_UTF8), eq("three".getBytes()));
// The choice of xml files is arbitrary.
runCommandForced(
"--client=NewRegistrar",
readResourceUtf8(getClass(), "testdata/contact_create.xml"),
readResourceUtf8(getClass(), "testdata/domain_check.xml"),
readResourceUtf8(getClass(), "testdata/domain_check_fee.xml"));
eppVerifier().verifySent("contact_create.xml", "domain_check.xml", "domain_check_fee.xml");
}
@Test

View file

@ -14,30 +14,13 @@
package google.registry.tools;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.flows.EppServletUtils.APPLICATION_EPP_XML_UTF8;
import static google.registry.testing.DatastoreHelper.createTlds;
import static google.registry.util.ResourceUtils.readResourceUtf8;
import static google.registry.xml.XmlTestUtils.assertXmlEquals;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Arrays.binarySearch;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import com.google.common.collect.ImmutableMap;
import google.registry.testing.InjectRule;
import google.registry.tools.ServerSideCommand.Connection;
import org.junit.Before;
import org.junit.Rule;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import java.util.List;
/**
* Abstract class for commands that construct + send EPP commands.
*
@ -45,70 +28,18 @@ import java.util.List;
*/
public abstract class EppToolCommandTestCase<C extends EppToolCommand> extends CommandTestCase<C> {
@Rule
public InjectRule inject = new InjectRule();
@Mock
Connection connection;
@Captor
ArgumentCaptor<byte[]> xml;
@Before
public void init() throws Exception {
// Create two TLDs for commands that allow multiple TLDs at once.
createTlds("tld", "tld2");
command.setConnection(connection);
initEppToolCommandTestCase();
}
/** Subclasses can override this to perform additional initialization. */
void initEppToolCommandTestCase() throws Exception {}
/** Helper to get a new {@link EppVerifier} instance. */
EppVerifier eppVerifier() {
return new EppVerifier("NewRegistrar", false, false);
}
/** Class for verifying EPP commands sent to the server. */
class EppVerifier {
private final String clientIdentifier;
private final boolean superuser;
private final boolean dryRun;
private EppVerifier(String clientIdentifier, boolean superuser, boolean dryRun) {
this.clientIdentifier = clientIdentifier;
this.superuser = superuser;
this.dryRun = dryRun;
}
EppVerifier setClientIdentifier(String clientIdentifier) {
return new EppVerifier(clientIdentifier, superuser, dryRun);
}
EppVerifier asSuperuser() {
return new EppVerifier(clientIdentifier, true, dryRun);
}
EppVerifier asDryRun() {
return new EppVerifier(clientIdentifier, superuser, true);
}
void verifySent(String... filesToMatch) throws Exception {
ImmutableMap<String, ?> params = ImmutableMap.of(
"clientIdentifier", clientIdentifier,
"superuser", superuser,
"dryRun", dryRun);
verify(connection, times(filesToMatch.length))
.send(eq("/_dr/epptool"), eq(params), eq(APPLICATION_EPP_XML_UTF8), xml.capture());
List<byte[]> capturedXml = xml.getAllValues();
assertThat(filesToMatch).hasLength(capturedXml.size());
for (String fileToMatch : filesToMatch) {
assertXmlEquals(
readResourceUtf8(getClass(), fileToMatch),
new String(capturedXml.get(binarySearch(filesToMatch, fileToMatch)), UTF_8));
}
}
/** Helper to get a new {@link EppToolVerifier} instance. */
EppToolVerifier eppVerifier() {
return new EppToolVerifier().withConnection(connection).withClientIdentifier("NewRegistrar");
}
}

View file

@ -0,0 +1,97 @@
// Copyright 2016 The Domain Registry 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.collect.Iterables.pairUp;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.util.ResourceUtils.readResourceUtf8;
import static google.registry.xml.XmlTestUtils.assertXmlEquals;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Arrays.asList;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import com.google.common.base.Pair;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableMap;
import com.google.common.net.MediaType;
import google.registry.tools.ServerSideCommand.Connection;
import org.mockito.ArgumentCaptor;
import java.net.URLDecoder;
import java.util.List;
import java.util.Map;
/** Class for verifying EPP commands sent to the server via the tool endpoint. */
public class EppToolVerifier {
private final Connection connection;
private final String clientIdentifier;
private final boolean superuser;
private final boolean dryRun;
public EppToolVerifier() {
this(null, null, false, false);
}
private EppToolVerifier(
Connection connection, String clientIdentifier, boolean superuser, boolean dryRun) {
this.connection = connection;
this.clientIdentifier = clientIdentifier;
this.superuser = superuser;
this.dryRun = dryRun;
}
EppToolVerifier withConnection(Connection connection) {
return new EppToolVerifier(connection, clientIdentifier, superuser, dryRun);
}
EppToolVerifier withClientIdentifier(String clientIdentifier) {
return new EppToolVerifier(connection, clientIdentifier, superuser, dryRun);
}
EppToolVerifier asSuperuser() {
return new EppToolVerifier(connection, clientIdentifier, true, dryRun);
}
EppToolVerifier asDryRun() {
return new EppToolVerifier(connection, clientIdentifier, superuser, true);
}
void verifySent(String... xmlToMatch) throws Exception {
ArgumentCaptor<byte[]> params = ArgumentCaptor.forClass(byte[].class);
verify(connection, times(xmlToMatch.length)).send(
eq("/_dr/epptool"),
eq(ImmutableMap.<String, Object>of()),
eq(MediaType.FORM_DATA),
params.capture());
List<byte[]> capturedParams = params.getAllValues();
assertThat(capturedParams).hasSize(xmlToMatch.length);
for (Pair<String, byte[]> xmlAndParams : pairUp(asList(xmlToMatch), capturedParams)) {
Map<String, String> map = Splitter.on('&').withKeyValueSeparator('=')
.split(new String(xmlAndParams.getSecond(), UTF_8));
assertThat(map).hasSize(4);
assertXmlEquals(
readResourceUtf8(getClass(), "testdata/" + xmlAndParams.getFirst()),
URLDecoder.decode(map.get("xml"), UTF_8.toString()));
assertThat(map).containsEntry("dryRun", Boolean.toString(dryRun));
assertThat(map).containsEntry("clientIdentifier", clientIdentifier);
assertThat(map).containsEntry("superuser", Boolean.toString(superuser));
}
}
}

View file

@ -19,6 +19,10 @@ import static java.nio.charset.StandardCharsets.UTF_8;
import com.beust.jcommander.ParameterException;
import google.registry.testing.InjectRule;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import java.io.ByteArrayInputStream;
@ -26,11 +30,14 @@ import java.io.ByteArrayInputStream;
/** Unit tests for {@link ExecuteEppCommand}. */
public class ExecuteEppCommandTest extends EppToolCommandTestCase<ExecuteEppCommand> {
@Rule
public InjectRule inject = new InjectRule();
private String xmlInput;
private String eppFile;
@Override
void initEppToolCommandTestCase() throws Exception {
@Before
public void initCommand() throws Exception {
xmlInput = readResourceUtf8(ExecuteEppCommandTest.class, "testdata/contact_create.xml");
eppFile = writeToNamedTmpFile("eppFile", xmlInput);
}
@ -38,19 +45,19 @@ public class ExecuteEppCommandTest extends EppToolCommandTestCase<ExecuteEppComm
@Test
public void testSuccess() throws Exception {
runCommand("--client=NewRegistrar", "--force", eppFile);
eppVerifier().verifySent("testdata/contact_create.xml");
eppVerifier().verifySent("contact_create.xml");
}
@Test
public void testSuccess_dryRun() throws Exception {
runCommand("--client=NewRegistrar", "--dry_run", eppFile);
eppVerifier().asDryRun().verifySent("testdata/contact_create.xml");
eppVerifier().asDryRun().verifySent("contact_create.xml");
}
@Test
public void testSuccess_withSuperuser() throws Exception {
runCommand("--client=NewRegistrar", "--superuser", "--force", eppFile);
eppVerifier().asSuperuser().verifySent("testdata/contact_create.xml");
eppVerifier().asSuperuser().verifySent("contact_create.xml");
}
@Test
@ -58,7 +65,7 @@ public class ExecuteEppCommandTest extends EppToolCommandTestCase<ExecuteEppComm
inject.setStaticField(
ExecuteEppCommand.class, "stdin", new ByteArrayInputStream(xmlInput.getBytes(UTF_8)));
runCommand("--client=NewRegistrar", "--force");
eppVerifier().verifySent("testdata/contact_create.xml");
eppVerifier().verifySent("contact_create.xml");
}
@Test
@ -66,7 +73,7 @@ public class ExecuteEppCommandTest extends EppToolCommandTestCase<ExecuteEppComm
String xmlInput2 = readResourceUtf8(ExecuteEppCommandTest.class, "testdata/domain_check.xml");
String eppFile2 = writeToNamedTmpFile("eppFile2", xmlInput2);
runCommand("--client=NewRegistrar", "--force", eppFile, eppFile2);
eppVerifier().verifySent("testdata/contact_create.xml", "testdata/domain_check.xml");
eppVerifier().verifySent("contact_create.xml", "domain_check.xml");
}
@Test

View file

@ -76,9 +76,9 @@ public class UniformRapidSuspensionCommandTest
"--hosts=urs1.example.com,urs2.example.com",
"--dsdata={\"keyTag\":1,\"alg\":1,\"digestType\":1,\"digest\":\"abc\"}");
eppVerifier()
.setClientIdentifier("CharlestonRoad")
.withClientIdentifier("CharlestonRoad")
.asSuperuser()
.verifySent("testdata/uniform_rapid_suspension.xml");
.verifySent("uniform_rapid_suspension.xml");
assertInStdout("uniform_rapid_suspension --undo");
assertInStdout("--domain_name evil.tld");
assertInStdout("--hosts ns1.example.com,ns2.example.com");
@ -93,9 +93,9 @@ public class UniformRapidSuspensionCommandTest
persistDomainWithHosts(urs2, ns1);
runCommandForced("--domain_name=evil.tld", "--hosts=urs1.example.com,urs2.example.com");
eppVerifier()
.setClientIdentifier("CharlestonRoad")
.withClientIdentifier("CharlestonRoad")
.asSuperuser()
.verifySent("testdata/uniform_rapid_suspension_existing_host.xml");
.verifySent("uniform_rapid_suspension_existing_host.xml");
assertInStdout("uniform_rapid_suspension --undo ");
assertInStdout("--domain_name evil.tld");
assertInStdout("--hosts ns1.example.com,urs2.example.com");
@ -129,9 +129,9 @@ public class UniformRapidSuspensionCommandTest
runCommandForced(
"--domain_name=evil.tld", "--undo", "--hosts=ns1.example.com,ns2.example.com");
eppVerifier()
.setClientIdentifier("CharlestonRoad")
.withClientIdentifier("CharlestonRoad")
.asSuperuser()
.verifySent("testdata/uniform_rapid_suspension_undo.xml");
.verifySent("uniform_rapid_suspension_undo.xml");
assertNotInStdout("--undo"); // Undo shouldn't print a new undo command.
}
@ -144,9 +144,9 @@ public class UniformRapidSuspensionCommandTest
"--locks_to_preserve=serverDeleteProhibited",
"--hosts=ns1.example.com,ns2.example.com");
eppVerifier()
.setClientIdentifier("CharlestonRoad")
.withClientIdentifier("CharlestonRoad")
.asSuperuser()
.verifySent("testdata/uniform_rapid_suspension_undo_preserve.xml");
.verifySent("uniform_rapid_suspension_undo_preserve.xml");
assertNotInStdout("--undo"); // Undo shouldn't print a new undo command.
}

View file

@ -25,35 +25,35 @@ public class UpdateServerLocksCommandTest extends EppToolCommandTestCase<UpdateS
public void testSuccess_applyOne() throws Exception {
runCommandForced("--client=NewRegistrar", "--registrar_request=true", "--reason=Test",
"--domain_name=example.tld", "--apply=serverRenewProhibited");
eppVerifier().verifySent("testdata/update_server_locks_apply_one.xml");
eppVerifier().verifySent("update_server_locks_apply_one.xml");
}
@Test
public void testSuccess_multipleWordReason() throws Exception {
runCommandForced("--client=NewRegistrar", "--registrar_request=false",
"--reason=\"Test this\"", "--domain_name=example.tld", "--apply=serverRenewProhibited");
eppVerifier().verifySent("testdata/update_server_locks_multiple_word_reason.xml");
eppVerifier().verifySent("update_server_locks_multiple_word_reason.xml");
}
@Test
public void testSuccess_removeOne() throws Exception {
runCommandForced("--client=NewRegistrar", "--registrar_request=true", "--reason=Test",
"--domain_name=example.tld", "--remove=serverRenewProhibited");
eppVerifier().verifySent("testdata/update_server_locks_remove_one.xml");
eppVerifier().verifySent("update_server_locks_remove_one.xml");
}
@Test
public void testSuccess_applyAll() throws Exception {
runCommandForced("--client=NewRegistrar", "--registrar_request=true", "--reason=Test",
"--domain_name=example.tld", "--apply=all");
eppVerifier().verifySent("testdata/update_server_locks_apply_all.xml");
eppVerifier().verifySent("update_server_locks_apply_all.xml");
}
@Test
public void testSuccess_removeAll() throws Exception {
runCommandForced("--client=NewRegistrar", "--registrar_request=true", "--reason=Test",
"--domain_name=example.tld", "--remove=all");
eppVerifier().verifySent("testdata/update_server_locks_remove_all.xml");
eppVerifier().verifySent("update_server_locks_remove_all.xml");
}
@Test