4242import org .junit .jupiter .api .Assertions ;
4343import org .junit .jupiter .api .BeforeEach ;
4444import org .junit .jupiter .api .Test ;
45+ import org .junit .jupiter .api .TestInfo ;
4546import org .springframework .beans .factory .annotation .Autowired ;
4647import org .springframework .boot .test .context .SpringBootTest ;
4748import org .springframework .boot .web .server .LocalServerPort ;
4849import org .springframework .test .context .ActiveProfiles ;
50+ import org .springframework .test .context .DynamicPropertyRegistry ;
51+ import org .springframework .test .context .DynamicPropertySource ;
52+ import org .testcontainers .containers .DockerComposeContainer ;
53+ import org .testcontainers .containers .wait .strategy .Wait ;
54+ import org .testcontainers .junit .jupiter .Container ;
55+ import org .testcontainers .junit .jupiter .Testcontainers ;
4956import org .web3j .crypto .Hash ;
5057import org .web3j .crypto .Sign ;
5158
59+ import java .io .File ;
5260import java .math .BigInteger ;
5361import java .util .ArrayList ;
5462import java .util .List ;
5563import java .util .Optional ;
5664import java .util .concurrent .CompletableFuture ;
5765import java .util .concurrent .TimeUnit ;
66+ import java .util .concurrent .TimeoutException ;
5867import java .util .stream .IntStream ;
5968
6069import static com .iexec .commons .poco .chain .ChainTaskStatus .ACTIVE ;
6170import static com .iexec .commons .poco .chain .ChainTaskStatus .UNSET ;
71+ import static org .assertj .core .api .Assertions .assertThat ;
6272
6373@ Slf4j
64- @ SpringBootTest ( webEnvironment = SpringBootTest . WebEnvironment . RANDOM_PORT )
74+ @ Testcontainers
6575@ ActiveProfiles ("itest" )
76+ @ SpringBootTest (webEnvironment = SpringBootTest .WebEnvironment .RANDOM_PORT )
6677class IntegrationTests {
6778
6879 public static final String USER = "admin" ;
@@ -71,8 +82,20 @@ class IntegrationTests {
7182 public static final int MAX_BLOCK_TO_WAIT = 3 ;
7283 public static final int POLLING_PER_BLOCK = 2 ;
7384 public static final int POLLING_INTERVAL_MS = BLOCK_TIME_MS / POLLING_PER_BLOCK ;
74- public static final int MAX_POLLING_ATTEMPTS = MAX_BLOCK_TO_WAIT
75- * POLLING_PER_BLOCK ;
85+ public static final int MAX_POLLING_ATTEMPTS = MAX_BLOCK_TO_WAIT * POLLING_PER_BLOCK ;
86+
87+ @ Container
88+ static DockerComposeContainer <?> environment = new DockerComposeContainer <>(new File ("docker-compose.yml" ))
89+ .withExposedService ("ibaa-chain" , 8545 , Wait .forListeningPort ())
90+ .withExposedService ("ibaa-blockchain-adapter-mongo" , 13012 , Wait .forListeningPort ());
91+
92+ @ DynamicPropertySource
93+ static void registerProperties (DynamicPropertyRegistry registry ) {
94+ registry .add ("chain.id" , () -> "65535" );
95+ registry .add ("chain.hubAddress" , () -> "0xC129e7917b7c7DeDfAa5Fff1FB18d5D7050fE8ca" );
96+ registry .add ("chain.nodeAddress" , () -> getServiceUrl (environment .getServicePort ("ibaa-chain" , 8545 )));
97+ registry .add ("spring.data.mongodb.port" , () -> environment .getServicePort ("ibaa-blockchain-adapter-mongo" , 13012 ));
98+ }
7699
77100 @ LocalServerPort
78101 private int randomServerPort ;
@@ -91,9 +114,15 @@ class IntegrationTests {
91114 private BlockchainAdapterApiClient appClient ;
92115
93116 @ BeforeEach
94- void setUp () {
117+ void setUp (TestInfo testInfo ) {
118+ log .info (">>> {}" , testInfo .getDisplayName ());
95119 appClient = BlockchainAdapterApiClientBuilder
96- .getInstanceWithBasicAuth (Logger .Level .FULL , "http://localhost:" + randomServerPort , USER , PASSWORD );
120+ .getInstanceWithBasicAuth (Logger .Level .FULL , getServiceUrl (randomServerPort ), USER , PASSWORD );
121+ }
122+
123+ private static String getServiceUrl (int servicePort ) {
124+ log .info ("service url http://localhost:{}" , servicePort );
125+ return "http://localhost:" + servicePort ;
97126 }
98127
99128 @ Test
@@ -137,7 +166,7 @@ public void shouldBeFinalized() throws Exception {
137166 }
138167
139168 @ Test
140- public void shouldBurstTransactionsWithAverageOfOneTxPerBlock (){
169+ public void shouldBurstTransactionsWithAverageOfOneTxPerBlock () throws Exception {
141170 int taskVolume = 10 ;//small volume ensures reasonable execution time on CI/CD
142171 String dealId = triggerDeal (taskVolume );
143172 List <CompletableFuture <Void >> txCompletionWatchers = new ArrayList <>();
@@ -167,7 +196,7 @@ public void shouldBurstTransactionsWithAverageOfOneTxPerBlock(){
167196 txCompletionWatchers .forEach (CompletableFuture ::join );
168197 }
169198
170- private String triggerDeal (int taskVolume ) {
199+ private String triggerDeal (int taskVolume ) throws Exception {
171200 int secondsPollingInterval = POLLING_INTERVAL_MS / 1000 ;
172201 int secondsTimeout = secondsPollingInterval * MAX_POLLING_ATTEMPTS ;
173202 String appAddress = iexecHubService .createApp (buildRandomName ("app" ),
@@ -208,10 +237,9 @@ private String triggerDeal(int taskVolume) {
208237 String dealId = brokerService .matchOrders (brokerOrder );
209238 Assertions .assertTrue (StringUtils .isNotEmpty (dealId ));
210239 log .info ("Created deal: {}" , dealId );
211- //no need to wait since broker is synchronous, just checking deal
212- //existence for double checking
240+ // no need to wait since broker is synchronous, just checking deal existence
213241 Optional <ChainDeal > chainDeal = iexecHubService .getChainDeal (dealId );
214- Assertions . assertTrue (chainDeal .isPresent () );
242+ assertThat (chainDeal ) .isPresent ();
215243 return dealId ;
216244 }
217245
@@ -303,18 +331,18 @@ private void waitStatus(String chainTaskId, ChainTaskStatus statusToWait, int po
303331 ChainTaskStatus status = null ;
304332 int attempts = 0 ;
305333 while (true ) {
306- log .info ("Status [status:{}, chainTaskId:{}]" , status , chainTaskId );
334+ attempts ++;
335+ log .info ("Status [status:{}, chainTaskId:{}, attempt:{}]" , status , chainTaskId , attempts );
307336 status = iexecHubService .getChainTask (chainTaskId )
308337 .map (ChainTask ::getStatus )
309338 .orElse (UNSET );
310- attempts ++;
311339 if (status .equals (statusToWait ) || attempts > maxAttempts ) {
312340 break ;
313341 }
314342 TimeUnit .MILLISECONDS .sleep (pollingTimeMs );
315343 }
316344 if (!status .equals (statusToWait )) {
317- throw new Exception ("Too long to wait for task: " + chainTaskId );
345+ throw new TimeoutException ("Too long to wait for task: " + chainTaskId );
318346 }
319347 log .info ("Status reached [status:{}, chainTaskId:{}]" , status , chainTaskId );
320348 }
@@ -328,15 +356,16 @@ private void waitBeforeFinalizing(String chainTaskId) throws Exception {
328356 int winnerCounter = chainTask .getWinnerCounter ();
329357 int revealCounter = chainTask .getRevealCounter ();
330358 int attempts = 0 ;
359+ log .info ("{} {}" , POLLING_INTERVAL_MS , MAX_POLLING_ATTEMPTS );
331360 while (revealCounter != winnerCounter ) {
332- log .info ("Waiting for reveals ({}/{})" , revealCounter , winnerCounter );
333- Thread .sleep (POLLING_INTERVAL_MS );
361+ attempts ++;
362+ log .info ("Waiting for reveals ({}/{}), attempt {}" , revealCounter , winnerCounter , attempts );
363+ Thread .sleep (BLOCK_TIME_MS );
334364 revealCounter = iexecHubService .getChainTask (chainTaskId )
335365 .map (ChainTask ::getRevealCounter )
336366 .orElse (0 );
337- attempts ++;
338- if (attempts == MAX_POLLING_ATTEMPTS ) {
339- throw new Exception ("Too long to wait for reveal: " + chainTaskId );
367+ if (attempts == MAX_BLOCK_TO_WAIT ) {
368+ throw new TimeoutException ("Too long to wait for reveal: " + chainTaskId );
340369 }
341370 }
342371 log .info ("All revealed ({}/{})" , revealCounter , winnerCounter );
0 commit comments