Skip to content

Commit ece2f55

Browse files
committed
feat: update exit cause handling to return a list of causes in PostCompute and PreCompute services
1 parent 0a884fe commit ece2f55

File tree

4 files changed

+81
-82
lines changed

4 files changed

+81
-82
lines changed

src/main/java/com/iexec/worker/compute/post/PostComputeService.java

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -220,11 +220,11 @@ public PostComputeResponse runTeePostCompute(TaskDescription taskDescription,
220220
}
221221
if (finalStatus == DockerRunFinalStatus.FAILED) {
222222
int exitCode = dockerResponse.getContainerExitCode();
223-
ReplicateStatusCause exitCause = getExitCause(chainTaskId, exitCode);
223+
List<ReplicateStatusCause> exitCauses = getExitCauses(chainTaskId, exitCode);
224224
log.error("Failed to run tee post-compute [chainTaskId:{}, " +
225-
"exitCode:{}, exitCause:{}]", chainTaskId, exitCode, exitCause);
225+
"exitCode:{}, exitCause:{}]", chainTaskId, exitCode, exitCauses);
226226
return PostComputeResponse.builder()
227-
.exitCauses(List.of(exitCause))
227+
.exitCauses(exitCauses)
228228
.build();
229229
}
230230
return PostComputeResponse.builder()
@@ -233,25 +233,17 @@ public PostComputeResponse runTeePostCompute(TaskDescription taskDescription,
233233
.build();
234234
}
235235

236-
private ReplicateStatusCause getExitCause(String chainTaskId, Integer exitCode) {
237-
ReplicateStatusCause cause = null;
238-
if (exitCode != null && exitCode != 0) {
239-
switch (exitCode) {
240-
case 1:
241-
// Use first cause from bulk processing for now
242-
cause = computeExitCauseService.getExitCausesAndPruneForGivenComputeStage(chainTaskId, ComputeStage.POST, POST_COMPUTE_FAILED_UNKNOWN_ISSUE).get(0);
243-
break;
244-
case 2:
245-
cause = ReplicateStatusCause.POST_COMPUTE_EXIT_REPORTING_FAILED;
246-
break;
247-
case 3:
248-
cause = ReplicateStatusCause.POST_COMPUTE_TASK_ID_MISSING;
249-
break;
250-
default:
251-
break;
252-
}
236+
private List<ReplicateStatusCause> getExitCauses(String chainTaskId, Integer exitCode) {
237+
if (exitCode == null || exitCode == 0) {
238+
return List.of();
253239
}
254-
return cause;
240+
return switch (exitCode) {
241+
case 1 ->
242+
computeExitCauseService.getExitCausesAndPruneForGivenComputeStage(chainTaskId, ComputeStage.POST, POST_COMPUTE_FAILED_UNKNOWN_ISSUE);
243+
case 2 -> List.of(ReplicateStatusCause.POST_COMPUTE_EXIT_REPORTING_FAILED);
244+
case 3 -> List.of(ReplicateStatusCause.POST_COMPUTE_TASK_ID_MISSING);
245+
default -> List.of();
246+
};
255247
}
256248

257249
private String getTaskTeePostComputeContainerName(String chainTaskId) {

src/main/java/com/iexec/worker/compute/pre/PreComputeService.java

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -156,38 +156,29 @@ private List<ReplicateStatusCause> downloadDatasetAndFiles(
156156
Integer exitCode = prepareTeeInputData(taskDescription, secureSession);
157157
if (exitCode == null || exitCode != 0) {
158158
String chainTaskId = taskDescription.getChainTaskId();
159-
ReplicateStatusCause exitCause = getExitCause(chainTaskId, exitCode); // TODO: Handle list of exit causes
159+
List<ReplicateStatusCause> exitCauses = getExitCauses(chainTaskId, exitCode);
160160
log.error("Failed to prepare TEE input data [chainTaskId:{}, exitCode:{}, exitCauses:{}]",
161-
chainTaskId, exitCode, exitCause);
162-
return List.of(exitCause);
161+
chainTaskId, exitCode, exitCauses);
162+
return exitCauses;
163163
}
164164
} catch (TimeoutException e) {
165165
return List.of(PRE_COMPUTE_TIMEOUT);
166166
}
167167
return List.of();
168168
}
169169

170-
private ReplicateStatusCause getExitCause(String chainTaskId, Integer exitCode) {
171-
ReplicateStatusCause cause = null;
170+
private List<ReplicateStatusCause> getExitCauses(String chainTaskId, Integer exitCode) {
172171
if (exitCode == null) {
173-
cause = PRE_COMPUTE_IMAGE_MISSING;
172+
return List.of(PRE_COMPUTE_IMAGE_MISSING);
174173
} else {
175-
switch (exitCode) {
176-
case 1:
177-
// Use first cause from bulk processing for now
178-
cause = computeExitCauseService.getExitCausesAndPruneForGivenComputeStage(chainTaskId, ComputeStage.PRE, PRE_COMPUTE_FAILED_UNKNOWN_ISSUE).get(0);
179-
break;
180-
case 2:
181-
cause = ReplicateStatusCause.PRE_COMPUTE_EXIT_REPORTING_FAILED;
182-
break;
183-
case 3:
184-
cause = ReplicateStatusCause.PRE_COMPUTE_TASK_ID_MISSING;
185-
break;
186-
default:
187-
break;
188-
}
174+
return switch (exitCode) {
175+
case 1 ->
176+
computeExitCauseService.getExitCausesAndPruneForGivenComputeStage(chainTaskId, ComputeStage.PRE, PRE_COMPUTE_FAILED_UNKNOWN_ISSUE);
177+
case 2 -> List.of(ReplicateStatusCause.PRE_COMPUTE_EXIT_REPORTING_FAILED);
178+
case 3 -> List.of(ReplicateStatusCause.PRE_COMPUTE_TASK_ID_MISSING);
179+
default -> List.of();
180+
};
189181
}
190-
return cause;
191182
}
192183

193184

src/test/java/com/iexec/worker/compute/post/PostComputeServiceTests.java

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,14 @@
4343
import lombok.extern.slf4j.Slf4j;
4444
import org.junit.jupiter.api.BeforeEach;
4545
import org.junit.jupiter.api.Test;
46+
import org.junit.jupiter.api.extension.ExtendWith;
4647
import org.junit.jupiter.api.io.TempDir;
4748
import org.junit.jupiter.params.ParameterizedTest;
4849
import org.junit.jupiter.params.provider.MethodSource;
4950
import org.mockito.ArgumentCaptor;
5051
import org.mockito.InjectMocks;
5152
import org.mockito.Mock;
52-
import org.mockito.MockitoAnnotations;
53+
import org.mockito.junit.jupiter.MockitoExtension;
5354

5455
import java.io.File;
5556
import java.io.IOException;
@@ -67,13 +68,13 @@
6768
import static org.mockito.Mockito.*;
6869

6970
@Slf4j
71+
@ExtendWith(MockitoExtension.class)
7072
class PostComputeServiceTests {
7173

7274
private static final String CHAIN_TASK_ID = "CHAIN_TASK_ID";
7375
private static final String DATASET_URI = "DATASET_URI";
7476
private static final String WORKER_NAME = "WORKER_NAME";
7577
private static final String TEE_POST_COMPUTE_IMAGE = "TEE_POST_COMPUTE_IMAGE";
76-
private static final long TEE_POST_COMPUTE_HEAP = 1024;
7778
private static final String TEE_POST_COMPUTE_ENTRYPOINT = "postComputeEntrypoint";
7879
private static final TeeSessionGenerationResponse SECURE_SESSION = mock(TeeSessionGenerationResponse.class);
7980
private static final long MAX_EXECUTION_TIME = 1000;
@@ -118,13 +119,6 @@ class PostComputeServiceTests {
118119

119120
@BeforeEach
120121
void beforeEach() {
121-
MockitoAnnotations.openMocks(this);
122-
when(dockerService.getClient()).thenReturn(dockerClientInstanceMock);
123-
when(teeServicesManager.getTeeService(any())).thenReturn(teeMockedService);
124-
when(properties.getPreComputeProperties()).thenReturn(preComputeProperties);
125-
when(properties.getPostComputeProperties()).thenReturn(postComputeProperties);
126-
when(teeServicesPropertiesService.getTeeServicesProperties(CHAIN_TASK_ID)).thenReturn(properties);
127-
128122
output = jUnitTemporaryFolder.getAbsolutePath();
129123
iexecOut = output + IexecFileHelper.SLASH_IEXEC_OUT;
130124
computedJson = iexecOut + IexecFileHelper.SLASH_COMPUTED_JSON;
@@ -218,17 +212,18 @@ void shouldRunTeePostComputeAndConnectToLasNetwork() {
218212
.maxExecutionTime(MAX_EXECUTION_TIME)
219213
.build();
220214
List<String> env = Arrays.asList("var0", "var1");
215+
when(dockerService.getClient()).thenReturn(dockerClientInstanceMock);
216+
when(teeServicesManager.getTeeService(any())).thenReturn(teeMockedService);
217+
when(teeServicesPropertiesService.getTeeServicesProperties(CHAIN_TASK_ID)).thenReturn(properties);
218+
when(properties.getPostComputeProperties()).thenReturn(postComputeProperties);
221219
when(postComputeProperties.getImage()).thenReturn(TEE_POST_COMPUTE_IMAGE);
222-
when(postComputeProperties.getHeapSizeInBytes()).thenReturn(TEE_POST_COMPUTE_HEAP);
223220
when(postComputeProperties.getEntrypoint()).thenReturn(TEE_POST_COMPUTE_ENTRYPOINT);
224221
when(dockerClientInstanceMock.isImagePresent(TEE_POST_COMPUTE_IMAGE))
225222
.thenReturn(true);
226223
when(teeMockedService.buildPostComputeDockerEnv(taskDescription, SECURE_SESSION))
227224
.thenReturn(env);
228225
String iexecOutBind = iexecOut + ":" + IexecFileHelper.SLASH_IEXEC_OUT;
229226
when(dockerService.getIexecOutBind(CHAIN_TASK_ID)).thenReturn(iexecOutBind);
230-
when(workerConfigService.getTaskOutputDir(CHAIN_TASK_ID)).thenReturn(output);
231-
when(workerConfigService.getTaskIexecOutDir(CHAIN_TASK_ID)).thenReturn(iexecOut);
232227
when(workerConfigService.getWorkerName()).thenReturn(WORKER_NAME);
233228
when(workerConfigService.getDockerNetworkName()).thenReturn(lasNetworkName);
234229
DockerRunResponse expectedDockerRunResponse = DockerRunResponse
@@ -276,9 +271,10 @@ void shouldNotRunTeePostComputeSinceDockerImageNotFoundLocally() {
276271
.datasetUri(DATASET_URI)
277272
.maxExecutionTime(MAX_EXECUTION_TIME)
278273
.build();
274+
when(dockerService.getClient()).thenReturn(dockerClientInstanceMock);
275+
when(teeServicesPropertiesService.getTeeServicesProperties(CHAIN_TASK_ID)).thenReturn(properties);
276+
when(properties.getPostComputeProperties()).thenReturn(postComputeProperties);
279277
when(postComputeProperties.getImage()).thenReturn(TEE_POST_COMPUTE_IMAGE);
280-
when(postComputeProperties.getHeapSizeInBytes()).thenReturn(TEE_POST_COMPUTE_HEAP);
281-
when(postComputeProperties.getEntrypoint()).thenReturn(TEE_POST_COMPUTE_ENTRYPOINT);
282278
when(dockerClientInstanceMock.isImagePresent(TEE_POST_COMPUTE_IMAGE))
283279
.thenReturn(false);
284280

@@ -298,17 +294,18 @@ void shouldRunTeePostComputeWithFailDockerResponse(Map.Entry<Integer, ReplicateS
298294
.maxExecutionTime(MAX_EXECUTION_TIME)
299295
.build();
300296
List<String> env = Arrays.asList("var0", "var1");
297+
when(dockerService.getClient()).thenReturn(dockerClientInstanceMock);
298+
when(teeServicesManager.getTeeService(any())).thenReturn(teeMockedService);
299+
when(teeServicesPropertiesService.getTeeServicesProperties(CHAIN_TASK_ID)).thenReturn(properties);
300+
when(properties.getPostComputeProperties()).thenReturn(postComputeProperties);
301301
when(postComputeProperties.getImage()).thenReturn(TEE_POST_COMPUTE_IMAGE);
302-
when(postComputeProperties.getHeapSizeInBytes()).thenReturn(TEE_POST_COMPUTE_HEAP);
303302
when(postComputeProperties.getEntrypoint()).thenReturn(TEE_POST_COMPUTE_ENTRYPOINT);
304303
when(dockerClientInstanceMock.isImagePresent(TEE_POST_COMPUTE_IMAGE))
305304
.thenReturn(true);
306305
when(teeMockedService.buildPostComputeDockerEnv(taskDescription, SECURE_SESSION))
307306
.thenReturn(env);
308307
String iexecOutBind = iexecOut + ":" + IexecFileHelper.SLASH_IEXEC_OUT;
309308
when(dockerService.getIexecOutBind(CHAIN_TASK_ID)).thenReturn(iexecOutBind);
310-
when(workerConfigService.getTaskOutputDir(CHAIN_TASK_ID)).thenReturn(output);
311-
when(workerConfigService.getTaskIexecOutDir(CHAIN_TASK_ID)).thenReturn(iexecOut);
312309
when(workerConfigService.getWorkerName()).thenReturn(WORKER_NAME);
313310
when(workerConfigService.getDockerNetworkName()).thenReturn("lasNetworkName");
314311
DockerRunResponse expectedDockerRunResponse =
@@ -318,8 +315,11 @@ void shouldRunTeePostComputeWithFailDockerResponse(Map.Entry<Integer, ReplicateS
318315
.build();
319316
when(dockerService.run(any())).thenReturn(expectedDockerRunResponse);
320317
when(sgxService.getSgxDriverMode()).thenReturn(SgxDriverMode.LEGACY);
321-
when(computeExitCauseService.getExitCausesAndPruneForGivenComputeStage(CHAIN_TASK_ID, ComputeStage.POST, POST_COMPUTE_FAILED_UNKNOWN_ISSUE))
322-
.thenReturn(List.of(exitCodeKeyToExpectedCauseValue.getValue()));
318+
// Only stub computeExitCauseService for exitCode == 1
319+
if (exitCodeKeyToExpectedCauseValue.getKey() == 1) {
320+
when(computeExitCauseService.getExitCausesAndPruneForGivenComputeStage(CHAIN_TASK_ID, ComputeStage.POST, POST_COMPUTE_FAILED_UNKNOWN_ISSUE))
321+
.thenReturn(List.of(exitCodeKeyToExpectedCauseValue.getValue()));
322+
}
323323

324324
PostComputeResponse postComputeResponse =
325325
postComputeService.runTeePostCompute(taskDescription, SECURE_SESSION);
@@ -346,15 +346,17 @@ void shouldNotRunTeePostComputeSinceTimeout() {
346346
.maxExecutionTime(MAX_EXECUTION_TIME)
347347
.build();
348348
List<String> env = Arrays.asList("var0", "var1");
349+
when(dockerService.getClient()).thenReturn(dockerClientInstanceMock);
350+
when(teeServicesManager.getTeeService(any())).thenReturn(teeMockedService);
351+
when(teeServicesPropertiesService.getTeeServicesProperties(CHAIN_TASK_ID)).thenReturn(properties);
352+
when(properties.getPostComputeProperties()).thenReturn(postComputeProperties);
349353
when(postComputeProperties.getImage()).thenReturn(TEE_POST_COMPUTE_IMAGE);
350-
when(postComputeProperties.getHeapSizeInBytes()).thenReturn(TEE_POST_COMPUTE_HEAP);
351354
when(postComputeProperties.getEntrypoint()).thenReturn(TEE_POST_COMPUTE_ENTRYPOINT);
352355
when(dockerClientInstanceMock.isImagePresent(TEE_POST_COMPUTE_IMAGE))
353356
.thenReturn(true);
354357
when(teeMockedService.buildPostComputeDockerEnv(taskDescription, SECURE_SESSION))
355358
.thenReturn(env);
356359
when(dockerService.getIexecOutBind(CHAIN_TASK_ID)).thenReturn("/iexec_out:/iexec_out");
357-
when(workerConfigService.getTaskOutputDir(CHAIN_TASK_ID)).thenReturn(output);
358360
when(workerConfigService.getWorkerName()).thenReturn(WORKER_NAME);
359361
when(workerConfigService.getDockerNetworkName()).thenReturn("lasNetworkName");
360362
DockerRunResponse expectedDockerRunResponse =

0 commit comments

Comments
 (0)