diff --git a/build.sbt b/build.sbt index d1329d2..ce508f1 100644 --- a/build.sbt +++ b/build.sbt @@ -1,3 +1,5 @@ +import scala.collection.Seq + lazy val root = (project in file(".")) .enablePlugins(GatlingPlugin) .settings( diff --git a/src/test/resources/application.conf b/src/test/resources/application.conf index 2851484..fb28b78 100644 --- a/src/test/resources/application.conf +++ b/src/test/resources/application.conf @@ -46,14 +46,7 @@ perftest { #requestPercentageFailureThreshold = 1 } - # if true, saves NDJSON to a txt file - # Each "no-of-json-lines" generates an NDJSON payload containing all 6 ISA account types. - # For example: - # no-of-json-lines = 1 → 6 JSON objects(6 NDJSON lines) - # no-of-json-lines = N → 6 x N JSON objects (N NDJSON lines) - # With the existing payload "no-of-json-lines = 5832" creates a 10MB ndjson file - # "no-of-json-lines = 364" creates a 1MB ndjson file - # set 'save-to-file = true' only when tests are running locally - saveMonthlyReturnLocally { - no-of-json-lines = 5832 - } +# numOfIsaAccountSets = 1 → 4 JSON objects(4 NDJSON lines) +monthlyReturnsTestPayload { + numOfIsaAccountSets = 4000 +} diff --git a/src/test/resources/journeys.conf b/src/test/resources/journeys.conf index fc8df28..9d09061 100644 --- a/src/test/resources/journeys.conf +++ b/src/test/resources/journeys.conf @@ -15,37 +15,34 @@ # Configure here your journeys. A journey is a sequence of requests at a certain load. journeys { - monthly-returns-submission-journey = { - description = "Monthly returns submission journey" - load = 10 - parts = [ - monthly-returns-submission-journey - ] - } - - monthly-returns-declaration-journey = { - description = "monthly returns declaration journey" - load = 50 + submit-monthly-returns = { + description = "Submit Monthly Returns Journey" + load = 2 parts = [ - monthly-returns-declaration-journey + submit-monthly-returns ] - } - - monthly-reconciliation-report-summary-journey = { - description = "Monthly reconciliation report summary journey" - load = 50 + }, + nps-report-summary-callback = { + description = "NPS Report Summary Callback Journey" + load = 2 parts = [ - monthly-reconciliation-report-summary-journey + nps-report-summary-callback ] - } + }, + nps-retrieve-monthly-summary-and-report = { + description = "NPS Retrieve Monthly Summary and Report Journey" + load = 5 + parts = [ + nps-retrieve-monthly-summary-and-report + ] + } } # Default behaviour is to run all journeys. If that is not what you need you can specify the list of journeys to run journeysToRun = [ - monthly-returns-submission-journey, - monthly-returns-declaration-journey, - monthly-reconciliation-report-summary-journey + submit-monthly-returns, + nps-report-summary-callback ] # You can specify the same list of journeys via environment variables: diff --git a/src/test/scala/uk/gov/hmrc/perftests/disareturns/MonthlyReturnsSubmissionRequests.scala b/src/test/scala/uk/gov/hmrc/perftests/disareturns/MonthlyReturnsSubmissionRequests.scala index 1f52027..a97f04b 100644 --- a/src/test/scala/uk/gov/hmrc/perftests/disareturns/MonthlyReturnsSubmissionRequests.scala +++ b/src/test/scala/uk/gov/hmrc/perftests/disareturns/MonthlyReturnsSubmissionRequests.scala @@ -19,15 +19,30 @@ package uk.gov.hmrc.perftests.disareturns import io.gatling.core.Predef._ import io.gatling.http.Predef._ import io.gatling.http.request.builder.HttpRequestBuilder -import uk.gov.hmrc.perftests.disareturns.Util.MockMonthlyReturnData.validNdjsonTestData +import uk.gov.hmrc.perftests.disareturns.Util.NdjsonPayloadGenerator import uk.gov.hmrc.perftests.disareturns.constant.AppConfig.{disaReturnsHost, disaReturnsRoute} import uk.gov.hmrc.perftests.disareturns.constant.Headers.headerWithClientIdAndBearerToken +import java.nio.file.{Files, Paths, StandardOpenOption} + object MonthlyReturnsSubmissionRequests { + + private val submissionPayloadFilePath: String = { + val path = "target/monthly-return-payload.ndjson" + val ndjson = NdjsonPayloadGenerator.generateNdjsonPayload() + val filePath = Paths.get(path) + Files.write(filePath, ndjson.getBytes("UTF-8"), + StandardOpenOption.CREATE, + StandardOpenOption.TRUNCATE_EXISTING + ) + path + } + val submitMonthlyReport: HttpRequestBuilder = http("Submit monthly report") .post(s"$disaReturnsHost$disaReturnsRoute#{isaManagerReference}/#{taxYear}/#{month}") .headers(headerWithClientIdAndBearerToken) - .body(StringBody(validNdjsonTestData())) + .body(RawFileBody(submissionPayloadFilePath)).asJson .check(status.is(204)) + } diff --git a/src/test/scala/uk/gov/hmrc/perftests/disareturns/MonthlyReturnsSubmissionSimulation.scala b/src/test/scala/uk/gov/hmrc/perftests/disareturns/MonthlyReturnsSubmissionSimulation.scala index 9e32d8a..ae93325 100644 --- a/src/test/scala/uk/gov/hmrc/perftests/disareturns/MonthlyReturnsSubmissionSimulation.scala +++ b/src/test/scala/uk/gov/hmrc/perftests/disareturns/MonthlyReturnsSubmissionSimulation.scala @@ -16,15 +16,16 @@ package uk.gov.hmrc.perftests.disareturns -import io.gatling.core.Predef.feed +import io.gatling.core.Predef._ import io.gatling.core.structure.ChainBuilder import uk.gov.hmrc.performance.simulation.PerformanceTestRunner import uk.gov.hmrc.perftests.disareturns.MonthlyReconciliationReportRequests.{getReportingResultsSummary, submitReturnSummaryCallback} -import uk.gov.hmrc.perftests.disareturns.MonthlyReturnLoginRequest.getBearerToken import uk.gov.hmrc.perftests.disareturns.MonthlyReturnsDeclarationRequest.submitDeclaration import uk.gov.hmrc.perftests.disareturns.MonthlyReturnsSubmissionRequests.submitMonthlyReport -import uk.gov.hmrc.perftests.disareturns.Util.RandomDataGenerator.{generateRandomISAReference, getMonth, getTaxYear} -import uk.gov.hmrc.perftests.disareturns.models.TestDataSetupResult +import uk.gov.hmrc.perftests.disareturns.TestOnlyRequests.openObligationStatus +import uk.gov.hmrc.perftests.disareturns.Util.DirectMemoryLogger +import uk.gov.hmrc.perftests.disareturns.Util.RandomDataGenerator.{getMonth, getTaxYear} +import uk.gov.hmrc.perftests.disareturns.models.{Applications, IsaManagers} import uk.gov.hmrc.perftests.disareturns.testSetup.BaseRequests import scala.concurrent.Await @@ -32,70 +33,91 @@ import scala.concurrent.duration.DurationInt class MonthlyReturnsSubmissionSimulation extends PerformanceTestRunner with BaseRequests { - var setupData: TestDataSetupResult = _ + var setupIsaManagers: IsaManagers = _ + var setupIsaApplications: Applications = _ before { - setupData = Await.result(testDataSetup(), 30.seconds) + setupIsaManagers = Await.result(setupTestData(), 30.seconds) + setupIsaApplications = Await.result(setupApplications(), 30.seconds) + + val scheduler = java.util.concurrent.Executors.newSingleThreadScheduledExecutor() + + scheduler.scheduleAtFixedRate( + new Runnable { + override def run(): Unit = DirectMemoryLogger.log() + }, + 0, + 5, + java.util.concurrent.TimeUnit.SECONDS + ) } after { - testDataCleanUp(setupData) + testDataCleanUp(setupIsaApplications) } - val bearerTokenFeeder: ChainBuilder = feed(Iterator.continually(Map("bearerToken" -> setupData.bearerToken))) - - val clientIdFeeder: ChainBuilder = feed( - Iterator.continually(Map("clientId" -> setupData.clientIds(scala.util.Random.nextInt(setupData.clientIds.size)))) - ) - def generateReportInformationForTheSubmission(): Iterator[Map[String, String]] = - Iterator.continually( - Map( - "isaManagerReference" -> generateRandomISAReference(1, 500), - "taxYear" -> getTaxYear, - "month" -> getMonth - ) + val appFeeder: ChainBuilder = + feed( + Iterator + .continually(setupIsaApplications.applications) + .flatten + .map { im => + Map( + "clientId" -> im.clientId, + "applicationId" -> im.applicationId) + } ) - def generateReportInformationForTheDeclaration(): Iterator[Map[String, String]] = - Iterator.continually( - Map( - "isaManagerReference" -> generateRandomISAReference(501, 999), - "taxYear" -> getTaxYear, - "month" -> getMonth - ) + val isaManagerFeeder: ChainBuilder = + feed( + Iterator + .continually(setupIsaManagers.isaManager) + .flatten + .map { im => + Map( + "isaManagerReference" -> im.zRef, + "bearerToken" -> im.bearerToken, + "taxYear" -> getTaxYear, + "month" -> getMonth + ) + } ) setup( - "monthly-returns-submission-journey", - "Monthly returns submission journey" - ) withActions (feed( - generateReportInformationForTheSubmission() - ).actionBuilders ++ clientIdFeeder.actionBuilders: _*) withRequests ( - getBearerToken, - submitMonthlyReport + "submit-monthly-returns", + "Submit Monthly Returns" + ).withActions( + isaManagerFeeder.actionBuilders ++ appFeeder.actionBuilders: _* + ).withRequests( + openObligationStatus, + submitMonthlyReport, + submitDeclaration ) setup( - "monthly-returns-declaration-journey", - "Monthly returns declaration journey" - ) withActions (feed( - generateReportInformationForTheDeclaration() - ).actionBuilders ++ clientIdFeeder.actionBuilders: _*) withRequests ( - getBearerToken, - submitDeclaration + "nps-report-summary-callback", + "NPS Report Summary Callback" + ).withActions( + isaManagerFeeder.actionBuilders ++ appFeeder.actionBuilders: _* + ).withRequests( + submitReturnSummaryCallback ) + //TODO: Ticket raised - DFI-1720 + // - to implement request to test support API to setup reconciliation report + // - to implement request to get reconciliation report + // - remove NPS callback as this is tested separately setup( - "monthly-reconciliation-report-summary-journey", - "Monthly reconciliation report summary journey" - ) withActions (feed( - generateReportInformationForTheSubmission() - ).actionBuilders: _*) withRequests ( - getBearerToken, + "nps-retrieve-monthly-summary-and-report", + "NPS Retrieve Monthly Summary and Report" + ).withActions( + isaManagerFeeder.actionBuilders ++ appFeeder.actionBuilders: _* + ).withRequests( submitReturnSummaryCallback, getReportingResultsSummary ) + runSimulation() } diff --git a/src/test/scala/uk/gov/hmrc/perftests/disareturns/TestOnlyRequests.scala b/src/test/scala/uk/gov/hmrc/perftests/disareturns/TestOnlyRequests.scala new file mode 100644 index 0000000..8963a24 --- /dev/null +++ b/src/test/scala/uk/gov/hmrc/perftests/disareturns/TestOnlyRequests.scala @@ -0,0 +1,32 @@ +/* + * Copyright 2023 HM Revenue & Customs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package uk.gov.hmrc.perftests.disareturns + +import io.gatling.core.Predef._ +import io.gatling.http.Predef._ +import io.gatling.http.request.builder.HttpRequestBuilder +import uk.gov.hmrc.perftests.disareturns.constant.AppConfig.{disaReturnsStubHost, openObligationStatusPath} +import uk.gov.hmrc.perftests.disareturns.constant.Headers.headerWithClientIdAndBearerToken + +object TestOnlyRequests { + val openObligationStatus: HttpRequestBuilder = + http("Open Obligation Status") + .post(s"$disaReturnsStubHost$openObligationStatusPath#{isaManagerReference}") + .headers(headerWithClientIdAndBearerToken) + .body(StringBody("")) + .check(status.is(200)) +} diff --git a/src/test/scala/uk/gov/hmrc/perftests/disareturns/Util/DirectMemoryLogger.scala b/src/test/scala/uk/gov/hmrc/perftests/disareturns/Util/DirectMemoryLogger.scala new file mode 100644 index 0000000..86b0d1e --- /dev/null +++ b/src/test/scala/uk/gov/hmrc/perftests/disareturns/Util/DirectMemoryLogger.scala @@ -0,0 +1,40 @@ +/* + * Copyright 2026 HM Revenue & Customs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package uk.gov.hmrc.perftests.disareturns.Util + +import java.lang.management.{BufferPoolMXBean, ManagementFactory} +import scala.jdk.CollectionConverters._ + +object DirectMemoryLogger { + + def log(): Unit = { + val bufferPools: Seq[BufferPoolMXBean] = + ManagementFactory.getPlatformMXBeans(classOf[BufferPoolMXBean]).asScala.toSeq + + bufferPools.foreach { pool => + if (pool.getName == "direct") { + val usedMb = pool.getMemoryUsed / 1024 / 1024 + val capMb = pool.getTotalCapacity / 1024 / 1024 + val count = pool.getCount + + println( + s"[DIRECT MEMORY] Used: ${usedMb}MB | Capacity: ${capMb}MB | Buffers: $count" + ) + } + } + } +} \ No newline at end of file diff --git a/src/test/scala/uk/gov/hmrc/perftests/disareturns/Util/MockMonthlyReturnData.scala b/src/test/scala/uk/gov/hmrc/perftests/disareturns/Util/NdjsonPayloadGenerator.scala similarity index 60% rename from src/test/scala/uk/gov/hmrc/perftests/disareturns/Util/MockMonthlyReturnData.scala rename to src/test/scala/uk/gov/hmrc/perftests/disareturns/Util/NdjsonPayloadGenerator.scala index 49c700c..a251686 100644 --- a/src/test/scala/uk/gov/hmrc/perftests/disareturns/Util/MockMonthlyReturnData.scala +++ b/src/test/scala/uk/gov/hmrc/perftests/disareturns/Util/NdjsonPayloadGenerator.scala @@ -16,13 +16,16 @@ package uk.gov.hmrc.perftests.disareturns.Util -import com.typesafe.config.ConfigFactory +import com.typesafe.config.{Config, ConfigFactory} import play.api.libs.json.{JsValue, Json} import uk.gov.hmrc.perftests.disareturns.models.isaAccounts.{LifetimeISASubscriptionPayload, LiftimeISAClosurePayload, StandardISAClosurePayload, StandardISASubscriptionPayload} -object MockMonthlyReturnData extends NdjsonSupport { - private val config = ConfigFactory.load() - private val noOfJsons: Int = config.getInt("saveMonthlyReturnLocally.no-of-json-lines") +import java.nio.file.{Files, Paths, StandardOpenOption} + +object NdjsonPayloadGenerator extends NdjsonSupport { + private val config: Config = ConfigFactory.load() + private val numOfIsaAccountSets: Int = config.getInt("monthlyReturnsTestPayload.numOfIsaAccountSets") + def getLISASubscriptionPayload( nino: String, accountNumber: String @@ -107,39 +110,30 @@ object MockMonthlyReturnData extends NdjsonSupport { "VOID" ) - def validNdjsonTestData(): String = { - - def generatePayloadBlock(): Seq[JsValue] = { - val lisaSubscriptionPayload = - getLISASubscriptionPayload(RandomDataGenerator.generateNino(), RandomDataGenerator.generateAccountNumber()) - - val lisaClosurePayload = - getLISAClosurePayload(RandomDataGenerator.generateNino(), RandomDataGenerator.generateAccountNumber()) - - val sisaSubscriptionPayload = - getSISASubscriptionPayload(RandomDataGenerator.generateNino(), RandomDataGenerator.generateAccountNumber()) - - val sisaClosurePayload = - getSISAClosurePayload(RandomDataGenerator.generateNino(), RandomDataGenerator.generateAccountNumber()) + private val isaAccountBuilders: Seq[(String, String) => JsValue] = Seq( + (nino, acc) => Json.toJson(getLISASubscriptionPayload(nino, acc)), + (nino, acc) => Json.toJson(getLISAClosurePayload(nino, acc)), + (nino, acc) => Json.toJson(getSISASubscriptionPayload(nino, acc)), + (nino, acc) => Json.toJson(getSISAClosurePayload(nino, acc)) + ) - Seq( - Json.toJson(lisaSubscriptionPayload), - Json.toJson(lisaClosurePayload), - Json.toJson(sisaSubscriptionPayload), - Json.toJson(sisaClosurePayload) - ) + private def generateEachIsaAccountType(): Seq[JsValue] = + isaAccountBuilders.map { build => + val nino = RandomDataGenerator.generateNino() + val account = RandomDataGenerator.generateAccountNumber() + build(nino, account) } - val allPayloads: Seq[JsValue] = - Seq.fill(noOfJsons)(generatePayloadBlock()).flatten - - val ndjsonString = toNdjson(allPayloads) + def generateNdjsonPayload(): String = { + val allEvents: Seq[JsValue] = Seq.fill(numOfIsaAccountSets)(generateEachIsaAccountType()).flatten + toNdjson(allEvents) + } - /** Uncomment below code to save the ndjson fine in case for the testing purposes. 5832 * 4 creates a 10MB NDJson - * file, where 4 are the different types of subscription. - */ - /** val path = Paths.get("test-data.txt") Files.write(path, ndjsonString.getBytes(StandardCharsets.UTF_8))* */ - ndjsonString + def generateNdjsonFile(filePath: String): String = { + val ndjson = generateNdjsonPayload() + val path = Paths.get(filePath) + Files.write(path, ndjson.getBytes("UTF-8"), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING) + filePath } } diff --git a/src/test/scala/uk/gov/hmrc/perftests/disareturns/Util/RandomDataGenerator.scala b/src/test/scala/uk/gov/hmrc/perftests/disareturns/Util/RandomDataGenerator.scala index 7802d73..5ce6b99 100644 --- a/src/test/scala/uk/gov/hmrc/perftests/disareturns/Util/RandomDataGenerator.scala +++ b/src/test/scala/uk/gov/hmrc/perftests/disareturns/Util/RandomDataGenerator.scala @@ -34,12 +34,6 @@ object RandomDataGenerator { f"STD$number%06d" } - def generateRandomISAReference(min: Int, max: Int): String = { - require(min <= max, "min must be <= max") - val num = scala.util.Random.nextInt(max - min + 1) + min - f"Z$num%04d" - } - def getMonth: String = { val dateFormatter = DateTimeFormatter.ofPattern("MMM") LocalDate.now().format(dateFormatter).toUpperCase diff --git a/src/test/scala/uk/gov/hmrc/perftests/disareturns/constant/AppConfig.scala b/src/test/scala/uk/gov/hmrc/perftests/disareturns/constant/AppConfig.scala index 890ffc2..e3f0420 100644 --- a/src/test/scala/uk/gov/hmrc/perftests/disareturns/constant/AppConfig.scala +++ b/src/test/scala/uk/gov/hmrc/perftests/disareturns/constant/AppConfig.scala @@ -27,6 +27,7 @@ object AppConfig extends ServicesConfiguration { val ggSignInUrl = s"$authHost/government-gateway/session/login" val disaReturnsStubHost: String = baseUrlFor("disa-returns-stub") val reportingWindowPath: String = "/test-only/etmp/reporting-window-state" + val openObligationStatusPath: String = "/test-only/etmp/open-obligation-status/" val third_party_application_host: String = baseUrlFor("third-party-application") val ppns_host: String = baseUrlFor("push-pull-notification") val api_subscription_fields_host: String = baseUrlFor("api-subscription-fields") diff --git a/src/test/scala/uk/gov/hmrc/perftests/disareturns/models/TestDataSetupResult.scala b/src/test/scala/uk/gov/hmrc/perftests/disareturns/models/IsaManagers.scala similarity index 70% rename from src/test/scala/uk/gov/hmrc/perftests/disareturns/models/TestDataSetupResult.scala rename to src/test/scala/uk/gov/hmrc/perftests/disareturns/models/IsaManagers.scala index 55f7f8d..7e6a5c0 100644 --- a/src/test/scala/uk/gov/hmrc/perftests/disareturns/models/TestDataSetupResult.scala +++ b/src/test/scala/uk/gov/hmrc/perftests/disareturns/models/IsaManagers.scala @@ -16,8 +16,17 @@ package uk.gov.hmrc.perftests.disareturns.models -case class TestDataSetupResult( +case class IsaManagers( + isaManager: Seq[IsaManager] +) + +case class IsaManager( + zRef: String, bearerToken: String, - clientIds: List[String], - applicationIds: List[String] ) + +case class Applications(applications: Seq[Application]) + +case class Application(bearer: String, + clientId: String, + applicationId: String) diff --git a/src/test/scala/uk/gov/hmrc/perftests/disareturns/testSetup/AuthRequests.scala b/src/test/scala/uk/gov/hmrc/perftests/disareturns/testSetup/AuthRequests.scala index 08c81bc..1d67620 100644 --- a/src/test/scala/uk/gov/hmrc/perftests/disareturns/testSetup/AuthRequests.scala +++ b/src/test/scala/uk/gov/hmrc/perftests/disareturns/testSetup/AuthRequests.scala @@ -18,7 +18,6 @@ package uk.gov.hmrc.perftests.disareturns.testSetup import play.api.libs.ws.DefaultBodyWritables.writeableOf_String import play.api.libs.ws.ahc.StandaloneAhcWSClient -import uk.gov.hmrc.perftests.disareturns.Util.RandomDataGenerator.generateRandomISAReference import uk.gov.hmrc.perftests.disareturns.constant.AppConfig.ggSignInUrl import uk.gov.hmrc.perftests.disareturns.models.{SetupAssertions, SetupFailure} @@ -49,10 +48,10 @@ class AuthRequests(ws: StandaloneAhcWSClient)(implicit ec: ExecutionContext) ext | ] |}""".stripMargin - def getSubmissionBearerToken: Future[String] = { + def getSubmissionBearerToken(zRef: String): Future[String] = { val url = ggSignInUrl val bearerRegex = "Bearer\\s+\\S+".r - val payload = authRequestPayload.replaceAll("isaReference", generateRandomISAReference(1, 500)) + val payload = authRequestPayload.replaceAll("isaReference", zRef) ws.url(url) .addHttpHeaders( "Content-Type" -> "application/json" diff --git a/src/test/scala/uk/gov/hmrc/perftests/disareturns/testSetup/BaseRequests.scala b/src/test/scala/uk/gov/hmrc/perftests/disareturns/testSetup/BaseRequests.scala index 77db89a..799d12c 100644 --- a/src/test/scala/uk/gov/hmrc/perftests/disareturns/testSetup/BaseRequests.scala +++ b/src/test/scala/uk/gov/hmrc/perftests/disareturns/testSetup/BaseRequests.scala @@ -20,49 +20,83 @@ import akka.actor.ActorSystem import akka.stream.Materializer import org.scalatest.Assertions.cancel import play.api.libs.ws.ahc.StandaloneAhcWSClient -import uk.gov.hmrc.perftests.disareturns.models.TestDataSetupResult +import uk.gov.hmrc.perftests.disareturns.models.{Application, Applications, IsaManager, IsaManagers} import scala.concurrent.{ExecutionContext, Future} +import scala.util.control.NonFatal trait BaseRequests { - implicit val system: ActorSystem = ActorSystem("setup-system") - implicit val mat: Materializer = Materializer(system) - implicit val ec: ExecutionContext = system.dispatcher + implicit val system: ActorSystem = ActorSystem("setup-system") + implicit val mat: Materializer = Materializer(system) + implicit val ec: ExecutionContext = system.dispatcher val wsClient: StandaloneAhcWSClient = StandaloneAhcWSClient() - val authRequests = new AuthRequests(wsClient) - val thirdPartyApplicationRequests = new ThirdPartyApplicationRequests(wsClient) - val reportingWindowRequests = new ReportingWindowRequests(wsClient) - val noOfThirdPartyApplications = 10 + val authRequests = new AuthRequests(wsClient) + val thirdPartyApplicationRequests = new ThirdPartyApplicationRequests(wsClient) + val stubTestOnlyRequests = new ReportingWindowRequest(wsClient) + val noOfThirdPartyApplications = 10 + val noOfZReferences = 100 + + def setupTestData(): Future[IsaManagers] = { + + val zRefs: List[String] = + (0 until noOfZReferences) + .map(i => { + require(i < 10000, "Exceeded max ZRef limit (Z9999)") + f"Z$i%04d" + }) + .toList - def testDataSetup(): Future[TestDataSetupResult] = { val setup = for { - bearerToken <- authRequests.getSubmissionBearerToken - _ <- reportingWindowRequests.setReportingWindowsOpen() - apps <- Future.traverse((1 to noOfThirdPartyApplications).toList) { _ => - for { - app <- thirdPartyApplicationRequests.createClientApplication(bearerToken) - _ <- thirdPartyApplicationRequests.createNotificationBox(app.clientId) - } yield app - } - _ <- thirdPartyApplicationRequests.createSubscriptionFields() - } yield TestDataSetupResult( - bearerToken = bearerToken, - clientIds = apps.map(_.clientId), - applicationIds = apps.map(_.applicationId) - ) + _ <- stubTestOnlyRequests.setReportingWindowsOpen() + + isaManagers <- Future.traverse(zRefs) { zRef => + for { + bearerToken <- authRequests.getSubmissionBearerToken(zRef) + } yield IsaManager( + zRef = zRef, + bearerToken = bearerToken + ) + } + } yield IsaManagers(isaManager = isaManagers) + setup.recover { case e => cancel(s"Test has been aborted due to test setup failure: ${e.getMessage}") } } - def testDataCleanUp(setupData: TestDataSetupResult): Future[Unit] = - Future - .traverse(setupData.applicationIds)(appId => - thirdPartyApplicationRequests.deleteClientApplication(setupData.bearerToken, appId) + def setupApplications(): Future[Applications] = { + + val setupFutures: Seq[Future[Application]] = (1 to noOfThirdPartyApplications).map { _ => + for { + bearerToken <- authRequests.getSubmissionBearerToken("Z1234") + app <- thirdPartyApplicationRequests.createClientApplication(bearerToken) + _ <- thirdPartyApplicationRequests.createNotificationBox(app.clientId) + _ <- thirdPartyApplicationRequests.createSubscriptionFields() + } yield Application( + bearer = bearerToken, + clientId = app.clientId, + applicationId = app.applicationId ) - .map(_ => ()) - .andThen { case _ => - wsClient.close() - system.terminate() - } + } + + Future.sequence(setupFutures).map(Applications.apply).recover { case NonFatal(e) => + cancel(s"Test has been aborted due to test setup failure: ${e.getMessage}") + } + } + + def testDataCleanUp(applications: Applications): Future[Unit] = { + + val cleanupFutures: Seq[Future[Unit]] = applications.applications.map { app => + thirdPartyApplicationRequests + .deleteClientApplication(app.bearer, app.applicationId) + .recover { case NonFatal(e) => + println(s"Warning: failed to delete application ${app.applicationId}: ${e.getMessage}") + () + } + } + Future.sequence(cleanupFutures).map(_ => ()).andThen { case _ => + wsClient.close() + system.terminate() + } + } } diff --git a/src/test/scala/uk/gov/hmrc/perftests/disareturns/testSetup/ReportingWindowRequests.scala b/src/test/scala/uk/gov/hmrc/perftests/disareturns/testSetup/ReportingWindowRequest.scala similarity index 93% rename from src/test/scala/uk/gov/hmrc/perftests/disareturns/testSetup/ReportingWindowRequests.scala rename to src/test/scala/uk/gov/hmrc/perftests/disareturns/testSetup/ReportingWindowRequest.scala index 0095015..7d13f1a 100644 --- a/src/test/scala/uk/gov/hmrc/perftests/disareturns/testSetup/ReportingWindowRequests.scala +++ b/src/test/scala/uk/gov/hmrc/perftests/disareturns/testSetup/ReportingWindowRequest.scala @@ -27,7 +27,7 @@ import javax.inject.Singleton import scala.concurrent.{ExecutionContext, Future} @Singleton -class ReportingWindowRequests(ws: StandaloneAhcWSClient)(implicit ec: ExecutionContext) extends SetupAssertions { +class ReportingWindowRequest(ws: StandaloneAhcWSClient)(implicit ec: ExecutionContext) extends SetupAssertions { val reportingWindowPayload: JsObject = Json.obj("reportingWindowOpen" -> true) def setReportingWindowsOpen(): Future[Unit] =