diff --git a/java/com/google/domain/registry/loadtest/LoadTestAction.java b/java/com/google/domain/registry/loadtest/LoadTestAction.java index b34476cc8..01971448d 100644 --- a/java/com/google/domain/registry/loadtest/LoadTestAction.java +++ b/java/com/google/domain/registry/loadtest/LoadTestAction.java @@ -61,22 +61,111 @@ public class LoadTestAction implements Runnable { private static final Random random = new Random(); - @Inject @Parameter("loadtestClientId") String clientId; - @Inject @Parameter("tld") String tld; - @Inject @Parameter("delaySeconds") int delaySeconds; - @Inject @Parameter("runSeconds") int runSeconds; - @Inject @Parameter("successfulDomainCreates") int successfulDomainCreates; - @Inject @Parameter("failedDomainCreates") int failedDomainCreates; - @Inject @Parameter("domainInfos") int domainInfos; - @Inject @Parameter("domainChecks") int domainChecks; - @Inject @Parameter("successfulContactCreates") int successfulContactCreates; - @Inject @Parameter("failedContactCreates") int failedContactCreates; - @Inject @Parameter("contactInfos") int contactInfos; - @Inject @Parameter("successfulHostCreates") int successfulHostCreates; - @Inject @Parameter("failedHostCreates") int failedHostCreates; - @Inject @Parameter("hostInfos") int hostInfos; - @Inject TaskEnqueuer taskEnqueuer; - @Inject LoadTestAction() {} + /** The client identifier of the registrar to use for load testing. */ + @Inject + @Parameter("loadtestClientId") + String clientId; + + /** + * The number of seconds to delay the execution of the first load testing tasks by. Preparatory + * work of creating independent contacts and hosts that will be used for later domain creation + * testing occurs during this period, so make sure that it is long enough. + */ + @Inject + @Parameter("delaySeconds") + int delaySeconds; + + /** + * The number of seconds that tasks will be enqueued for. Note that if system QPS cannot handle + * the given load then it will take longer than this number of seconds for the test to complete. + */ + @Inject + @Parameter("runSeconds") + int runSeconds; + + /** The number of successful domain creates to enqueue per second over the length of the test. */ + @Inject + @Parameter("successfulDomainCreates") + int successfulDomainCreatesPerSecond; + + /** The number of failed domain creates to enqueue per second over the length of the test. */ + @Inject + @Parameter("failedDomainCreates") + int failedDomainCreatesPerSecond; + + /** The number of successful domain infos to enqueue per second over the length of the test. */ + @Inject + @Parameter("domainInfos") + int domainInfosPerSecond; + + /** The number of successful domain checks to enqueue per second over the length of the test. */ + @Inject + @Parameter("domainChecks") + int domainChecksPerSecond; + + /** The number of successful contact creates to enqueue per second over the length of the test. */ + @Inject + @Parameter("successfulContactCreates") + int successfulContactCreatesPerSecond; + + /** The number of failed contact creates to enqueue per second over the length of the test. */ + @Inject + @Parameter("failedContactCreates") + int failedContactCreatesPerSecond; + + /** The number of successful contact infos to enqueue per second over the length of the test. */ + @Inject + @Parameter("contactInfos") + int contactInfosPerSecond; + + /** The number of successful host creates to enqueue per second over the length of the test. */ + @Inject + @Parameter("successfulHostCreates") + int successfulHostCreatesPerSecond; + + /** The number of failed host creates to enqueue per second over the length of the test. */ + @Inject + @Parameter("failedHostCreates") + int failedHostCreatesPerSecond; + + /** The number of successful host infos to enqueue per second over the length of the test. */ + @Inject + @Parameter("hostInfos") + int hostInfosPerSecond; + + @Inject + TaskEnqueuer taskEnqueuer; + + private final String xmlContactCreateTmpl; + private final String xmlContactCreateFail; + private final String xmlContactInfo; + private final String xmlDomainCheck; + private final String xmlDomainCreateTmpl; + private final String xmlDomainCreateFail; + private final String xmlDomainInfo; + private final String xmlHostCreateTmpl; + private final String xmlHostCreateFail; + private final String xmlHostInfo; + + @Inject + LoadTestAction(@Parameter("tld") String tld) { + xmlContactCreateTmpl = loadXml("contact_create"); + xmlContactCreateFail = xmlContactCreateTmpl.replace("%contact%", EXISTING_CONTACT); + xmlContactInfo = loadXml("contact_info").replace("%contact%", EXISTING_CONTACT); + xmlDomainCheck = + loadXml("domain_check").replace("%tld%", tld).replace("%domain%", EXISTING_DOMAIN); + xmlDomainCreateTmpl = loadXml("domain_create").replace("%tld%", tld); + xmlDomainCreateFail = + xmlDomainCreateTmpl + .replace("%domain%", EXISTING_DOMAIN) + .replace("%contact%", EXISTING_CONTACT) + .replace("%host%", EXISTING_HOST); + xmlDomainInfo = + loadXml("domain_info").replace("%tld%", tld).replace("%domain%", EXISTING_DOMAIN); + xmlHostCreateTmpl = loadXml("host_create"); + xmlHostCreateFail = xmlHostCreateTmpl.replace("%host%", EXISTING_HOST); + xmlHostInfo = loadXml("host_info").replace("%host%", EXISTING_HOST); + } @Override public void run() { @@ -88,14 +177,14 @@ public class LoadTestAction implements Runnable { ImmutableList.Builder preTaskXmls = new ImmutableList.Builder<>(); ImmutableList.Builder contactNamesBuilder = new ImmutableList.Builder<>(); ImmutableList.Builder hostPrefixesBuilder = new ImmutableList.Builder<>(); - for (int i = 0; i < successfulDomainCreates; i++) { + for (int i = 0; i < successfulDomainCreatesPerSecond; i++) { String contactName = getRandomLabel(MAX_CONTACT_LENGTH); String hostPrefix = getRandomLabel(ARBITRARY_VALID_HOST_LENGTH); contactNamesBuilder.add(contactName); hostPrefixesBuilder.add(hostPrefix); preTaskXmls.add( - loadXml("contact_create").replace("%contact%", contactName), - loadXml("host_create").replace("%host%", hostPrefix)); + xmlContactCreateTmpl.replace("%contact%", contactName), + xmlHostCreateTmpl.replace("%host%", hostPrefix)); } enqueue(createTasks(preTaskXmls.build(), DateTime.now(UTC))); ImmutableList contactNames = contactNamesBuilder.build(); @@ -106,72 +195,44 @@ public class LoadTestAction implements Runnable { DateTime startSecond = initialStartSecond.plusSeconds(offsetSeconds); // The first "failed" creates might actually succeed if the object doesn't already exist, but // that shouldn't affect the load numbers. - tasks.addAll(createTasks( - createNumCopies( - loadXml("contact_create").replace("%contact%", EXISTING_CONTACT), - failedContactCreates), - startSecond)); - tasks.addAll(createTasks( - createNumCopies( - loadXml("host_create").replace("%host%", EXISTING_HOST), - failedHostCreates), - startSecond)); - tasks.addAll(createTasks( - createNumCopies( - loadXml("domain_create") - .replace("%tld%", tld) - .replace("%domain%", EXISTING_DOMAIN) - .replace("%contact%", EXISTING_CONTACT) - .replace("%host%", EXISTING_HOST), - failedDomainCreates), - startSecond)); + tasks.addAll( + createTasks( + createNumCopies(xmlContactCreateFail, failedContactCreatesPerSecond), startSecond)); + tasks.addAll( + createTasks(createNumCopies(xmlHostCreateFail, failedHostCreatesPerSecond), startSecond)); + tasks.addAll( + createTasks( + createNumCopies(xmlDomainCreateFail, failedDomainCreatesPerSecond), startSecond)); // We can do infos on the known existing objects. - tasks.addAll(createTasks( - createNumCopies( - loadXml("contact_info").replace("%contact%", EXISTING_CONTACT), - contactInfos), - startSecond)); - tasks.addAll(createTasks( - createNumCopies( - loadXml("host_info").replace("%host%", EXISTING_HOST), - hostInfos), - startSecond)); - tasks.addAll(createTasks( - createNumCopies( - loadXml("domain_info") - .replace("%tld%", tld) - .replace("%domain%", EXISTING_DOMAIN), - domainInfos), - startSecond)); + tasks.addAll( + createTasks(createNumCopies(xmlContactInfo, contactInfosPerSecond), startSecond)); + tasks.addAll(createTasks(createNumCopies(xmlHostInfo, hostInfosPerSecond), startSecond)); + tasks.addAll(createTasks(createNumCopies(xmlDomainInfo, domainInfosPerSecond), startSecond)); // The domain check template uses "example.TLD" which won't exist, and one existing domain. - tasks.addAll(createTasks( - createNumCopies( - loadXml("domain_check") - .replace("%tld%", tld) - .replace("%domain%", EXISTING_DOMAIN), - domainChecks), - startSecond)); + tasks.addAll( + createTasks(createNumCopies(xmlDomainCheck, domainChecksPerSecond), startSecond)); // Do successful creates on random names - tasks.addAll(createTasks( - transform( - createNumCopies(loadXml("contact_create"), successfulContactCreates), - randomNameReplacer("%contact%", MAX_CONTACT_LENGTH)), - startSecond)); - tasks.addAll(createTasks( - transform( - createNumCopies(loadXml("host_create"), successfulHostCreates), - randomNameReplacer("%host%", ARBITRARY_VALID_HOST_LENGTH)), - startSecond)); - tasks.addAll(createTasks( - FluentIterable - .from(createNumCopies( - loadXml("domain_create").replace("%tld%", tld), - successfulDomainCreates)) - .transform(randomNameReplacer("%domain%", MAX_DOMAIN_LABEL_LENGTH)) - .transform(listNameReplacer("%contact%", contactNames)) - .transform(listNameReplacer("%host%", hostPrefixes)) - .toList(), - startSecond)); + tasks.addAll( + createTasks( + transform( + createNumCopies(xmlContactCreateTmpl, successfulContactCreatesPerSecond), + randomNameReplacer("%contact%", MAX_CONTACT_LENGTH)), + startSecond)); + tasks.addAll( + createTasks( + transform( + createNumCopies(xmlHostCreateTmpl, successfulHostCreatesPerSecond), + randomNameReplacer("%host%", ARBITRARY_VALID_HOST_LENGTH)), + startSecond)); + tasks.addAll( + createTasks( + FluentIterable.from( + createNumCopies(xmlDomainCreateTmpl, successfulDomainCreatesPerSecond)) + .transform(randomNameReplacer("%domain%", MAX_DOMAIN_LABEL_LENGTH)) + .transform(listNameReplacer("%contact%", contactNames)) + .transform(listNameReplacer("%host%", hostPrefixes)) + .toList(), + startSecond)); } enqueue(tasks.build()); } diff --git a/java/com/google/domain/registry/loadtest/LoadTestModule.java b/java/com/google/domain/registry/loadtest/LoadTestModule.java index a548372d4..e9f16d423 100644 --- a/java/com/google/domain/registry/loadtest/LoadTestModule.java +++ b/java/com/google/domain/registry/loadtest/LoadTestModule.java @@ -14,7 +14,7 @@ package com.google.domain.registry.loadtest; -import static com.google.domain.registry.request.RequestParameters.extractIntParameter; +import static com.google.domain.registry.request.RequestParameters.extractOptionalIntParameter; import static com.google.domain.registry.request.RequestParameters.extractRequiredParameter; import com.google.domain.registry.request.Parameter; @@ -22,6 +22,8 @@ import com.google.domain.registry.request.Parameter; import dagger.Module; import dagger.Provides; +import org.joda.time.Minutes; + import javax.servlet.http.HttpServletRequest; /** @@ -43,72 +45,74 @@ public final class LoadTestModule { @Provides @Parameter("delaySeconds") static int provideDelaySeconds(HttpServletRequest req) { - return extractIntParameter(req, "delaySeconds"); + return extractOptionalIntParameter(req, "delaySeconds") + .or(Minutes.ONE.toStandardSeconds().getSeconds()); } @Provides @Parameter("runSeconds") static int provideRunSeconds(HttpServletRequest req) { - return extractIntParameter(req, "runSeconds"); + return extractOptionalIntParameter(req, "runSeconds") + .or(Minutes.ONE.toStandardSeconds().getSeconds()); } @Provides @Parameter("successfulDomainCreates") static int provideSuccessfulDomainCreates(HttpServletRequest req) { - return extractIntParameter(req, "successfulDomainCreates"); + return extractOptionalIntParameter(req, "successfulDomainCreates").or(0); } @Provides @Parameter("failedDomainCreates") static int provideFailedDomainCreates(HttpServletRequest req) { - return extractIntParameter(req, "failedDomainCreates"); + return extractOptionalIntParameter(req, "failedDomainCreates").or(0); } @Provides @Parameter("domainInfos") static int provideDomainInfos(HttpServletRequest req) { - return extractIntParameter(req, "domainInfos"); + return extractOptionalIntParameter(req, "domainInfos").or(0); } @Provides @Parameter("domainChecks") static int provideDomainChecks(HttpServletRequest req) { - return extractIntParameter(req, "domainChecks"); + return extractOptionalIntParameter(req, "domainChecks").or(0); } @Provides @Parameter("successfulContactCreates") static int provideSuccessfulContactCreates(HttpServletRequest req) { - return extractIntParameter(req, "successfulContactCreates"); + return extractOptionalIntParameter(req, "successfulContactCreates").or(0); } @Provides @Parameter("failedContactCreates") static int provideFailedContactCreates(HttpServletRequest req) { - return extractIntParameter(req, "failedContactCreates"); + return extractOptionalIntParameter(req, "failedContactCreates").or(0); } @Provides @Parameter("contactInfos") static int provideContactInfos(HttpServletRequest req) { - return extractIntParameter(req, "contactInfos"); + return extractOptionalIntParameter(req, "contactInfos").or(0); } @Provides @Parameter("successfulHostCreates") static int provideSuccessfulHostCreates(HttpServletRequest req) { - return extractIntParameter(req, "successfulHostCreates"); + return extractOptionalIntParameter(req, "successfulHostCreates").or(0); } @Provides @Parameter("failedHostCreates") static int provideFailedHostCreates(HttpServletRequest req) { - return extractIntParameter(req, "failedHostCreates"); + return extractOptionalIntParameter(req, "failedHostCreates").or(0); } @Provides @Parameter("hostInfos") static int provideHostInfos(HttpServletRequest req) { - return extractIntParameter(req, "hostInfos"); + return extractOptionalIntParameter(req, "hostInfos").or(0); } }