Refactor LordnTask to LordnTaskUtils

Made it clear that it is a util class and moved some of the functions only used in NordnUploadAction (to NordnUploadAction). Also used Retrier to handle retries when leasing tasks.

These changes allow us to no longer use InjectRule in related unit tests.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=217761117
This commit is contained in:
jianglai 2018-10-18 13:45:30 -07:00
parent 0f1f418034
commit b254269d2f
10 changed files with 170 additions and 176 deletions

View file

@ -52,8 +52,8 @@ import static google.registry.testing.TaskQueueHelper.assertDnsTasksEnqueued;
import static google.registry.testing.TaskQueueHelper.assertNoDnsTasksEnqueued;
import static google.registry.testing.TaskQueueHelper.assertNoTasksEnqueued;
import static google.registry.testing.TaskQueueHelper.assertTasksEnqueued;
import static google.registry.tmch.LordnTask.QUEUE_CLAIMS;
import static google.registry.tmch.LordnTask.QUEUE_SUNRISE;
import static google.registry.tmch.LordnTaskUtils.QUEUE_CLAIMS;
import static google.registry.tmch.LordnTaskUtils.QUEUE_SUNRISE;
import static google.registry.util.DateTimeUtils.END_OF_TIME;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import static org.joda.money.CurrencyUnit.EUR;

View file

@ -97,7 +97,7 @@ import google.registry.model.smd.EncodedSignedMark;
import google.registry.model.transfer.TransferData;
import google.registry.model.transfer.TransferData.Builder;
import google.registry.model.transfer.TransferStatus;
import google.registry.tmch.LordnTask;
import google.registry.tmch.LordnTaskUtils;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
@ -363,9 +363,10 @@ public class DatastoreHelper {
/** Persists a domain and enqueues a LORDN task of the appropriate type for it. */
public static DomainResource persistDomainAndEnqueueLordn(final DomainResource domain) {
final DomainResource persistedDomain = persistResource(domain);
// Calls {@link LordnTask#enqueueDomainResourceTask} wrapped in an ofy transaction so that the
// Calls {@link LordnTaskUtils#enqueueDomainResourceTask} wrapped in an ofy transaction so that
// the
// transaction time is set correctly.
ofy().transactNew(() -> LordnTask.enqueueDomainResourceTask(persistedDomain));
ofy().transactNew(() -> LordnTaskUtils.enqueueDomainResourceTask(persistedDomain));
return persistedDomain;
}

View file

@ -22,18 +22,7 @@ import static google.registry.testing.DatastoreHelper.persistActiveContact;
import static google.registry.testing.DatastoreHelper.persistDomainAndEnqueueLordn;
import static google.registry.testing.JUnitBackports.assertThrows;
import static google.registry.testing.TaskQueueHelper.assertTasksEnqueued;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import com.google.appengine.api.taskqueue.LeaseOptions;
import com.google.appengine.api.taskqueue.Queue;
import com.google.appengine.api.taskqueue.TaskHandle;
import com.google.appengine.api.taskqueue.TaskOptions;
import com.google.appengine.api.taskqueue.TaskOptions.Method;
import com.google.appengine.api.taskqueue.TransientFailureException;
import com.google.apphosting.api.DeadlineExceededException;
import com.google.common.collect.ImmutableList;
import com.googlecode.objectify.Key;
import google.registry.model.domain.DomainResource;
import google.registry.model.domain.launch.LaunchNotice;
@ -44,7 +33,6 @@ import google.registry.testing.FakeClock;
import google.registry.testing.InjectRule;
import google.registry.testing.TaskQueueHelper.TaskMatcher;
import google.registry.util.Clock;
import java.util.List;
import org.joda.time.DateTime;
import org.junit.Before;
import org.junit.Rule;
@ -52,9 +40,9 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/** Unit tests for {@link LordnTask}. */
/** Unit tests for {@link LordnTaskUtils}. */
@RunWith(JUnit4.class)
public class LordnTaskTest {
public class LordnTaskUtilsTest {
private static final Clock clock = new FakeClock(DateTime.parse("2010-05-01T10:11:12Z"));
@ -70,32 +58,9 @@ public class LordnTaskTest {
public void before() {
createTld("example");
inject.setStaticField(Ofy.class, "clock", clock);
inject.setStaticField(LordnTask.class, "backOffMillis", 1L);
}
@Test
public void test_convertTasksToCsv() {
List<TaskHandle> tasks = ImmutableList.of(
makeTaskHandle("task1", "example", "csvLine1", "lordn-sunrise"),
makeTaskHandle("task2", "example", "csvLine2", "lordn-sunrise"),
makeTaskHandle("task3", "example", "ending", "lordn-sunrise"));
assertThat(LordnTask.convertTasksToCsv(tasks, clock.nowUtc(), "col1,col2"))
.isEqualTo("1,2010-05-01T10:11:12.000Z,3\ncol1,col2\ncsvLine1\ncsvLine2\nending\n");
}
@Test
public void test_convertTasksToCsv_doesntFailOnEmptyTasks() {
assertThat(
LordnTask.convertTasksToCsv(ImmutableList.of(), clock.nowUtc(), "col1,col2"))
.isEqualTo("1,2010-05-01T10:11:12.000Z,0\ncol1,col2\n");
}
@Test
public void test_convertTasksToCsv_throwsNpeOnNullTasks() {
assertThrows(
NullPointerException.class,
() -> LordnTask.convertTasksToCsv(null, clock.nowUtc(), "header"));
}
private DomainResource.Builder newDomainBuilder(DateTime applicationTime) {
return new DomainResource.Builder()
@ -173,38 +138,6 @@ public class LordnTaskTest {
public void test_enqueueDomainResourceTask_throwsNpeOnNullDomain() {
assertThrows(
NullPointerException.class,
() -> ofy().transactNew(() -> LordnTask.enqueueDomainResourceTask(null)));
}
@SuppressWarnings("unchecked")
@Test
public void test_loadAllTasks_retryLogic_thirdTrysTheCharm() {
Queue queue = mock(Queue.class);
TaskHandle task = new TaskHandle(TaskOptions.Builder.withTaskName("blah"), "blah");
when(queue.leaseTasks(any(LeaseOptions.class)))
.thenThrow(TransientFailureException.class)
.thenThrow(DeadlineExceededException.class)
.thenReturn(ImmutableList.of(task), ImmutableList.of());
assertThat(LordnTask.loadAllTasks(queue, "tld")).containsExactly(task);
}
@SuppressWarnings("unchecked")
@Test
public void test_loadAllTasks_retryLogic_allFailures() {
Queue queue = mock(Queue.class);
when(queue.leaseTasks(any(LeaseOptions.class))).thenThrow(TransientFailureException.class);
RuntimeException thrown =
assertThrows(RuntimeException.class, () -> LordnTask.loadAllTasks(queue, "tld"));
assertThat(thrown).hasMessageThat().contains("Error leasing tasks");
}
private static TaskHandle makeTaskHandle(
String taskName,
String tag,
String payload,
String queue) {
return new TaskHandle(
TaskOptions.Builder.withPayload(payload).method(Method.PULL).tag(tag).taskName(taskName),
queue);
() -> ofy().transactNew(() -> LordnTaskUtils.enqueueDomainResourceTask(null)));
}
}

View file

@ -32,13 +32,21 @@ import static java.nio.charset.StandardCharsets.UTF_8;
import static javax.servlet.http.HttpServletResponse.SC_ACCEPTED;
import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import com.google.appengine.api.taskqueue.LeaseOptions;
import com.google.appengine.api.taskqueue.Queue;
import com.google.appengine.api.taskqueue.TaskHandle;
import com.google.appengine.api.taskqueue.TaskOptions;
import com.google.appengine.api.taskqueue.TaskOptions.Method;
import com.google.appengine.api.taskqueue.TransientFailureException;
import com.google.appengine.api.urlfetch.HTTPHeader;
import com.google.appengine.api.urlfetch.HTTPRequest;
import com.google.appengine.api.urlfetch.HTTPResponse;
import com.google.appengine.api.urlfetch.URLFetchService;
import com.google.apphosting.api.DeadlineExceededException;
import com.google.common.base.VerifyException;
import com.google.common.collect.ImmutableList;
import google.registry.model.domain.DomainResource;
@ -55,6 +63,7 @@ import google.registry.util.Retrier;
import google.registry.util.TaskQueueUtils;
import google.registry.util.UrlFetchException;
import java.net.URL;
import java.util.List;
import java.util.Optional;
import java.util.Random;
import org.joda.time.DateTime;
@ -71,15 +80,15 @@ import org.mockito.Mock;
@RunWith(JUnit4.class)
public class NordnUploadActionTest {
private static final String CLAIMS_CSV = "1,2000-01-01T00:00:00.000Z,1\n"
private static final String CLAIMS_CSV = "1,2010-05-01T10:11:12.000Z,1\n"
+ "roid,domain-name,notice-id,registrar-id,registration-datetime,ack-datetime,"
+ "application-datetime\n"
+ "2-TLD,claims-landrush1.tld,landrush1tcn,99999,2000-01-01T00:00:00.000Z,"
+ "2-TLD,claims-landrush1.tld,landrush1tcn,99999,2010-05-01T10:11:12.000Z,"
+ "1969-12-31T23:00:00.000Z,1969-12-31T00:00:00.000Z\n";
private static final String SUNRISE_CSV = "1,2000-01-01T00:00:00.000Z,1\n"
private static final String SUNRISE_CSV = "1,2010-05-01T10:11:12.000Z,1\n"
+ "roid,domain-name,SMD-id,registrar-id,registration-datetime,application-datetime\n"
+ "2-TLD,sunrise1.tld,my-smdid,99999,2000-01-01T00:00:00.000Z,1969-12-31T00:00:00.000Z\n";
+ "2-TLD,sunrise1.tld,my-smdid,99999,2010-05-01T10:11:12.000Z,1969-12-31T00:00:00.000Z\n";
private static final String LOCATION_URL = "http://trololol";
@ -94,7 +103,7 @@ public class NordnUploadActionTest {
@Mock private HTTPResponse httpResponse;
@Captor private ArgumentCaptor<HTTPRequest> httpRequestCaptor;
private final FakeClock clock = new FakeClock(DateTime.parse("2000-01-01TZ"));
private final FakeClock clock = new FakeClock(DateTime.parse("2010-05-01T10:11:12Z"));
private final LordnRequestInitializer lordnRequestInitializer = new LordnRequestInitializer();
private final NordnUploadAction action = new NordnUploadAction();
@ -117,6 +126,54 @@ public class NordnUploadActionTest {
action.tld = "tld";
action.tmchMarksdbUrl = "http://127.0.0.1";
action.random = new Random();
action.retrier = new Retrier(new FakeSleeper(clock), 3);
}
@Test
public void test_convertTasksToCsv() {
List<TaskHandle> tasks =
ImmutableList.of(
makeTaskHandle("task1", "example", "csvLine1", "lordn-sunrise"),
makeTaskHandle("task2", "example", "csvLine2", "lordn-sunrise"),
makeTaskHandle("task3", "example", "ending", "lordn-sunrise"));
assertThat(NordnUploadAction.convertTasksToCsv(tasks, clock.nowUtc(), "col1,col2"))
.isEqualTo("1,2010-05-01T10:11:12.000Z,3\ncol1,col2\ncsvLine1\ncsvLine2\nending\n");
}
@Test
public void test_convertTasksToCsv_doesntFailOnEmptyTasks() {
assertThat(NordnUploadAction.convertTasksToCsv(ImmutableList.of(), clock.nowUtc(), "col1,col2"))
.isEqualTo("1,2010-05-01T10:11:12.000Z,0\ncol1,col2\n");
}
@Test
public void test_convertTasksToCsv_throwsNpeOnNullTasks() {
assertThrows(
NullPointerException.class,
() -> NordnUploadAction.convertTasksToCsv(null, clock.nowUtc(), "header"));
}
@SuppressWarnings("unchecked")
@Test
public void test_loadAllTasks_retryLogic_thirdTrysTheCharm() {
Queue queue = mock(Queue.class);
TaskHandle task = new TaskHandle(TaskOptions.Builder.withTaskName("blah"), "blah");
when(queue.leaseTasks(any(LeaseOptions.class)))
.thenThrow(TransientFailureException.class)
.thenThrow(DeadlineExceededException.class)
.thenReturn(ImmutableList.of(task), ImmutableList.of());
assertThat(action.loadAllTasks(queue, "tld")).containsExactly(task);
}
@SuppressWarnings("unchecked")
@Test
public void test_loadAllTasks_retryLogic_allFailures() {
Queue queue = mock(Queue.class);
when(queue.leaseTasks(any(LeaseOptions.class)))
.thenThrow(new TransientFailureException("some transient error"));
RuntimeException thrown =
assertThrows(TransientFailureException.class, () -> action.loadAllTasks(queue, "tld"));
assertThat(thrown).hasMessageThat().isEqualTo("some transient error");
}
@Test
@ -230,4 +287,11 @@ public class NordnUploadActionTest {
.setApplicationTime(domain.getCreationTime().minusDays(1))
.build());
}
private static TaskHandle makeTaskHandle(
String taskName, String tag, String payload, String queue) {
return new TaskHandle(
TaskOptions.Builder.withPayload(payload).method(Method.PULL).tag(tag).taskName(taskName),
queue);
}
}

View file

@ -21,7 +21,7 @@ import org.junit.runners.Suite.SuiteClasses;
/** Convenience class to run all TMCH tests inside IDE with one keystroke. */
@RunWith(Suite.class)
@SuiteClasses({
LordnTaskTest.class,
LordnTaskUtilsTest.class,
NordnUploadAction.class,
NordnVerifyAction.class,
SmdrlCsvParserTest.class,