diff --git a/ledger/ledger-api-test-tool/src/main/scala/com/daml/ledger/api/testtool/LedgerApiTestTool.scala b/ledger/ledger-api-test-tool/src/main/scala/com/daml/ledger/api/testtool/LedgerApiTestTool.scala index bde96cb272..ec7cbbf627 100644 --- a/ledger/ledger-api-test-tool/src/main/scala/com/daml/ledger/api/testtool/LedgerApiTestTool.scala +++ b/ledger/ledger-api-test-tool/src/main/scala/com/daml/ledger/api/testtool/LedgerApiTestTool.scala @@ -9,6 +9,7 @@ import java.nio.file.{Files, Paths, StandardCopyOption} import com.daml.ledger.api.testtool.infrastructure.Reporter.ColorizedPrintStreamReporter import com.daml.ledger.api.testtool.infrastructure.{ Dars, + Errors, LedgerSessionConfiguration, LedgerTestCase, LedgerTestCasesRunner, @@ -161,8 +162,12 @@ object LedgerApiTestTool { config.verbose, ).report(summaries) sys.exit(exitCode(summaries, config.mustFail)) - case Failure(e) => - logger.error(e.getMessage, e) + case Failure(exception: Errors.FrameworkException) => + logger.error(exception.getMessage) + logger.debug(exception.getMessage, exception) + sys.exit(1) + case Failure(exception) => + logger.error(exception.getMessage, exception) sys.exit(1) } } diff --git a/ledger/ledger-api-test-tool/src/main/scala/com/daml/ledger/api/testtool/infrastructure/Errors.scala b/ledger/ledger-api-test-tool/src/main/scala/com/daml/ledger/api/testtool/infrastructure/Errors.scala new file mode 100644 index 0000000000..d86ca32b19 --- /dev/null +++ b/ledger/ledger-api-test-tool/src/main/scala/com/daml/ledger/api/testtool/infrastructure/Errors.scala @@ -0,0 +1,14 @@ +// Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +package com.daml.ledger.api.testtool.infrastructure + +object Errors { + + sealed abstract class FrameworkException(message: String, cause: Throwable) + extends RuntimeException(message, cause) + + final class ParticipantConnectionException(address: String, cause: Throwable) + extends FrameworkException(s"Could not connect to the participant at $address.", cause) + +} diff --git a/ledger/ledger-api-test-tool/src/main/scala/com/daml/ledger/api/testtool/infrastructure/participant/ParticipantSession.scala b/ledger/ledger-api-test-tool/src/main/scala/com/daml/ledger/api/testtool/infrastructure/participant/ParticipantSession.scala index 387b5aae61..3e4de24d6c 100644 --- a/ledger/ledger-api-test-tool/src/main/scala/com/daml/ledger/api/testtool/infrastructure/participant/ParticipantSession.scala +++ b/ledger/ledger-api-test-tool/src/main/scala/com/daml/ledger/api/testtool/infrastructure/participant/ParticipantSession.scala @@ -3,7 +3,7 @@ package com.daml.ledger.api.testtool.infrastructure.participant -import com.daml.ledger.api.testtool.infrastructure.LedgerServices +import com.daml.ledger.api.testtool.infrastructure.{Errors, LedgerServices} import com.daml.ledger.api.v1.ledger_identity_service.GetLedgerIdentityRequest import com.daml.ledger.api.v1.transaction_service.GetLedgerEndRequest import com.daml.timer.RetryStrategy @@ -12,6 +12,8 @@ import org.slf4j.LoggerFactory import scala.concurrent.duration.DurationInt import scala.concurrent.{ExecutionContext, Future} +import scala.util.Failure +import scala.util.control.NonFatal private[infrastructure] final class ParticipantSession private ( config: ParticipantSessionConfiguration, @@ -56,11 +58,22 @@ object ParticipantSession { )(implicit executionContext: ExecutionContext): Future[ParticipantSession] = { val services = new LedgerServices(channel) for { - ledgerId <- RetryStrategy.exponentialBackoff(10, 10.millis) { (attempt, wait) => - logger.debug( - s"Fetching ledgerId to create context (attempt #$attempt, next one in $wait)...") - services.identity.getLedgerIdentity(new GetLedgerIdentityRequest).map(_.ledgerId) - } + // Keep retrying for about a minute. + ledgerId <- RetryStrategy + .exponentialBackoff(10, 100.millis) { (attempt, wait) => + services.identity + .getLedgerIdentity(new GetLedgerIdentityRequest) + .map(_.ledgerId) + .andThen { + case Failure(_) => + logger.info( + s"Could not connect to the participant (attempt #$attempt). Trying again in $wait...") + } + } + .recoverWith { + case NonFatal(exception) => + Future.failed(new Errors.ParticipantConnectionException(config.address, exception)) + } } yield new ParticipantSession(config, services, ledgerId) } } diff --git a/ledger/ledger-api-test-tool/src/main/scala/com/daml/ledger/api/testtool/infrastructure/participant/ParticipantSessionManager.scala b/ledger/ledger-api-test-tool/src/main/scala/com/daml/ledger/api/testtool/infrastructure/participant/ParticipantSessionManager.scala index 0ac4b7cefa..e64380eb88 100644 --- a/ledger/ledger-api-test-tool/src/main/scala/com/daml/ledger/api/testtool/infrastructure/participant/ParticipantSessionManager.scala +++ b/ledger/ledger-api-test-tool/src/main/scala/com/daml/ledger/api/testtool/infrastructure/participant/ParticipantSessionManager.scala @@ -69,9 +69,10 @@ object ParticipantSessionManager { } channelBuilder.maxInboundMessageSize(10000000) val channel = channelBuilder.build() - logger.info(s"Connected to participant at ${config.address}.") - ParticipantSession(config, channel).map(session => - new Session(config, session, channel, eventLoopGroup)) + ParticipantSession(config, channel).map { session => + logger.info(s"Connected to participant at ${config.address}.") + new Session(config, session, channel, eventLoopGroup) + } } private final class Session(