Skip to content

Commit

Permalink
feat: integrate new enterprise start mecanism depending on deployment…
Browse files Browse the repository at this point in the history
…, closes HYB-567

Modifications:
* Drop unexisting methods
* Integrate new enterprise start depending on deployment
  • Loading branch information
tpetillot committed Apr 8, 2024
1 parent 6381439 commit e427bc9
Show file tree
Hide file tree
Showing 7 changed files with 26 additions and 167 deletions.
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ githubPath := "gatling/gatling-sbt-plugin"

libraryDependencies ++= Seq(
"org.scalatest" %% "scalatest" % "3.2.18" % Test,
"io.gatling" % "gatling-enterprise-plugin-commons" % "1.9.0-M13"
"io.gatling" % "gatling-enterprise-plugin-commons" % "1.9.0-M14"
)

scriptedLaunchOpts := {
Expand Down
52 changes: 5 additions & 47 deletions src/main/scala/io/gatling/sbt/GatlingKeys.scala
Original file line number Diff line number Diff line change
Expand Up @@ -51,18 +51,8 @@ object GatlingKeys {
|$documentationReference.
|""".stripMargin)

val enterpriseSimulationClass = settingKey[String](s"""Simulation class name, used when creating a simulation.
|${systemPropertyDescription("gatling.enterprise.simulationClass")}.
|$documentationReference.
|""".stripMargin)

val enterpriseTeamId = settingKey[String](s"""Team ID on Gatling Enterprise. Used as default team on simulation and package on creation.
|${systemPropertyDescription("gatling.enterprise.teamId")}.
|$documentationReference.
|""".stripMargin)

val enterpriseSimulationId =
settingKey[String](s"""Simulation ID on Gatling Enterprise. Used by `enterpriseStart` (and `enterprisePackage` if `enterprisePackageId` isn't configured).
settingKey[String](s"""Simulation ID on Gatling Enterprise. Used by `enterprisePackage` if `enterprisePackageId` isn't configured.
|${systemPropertyDescription("gatling.enterprise.simulationId")}.
|$documentationReference.
|""".stripMargin)
Expand All @@ -81,34 +71,6 @@ object GatlingKeys {
|""".stripMargin
)

val enterpriseSimulationSystemProperties = settingKey[Map[String, String]](
s"""Provides additional system properties when starting a simulation, in addition to the ones which may already be defined for that simulation.
|${systemPropertyDescription("gatling.enterprise.simulationSystemProperties")} with the format key1=value1,key2=value2
|$documentationReference.
|""".stripMargin
)

val enterpriseSimulationSystemPropertiesString = settingKey[String](
s"""Alternative to enterpriseSimulationSystemProperties. Use the format key1=value1,key2=value2
|${systemPropertyDescription("gatling.enterprise.simulationSystemProperties")}.
|$documentationReference.
|""".stripMargin
)

val enterpriseSimulationEnvironmentVariables = settingKey[Map[String, String]](
s"""Provides additional environment variables when starting a simulation, in addition to the ones which may already be defined for that simulation.
|${systemPropertyDescription("gatling.enterprise.simulationEnvironmentVariables")} with the format key1=value1,key2=value2
|$documentationReference.
|""".stripMargin
)

val enterpriseSimulationEnvironmentVariablesString = settingKey[String](
s"""Alternative to enterpriseSimulationEnvironmentVariables. Use the format key1=value1,key2=value2.
|${systemPropertyDescription("gatling.enterprise.simulationEnvironmentVariables")}.
|$documentationReference.
|""".stripMargin
)

// Enterprise Tasks
val enterprisePackage = taskKey[File](s"""Build a package for Gatling Enterprise.
|$documentationReference.
Expand All @@ -120,17 +82,13 @@ object GatlingKeys {
|""".stripMargin
)

val enterpriseStart = inputKey[Unit](s"""Start a simulation for Gatling Enterprise. Require `enterpriseApiToken`.
|In batch mode, if `enterpriseSimulationId` isn't configured, requires:
|- `enterpriseSimulationClass` if there's more than one simulation class defined
|- `enterpriseTeamId` if there's more than one team related to the API Token
|- `enterpriseTeamId` if there's more than one team related to the API Token
|- `enterprisePackageId` if you want to use an existing package on created simulation
val enterpriseDeploy = taskKey[Unit]("Deploy a package and configured simulations")

val enterpriseStart = inputKey[Unit](s"""Start a simulation deployed with `enterpriseDeploy`. Require `enterpriseApiToken`.
|In batch mode, simulation name is required as first argument.
|$documentationReference.
|""".stripMargin)

val enterpriseDeploy = taskKey[Unit]("Deploy a package and configured simulations")

val assembly = taskKey[File](
"Builds a package for Gatling Enterprise (deprecated, please use 'Gatling / enterprisePackage' or 'GatlingIt / enterprisePackage' instead)."
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

package io.gatling.sbt.settings.gatling

import io.gatling.plugin.client.http.HttpEnterpriseClient
import io.gatling.plugin.client.HttpEnterpriseClient
import io.gatling.plugin.exceptions.UnsupportedClientException
import io.gatling.sbt.BuildInfo
import io.gatling.sbt.GatlingKeys._
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,29 +47,23 @@ object EnterpriseSettings {
def settings(config: Configuration) = {
val taskPackage = new TaskEnterprisePackage(config)
val taskUpload = new TaskEnterpriseUpload(config, taskPackage)
val taskStart = new TaskEnterpriseStart(config, taskPackage)
val taskDeploy = new TaskEnterpriseDeploy(config, taskPackage)
val taskStart = new TaskEnterpriseStart(config, taskDeploy)

Seq(
config / enterpriseUrl := new URL("https://cloud.gatling.io"),
config / enterprisePackage := taskPackage.buildEnterprisePackage.value,
config / enterpriseUpload := taskUpload.uploadEnterprisePackage.value,
config / enterpriseStart := taskStart.enterpriseSimulationStart.evaluated,
config / enterpriseDeploy := taskDeploy.enterpriseDeploy.value,
config / enterpriseStart := taskStart.enterpriseSimulationStart.evaluated,
config / enterprisePackageId := sys.props.get("gatling.enterprise.packageId").getOrElse(""),
config / enterpriseTeamId := sys.props.get("gatling.enterprise.teamId").getOrElse(""),
config / enterpriseSimulationId := sys.props.get("gatling.enterprise.simulationId").getOrElse(""),
config / enterpriseControlPlaneUrl := sys.props
.get("gatling.enterprise.controlPlaneUrl")
.map(configString => new URL(configString)),
config / waitForRunEnd := jl.Boolean.getBoolean("gatling.enterprise.waitForRunEnd"),
config / enterpriseSimulationSystemProperties := Map.empty,
config / enterpriseSimulationSystemPropertiesString := sys.props.get("gatling.enterprise.simulationSystemProperties").getOrElse(""),
config / enterpriseSimulationEnvironmentVariables := Map.empty,
config / enterpriseSimulationEnvironmentVariablesString := sys.props.get("gatling.enterprise.simulationEnvironmentVariables").getOrElse(""),
config / enterpriseApiToken := sys.props.get("gatling.enterprise.apiToken").orElse(sys.env.get("GATLING_ENTERPRISE_API_TOKEN")).getOrElse(""),
config / packageBin := (config / enterprisePackage).value, // If we directly use config / enterprisePackage for publishing, classifiers (-tests or -it) are not correctly handled.
config / enterpriseSimulationClass := sys.props.get("gatling.enterprise.simulationClass").getOrElse("")
config / packageBin := (config / enterprisePackage).value // If we directly use config / enterprisePackage for publishing, classifiers (-tests or -it) are not correctly handled.
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,9 @@

package io.gatling.sbt.settings.gatling

import java.util.UUID

import scala.jdk.CollectionConverters._
import scala.util.{ Failure, Try }

import io.gatling.plugin.exceptions._
import io.gatling.plugin.model.Simulation

import sbt.Configuration
import sbt.internal.util.ManagedLogger
Expand All @@ -40,58 +36,17 @@ class RecoverEnterprisePluginException(config: Configuration) {
|""".stripMargin
)
Failure(ErrorAlreadyLoggedException)
case e: SeveralTeamsFoundException =>
val teams = e.getAvailableTeams.asScala
logger.error(s"""More than 1 team were found while creating a simulation.
|Available teams:
|${teams.map(team => s"- ${team.id} (${team.name})").mkString("\n")}
|Specify the team you want to use with -Dgatling.enterprise.teamId=<teamId>, or add the configuration to your build.sbt, e.g.:
|${config.id} / enterpriseTeamId := "${teams.head.id}"
|""".stripMargin)
Failure(ErrorAlreadyLoggedException)
case e: SeveralSimulationClassNamesFoundException =>
val simulationClasses = e.getAvailableSimulationClassNames.asScala
logger.error(
s"""Several simulation classes were found
|${simulationClasses.map("- " + _).mkString("\n")}
|Specify the simulation you want to use with -Dgatling.enterprise.simulationClass=<className>, or add the configuration to your build.sbt, e.g.:
|${config.id} / simulationClass := "${simulationClasses.head}"
|""".stripMargin
)
Failure(ErrorAlreadyLoggedException)
case e: UserQuitException =>
logger.warn(e.getMessage)
Failure(ErrorAlreadyLoggedException)
case e: SimulationStartException =>
if (e.isCreated) {
logCreatedSimulation(logger, e.getSimulation)
}
logSimulationConfiguration(logger, simulationIdSetting = None, waitForRunEndSetting = false, e.getSimulation.id)
Failure(e.getCause)
}

protected def logCreatedSimulation(logger: ManagedLogger, simulation: Simulation): Unit =
logger.info(s"Created simulation named ${simulation.name} with ID '${simulation.id}'")

protected def logSimulationConfiguration(
logger: ManagedLogger,
simulationIdSetting: Option[UUID],
waitForRunEndSetting: Boolean,
simulationId: UUID
): Unit = {
if (simulationIdSetting.isEmpty) {
logger.info(
s"""To start again the same simulation, specify -Dgatling.enterprise.simulationId=$simulationId, or add the configuration to your SBT settings, e.g.:
|${config.id} / enterpriseSimulationId := "$simulationId"
|""".stripMargin
)
}
protected def logSimulationConfiguration(logger: ManagedLogger, waitForRunEndSetting: Boolean): Unit =
if (!waitForRunEndSetting) {
logger.info(
s"""To wait for the end of the run when starting a simulation on Gatling Enterprise, specify -Dgatling.enterprise.waitForRunEnd=true, or add the configuration to your SBT settings, e.g.:
|${config.id} / waitForRunEnd := true
|""".stripMargin
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,16 @@ package io.gatling.sbt.settings.gatling
import scala.util.Try

import io.gatling.plugin.deployment.DeploymentConfiguration
import io.gatling.plugin.model.BuildTool
import io.gatling.plugin.model._
import io.gatling.sbt.BuildInfo
import io.gatling.sbt.GatlingKeys._
import io.gatling.sbt.settings.gatling.EnterpriseUtils.*
import io.gatling.sbt.settings.gatling.EnterpriseUtils._

import sbt._
import sbt.Keys._

class TaskEnterpriseDeploy(config: Configuration, enterprisePackage: TaskEnterprisePackage) extends RecoverEnterprisePluginException(config) {
val enterpriseDeploy: InitializeTask[Unit] = Def.task {
val enterpriseDeploy: InitializeTask[DeploymentInfo] = Def.task {
val logger = streams.value.log
val enterprisePlugin = EnterprisePluginTask.batchEnterprisePluginTask(config).value
val packageFile = enterprisePackage.buildEnterprisePackage.value
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,20 @@

package io.gatling.sbt.settings.gatling

import java.{ util => ju }
import java.util.UUID

import scala.jdk.CollectionConverters._
import scala.util.{ Failure, Success, Try }

import io.gatling.plugin.EnterprisePlugin
import io.gatling.plugin.model.{ RunSummary, SimulationStartResult }
import io.gatling.plugin.util.PropertiesParserUtil
import io.gatling.plugin.model.RunSummary
import io.gatling.sbt.GatlingKeys._
import io.gatling.sbt.settings.gatling.EnterprisePluginTask._
import io.gatling.sbt.settings.gatling.EnterpriseUtils._

import sbt.{ Configuration, Def }
import sbt.Keys._
import sbt.complete.DefaultParsers._
import sbt.internal.util.ManagedLogger

class TaskEnterpriseStart(config: Configuration, enterprisePackage: TaskEnterprisePackage) extends RecoverEnterprisePluginException(config) {
class TaskEnterpriseStart(config: Configuration, taskEnterpriseDeploy: TaskEnterpriseDeploy) extends RecoverEnterprisePluginException(config) {

private val enterprisePluginTask = Def.inputTaskDyn[EnterprisePlugin] {
val enterpriseStartCommand = EnterpriseStartCommand.parser.parsed
Expand All @@ -45,66 +41,22 @@ class TaskEnterpriseStart(config: Configuration, enterprisePackage: TaskEnterpri
val enterpriseSimulationStart: InitializeInputTask[Unit] = Def.inputTask {
val logger = streams.value.log
val enterprisePlugin = enterprisePluginTask.evaluated
val file = enterprisePackage.buildEnterprisePackage.value
val simulationIdSetting = configOptionalString(config / enterpriseSimulationId).value.map(UUID.fromString)
val simulationClassname = configOptionalString(config / enterpriseSimulationClass).value
val systemProperties = selectProperties((config / enterpriseSimulationSystemProperties).value, (config / enterpriseSimulationSystemPropertiesString).value)
val environmentVariables =
selectProperties((config / enterpriseSimulationEnvironmentVariables).value, (config / enterpriseSimulationEnvironmentVariablesString).value)
val deploymentInfo = taskEnterpriseDeploy.enterpriseDeploy.value
val waitForRunEndSetting = waitForRunEnd.value
val simulationName = spaceDelimited("<arg>").parsed.headOption

val simulationStartResult =
Try {
simulationIdSetting match {
case Some(simulationId) =>
logger.info(s"Uploading and starting simulation...")
enterprisePlugin.uploadPackageAndStartSimulation(simulationId, systemProperties, environmentVariables, simulationClassname.orNull, file)
case _ =>
logger.info("Creating and starting simulation...")
val defaultSimulationTeamId = configOptionalString(config / enterpriseTeamId).value.map(UUID.fromString)
val packageId = configOptionalString(config / enterprisePackageId).value.map(UUID.fromString)
val groupId = (config / organization).value
val artifactId = (config / normalizedName).value
enterprisePlugin.createAndStartSimulation(
defaultSimulationTeamId.orNull,
groupId,
artifactId,
simulationClassname.orNull,
packageId.orNull,
systemProperties,
environmentVariables,
file
)
}
}.recoverWith(recoverEnterprisePluginException(logger)).get
val runSummary = enterprisePlugin.startSimulation(simulationName.orNull, deploymentInfo)

logStartResult(logger, simulationStartResult, simulationIdSetting, waitForRunEndSetting, baseUrl = (config / enterpriseUrl).value)
logStartResult(logger, runSummary, waitForRunEndSetting, baseUrl = (config / enterpriseUrl).value)

maybeWaitForRunEnd(logger, enterprisePlugin, waitForRunEndSetting, simulationStartResult.runSummary)
maybeWaitForRunEnd(logger, enterprisePlugin, waitForRunEndSetting, runSummary)
}

private def selectProperties(propertiesMap: Map[String, String], propertiesString: String): ju.Map[String, String] =
if (propertiesMap == null || propertiesMap.isEmpty) {
PropertiesParserUtil.parseProperties(propertiesString)
} else {
propertiesMap.asJava
}

private def logStartResult(
logger: ManagedLogger,
simulationStartResult: SimulationStartResult,
simulationIdSetting: Option[UUID],
waitForRunEndSetting: Boolean,
baseUrl: sbt.URL
): Unit = {
if (simulationStartResult.createdSimulation) {
logCreatedSimulation(logger, simulationStartResult.simulation)
}

logSimulationConfiguration(logger, simulationIdSetting, waitForRunEndSetting, simulationStartResult.simulation.id)
private def logStartResult(logger: ManagedLogger, runSummary: RunSummary, waitForRunEndSetting: Boolean, baseUrl: sbt.URL): Unit = {
logSimulationConfiguration(logger, waitForRunEndSetting)

val reportsUrl = baseUrl.toExternalForm + simulationStartResult.runSummary.reportsPath
logger.success(s"Simulation successfully started; once running, reports will be available at $reportsUrl")
val reportsUrl = baseUrl.toExternalForm + runSummary.reportsPath
logger.success(s"Simulation successfully started; reports available at $reportsUrl")
}

private def maybeWaitForRunEnd(
Expand Down

0 comments on commit e427bc9

Please sign in to comment.