From 7f267b816ac5be5d92c5fb3c1463f3414b607e1e Mon Sep 17 00:00:00 2001 From: Jeremy Bernard Date: Fri, 28 Nov 2025 09:57:02 +0100 Subject: [PATCH 1/2] feat: stop embedding category, app and dataset models in deal model --- .../iexec/commons/poco/chain/ChainDeal.java | 20 ++++++- .../poco/chain/IexecHubAbstractService.java | 57 +++++++++++++++---- .../commons/poco/task/TaskDescription.java | 45 +++++++++++---- .../com/iexec/commons/poco/utils/Retryer.java | 38 ++++++------- .../chain/IexecHubAbstractServiceTest.java | 50 +++++++++++----- .../poco/task/TaskDescriptionTests.java | 13 +++-- .../iexec/commons/poco/utils/RetryerTest.java | 12 ++-- 7 files changed, 162 insertions(+), 73 deletions(-) diff --git a/src/main/java/com/iexec/commons/poco/chain/ChainDeal.java b/src/main/java/com/iexec/commons/poco/chain/ChainDeal.java index 53ec2d4..3e9a806 100644 --- a/src/main/java/com/iexec/commons/poco/chain/ChainDeal.java +++ b/src/main/java/com/iexec/commons/poco/chain/ChainDeal.java @@ -28,8 +28,20 @@ public class ChainDeal { String chainDealId; + /** + * @deprecated not consistent with Smart Contracts + */ + @Deprecated(forRemoval = true) ChainApp chainApp; + /** + * @deprecated not consistent with Smart Contracts + */ + @Deprecated(forRemoval = true) ChainDataset chainDataset; + /** + * @deprecated not consistent with Smart Contracts + */ + @Deprecated(forRemoval = true) ChainCategory chainCategory; // deal_pt1 String dappPointer; @@ -59,9 +71,7 @@ public class ChainDeal { BigInteger schedulerRewardRatio; public boolean containsDataset() { - return getChainDataset() != null && - getChainDataset().getChainDatasetId() != null && - !getChainDataset().getChainDatasetId().equals(BytesUtils.EMPTY_ADDRESS); + return dataPointer != null && !BytesUtils.EMPTY_ADDRESS.equals(dataPointer); } public static ChainDeal parts2ChainDeal(String chainDealId, IexecHubContract.Deal deal, ChainCategory category) { @@ -71,6 +81,10 @@ public static ChainDeal parts2ChainDeal(String chainDealId, IexecHubContract.Dea return create(chainDealId, deal, category, null, null); } + /** + * @deprecated app, category and dataset will no more be embedded in deal to stick to on-chain models + */ + @Deprecated(forRemoval = true) public static ChainDeal parts2ChainDeal(String chainDealId, IexecHubContract.Deal deal, ChainApp app, ChainCategory category, ChainDataset dataset) { if (deal == null || app == null || category == null) { return ChainDeal.builder().build(); diff --git a/src/main/java/com/iexec/commons/poco/chain/IexecHubAbstractService.java b/src/main/java/com/iexec/commons/poco/chain/IexecHubAbstractService.java index a441ecb..2c1bda6 100644 --- a/src/main/java/com/iexec/commons/poco/chain/IexecHubAbstractService.java +++ b/src/main/java/com/iexec/commons/poco/chain/IexecHubAbstractService.java @@ -162,11 +162,11 @@ public IexecHubContract getHubContract() { * @param maxRetry number of maximum retry * @return optional ChainDeal */ - Optional repeatGetChainDeal(String chainDealId, - long retryDelay, - int maxRetry) { + Optional repeatGetChainDeal(final String chainDealId, + final long retryDelay, + final int maxRetry) { return new Retryer>() - .repeatCall(() -> getChainDealWithDetails(chainDealId), + .repeatCall(() -> getChainDeal(chainDealId), Optional::isEmpty, retryDelay, maxRetry, String.format("getChainDeal(chainDealId) [chainDealId:%s]", chainDealId)); @@ -210,7 +210,9 @@ public Optional getChainDeal(String chainDealId) { * * @param chainDealId blockchain ID of the deal (e.g: 0x123..abc) * @return deal object + * @deprecated on-chain app, category, dataset and deal are fetched separately (see repeatGetTaskDescriptionFromChain) */ + @Deprecated(forRemoval = true) public Optional getChainDealWithDetails(String chainDealId) { final byte[] chainDealIdBytes = BytesUtils.stringToBytes(chainDealId); try { @@ -258,9 +260,9 @@ private Optional validateChainDeal(final ChainDeal chainDeal) { * @param maxRetry number of maximum retry * @return optional ChainTask */ - Optional repeatGetChainTask(String chainTaskId, - long retryDelay, - int maxRetry) { + Optional repeatGetChainTask(final String chainTaskId, + final long retryDelay, + final int maxRetry) { return new Retryer>() .repeatCall(() -> getChainTask(chainTaskId), Optional::isEmpty, @@ -458,9 +460,18 @@ public TaskDescription getTaskDescription(String chainTaskId) { return taskDescriptions.get(chainTaskId); } - Optional repeatGetTaskDescriptionFromChain(String chainTaskId, - long retryDelay, - int maxRetry) { + /** + * Retrieves task, deal, category, app and dataset models on PoCo Smart Contracts to build a task description. + * + * @param chainTaskId ID of the task + * @param retryDelay Interval between consecutive attempts while reading on the blockchain network + * @param maxRetry Maximum number of attempts + * @return The aggregate {@code TaskDescription}. + * If the maximum number of attempts is reached without retrieving data, an empty result will be returned. + */ + Optional repeatGetTaskDescriptionFromChain(final String chainTaskId, + final long retryDelay, + final int maxRetry) { // If retryDelay is 0, a runtime exception will be thrown from failsafe library if (retryDelay == 0) { log.warn("retry delay cannot be 0 [chainTaskId:{}]", chainTaskId); @@ -478,9 +489,31 @@ Optional repeatGetTaskDescriptionFromChain(String chainTaskId, return Optional.empty(); } - final TaskDescription taskDescription = TaskDescription.toTaskDescription(chainDeal, chainTask); + final ChainCategory chainCategory = new Retryer>() + .repeatCall(() -> getChainCategory(chainDeal.getCategory().longValue()), + Optional::isEmpty, + retryDelay, maxRetry, + String.format("getChainCategory() [category:%s]", chainDeal.getCategory().longValue())) + .orElse(null); + + final ChainApp chainApp = new Retryer>() + .repeatCall(() -> getChainApp(chainDeal.getDappPointer()), + Optional::isEmpty, + retryDelay, maxRetry, + String.format("getChainApp() [address:%s]", chainDeal.getDappPointer())) + .orElse(null); + + final ChainDataset chainDataset = new Retryer>() + .repeatCall(() -> getChainDataset(chainDeal.getDataPointer()), + Optional::isEmpty, + retryDelay, maxRetry, + String.format("getChainDataset() [address:%s]", chainDeal.getDataPointer())) + .orElse(null); + + final TaskDescription taskDescription = TaskDescription.toTaskDescription( + chainDeal, chainTask, chainCategory, chainApp, chainDataset); // taskDescription cannot be null here as chainTask and ChainDeal are not - return taskDescription != null ? Optional.of(taskDescription) : Optional.empty(); + return Optional.ofNullable(taskDescription); } /** diff --git a/src/main/java/com/iexec/commons/poco/task/TaskDescription.java b/src/main/java/com/iexec/commons/poco/task/TaskDescription.java index 3aa60b8..2997da6 100644 --- a/src/main/java/com/iexec/commons/poco/task/TaskDescription.java +++ b/src/main/java/com/iexec/commons/poco/task/TaskDescription.java @@ -17,9 +17,7 @@ package com.iexec.commons.poco.task; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.iexec.commons.poco.chain.ChainDeal; -import com.iexec.commons.poco.chain.ChainTask; -import com.iexec.commons.poco.chain.DealParams; +import com.iexec.commons.poco.chain.*; import com.iexec.commons.poco.dapp.DappType; import com.iexec.commons.poco.tee.TeeEnclaveConfiguration; import com.iexec.commons.poco.tee.TeeFramework; @@ -42,6 +40,7 @@ public class TaskDescription { // assets DappType appType; String appUri; + String appChecksum; TeeEnclaveConfiguration appEnclaveConfiguration; String datasetUri; String datasetChecksum; @@ -181,24 +180,50 @@ public boolean requiresTdx() { * @param chainDeal On-chain deal from PoCo smart contracts * @param chainTask On-chain task from PoCo smart contracts * @return the created taskDescription + * @deprecated app, category and dataset models will be removed from deal model */ + @Deprecated(forRemoval = true) public static TaskDescription toTaskDescription(final ChainDeal chainDeal, final ChainTask chainTask) { if (chainDeal == null || chainTask == null) { return null; } - String datasetUri = ""; - String datasetChecksum = ""; + return toTaskDescription( + chainDeal, chainTask, chainDeal.getChainCategory(), chainDeal.getChainApp(), chainDeal.getChainDataset()); + } + + /** + * Create a {@link TaskDescription} from the provided chain deal. This method + * if preferred to constructors or the builder method. + * + * @param chainDeal On-chain deal from PoCo smart contracts + * @param chainTask On-chain task from PoCo smart contracts + * @param chainCategory On-chain category from PoCo smart contracts + * @param chainApp On-chain application from PoCo smart contracts + * @param chainDataset On-chain dataset from PoCo smart contracts + * @return the created taskDescription + */ + public static TaskDescription toTaskDescription(final ChainDeal chainDeal, + final ChainTask chainTask, + final ChainCategory chainCategory, + final ChainApp chainApp, + final ChainDataset chainDataset) { + if (chainDeal == null || chainTask == null || chainCategory == null || chainApp == null || (chainDeal.containsDataset() && chainDataset == null)) { + return null; + } + String datasetUri = null; + String datasetChecksum = null; if (chainDeal.containsDataset()) { - datasetUri = chainDeal.getChainDataset().getMultiaddr(); - datasetChecksum = chainDeal.getChainDataset().getChecksum(); + datasetUri = chainDataset.getMultiaddr(); + datasetChecksum = chainDataset.getChecksum(); } final String tag = chainDeal.getTag(); return TaskDescription.builder() .chainTaskId(chainTask.getChainTaskId()) // assets .appType(DappType.DOCKER) - .appUri(chainDeal.getChainApp().getMultiaddr()) - .appEnclaveConfiguration(chainDeal.getChainApp().getEnclaveConfiguration()) + .appUri(chainApp.getMultiaddr()) + .appChecksum(chainApp.getChecksum()) + .appEnclaveConfiguration(chainApp.getEnclaveConfiguration()) .datasetUri(datasetUri) .datasetChecksum(datasetChecksum) // deal @@ -227,7 +252,7 @@ public static TaskDescription toTaskDescription(final ChainDeal chainDeal, final // task .chainDealId(chainDeal.getChainDealId()) .botIndex(chainTask.getIdx()) - .maxExecutionTime(chainDeal.getChainCategory().getMaxExecutionTime()) // https://github.com/iExecBlockchainComputing/PoCo/blob/v5/contracts/modules/delegates/IexecPoco2Delegate.sol#L111 + .maxExecutionTime(chainCategory.getMaxExecutionTime()) .contributionDeadline(chainTask.getContributionDeadline()) .finalDeadline(chainTask.getFinalDeadline()) .build(); diff --git a/src/main/java/com/iexec/commons/poco/utils/Retryer.java b/src/main/java/com/iexec/commons/poco/utils/Retryer.java index edbb67f..cd0ee29 100644 --- a/src/main/java/com/iexec/commons/poco/utils/Retryer.java +++ b/src/main/java/com/iexec/commons/poco/utils/Retryer.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2023 IEXEC BLOCKCHAIN TECH + * Copyright 2020-2025 IEXEC BLOCKCHAIN TECH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,41 +35,39 @@ public class Retryer { * @param retryIfPredicate condition for retrying the supplying method call * @param retryDelay delay in ms between two tries * @param maxRetry number of maximum retries - * @param logContext human readable content to be display + * @param logContext human-readable content to be displayed * @return an object that the supplying method provides */ - public T repeatCall(CheckedSupplier supplier, - Predicate retryIfPredicate, - long retryDelay, - int maxRetry, - String logContext) { - String context = "\"" + logContext + "\""; + public T repeatCall(final CheckedSupplier supplier, + final Predicate retryIfPredicate, + final long retryDelay, + final int maxRetry, + final String logContext) { if (retryDelay == 0) { - log.error("Cannot repeat call {} without delay " + - "[retryDelay:{}ms, maxRetry:{}]", + log.error("Cannot repeat call {} without delay [retryDelay:{}ms, maxRetry:{}]", logContext, retryDelay, maxRetry); return null; } - RetryPolicy retryPolicy = + final RetryPolicy retryPolicy = new RetryPolicy() .handleResultIf(retryIfPredicate) //retry if .withDelay(Duration.ofMillis(retryDelay)) .withMaxRetries(maxRetry) - .onRetry(e -> logWarnRetry(context, - retryDelay, maxRetry, e.getAttemptCount())) - .onRetriesExceeded(e -> logErrorOnMaxRetry(context, - retryDelay, maxRetry)); + .onRetry(e -> logWarnRetry( + logContext, retryDelay, maxRetry, e.getAttemptCount())) + .onRetriesExceeded(e -> logErrorOnMaxRetry( + logContext, retryDelay, maxRetry)); return Failsafe.with(retryPolicy) .get(supplier); } - private void logWarnRetry(String context, long retryDelay, int maxRetry, int attempt) { - log.warn("Failed to {}, about to retry [retryDelay:{}ms, maxRetry:{}" + - ", attempt:{}]", context, retryDelay, maxRetry, attempt); + private void logWarnRetry(final String context, final long retryDelay, final int maxRetry, final int attempt) { + log.warn("Failed to \"{}\", about to retry [retryDelay:{}ms, maxRetry:{}, attempt:{}]", + context, retryDelay, maxRetry, attempt); } - private void logErrorOnMaxRetry(String context, long retryDelay, int maxRetry) { - log.error("Failed to {} after max retry [retryDelay:{}ms, maxRetry:{}]", + private void logErrorOnMaxRetry(final String context, final long retryDelay, final int maxRetry) { + log.error("Failed to \"{}\" after max retry [retryDelay:{}ms, maxRetry:{}]", context, retryDelay, maxRetry); } diff --git a/src/test/java/com/iexec/commons/poco/chain/IexecHubAbstractServiceTest.java b/src/test/java/com/iexec/commons/poco/chain/IexecHubAbstractServiceTest.java index 6b9ecdc..6f75d63 100644 --- a/src/test/java/com/iexec/commons/poco/chain/IexecHubAbstractServiceTest.java +++ b/src/test/java/com/iexec/commons/poco/chain/IexecHubAbstractServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2024 IEXEC BLOCKCHAIN TECH + * Copyright 2020-2025 IEXEC BLOCKCHAIN TECH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package com.iexec.commons.poco.chain; import com.iexec.commons.poco.contract.generated.IexecHubContract; +import com.iexec.commons.poco.dapp.DappType; import com.iexec.commons.poco.task.TaskDescription; import com.iexec.commons.poco.utils.BytesUtils; import org.junit.jupiter.api.Test; @@ -133,7 +134,7 @@ void repeatGetChainTaskWithFailure() { void repeatGetChainDealWithSuccess() { ChainDeal chainDeal = getMockDeal(); - when(iexecHubAbstractService.getChainDealWithDetails(CHAIN_DEAL_ID)) + when(iexecHubAbstractService.getChainDeal(CHAIN_DEAL_ID)) .thenReturn(Optional.empty()) .thenReturn(Optional.empty()) .thenReturn(Optional.of(chainDeal)); @@ -145,12 +146,12 @@ void repeatGetChainDealWithSuccess() { assertThat(foundDeal).isEqualTo(Optional.of(chainDeal)); verify(iexecHubAbstractService, times(3)) - .getChainDealWithDetails(CHAIN_DEAL_ID); + .getChainDeal(CHAIN_DEAL_ID); } @Test void repeatGetChainDealWithFailure() { - when(iexecHubAbstractService.getChainDealWithDetails(CHAIN_DEAL_ID)) + when(iexecHubAbstractService.getChainDeal(CHAIN_DEAL_ID)) .thenReturn(Optional.empty()); when(iexecHubAbstractService.repeatGetChainDeal(CHAIN_DEAL_ID, RETRY_DELAY, MAX_RETRY)) .thenCallRealMethod(); @@ -160,26 +161,44 @@ void repeatGetChainDealWithFailure() { assertThat(foundDeal).isEmpty(); verify(iexecHubAbstractService, times(1 + MAX_RETRY)) - .getChainDealWithDetails(CHAIN_DEAL_ID); + .getChainDeal(CHAIN_DEAL_ID); } @Test void repeatGetTaskDescriptionFromChainWithSuccess() { - ChainTask task = getMockTask(); - ChainDeal deal = getMockDeal(); + final ChainTask task = getMockTask(); + final ChainDeal deal = getMockDeal(); when(iexecHubAbstractService.repeatGetChainTask(CHAIN_TASK_ID, RETRY_DELAY, MAX_RETRY)) .thenReturn(Optional.of(task)); when(iexecHubAbstractService.repeatGetChainDeal(CHAIN_DEAL_ID, RETRY_DELAY, MAX_RETRY)) .thenReturn(Optional.of(deal)); + when(iexecHubAbstractService.getChainCategory(anyLong())) + .thenReturn(Optional.of(ChainCategory.builder().build())); + when(iexecHubAbstractService.getChainApp(anyString())) + .thenReturn(Optional.of(ChainApp.builder().build())); + when(iexecHubAbstractService.getChainDataset(anyString())) + .thenReturn(Optional.of(ChainDataset.builder().build())); when(iexecHubAbstractService.repeatGetTaskDescriptionFromChain(CHAIN_TASK_ID, RETRY_DELAY, MAX_RETRY)) .thenCallRealMethod(); - Optional taskDescription = - iexecHubAbstractService.repeatGetTaskDescriptionFromChain(CHAIN_TASK_ID, RETRY_DELAY, MAX_RETRY); + final TaskDescription taskDescription = iexecHubAbstractService + .repeatGetTaskDescriptionFromChain(CHAIN_TASK_ID, RETRY_DELAY, MAX_RETRY) + .orElse(null); + + final TaskDescription expectedTaskDescription = TaskDescription.builder() + .chainTaskId(CHAIN_TASK_ID) + .appType(DappType.DOCKER) + .appAddress(deal.getDappPointer()) + .datasetAddress(deal.getDataPointer()) + .category(deal.getCategory()) + .dealParams(DealParams.builder().build()) + .startTime(deal.getStartTime().intValue()) + .botFirstIndex(deal.getBotFirst().intValue()) + .botSize(deal.getBotSize().intValue()) + .build(); - assertThat(taskDescription.map(TaskDescription::getChainTaskId)).hasValue(task.getChainTaskId()); - assertThat(taskDescription.map(TaskDescription::getBotSize)).hasValue(deal.getBotSize().intValue()); + assertThat(taskDescription).isEqualTo(expectedTaskDescription); } @Test @@ -276,11 +295,14 @@ private ChainTask getMockTask() { private ChainDeal getMockDeal() { return ChainDeal.builder() .chainApp(ChainApp.builder().multiaddr("").build()) - .params(DealParams.builder().build()) .chainCategory(ChainCategory.builder().build()) + .dappPointer("0x1") + .dataPointer(BytesUtils.EMPTY_ADDRESS) + .category(BigInteger.ZERO) + .params(DealParams.builder().build()) .startTime(BigInteger.TEN) - .botSize(BigInteger.ONE) .botFirst(BigInteger.ONE) + .botSize(BigInteger.ONE) .build(); } -} \ No newline at end of file +} diff --git a/src/test/java/com/iexec/commons/poco/task/TaskDescriptionTests.java b/src/test/java/com/iexec/commons/poco/task/TaskDescriptionTests.java index 1cb5b42..1e42499 100644 --- a/src/test/java/com/iexec/commons/poco/task/TaskDescriptionTests.java +++ b/src/test/java/com/iexec/commons/poco/task/TaskDescriptionTests.java @@ -34,6 +34,7 @@ import java.util.stream.Stream; import static com.iexec.commons.poco.utils.BytesUtils.EMPTY_ADDRESS; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; class TaskDescriptionTests { @@ -107,9 +108,6 @@ void toTaskDescription() { .iexecResultEncryption(IS_RESULT_ENCRYPTION) .build(); final ChainDeal chainDeal = ChainDeal.builder() - .chainApp(chainApp) - .chainDataset(chainDataset) - .chainCategory(chainCategory) .dappPointer(APP_ADDRESS) .dappOwner(APP_OWNER) .dappPrice(APP_PRICE) @@ -136,7 +134,8 @@ void toTaskDescription() { .idx(TASK_IDX) .build(); - final TaskDescription task = TaskDescription.toTaskDescription(chainDeal, chainTask); + final TaskDescription task = TaskDescription.toTaskDescription( + chainDeal, chainTask, chainCategory, chainApp, chainDataset); final TaskDescription expectedTaskDescription = TaskDescription.builder() .chainTaskId(CHAIN_TASK_ID) @@ -144,6 +143,8 @@ void toTaskDescription() { .appType(APP_TYPE) .appUri(APP_URI) .appEnclaveConfiguration(enclaveConfiguration) + .datasetUri(DATASET_URI) + .datasetChecksum(DATASET_CHECKSUM) // deals .appAddress(APP_ADDRESS) .appOwner(APP_OWNER) @@ -173,7 +174,7 @@ void toTaskDescription() { .datasetChecksum(DATASET_CHECKSUM) .build(); - assertEquals(expectedTaskDescription, task); + assertThat(task).isEqualTo(expectedTaskDescription); assertTrue(task.containsCallback()); } @@ -306,7 +307,7 @@ void shouldGenerateAppCommandWithEntrypointAndArgs() { .appEnclaveConfiguration(TeeEnclaveConfiguration.builder().entrypoint(ENTRYPOINT).build()) .dealParams(DealParams.builder().iexecArgs(CMD).build()) .build(); - assertEquals(ENTRYPOINT + " " + CMD, taskDescription.getAppCommand()); + assertThat(taskDescription.getAppCommand()).isEqualTo(ENTRYPOINT + " " + CMD); } // endregion diff --git a/src/test/java/com/iexec/commons/poco/utils/RetryerTest.java b/src/test/java/com/iexec/commons/poco/utils/RetryerTest.java index 9a90f34..ffc4ce6 100644 --- a/src/test/java/com/iexec/commons/poco/utils/RetryerTest.java +++ b/src/test/java/com/iexec/commons/poco/utils/RetryerTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2023 IEXEC BLOCKCHAIN TECH + * Copyright 2020-2025 IEXEC BLOCKCHAIN TECH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,13 +19,14 @@ import com.iexec.commons.poco.chain.IexecHubAbstractService; import org.apache.commons.lang3.StringUtils; import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; -import org.mockito.MockitoAnnotations; +import org.mockito.junit.jupiter.MockitoExtension; import static org.mockito.Mockito.*; +@ExtendWith(MockitoExtension.class) class RetryerTest { public static final String CONTRACT_ADDRESS = "0xcontract"; @@ -36,11 +37,6 @@ class RetryerTest { @Mock private IexecHubAbstractService iexecHubAbstractService; - @BeforeEach - void beforeEach() { - MockitoAnnotations.openMocks(this); - } - @Test void repeatCallWithSuccess() { when(iexecHubAbstractService.getOwner(CONTRACT_ADDRESS)) From 9a131f8577739749fefefa998c83a7a9b6ef6fe8 Mon Sep 17 00:00:00 2001 From: Jeremy Bernard Date: Fri, 28 Nov 2025 12:37:16 +0100 Subject: [PATCH 2/2] test: improve TaskDescription coverage --- .../commons/poco/task/TaskDescriptionTests.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/iexec/commons/poco/task/TaskDescriptionTests.java b/src/test/java/com/iexec/commons/poco/task/TaskDescriptionTests.java index 1e42499..c61c0ec 100644 --- a/src/test/java/com/iexec/commons/poco/task/TaskDescriptionTests.java +++ b/src/test/java/com/iexec/commons/poco/task/TaskDescriptionTests.java @@ -75,10 +75,21 @@ class TaskDescriptionTests { private static final String RESULT_STORAGE_PROXY = "resultStorageProxy"; @Test - void toTaskDescriptionWithNullDeal() { + void emptyTaskDescriptionWithNullDealAndTask() { assertNull(TaskDescription.toTaskDescription(null, null)); assertNull(TaskDescription.toTaskDescription(ChainDeal.builder().build(), null)); assertNull(TaskDescription.toTaskDescription(null, ChainTask.builder().build())); + assertNull(TaskDescription.toTaskDescription(ChainDeal.builder().build(), ChainTask.builder().build())); + } + + @Test + void emptyTaskDescriptionWithNullAssets() { + assertNull(TaskDescription.toTaskDescription(null, null, null, null, null)); + assertNull(TaskDescription.toTaskDescription(ChainDeal.builder().build(), null, null, null, null)); + assertNull(TaskDescription.toTaskDescription(null, ChainTask.builder().build(), null, null, null)); + assertNull(TaskDescription.toTaskDescription(null, null, ChainCategory.builder().build(), null, null)); + assertNull(TaskDescription.toTaskDescription(null, null, null, ChainApp.builder().build(), null)); + assertNull(TaskDescription.toTaskDescription(ChainDeal.builder().dataPointer("0x1").build(), null, null, ChainApp.builder().build(), null)); } @Test