mirror of
https://github.com/google/nomulus.git
synced 2025-05-05 06:27:51 +02:00
TldFanoutAction fans out a given endpoint to all TLDs (either TEST, REAL, or both). However, it is also used to delegate a single endpoint request that we want set in a specific queue (so we can control retries). We do that by setting the TLD list to "runInEmpty" rather than "forEachRealTld" or "forEachTestTld". Currently, using "runInEmpty" would still specify a TLD - but that TLD would be the empty string. This is a bug: it sets the TLD parameter to a bad value. It worked only because none of the endpoints called with "runInEmpty" were using the TLD parameter. However, this will (and does) break if either (a) the endpoint accepts an optional TLD parameter (like deleteProberData does), or (b) the given endpoint already has a TLD parameter in it (we want to run the endpoint with a single TLD, but still use the "fanout" to set the right queue). This CL fixes several things: - if runInEmpty is given, no TLD parameter is added - 'runInEmpty' is now mutually exclusive with 'forEach*Tld' and 'excludes' - we do some sanity checks and added logging - removed the buggy and unused "':tld' in path is replaced by TLD" - in the cron.xml, removed documentation for :tld and the broken :registrar Note that none of the endpoints that were used with runInEmpty fanout had the TLD parameter prior to deleteProberData ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=189954585
263 lines
8.9 KiB
Java
263 lines
8.9 KiB
Java
// 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.cron;
|
|
|
|
import static com.google.common.collect.ImmutableList.toImmutableList;
|
|
import static com.google.common.collect.Iterables.getLast;
|
|
import static com.google.common.truth.Truth.assertThat;
|
|
import static google.registry.testing.DatastoreHelper.createTlds;
|
|
import static google.registry.testing.DatastoreHelper.persistResource;
|
|
import static google.registry.testing.JUnitBackports.assertThrows;
|
|
import static google.registry.testing.TaskQueueHelper.assertNoTasksEnqueued;
|
|
import static google.registry.testing.TaskQueueHelper.assertTasksEnqueued;
|
|
|
|
import com.google.appengine.api.taskqueue.dev.QueueStateInfo.TaskStateInfo;
|
|
import com.google.appengine.tools.development.testing.LocalTaskQueueTestConfig;
|
|
import com.google.common.base.Joiner;
|
|
import com.google.common.base.Splitter;
|
|
import com.google.common.collect.ImmutableListMultimap;
|
|
import com.google.common.collect.ImmutableSet;
|
|
import google.registry.model.registry.Registry;
|
|
import google.registry.model.registry.Registry.TldType;
|
|
import google.registry.testing.AppEngineRule;
|
|
import google.registry.testing.FakeResponse;
|
|
import google.registry.testing.TaskQueueHelper.TaskMatcher;
|
|
import google.registry.util.Retrier;
|
|
import google.registry.util.TaskEnqueuer;
|
|
import java.util.List;
|
|
import java.util.Optional;
|
|
import java.util.stream.Stream;
|
|
import org.junit.Before;
|
|
import org.junit.Rule;
|
|
import org.junit.Test;
|
|
import org.junit.runner.RunWith;
|
|
import org.junit.runners.JUnit4;
|
|
|
|
/** Unit tests for {@link TldFanoutAction}. */
|
|
@RunWith(JUnit4.class)
|
|
public class TldFanoutActionTest {
|
|
|
|
private static final String ENDPOINT = "/the/servlet";
|
|
private static final String QUEUE = "the-queue";
|
|
private final FakeResponse response = new FakeResponse();
|
|
|
|
@Rule
|
|
public final AppEngineRule appEngine = AppEngineRule.builder()
|
|
.withDatastore()
|
|
.withTaskQueue(Joiner.on('\n').join(
|
|
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>",
|
|
"<queue-entries>",
|
|
" <queue>",
|
|
" <name>the-queue</name>",
|
|
" <rate>1/s</rate>",
|
|
" </queue>",
|
|
"</queue-entries>"))
|
|
.build();
|
|
|
|
private static ImmutableListMultimap<String, String> getParamsMap(String... keysAndValues) {
|
|
ImmutableListMultimap.Builder<String, String> params = new ImmutableListMultimap.Builder<>();
|
|
params.put("queue", QUEUE);
|
|
params.put("endpoint", ENDPOINT);
|
|
for (int i = 0; i < keysAndValues.length; i += 2) {
|
|
params.put(keysAndValues[i], keysAndValues[i + 1]);
|
|
}
|
|
return params.build();
|
|
}
|
|
|
|
private void run(ImmutableListMultimap<String, String> params) throws Exception {
|
|
TldFanoutAction action = new TldFanoutAction();
|
|
action.params = params;
|
|
action.endpoint = getLast(params.get("endpoint"));
|
|
action.queue = getLast(params.get("queue"));
|
|
action.excludes = params.containsKey("exclude")
|
|
? ImmutableSet.copyOf(Splitter.on(',').split(params.get("exclude").get(0)))
|
|
: ImmutableSet.of();
|
|
action.taskEnqueuer = new TaskEnqueuer(new Retrier(null, 1));
|
|
action.response = response;
|
|
action.runInEmpty = params.containsKey("runInEmpty");
|
|
action.forEachRealTld = params.containsKey("forEachRealTld");
|
|
action.forEachTestTld = params.containsKey("forEachTestTld");
|
|
action.jitterSeconds = Optional.empty();
|
|
action.run();
|
|
}
|
|
|
|
@Before
|
|
public void before() throws Exception {
|
|
createTlds("com", "net", "org", "example");
|
|
persistResource(Registry.get("example").asBuilder().setTldType(TldType.TEST).build());
|
|
}
|
|
|
|
private static void assertTasks(String... tasks) throws Exception {
|
|
assertTasksEnqueued(
|
|
QUEUE,
|
|
Stream.of(tasks).map(
|
|
namespace ->
|
|
new TaskMatcher()
|
|
.url(ENDPOINT)
|
|
.header("content-type", "application/x-www-form-urlencoded")
|
|
.param("tld", namespace))
|
|
.collect(toImmutableList()));
|
|
}
|
|
|
|
private static void assertTaskWithoutTld() throws Exception {
|
|
assertTasksEnqueued(
|
|
QUEUE,
|
|
new TaskMatcher()
|
|
.url(ENDPOINT)
|
|
.header("content-type", "application/x-www-form-urlencoded"));
|
|
}
|
|
|
|
@Test
|
|
public void testSuccess_methodPostIsDefault() throws Exception {
|
|
run(getParamsMap("runInEmpty", ""));
|
|
assertTasksEnqueued(QUEUE, new TaskMatcher().method("POST"));
|
|
}
|
|
|
|
@Test
|
|
public void testFailure_noTlds() throws Exception {
|
|
assertThrows(IllegalArgumentException.class, () -> run(getParamsMap()));
|
|
}
|
|
|
|
@Test
|
|
public void testSuccess_runInEmpty() throws Exception {
|
|
run(getParamsMap("runInEmpty", ""));
|
|
assertTaskWithoutTld();
|
|
}
|
|
|
|
@Test
|
|
public void testSuccess_forEachRealTld() throws Exception {
|
|
run(getParamsMap("forEachRealTld", ""));
|
|
assertTasks("com", "net", "org");
|
|
}
|
|
|
|
@Test
|
|
public void testSuccess_forEachTestTld() throws Exception {
|
|
run(getParamsMap("forEachTestTld", ""));
|
|
assertTasks("example");
|
|
}
|
|
|
|
@Test
|
|
public void testSuccess_forEachTestTldAndForEachRealTld() throws Exception {
|
|
run(getParamsMap(
|
|
"forEachTestTld", "",
|
|
"forEachRealTld", ""));
|
|
assertTasks("com", "net", "org", "example");
|
|
}
|
|
|
|
@Test
|
|
public void testSuccess_runEverywhere() throws Exception {
|
|
run(getParamsMap("forEachTestTld", "", "forEachRealTld", ""));
|
|
assertTasks("com", "net", "org", "example");
|
|
}
|
|
|
|
@Test
|
|
public void testSuccess_excludeRealTlds() throws Exception {
|
|
run(getParamsMap(
|
|
"forEachRealTld", "",
|
|
"exclude", "com,net"));
|
|
assertTasks("org");
|
|
}
|
|
|
|
@Test
|
|
public void testSuccess_excludeTestTlds() throws Exception {
|
|
run(getParamsMap(
|
|
"forEachTestTld", "",
|
|
"exclude", "example"));
|
|
assertNoTasksEnqueued(QUEUE);
|
|
}
|
|
|
|
@Test
|
|
public void testSuccess_excludeNonexistentTlds() throws Exception {
|
|
run(getParamsMap(
|
|
"forEachTestTld", "",
|
|
"forEachRealTld", "",
|
|
"exclude", "foo"));
|
|
assertTasks("com", "net", "org", "example");
|
|
}
|
|
|
|
@Test
|
|
public void testFailure_runInEmptyAndTest() throws Exception {
|
|
assertThrows(
|
|
IllegalArgumentException.class,
|
|
() ->
|
|
run(
|
|
getParamsMap(
|
|
"runInEmpty", "",
|
|
"forEachTestTld", "")));
|
|
}
|
|
|
|
@Test
|
|
public void testFailure_runInEmptyAndReal() throws Exception {
|
|
assertThrows(
|
|
IllegalArgumentException.class,
|
|
() ->
|
|
run(
|
|
getParamsMap(
|
|
"runInEmpty", "",
|
|
"forEachRealTld", "")));
|
|
}
|
|
|
|
@Test
|
|
public void testFailure_runInEmptyAndExclude() throws Exception {
|
|
assertThrows(
|
|
IllegalArgumentException.class,
|
|
() ->
|
|
run(
|
|
getParamsMap(
|
|
"runInEmpty", "",
|
|
"exclude", "foo")));
|
|
}
|
|
|
|
@Test
|
|
public void testSuccess_additionalArgsFlowThroughToPostParams() throws Exception {
|
|
run(getParamsMap("forEachTestTld", "", "newkey", "newval"));
|
|
assertTasksEnqueued(QUEUE,
|
|
new TaskMatcher().url("/the/servlet").param("newkey", "newval"));
|
|
}
|
|
|
|
@Test
|
|
public void testSuccess_returnHttpResponse() throws Exception {
|
|
run(getParamsMap("forEachRealTld", "", "endpoint", "/the/servlet"));
|
|
|
|
List<TaskStateInfo> taskList =
|
|
LocalTaskQueueTestConfig.getLocalTaskQueue().getQueueStateInfo().get(QUEUE).getTaskInfo();
|
|
|
|
assertThat(taskList).hasSize(3);
|
|
String expectedResponse = String.format(
|
|
"OK: Launched the following 3 tasks in queue the-queue\n"
|
|
+ "- Task: '%s', tld: 'com', endpoint: '/the/servlet'\n"
|
|
+ "- Task: '%s', tld: 'net', endpoint: '/the/servlet'\n"
|
|
+ "- Task: '%s', tld: 'org', endpoint: '/the/servlet'\n",
|
|
taskList.get(0).getTaskName(),
|
|
taskList.get(1).getTaskName(),
|
|
taskList.get(2).getTaskName());
|
|
assertThat(response.getPayload()).isEqualTo(expectedResponse);
|
|
}
|
|
|
|
@Test
|
|
public void testSuccess_returnHttpResponse_runInEmpty() throws Exception {
|
|
run(getParamsMap("runInEmpty", "", "endpoint", "/the/servlet"));
|
|
|
|
List<TaskStateInfo> taskList =
|
|
LocalTaskQueueTestConfig.getLocalTaskQueue().getQueueStateInfo().get(QUEUE).getTaskInfo();
|
|
|
|
assertThat(taskList).hasSize(1);
|
|
String expectedResponse = String.format(
|
|
"OK: Launched the following 1 tasks in queue the-queue\n"
|
|
+ "- Task: '%s', tld: '', endpoint: '/the/servlet'\n",
|
|
taskList.get(0).getTaskName());
|
|
assertThat(response.getPayload()).isEqualTo(expectedResponse);
|
|
}
|
|
}
|