Use native BatchInput for the sync batch-fetch REST-API
Use the BatchInput data type for the batch-fetch REST-API
for reducing the payload size, keeping the correct granularity
of the batch ref-update data and disallowing at protocol
level the possibility to split a batch into sync and async
executions.
Also avoid scheduing a batch as a series of individual
fetch operations of the individual refs, as a follow-up
of the review of Ifd2a28a6.
Change-Id: I1b8fcb0b803cd441f4fac21940c205767d0eb3a9
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/BatchFetchAction.java b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/BatchFetchAction.java
index b7b1ab1..ac3df43 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/BatchFetchAction.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/BatchFetchAction.java
@@ -21,10 +21,9 @@
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.googlesource.gerrit.plugins.replication.pull.api.FetchAction.BatchInput;
-import java.util.List;
@Singleton
-public class BatchFetchAction implements RestModifyView<ProjectResource, List<FetchAction.Input>> {
+public class BatchFetchAction implements RestModifyView<ProjectResource, BatchInput> {
private final FetchAction fetchAction;
@Inject
@@ -33,10 +32,8 @@
}
@Override
- public Response<?> apply(ProjectResource resource, List<FetchAction.Input> inputs)
+ public Response<?> apply(ProjectResource resource, BatchInput batchInput)
throws RestApiException {
- return Response.ok(
- fetchAction.apply(
- resource, BatchInput.fromInput(inputs.toArray(new FetchAction.Input[0]))));
+ return Response.ok(fetchAction.apply(resource, batchInput));
}
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/FetchAction.java b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/FetchAction.java
index d57ae0c..38d0cdd 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/FetchAction.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/FetchAction.java
@@ -76,7 +76,7 @@
public Set<String> refsNames;
public boolean async;
- static BatchInput fromInput(Input... input) {
+ public static BatchInput fromInput(Input... input) {
BatchInput batchInput = new BatchInput();
batchInput.async = input[0].async;
batchInput.label = input[0].label;
@@ -135,23 +135,14 @@
@SuppressWarnings("unchecked")
private Response.Accepted applyAsync(Project.NameKey project, BatchInput batchInput) {
- WorkQueue.Task<Void> task = null;
- Optional<String> url;
-
- for (String refName : batchInput.refsNames) {
- Input input = new Input();
- input.label = batchInput.label;
- input.async = batchInput.async;
- input.refName = refName;
- task =
- (Task<Void>)
- workQueue
- .getDefaultQueue()
- .submit(
- fetchJobFactory.create(
- project, input, PullReplicationApiRequestMetrics.get()));
- }
- url =
+ WorkQueue.Task<Void> task =
+ (Task<Void>)
+ workQueue
+ .getDefaultQueue()
+ .submit(
+ fetchJobFactory.create(
+ project, batchInput, PullReplicationApiRequestMetrics.get()));
+ Optional<String> url =
urlFormatter
.get()
.getRestUrl("a/config/server/tasks/" + HexFormat.fromInt(task.getTaskId()));
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/FetchCommand.java b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/FetchCommand.java
index 8b86965..47d5391 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/FetchCommand.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/FetchCommand.java
@@ -64,11 +64,11 @@
public void fetchAsync(
Project.NameKey name,
String label,
- String refName,
+ Set<String> refsNames,
PullReplicationApiRequestMetrics apiRequestMetrics)
throws InterruptedException, ExecutionException, RemoteConfigurationMissingException,
TimeoutException, TransportException {
- fetch(name, label, Set.of(refName), ASYNC, Optional.of(apiRequestMetrics));
+ fetch(name, label, refsNames, ASYNC, Optional.of(apiRequestMetrics));
}
public void fetchSync(Project.NameKey name, String label, Set<String> refsNames)
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/FetchJob.java b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/FetchJob.java
index a613c0e..0975045 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/FetchJob.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/FetchJob.java
@@ -18,6 +18,7 @@
import com.google.gerrit.entities.Project;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
+import com.googlesource.gerrit.plugins.replication.pull.api.FetchAction.BatchInput;
import com.googlesource.gerrit.plugins.replication.pull.api.exception.RemoteConfigurationMissingException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
@@ -28,38 +29,38 @@
public interface Factory {
FetchJob create(
- Project.NameKey project, FetchAction.Input input, PullReplicationApiRequestMetrics metrics);
+ Project.NameKey project, BatchInput input, PullReplicationApiRequestMetrics metrics);
}
private FetchCommand command;
private Project.NameKey project;
- private FetchAction.Input input;
+ private BatchInput batchInput;
private final PullReplicationApiRequestMetrics metrics;
@Inject
public FetchJob(
FetchCommand command,
@Assisted Project.NameKey project,
- @Assisted FetchAction.Input input,
+ @Assisted BatchInput batchInput,
@Assisted PullReplicationApiRequestMetrics metrics) {
this.command = command;
this.project = project;
- this.input = input;
+ this.batchInput = batchInput;
this.metrics = metrics;
}
@Override
public void run() {
try {
- command.fetchAsync(project, input.label, input.refName, metrics);
+ command.fetchAsync(project, batchInput.label, batchInput.refsNames, metrics);
} catch (InterruptedException
| ExecutionException
| RemoteConfigurationMissingException
| TimeoutException
| TransportException e) {
log.atSevere().withCause(e).log(
- "Exception during the async fetch call for project %s, label %s and ref name %s",
- project.get(), input.label, input.refName);
+ "Exception during the async fetch call for project %s, label %s and ref(s) name(s) %s",
+ project.get(), batchInput.label, batchInput.refsNames);
}
}
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/PullReplicationFilter.java b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/PullReplicationFilter.java
index 86fba22..368e61a 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/PullReplicationFilter.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/PullReplicationFilter.java
@@ -52,6 +52,7 @@
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.TypeLiteral;
+import com.googlesource.gerrit.plugins.replication.pull.api.FetchAction.BatchInput;
import com.googlesource.gerrit.plugins.replication.pull.api.FetchAction.Input;
import com.googlesource.gerrit.plugins.replication.pull.api.data.RevisionInput;
import com.googlesource.gerrit.plugins.replication.pull.api.data.RevisionsInput;
@@ -274,11 +275,11 @@
@SuppressWarnings("unchecked")
private Response<Map<String, Object>> doBatchFetch(HttpServletRequest httpRequest)
throws IOException, RestApiException {
- TypeLiteral<List<Input>> collectionType = new TypeLiteral<>() {};
- List<Input> inputs = readJson(httpRequest, collectionType.getType());
+ BatchInput batchInput = readJson(httpRequest, BatchInput.class);
IdString id = getProjectName(httpRequest).get();
- return (Response<Map<String, Object>>) batchFetchAction.apply(parseProjectResource(id), inputs);
+ return (Response<Map<String, Object>>)
+ batchFetchAction.apply(parseProjectResource(id), batchInput);
}
private <T> void writeResponse(HttpServletResponse httpResponse, Response<T> response)
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/client/FetchRestApiClient.java b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/client/FetchRestApiClient.java
index e682b71..614774d 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/client/FetchRestApiClient.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/client/FetchRestApiClient.java
@@ -160,17 +160,14 @@
NameKey project, List<String> refsInBatch, URIish targetUri, long startTimeNanos)
throws IOException {
boolean callAsync = !containsSyncFetchRef(refsInBatch);
+ String refsNamesBody = refsInBatch.stream().collect(Collectors.joining("\",\"", "\"", "\""));
String msgBody =
- refsInBatch.stream()
- .map(
- refName ->
- String.format(
- "{\"label\":\"%s\", \"ref_name\": \"%s\", \"async\":%s}",
- instanceId, refName, callAsync))
- .collect(Collectors.joining(","));
+ String.format(
+ "{\"label\":\"%s\", \"refs_names\": [ %s ], \"async\":%s}",
+ instanceId, refsNamesBody, callAsync);
String url = formatUrl(targetUri.toString(), project, "batch-fetch");
- HttpPost post = createPostRequest(url, "[" + msgBody + "]", startTimeNanos);
+ HttpPost post = createPostRequest(url, msgBody, startTimeNanos);
return executeRequest(post, bearerTokenProvider.get(), targetUri);
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/event/StreamEventListener.java b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/event/StreamEventListener.java
index 2f992cd..74bf51d 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/event/StreamEventListener.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/event/StreamEventListener.java
@@ -15,6 +15,7 @@
package com.googlesource.gerrit.plugins.replication.pull.event;
import static com.googlesource.gerrit.plugins.replication.pull.ApplyObjectCacheModule.APPLY_OBJECTS_CACHE;
+import static com.googlesource.gerrit.plugins.replication.pull.api.FetchAction.BatchInput.fromInput;
import static java.util.Objects.requireNonNull;
import com.google.common.base.Strings;
@@ -242,7 +243,9 @@
FetchAction.Input input = new FetchAction.Input();
input.refName = refName;
input.label = sourceInstanceId;
- workQueue.getDefaultQueue().submit(fetchJobFactory.create(projectNameKey, input, metrics));
+ workQueue
+ .getDefaultQueue()
+ .submit(fetchJobFactory.create(projectNameKey, fromInput(input), metrics));
}
private String getProjectRepositoryName(ProjectCreatedEvent projectCreatedEvent) {
diff --git a/src/test/java/com/googlesource/gerrit/plugins/replication/pull/api/BatchFetchActionTest.java b/src/test/java/com/googlesource/gerrit/plugins/replication/pull/api/BatchFetchActionTest.java
index e2e4cd3..9dc736f 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/replication/pull/api/BatchFetchActionTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/replication/pull/api/BatchFetchActionTest.java
@@ -19,7 +19,6 @@
import static com.google.common.truth.Truth.assertThat;
import static org.apache.http.HttpStatus.SC_OK;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -27,7 +26,7 @@
import com.google.gerrit.extensions.restapi.Response;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.server.project.ProjectResource;
-import java.util.List;
+import java.util.Set;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -52,54 +51,49 @@
}
@Test
- public void shouldDelegateToFetchActionWithBatchInputForListOfFetchInput()
- throws RestApiException {
- FetchAction.Input first = createInput(master);
- FetchAction.Input second = createInput(test);
+ public void shouldDelegateToFetchActionForEveryFetchInput() throws RestApiException {
+ FetchAction.BatchInput batchInput = createBatchInput(master, test);
- batchFetchAction.apply(projectResource, List.of(first, second));
+ batchFetchAction.apply(projectResource, batchInput);
- verify(fetchAction).apply(eq(projectResource), any(FetchAction.BatchInput.class));
+ verify(fetchAction).apply(projectResource, batchInput);
}
@Test
public void shouldReturnOkResponseCodeWhenAllInputsAreProcessedSuccessfully()
throws RestApiException {
- FetchAction.Input first = createInput(master);
- FetchAction.Input second = createInput(test);
+ FetchAction.BatchInput batchInput = createBatchInput(master, test);
when(fetchAction.apply(any(ProjectResource.class), any(FetchAction.BatchInput.class)))
.thenAnswer((Answer<Response<?>>) invocation -> Response.accepted("some-url"));
- Response<?> response = batchFetchAction.apply(projectResource, List.of(first, second));
+ Response<?> response = batchFetchAction.apply(projectResource, batchInput);
assertThat(response.statusCode()).isEqualTo(SC_OK);
}
@Test
- public void shouldReturnAResponsesOnSuccess() throws RestApiException {
- FetchAction.Input first = createInput(master);
- FetchAction.Input second = createInput(test);
+ public void shouldReturnAListWithAllResponsesOnSuccess() throws RestApiException {
+ FetchAction.BatchInput batchInput = createBatchInput(master, test);
+
String masterUrl = "master-url";
- String testUrl = "test-url";
- Response.Accepted batchResponse = Response.accepted(masterUrl);
+ Response.Accepted firstResponse = Response.accepted(masterUrl);
- when(fetchAction.apply(eq(projectResource), any(FetchAction.BatchInput.class)))
- .thenAnswer((Answer<Response<?>>) invocation -> batchResponse);
- Response<?> response = batchFetchAction.apply(projectResource, List.of(first, second));
+ when(fetchAction.apply(projectResource, batchInput))
+ .thenAnswer((Answer<Response<?>>) invocation -> firstResponse);
+ Response<?> response = batchFetchAction.apply(projectResource, batchInput);
- assertThat(response.value()).isEqualTo(batchResponse);
+ assertThat(response.value()).isEqualTo(firstResponse);
}
@Test(expected = RestApiException.class)
public void shouldThrowRestApiExceptionWhenProcessingFailsForAnInput() throws RestApiException {
- FetchAction.Input first = createInput(master);
- FetchAction.Input second = createInput(test);
+ FetchAction.BatchInput batchInput = createBatchInput(master, test);
String masterUrl = "master-url";
- when(fetchAction.apply(eq(projectResource), any(FetchAction.BatchInput.class)))
+ when(fetchAction.apply(projectResource, batchInput))
.thenThrow(new MergeConflictException("BOOM"));
- batchFetchAction.apply(projectResource, List.of(first, second));
+ batchFetchAction.apply(projectResource, batchInput);
}
private FetchAction.Input createInput(String refName) {
@@ -108,4 +102,11 @@
input.refName = refName;
return input;
}
+
+ private FetchAction.BatchInput createBatchInput(String... refNames) {
+ FetchAction.BatchInput batchInput = new FetchAction.BatchInput();
+ batchInput.label = label;
+ batchInput.refsNames = Set.of(refNames);
+ return batchInput;
+ }
}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/replication/pull/api/FetchCommandTest.java b/src/test/java/com/googlesource/gerrit/plugins/replication/pull/api/FetchCommandTest.java
index f8d12a9..ebf0076 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/replication/pull/api/FetchCommandTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/replication/pull/api/FetchCommandTest.java
@@ -86,7 +86,7 @@
@Test
public void shouldScheduleRefFetchWithDelay() throws Exception {
- objectUnderTest.fetchAsync(projectName, label, REF_NAME_TO_FETCH, apiRequestMetrics);
+ objectUnderTest.fetchAsync(projectName, label, Set.of(REF_NAME_TO_FETCH), apiRequestMetrics);
verify(source, times(1))
.schedule(
@@ -101,7 +101,7 @@
@Test
public void shouldMarkAllFetchTasksScheduled() throws Exception {
- objectUnderTest.fetchAsync(projectName, label, REF_NAME_TO_FETCH, apiRequestMetrics);
+ objectUnderTest.fetchAsync(projectName, label, Set.of(REF_NAME_TO_FETCH), apiRequestMetrics);
verify(source, times(1))
.schedule(projectName, REF_NAME_TO_FETCH, state, Optional.of(apiRequestMetrics));
diff --git a/src/test/java/com/googlesource/gerrit/plugins/replication/pull/api/PullReplicationFilterTest.java b/src/test/java/com/googlesource/gerrit/plugins/replication/pull/api/PullReplicationFilterTest.java
index bba638c..b193cd7 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/replication/pull/api/PullReplicationFilterTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/replication/pull/api/PullReplicationFilterTest.java
@@ -143,16 +143,11 @@
@Test
public void shouldFilterBatchFetchAction() throws Exception {
byte[] payloadBatchFetch =
- ("[{"
+ ("{"
+ "\"label\":\"Replication\", "
- + "\"ref_name\": \"refs/heads/master\", "
+ + "\"refs_names\": [ \"refs/heads/master\" , \"refs/heads/test\" ], "
+ "\"async\":false"
- + "},"
- + "{"
- + "\"label\":\"Replication\", "
- + "\"ref_name\": \"refs/heads/test\", "
- + "\"async\":false"
- + "}]")
+ + "}")
.getBytes(StandardCharsets.UTF_8);
defineBehaviours(payloadBatchFetch, BATCH_FETCH_URI);
diff --git a/src/test/java/com/googlesource/gerrit/plugins/replication/pull/client/FetchRestApiClientBase.java b/src/test/java/com/googlesource/gerrit/plugins/replication/pull/client/FetchRestApiClientBase.java
index e9e28ed..3aa5b5a 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/replication/pull/client/FetchRestApiClientBase.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/replication/pull/client/FetchRestApiClientBase.java
@@ -41,6 +41,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Optional;
+import java.util.stream.Collectors;
import org.apache.http.Header;
import org.apache.http.HttpHeaders;
import org.apache.http.client.methods.HttpDelete;
@@ -259,13 +260,13 @@
HttpPost httpPost = httpPostCaptor.getValue();
String expectedPayload =
- "[{\"label\":\"Replication\", \"ref_name\": \""
+ "{\"label\":\"Replication\", \"refs_names\": [ "
+ + '"'
+ refName
- + "\", \"async\":true},"
- + "{\"label\":\"Replication\", \"ref_name\": \""
- + refs.get(1)
- + "\", \"async\":true}"
- + "]";
+ + "\",\""
+ + testRef
+ + "\" ]"
+ + ", \"async\":true}";
assertThat(readPayload(httpPost)).isEqualTo(expectedPayload);
}
@@ -304,7 +305,7 @@
public void shouldCallSyncBatchFetchOnlyForMetaRef() throws Exception {
String metaRefName = "refs/changes/01/101/meta";
String expectedMetaRefPayload =
- "[{\"label\":\"Replication\", \"ref_name\": \"" + metaRefName + "\", \"async\":false}]";
+ "{\"label\":\"Replication\", \"refs_names\": [ \"" + metaRefName + "\" ], \"async\":false}";
when(config.getStringList("replication", null, "syncRefs"))
.thenReturn(new String[] {"^refs\\/changes\\/.*\\/meta"});
@@ -349,13 +350,12 @@
HttpPost httpPost = httpPostCaptor.getValue();
String expectedPayload =
- "[{\"label\":\"Replication\", \"ref_name\": \""
+ "{\"label\":\"Replication\", \"refs_names\": [ "
+ + '"'
+ refName
- + "\", \"async\":false},"
- + "{\"label\":\"Replication\", \"ref_name\": \""
+ + "\",\""
+ refs.get(1)
- + "\", \"async\":false}"
- + "]";
+ + "\" ], \"async\":false}";
assertThat(readPayload(httpPost)).isEqualTo(expectedPayload);
}
@@ -383,14 +383,9 @@
HttpPost httpPosts = httpPostCaptor.getValue();
String expectedSyncPayload =
- "["
- + "{\"label\":\"Replication\", \"ref_name\": \""
- + refName
- + "\", \"async\":false},"
- + "{\"label\":\"Replication\", \"ref_name\": \""
- + refs.get(1)
- + "\", \"async\":false}"
- + "]";
+ "{\"label\":\"Replication\", \"refs_names\": [ "
+ + refs.stream().map(r -> '"' + r + '"').collect(Collectors.joining(","))
+ + " ], \"async\":false}";
assertThat(readPayload(httpPosts)).isEqualTo(expectedSyncPayload);
}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/replication/pull/event/StreamEventListenerTest.java b/src/test/java/com/googlesource/gerrit/plugins/replication/pull/event/StreamEventListenerTest.java
index e91ce8d..0f4bd33 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/replication/pull/event/StreamEventListenerTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/replication/pull/event/StreamEventListenerTest.java
@@ -37,7 +37,7 @@
import com.googlesource.gerrit.plugins.replication.pull.Source;
import com.googlesource.gerrit.plugins.replication.pull.SourcesCollection;
import com.googlesource.gerrit.plugins.replication.pull.api.DeleteRefCommand;
-import com.googlesource.gerrit.plugins.replication.pull.api.FetchAction.Input;
+import com.googlesource.gerrit.plugins.replication.pull.api.FetchAction;
import com.googlesource.gerrit.plugins.replication.pull.api.FetchJob;
import com.googlesource.gerrit.plugins.replication.pull.api.ProjectInitializationAction;
import com.googlesource.gerrit.plugins.replication.pull.api.PullReplicationApiRequestMetrics;
@@ -70,7 +70,7 @@
@Mock private FetchJob.Factory fetchJobFactory;
@Mock private UpdateHeadCommand updateHeadCommand;
@Mock private DeleteRefCommand deleteRefCommand;
- @Captor ArgumentCaptor<Input> inputCaptor;
+ @Captor ArgumentCaptor<FetchAction.BatchInput> batchInputCaptor;
@Mock private PullReplicationApiRequestMetrics metrics;
@Mock private SourcesCollection sources;
@Mock private Source source;
@@ -181,11 +181,12 @@
objectUnderTest.onEvent(event);
- verify(fetchJobFactory).create(eq(Project.nameKey(TEST_PROJECT)), inputCaptor.capture(), any());
+ verify(fetchJobFactory)
+ .create(eq(Project.nameKey(TEST_PROJECT)), batchInputCaptor.capture(), any());
- Input input = inputCaptor.getValue();
- assertThat(input.label).isEqualTo(REMOTE_INSTANCE_ID);
- assertThat(input.refName).isEqualTo(TEST_REF_NAME);
+ FetchAction.BatchInput batchInput = batchInputCaptor.getValue();
+ assertThat(batchInput.label).isEqualTo(REMOTE_INSTANCE_ID);
+ assertThat(batchInput.refsNames).contains(TEST_REF_NAME);
verify(executor).submit(any(FetchJob.class));
}
@@ -253,11 +254,12 @@
objectUnderTest.onEvent(event);
- verify(fetchJobFactory).create(eq(Project.nameKey(TEST_PROJECT)), inputCaptor.capture(), any());
+ verify(fetchJobFactory)
+ .create(eq(Project.nameKey(TEST_PROJECT)), batchInputCaptor.capture(), any());
- Input input = inputCaptor.getValue();
+ FetchAction.BatchInput input = batchInputCaptor.getValue();
assertThat(input.label).isEqualTo(REMOTE_INSTANCE_ID);
- assertThat(input.refName).isEqualTo(FetchOne.ALL_REFS);
+ assertThat(input.refsNames).contains(FetchOne.ALL_REFS);
verify(executor).submit(any(FetchJob.class));
}