diff --git a/src/main/java/com/google/devtools/build/lib/buildeventstream/proto/build_event_stream.proto b/src/main/java/com/google/devtools/build/lib/buildeventstream/proto/build_event_stream.proto index 613a02a5ef91d8..6af667e3377751 100644 --- a/src/main/java/com/google/devtools/build/lib/buildeventstream/proto/build_event_stream.proto +++ b/src/main/java/com/google/devtools/build/lib/buildeventstream/proto/build_event_stream.proto @@ -1039,8 +1039,11 @@ message BuildMetrics { // Information about all workers that were alive during the invocation. message WorkerMetrics { - // Unique id of worker. - int32 worker_id = 1; + // Deprecated. Use worker_ids instead of this field. + int32 worker_id = 1 [deprecated = true]; + + // Ids of workers. Could be multiple in case of multiplex workers + repeated uint32 worker_ids = 8; // Worker process id. If there is no process for worker, equals to zero. uint32 process_id = 2; // Mnemonic of running worker. diff --git a/src/main/java/com/google/devtools/build/lib/worker/WorkerLifecycleManager.java b/src/main/java/com/google/devtools/build/lib/worker/WorkerLifecycleManager.java index b5f8f603599044..63c2c1ec608bfe 100644 --- a/src/main/java/com/google/devtools/build/lib/worker/WorkerLifecycleManager.java +++ b/src/main/java/com/google/devtools/build/lib/worker/WorkerLifecycleManager.java @@ -127,7 +127,7 @@ ImmutableSet collectEvictionCandidates( .filter( metric -> metric.getWorkerStat() != null - && idleWorkers.contains(metric.getWorkerProperties().getWorkerId())) + && idleWorkers.containsAll(metric.getWorkerProperties().getWorkerIds())) .collect(Collectors.toList()); if (idleWorkerMetrics.size() != idleWorkers.size()) { @@ -141,7 +141,7 @@ ImmutableSet collectEvictionCandidates( ImmutableSet.Builder candidates = ImmutableSet.builder(); int freeMemoryMb = 0; for (WorkerMetric metric : idleWorkerMetrics) { - candidates.add(metric.getWorkerProperties().getWorkerId()); + candidates.addAll(metric.getWorkerProperties().getWorkerIds()); freeMemoryMb += metric.getWorkerStat().getUsedMemoryInKB() / 1000; if (workerMemeoryUsageMb - freeMemoryMb <= memoryLimitMb) { diff --git a/src/main/java/com/google/devtools/build/lib/worker/WorkerMetric.java b/src/main/java/com/google/devtools/build/lib/worker/WorkerMetric.java index c6d40333739e00..3e32a97ae0d994 100644 --- a/src/main/java/com/google/devtools/build/lib/worker/WorkerMetric.java +++ b/src/main/java/com/google/devtools/build/lib/worker/WorkerMetric.java @@ -14,6 +14,7 @@ package com.google.devtools.build.lib.worker; import com.google.auto.value.AutoValue; +import com.google.common.collect.ImmutableList; import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos.BuildMetrics.WorkerMetrics; import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos.BuildMetrics.WorkerMetrics.WorkerStats; import java.time.Instant; @@ -55,7 +56,7 @@ public static WorkerStat create(int usedMemoryInKB, Instant lastCallTime, Instan /** Worker properties */ @AutoValue public abstract static class WorkerProperties { - public abstract int getWorkerId(); + public abstract ImmutableList getWorkerIds(); public abstract long getProcessId(); @@ -66,9 +67,13 @@ public abstract static class WorkerProperties { public abstract boolean isSandboxed(); public static WorkerProperties create( - int workerId, long processId, String mnemonic, boolean isMultiplex, boolean isSandboxed) { + ImmutableList workerIds, + long processId, + String mnemonic, + boolean isMultiplex, + boolean isSandboxed) { return new AutoValue_WorkerMetric_WorkerProperties( - workerId, processId, mnemonic, isMultiplex, isSandboxed); + workerIds, processId, mnemonic, isMultiplex, isSandboxed); } } @@ -78,7 +83,7 @@ public WorkerMetrics toProto() { WorkerMetrics.Builder builder = WorkerMetrics.newBuilder() - .setWorkerId(workerProperties.getWorkerId()) + .addAllWorkerIds(workerProperties.getWorkerIds()) .setProcessId((int) workerProperties.getProcessId()) .setMnemonic(workerProperties.getMnemonic()) .setIsSandbox(workerProperties.isSandboxed()) diff --git a/src/main/java/com/google/devtools/build/lib/worker/WorkerMetricsCollector.java b/src/main/java/com/google/devtools/build/lib/worker/WorkerMetricsCollector.java index b301f6db93f86f..97ad8b9926ab08 100644 --- a/src/main/java/com/google/devtools/build/lib/worker/WorkerMetricsCollector.java +++ b/src/main/java/com/google/devtools/build/lib/worker/WorkerMetricsCollector.java @@ -14,7 +14,6 @@ package com.google.devtools.build.lib.worker; -import static com.google.common.collect.ImmutableSet.toImmutableSet; import static java.nio.charset.StandardCharsets.UTF_8; import com.google.auto.value.AutoValue; @@ -49,13 +48,13 @@ public class WorkerMetricsCollector { private Clock clock; /** - * Mapping of worker ids to their metrics. Contains worker ids, which memory usage could be - * measured. + * Mapping of worker process ids to their properties. One process could be mapped to multiple + * workers because of multiplex workers. */ - private final Map workerIdToWorkerProperties = + private final Map processIdToWorkerProperties = new ConcurrentHashMap<>(); - private final Map workerLastCallTime = new ConcurrentHashMap<>(); + private final Map workerLastCallTime = new ConcurrentHashMap<>(); private MetricsWithTime lastMetrics; @@ -206,53 +205,47 @@ public ImmutableList collectMetrics(Duration interval) { public ImmutableList collectMetrics() { MemoryCollectionResult memoryCollectionResult = collectMemoryUsageByPid( - OS.getCurrent(), - workerIdToWorkerProperties.values().stream() - .map(WorkerMetric.WorkerProperties::getProcessId) - .collect(toImmutableSet())); + OS.getCurrent(), ImmutableSet.copyOf(processIdToWorkerProperties.keySet())); ImmutableMap pidToMemoryInKb = memoryCollectionResult.pidToMemoryInKb; Instant collectionTime = memoryCollectionResult.collectionTime; ImmutableList.Builder workerMetrics = new ImmutableList.Builder<>(); - List nonMeasurableWorkerIds = new ArrayList<>(); - for (WorkerMetric.WorkerProperties workerProperties : workerIdToWorkerProperties.values()) { + List nonMeasurableProcessIds = new ArrayList<>(); + for (WorkerMetric.WorkerProperties workerProperties : processIdToWorkerProperties.values()) { Long pid = workerProperties.getProcessId(); - Integer workerId = workerProperties.getWorkerId(); WorkerStat workerStats = WorkerStat.create( - pidToMemoryInKb.getOrDefault(pid, 0), - workerLastCallTime.get(workerId), - collectionTime); + pidToMemoryInKb.getOrDefault(pid, 0), workerLastCallTime.get(pid), collectionTime); workerMetrics.add( WorkerMetric.create( workerProperties, workerStats, /* isMeasurable= */ pidToMemoryInKb.containsKey(pid))); if (!pidToMemoryInKb.containsKey(pid)) { - nonMeasurableWorkerIds.add(workerId); + nonMeasurableProcessIds.add(pid); } } - workerIdToWorkerProperties.keySet().removeAll(nonMeasurableWorkerIds); + processIdToWorkerProperties.keySet().removeAll(nonMeasurableProcessIds); return updateLastCollectMetrics(workerMetrics.build(), collectionTime).metrics; } public void clear() { - workerIdToWorkerProperties.clear(); + processIdToWorkerProperties.clear(); workerLastCallTime.clear(); lastMetrics = null; } @VisibleForTesting - public Map getWorkerIdToWorkerProperties() { - return workerIdToWorkerProperties; + public Map getProcessIdToWorkerProperties() { + return processIdToWorkerProperties; } @VisibleForTesting - public Map getWorkerLastCallTime() { + public Map getWorkerLastCallTime() { return workerLastCallTime; } @@ -260,11 +253,35 @@ public Map getWorkerLastCallTime() { * Initializes workerIdToWorkerProperties for workers. If worker metrics already exists for this * worker, only updates workerLastCallTime. */ - public void registerWorker(WorkerMetric.WorkerProperties properties) { - int workerId = properties.getWorkerId(); + public synchronized void registerWorker( + int workerId, long processId, String mnemonic, boolean isMultiplex, boolean isSandboxed) { + WorkerMetric.WorkerProperties existingWorkerProperties = + processIdToWorkerProperties.get(processId); + + workerLastCallTime.put(processId, Instant.ofEpochMilli(clock.currentTimeMillis())); + + if (existingWorkerProperties == null) { + processIdToWorkerProperties.put( + processId, + WorkerMetric.WorkerProperties.create( + ImmutableList.of(workerId), processId, mnemonic, isMultiplex, isSandboxed)); + return; + } + + if (existingWorkerProperties.getWorkerIds().contains(workerId)) { + return; + } + + ImmutableList updatedWorkerIds = + ImmutableList.builder() + .addAll(existingWorkerProperties.getWorkerIds()) + .add(workerId) + .build(); - workerIdToWorkerProperties.putIfAbsent(workerId, properties); - workerLastCallTime.put(workerId, Instant.ofEpochMilli(clock.currentTimeMillis())); + WorkerMetric.WorkerProperties updatedWorkerProperties = + WorkerMetric.WorkerProperties.create( + updatedWorkerIds, processId, mnemonic, isMultiplex, isSandboxed); + processIdToWorkerProperties.put(processId, updatedWorkerProperties); } private synchronized MetricsWithTime updateLastCollectMetrics( diff --git a/src/main/java/com/google/devtools/build/lib/worker/WorkerSpawnRunner.java b/src/main/java/com/google/devtools/build/lib/worker/WorkerSpawnRunner.java index 7a7c11f70e2a6b..d5beddb20cae05 100644 --- a/src/main/java/com/google/devtools/build/lib/worker/WorkerSpawnRunner.java +++ b/src/main/java/com/google/devtools/build/lib/worker/WorkerSpawnRunner.java @@ -770,14 +770,12 @@ private WorkResponse executeRequest( } private void initializeMetrics(WorkerKey workerKey, Worker worker) { - WorkerMetric.WorkerProperties properties = - WorkerMetric.WorkerProperties.create( - worker.getWorkerId(), - worker.getProcessId(), - workerKey.getMnemonic(), - workerKey.isMultiplex(), - workerKey.isSandboxed()); - this.metricsCollector.registerWorker(properties); + this.metricsCollector.registerWorker( + worker.getWorkerId(), + worker.getProcessId(), + workerKey.getMnemonic(), + workerKey.isMultiplex(), + workerKey.isSandboxed()); } /** diff --git a/src/test/java/com/google/devtools/build/lib/profiler/ProfilerTest.java b/src/test/java/com/google/devtools/build/lib/profiler/ProfilerTest.java index 00003ad07f9905..1f2270f4b015a3 100644 --- a/src/test/java/com/google/devtools/build/lib/profiler/ProfilerTest.java +++ b/src/test/java/com/google/devtools/build/lib/profiler/ProfilerTest.java @@ -285,7 +285,7 @@ public void testProfilerWorkerMetrics() throws Exception { ImmutableList.of( WorkerMetric.create( WorkerMetric.WorkerProperties.create( - /* workerId= */ 1, + /* workerIds= */ ImmutableList.of(1), /* processId= */ 1, /* mnemonic= */ "dummy1", /* isMultiplex= */ true, @@ -294,7 +294,7 @@ public void testProfilerWorkerMetrics() throws Exception { /* isMeasurable= */ true), WorkerMetric.create( WorkerMetric.WorkerProperties.create( - /* workerId= */ 1, + /* workerIds= */ ImmutableList.of(1), /* processId= */ 1, /* mnemonic= */ "dummy2", /* isMultiplex= */ false, @@ -303,7 +303,7 @@ public void testProfilerWorkerMetrics() throws Exception { /* isMeasurable= */ true), WorkerMetric.create( WorkerMetric.WorkerProperties.create( - /* workerId= */ 1, + /* workerIds= */ ImmutableList.of(1), /* processId= */ 1, /* mnemonic= */ "dummy2", /* isMultiplex= */ false, diff --git a/src/test/java/com/google/devtools/build/lib/worker/WorkerLifecycleManagerTest.java b/src/test/java/com/google/devtools/build/lib/worker/WorkerLifecycleManagerTest.java index 027b9807a10738..4bf8372ac38c74 100644 --- a/src/test/java/com/google/devtools/build/lib/worker/WorkerLifecycleManagerTest.java +++ b/src/test/java/com/google/devtools/build/lib/worker/WorkerLifecycleManagerTest.java @@ -333,7 +333,11 @@ public void testGetEvictionCandidates_evictDifferentWorkerKeys() throws Exceptio private static WorkerMetric.WorkerProperties createWorkerProperties( int workerId, long processId, String mnemonic) { return WorkerMetric.WorkerProperties.create( - workerId, processId, mnemonic, /* isMultiplex= */ false, /* isSandboxed= */ false); + ImmutableList.of(workerId), + processId, + mnemonic, + /* isMultiplex= */ false, + /* isSandboxed= */ false); } private static WorkerMetric.WorkerStat createWorkerStat(int memoryUsage) { diff --git a/src/test/java/com/google/devtools/build/lib/worker/WorkerMetricsCollectorTest.java b/src/test/java/com/google/devtools/build/lib/worker/WorkerMetricsCollectorTest.java index e79b09dfa38cad..08cbc492dc7aed 100644 --- a/src/test/java/com/google/devtools/build/lib/worker/WorkerMetricsCollectorTest.java +++ b/src/test/java/com/google/devtools/build/lib/worker/WorkerMetricsCollectorTest.java @@ -104,58 +104,112 @@ public void testCollectStats_mutipleSubprocesses() throws Exception { public void testRegisterWorker_insertDifferent() throws Exception { WorkerMetric.WorkerProperties props1 = WorkerMetric.WorkerProperties.create( - /* workerId= */ 1, + /* workerIds= */ ImmutableList.of(1), /* processId= */ 100, /* mnemonic= */ "Javac", /* isMultiplex= */ true, /* isSandboxed= */ false); WorkerMetric.WorkerProperties props2 = WorkerMetric.WorkerProperties.create( - /* workerId= */ 2, + /* workerIds= */ ImmutableList.of(2), /* processId= */ 200, /* mnemonic= */ "CppCompile", /* isMultiplex= */ false, /* isSandboxed= */ true); - ImmutableMap map = - ImmutableMap.of(1, props1, 2, props2); - - spyCollector.registerWorker(props1); - assertThat(spyCollector.getWorkerIdToWorkerProperties()).hasSize(1); - spyCollector.registerWorker(props2); - assertThat(spyCollector.getWorkerIdToWorkerProperties()).hasSize(2); - assertThat(spyCollector.getWorkerIdToWorkerProperties()).isEqualTo(map); + ImmutableMap map = + ImmutableMap.of(100L, props1, 200L, props2); + + spyCollector.registerWorker( + props1.getWorkerIds().get(0), + props1.getProcessId(), + props1.getMnemonic(), + props1.isMultiplex(), + props1.isSandboxed()); + assertThat(spyCollector.getProcessIdToWorkerProperties()).hasSize(1); + spyCollector.registerWorker( + props2.getWorkerIds().get(0), + props2.getProcessId(), + props2.getMnemonic(), + props2.isMultiplex(), + props2.isSandboxed()); + assertThat(spyCollector.getProcessIdToWorkerProperties()).hasSize(2); + assertThat(spyCollector.getProcessIdToWorkerProperties()).isEqualTo(map); + } + + @Test + public void testRegisterWorker_insertMultiplex() throws Exception { + WorkerMetric.WorkerProperties props1 = + WorkerMetric.WorkerProperties.create( + /* workerIds= */ ImmutableList.of(1), + /* processId= */ 100L, + /* mnemonic= */ "Javac", + /* isMultiplex= */ true, + /* isSandboxed= */ true); + WorkerMetric.WorkerProperties props2 = + WorkerMetric.WorkerProperties.create( + /* workerIds= */ ImmutableList.of(2), + /* processId= */ 100L, + /* mnemonic= */ "Javac", + /* isMultiplex= */ true, + /* isSandboxed= */ true); + Instant registrationTime1 = Instant.ofEpochSecond(1000); + Instant registrationTime2 = registrationTime1.plusSeconds(10); + ImmutableMap map = + ImmutableMap.of( + 100L, + WorkerMetric.WorkerProperties.create( + /* workerIds= */ ImmutableList.of(1, 2), + /* processId= */ 100L, + /* mnemonic= */ "Javac", + /* isMultiplex= */ true, + /* isSandboxed= */ true)); + ImmutableMap lastCallMap1 = ImmutableMap.of(100L, registrationTime1); + ImmutableMap lastCallMap2 = ImmutableMap.of(100L, registrationTime2); + + clock.setTime(registrationTime1.toEpochMilli()); + registerWorker(spyCollector, props1); + + assertThat(spyCollector.getProcessIdToWorkerProperties()).hasSize(1); + assertThat(spyCollector.getWorkerLastCallTime()).isEqualTo(lastCallMap1); + + clock.setTime(registrationTime2.toEpochMilli()); + registerWorker(spyCollector, props2); + + assertThat(spyCollector.getProcessIdToWorkerProperties()).hasSize(1); + assertThat(spyCollector.getProcessIdToWorkerProperties()).isEqualTo(map); + assertThat(spyCollector.getWorkerLastCallTime()).isEqualTo(lastCallMap2); } @Test public void testRegisterWorker_insertSame() throws Exception { WorkerMetric.WorkerProperties props1 = WorkerMetric.WorkerProperties.create( - /*workerId= */ 1, - /*processId= */ 100, - /*mnemonic= */ "Javac", - /*isMultiplex= */ true, - /*isSandboxed= */ false); + /* workerIds= */ ImmutableList.of(1), + /* processId= */ 100, + /* mnemonic= */ "Javac", + /* isMultiplex= */ true, + /* isSandboxed= */ false); WorkerMetric.WorkerProperties props2 = WorkerMetric.WorkerProperties.create( - /*workerId= */ 1, - /*processId= */ 100, - /*mnemonic= */ "Javac", - /*isMultiplex= */ true, - /*isSandboxed= */ false); + /* workerIds= */ ImmutableList.of(1), + /* processId= */ 100, + /* mnemonic= */ "Javac", + /* isMultiplex= */ true, + /* isSandboxed= */ false); Instant registrationTime1 = Instant.ofEpochSecond(1000); Instant registrationTime2 = registrationTime1.plusSeconds(10); - ImmutableMap propertiesMap = ImmutableMap.of(1, props1); - ImmutableMap lastCallMap1 = ImmutableMap.of(1, registrationTime1); - ImmutableMap lastCallMap2 = ImmutableMap.of(1, registrationTime2); + ImmutableMap propertiesMap = ImmutableMap.of(100L, props1); + ImmutableMap lastCallMap1 = ImmutableMap.of(100L, registrationTime1); + ImmutableMap lastCallMap2 = ImmutableMap.of(100L, registrationTime2); clock.setTime(registrationTime1.toEpochMilli()); - spyCollector.registerWorker(props1); - assertThat(spyCollector.getWorkerIdToWorkerProperties()).isEqualTo(propertiesMap); + registerWorker(spyCollector, props1); + assertThat(spyCollector.getProcessIdToWorkerProperties()).isEqualTo(propertiesMap); assertThat(spyCollector.getWorkerLastCallTime()).isEqualTo(lastCallMap1); clock.setTime(registrationTime2.toEpochMilli()); - spyCollector.registerWorker(props2); - assertThat(spyCollector.getWorkerIdToWorkerProperties()).isEqualTo(propertiesMap); + registerWorker(spyCollector, props2); + assertThat(spyCollector.getProcessIdToWorkerProperties()).isEqualTo(propertiesMap); assertThat(spyCollector.getWorkerLastCallTime()).isEqualTo(lastCallMap2); } @@ -163,25 +217,25 @@ public void testRegisterWorker_insertSame() throws Exception { public void testcollectMetrics() throws Exception { WorkerMetric.WorkerProperties props1 = WorkerMetric.WorkerProperties.create( - /*workerId= */ 1, - /*processId= */ 100, - /*mnemonic= */ "Javac", - /*isMultiplex= */ true, - /*isSandboxed= */ false); + /* workerIds= */ ImmutableList.of(1), + /* processId= */ 100, + /* mnemonic= */ "Javac", + /* isMultiplex= */ true, + /* isSandboxed= */ false); WorkerMetric.WorkerProperties props2 = WorkerMetric.WorkerProperties.create( - /*workerId= */ 2, - /*processId= */ 200, - /*mnemonic= */ "CppCompile", - /*isMultiplex= */ false, - /*isSandboxed= */ true); + /* workerIds= */ ImmutableList.of(2), + /* processId= */ 200, + /* mnemonic= */ "CppCompile", + /* isMultiplex= */ false, + /* isSandboxed= */ true); WorkerMetric.WorkerProperties props3 = WorkerMetric.WorkerProperties.create( - /*workerId= */ 3, - /*processId= */ 300, - /*mnemonic= */ "Proto", - /*isMultiplex= */ true, - /*isSandboxed= */ true); + /* workerIds= */ ImmutableList.of(3), + /* processId= */ 300, + /* mnemonic= */ "Proto", + /* isMultiplex= */ true, + /* isSandboxed= */ true); Instant registrationTime = Instant.ofEpochSecond(1000); Instant collectionTime = registrationTime.plusSeconds(10); WorkerMetric.WorkerStat stat1 = @@ -194,10 +248,10 @@ public void testcollectMetrics() throws Exception { WorkerMetric workerMetric2 = WorkerMetric.create(props2, stat2, true); WorkerMetric workerMetric3 = WorkerMetric.create(props3, stat3, false); ImmutableSet expectedPids = ImmutableSet.of(100L, 200L, 300L); - ImmutableMap propsMap = + ImmutableMap propsMap = ImmutableMap.of( - 1, props1, - 2, props2); + 100L, props1, + 200L, props2); ImmutableMap memoryUsageMap = ImmutableMap.of( 100L, stat1.getUsedMemoryInKB(), @@ -213,14 +267,24 @@ public void testcollectMetrics() throws Exception { clock.setTime(registrationTime.toEpochMilli()); - spyCollector.registerWorker(props1); - spyCollector.registerWorker(props2); - spyCollector.registerWorker(props3); + registerWorker(spyCollector, props1); + registerWorker(spyCollector, props2); + registerWorker(spyCollector, props3); ImmutableList metrics = spyCollector.collectMetrics(); assertThat(metrics).containsExactlyElementsIn(expectedMetrics); - assertThat(spyCollector.getWorkerIdToWorkerProperties()).isEqualTo(propsMap); + assertThat(spyCollector.getProcessIdToWorkerProperties()).isEqualTo(propsMap); + } + + private static void registerWorker( + WorkerMetricsCollector collector, WorkerMetric.WorkerProperties props) { + collector.registerWorker( + props.getWorkerIds().get(0), + props.getProcessId(), + props.getMnemonic(), + props.isMultiplex(), + props.isSandboxed()); } private static class ManualClock implements Clock { diff --git a/src/test/java/com/google/devtools/build/lib/worker/WorkerSpawnRunnerTest.java b/src/test/java/com/google/devtools/build/lib/worker/WorkerSpawnRunnerTest.java index b42422b3857ca7..2eb0e7f89c94cd 100644 --- a/src/test/java/com/google/devtools/build/lib/worker/WorkerSpawnRunnerTest.java +++ b/src/test/java/com/google/devtools/build/lib/worker/WorkerSpawnRunnerTest.java @@ -18,7 +18,10 @@ import static com.google.devtools.build.lib.worker.TestUtils.createWorkerKey; import static org.junit.Assert.assertThrows; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.startsWith; import static org.mockito.Mockito.doNothing; @@ -112,7 +115,9 @@ public WorkerSpawnRunnerTest(boolean workerAsResource) { public void setUp() throws InterruptedException, IOException, ExecException { when(spawn.getInputFiles()).thenReturn(NestedSetBuilder.emptySet(Order.COMPILE_ORDER)); when(context.getArtifactExpander()).thenReturn((artifact, output) -> {}); - doNothing().when(metricsCollector).registerWorker(any()); + doNothing() + .when(metricsCollector) + .registerWorker(anyInt(), anyLong(), anyString(), anyBoolean(), anyBoolean()); when(spawn.getLocalResources()).thenReturn(ResourceSet.createWithRamCpu(100, 1)); when(resourceManager.acquireResources(any(), any(), any())).thenReturn(resourceHandle); when(resourceHandle.getWorker()).thenReturn(worker);