From 339704dd14c11fbbe4f75c77c48ee8ce54c9c384 Mon Sep 17 00:00:00 2001 From: Moritz Kiefer Date: Mon, 26 Oct 2020 09:08:03 +0100 Subject: [PATCH] Tests for timeouts to/from ledger in JSON API failure tests (#7791) * Tests for timeouts to/from ledger in JSON API failure tests changelog_begin changelog_end * Update ledger-service/http-json-testing/src/main/scala/com/daml/http/HttpServiceTestFixture.scala Co-authored-by: Stephen Compall * Update ledger-service/http-json-testing/src/main/scala/com/daml/http/HttpServiceTestFixture.scala Co-authored-by: Stephen Compall * Apply suggestions from code review Co-authored-by: Stephen Compall --- .../daml/http/HttpServiceTestFixture.scala | 14 +++++-- .../src/failure/scala/http/FailureTests.scala | 42 +++++++++++++++++++ 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/ledger-service/http-json-testing/src/main/scala/com/daml/http/HttpServiceTestFixture.scala b/ledger-service/http-json-testing/src/main/scala/com/daml/http/HttpServiceTestFixture.scala index c7fec1af5b9d..c546993c69ae 100644 --- a/ledger-service/http-json-testing/src/main/scala/com/daml/http/HttpServiceTestFixture.scala +++ b/ledger-service/http-json-testing/src/main/scala/com/daml/http/HttpServiceTestFixture.scala @@ -290,10 +290,10 @@ object HttpServiceTestFixture extends LazyLogging with Assertions with Inside { } } - def postJsonStringRequest(uri: Uri, jsonString: String, headers: List[HttpHeader])( + def postJsonStringRequestEncoded(uri: Uri, jsonString: String, headers: List[HttpHeader])( implicit as: ActorSystem, ec: ExecutionContext, - mat: Materializer): Future[(StatusCode, JsValue)] = { + mat: Materializer): Future[(StatusCode, String)] = { logger.info(s"postJson: ${uri.toString} json: ${jsonString: String}") Http() .singleRequest( @@ -305,10 +305,18 @@ object HttpServiceTestFixture extends LazyLogging with Assertions with Inside { ) .flatMap { resp => val bodyF: Future[String] = getResponseDataBytes(resp, debug = true) - bodyF.map(body => (resp.status, body.parseJson)) + bodyF.map(body => (resp.status, body)) } } + def postJsonStringRequest(uri: Uri, jsonString: String, headers: List[HttpHeader])( + implicit as: ActorSystem, + ec: ExecutionContext, + mat: Materializer): Future[(StatusCode, JsValue)] = + postJsonStringRequestEncoded(uri, jsonString, headers).map { + case (status, body) => (status, body.parseJson) + } + def postJsonRequest(uri: Uri, json: JsValue, headers: List[HttpHeader])( implicit as: ActorSystem, ec: ExecutionContext, diff --git a/ledger-service/http-json/src/failure/scala/http/FailureTests.scala b/ledger-service/http-json/src/failure/scala/http/FailureTests.scala index 1dfc574fd95d..dcb98de31cb1 100644 --- a/ledger-service/http-json/src/failure/scala/http/FailureTests.scala +++ b/ledger-service/http-json/src/failure/scala/http/FailureTests.scala @@ -11,8 +11,10 @@ import scala.concurrent.{Future, Promise} import scala.util.{Failure, Success} import com.daml.http.domain.Offset import com.daml.http.json.{JsonError, SprayJson} +import com.daml.http.util.FutureUtil import com.daml.ledger.api.testing.utils.SuiteResourceManagementAroundAll import com.daml.timer.RetryStrategy +import eu.rekawek.toxiproxy.model.ToxicDirection import org.scalatest._ import org.scalatest.concurrent.Eventually import scalaz.\/ @@ -72,6 +74,46 @@ final class FailureTests } yield succeed } + "Command submission timeouts" in withHttpService { (uri, encoder, _, client) => + import encoder.implicits._ + import json.JsonProtocol._ + for { + p <- allocateParty(client, "Alice") + (status, _) <- postCreateCommand( + accountCreateCommand(p, "23"), + encoder, + uri, + headersWithParties(List(p.unwrap))) + _ = status shouldBe StatusCodes.OK + // Client -> Server connection + _ = proxy.toxics().timeout("timeout", ToxicDirection.UPSTREAM, 0) + body <- FutureUtil.toFuture(SprayJson.encode1(accountCreateCommand(p, "24"))): Future[JsValue] + (status, output) <- postJsonStringRequestEncoded( + uri.withPath(Uri.Path("/v1/create")), + body.compactPrint, + headersWithParties(List(p.unwrap))) + _ = status shouldBe StatusCodes.ServiceUnavailable + _ = println(output.toString) + _ = output shouldBe "The server was not able to produce a timely response to your request.\r\nPlease try again in a short while!" + _ = proxy.toxics().get("timeout").remove() + (status, _) <- postCreateCommand( + accountCreateCommand(p, "25"), + encoder, + uri, + headersWithParties(List(p.unwrap))) + _ = status shouldBe StatusCodes.OK + // Server -> Client connection + _ = proxy.toxics().timeout("timeout", ToxicDirection.DOWNSTREAM, 0) + (status, output) <- postJsonStringRequestEncoded( + uri.withPath(Uri.Path("/v1/create")), + body.compactPrint, + headersWithParties(List(p.unwrap))) + _ = status shouldBe StatusCodes.ServiceUnavailable + _ = println(output.toString) + _ = output shouldBe "The server was not able to produce a timely response to your request.\r\nPlease try again in a short while!" + } yield succeed + } + "/v1/query GET succeeds after reconnect" in withHttpService[Assertion] { (uri, encoder, _, client) => for {