From 6ef804d4b489b6fabacbe4038eb419cc52243312 Mon Sep 17 00:00:00 2001 From: John Axe Date: Tue, 10 Dec 2024 18:27:52 -0300 Subject: [PATCH] feat: Refactor random data generation to use RandomProvider trait Replaced randomDigit and related methods with the generalized RandomProvider trait for a cleaner and more extensible design. Enhanced readability and maintainability by introducing implicit providers for common data types and improving validation logic. Updated feeder implementations and other code references to use the new randomValue abstraction. --- .../performance/example/feeders/Feeders.scala | 50 +++++++++---------- project/Dependencies.scala | 18 +++---- .../gatling/feeders/RandomDigitFeeder.scala | 5 +- .../gatling/utils/RandomDataGenerators.scala | 2 +- .../gatling/feeders/RandomFeedersSpec.scala | 22 ++++---- 5 files changed, 48 insertions(+), 49 deletions(-) diff --git a/example/src/test/scala/org/galaxio/performance/example/feeders/Feeders.scala b/example/src/test/scala/org/galaxio/performance/example/feeders/Feeders.scala index c3a0d96..7b0d9f4 100644 --- a/example/src/test/scala/org/galaxio/performance/example/feeders/Feeders.scala +++ b/example/src/test/scala/org/galaxio/performance/example/feeders/Feeders.scala @@ -12,17 +12,17 @@ import java.time.{LocalDateTime, ZoneId} object Feeders { - private val newYearDate = LocalDateTime.of(2020, 1, 1, 0, 0) - private val goToWorkDate = LocalDateTime.of(2020, 1, 9, 9, 0) + private val newYearDate = LocalDateTime.of(2020, 1, 1, 0, 0) + private val goToWorkDate = LocalDateTime.of(2020, 1, 9, 9, 0) private val formatterShort: DateTimeFormatter = DateTimeFormatter.ofPattern("MM:dd") -// override implicit def configuration: GatlingConfiguration = GatlingConfiguration.loadForTest() + // override implicit def configuration: GatlingConfiguration = GatlingConfiguration.loadForTest() // date2pattern val timeShort: Feeder[String] = CurrentDateFeeder("timeShort", formatterShort) // random date +/- 5 minutes with "Australia/Sydney" timezone - val ausTZ: ZoneId = ZoneId.of("Australia/Sydney") + val ausTZ: ZoneId = ZoneId.of("Australia/Sydney") val timezoneRandom: Feeder[String] = RandomDateFeeder("timezoneRandom", 5, 5, "hh:mm:dd", unit = ChronoUnit.MINUTES, timezone = ausTZ) @@ -43,10 +43,10 @@ object Feeders { RandomDateRangeFeeder("startOfVacation", "endOfVacation", 14, "yyyy-MM-dd", LocalDateTime.now(), ChronoUnit.DAYS) // random Int - val randomDigit: Feeder[Int] = RandomDigitFeeder("randomDigit") - val randomRangeInt: Feeder[Int] = CustomFeeder[Int]("randomRangeInt", RandomDataGenerators.randomDigit(1, 50)) + val randomDigit: Feeder[Int] = RandomDigitFeeder("randomDigit") + val randomRangeInt: Feeder[Int] = CustomFeeder[Int]("randomRangeInt", RandomDataGenerators.randomValue(1, 50)) val randomRangeFloat: Feeder[Any] = - CustomFeeder("randomRangeFloat", RandomDataGenerators.randomDigit (1.toFloat, 10.toFloat)) + CustomFeeder("randomRangeFloat", RandomDataGenerators.randomValue(1.toFloat, 10.toFloat)) // random phone // +7 country code is default @@ -64,8 +64,8 @@ object Feeders { val randomUsaPhone: Feeder[String] = RandomPhoneFeeder("randomUsaPhone", usaPhoneFormats) - val phoneFormatsFromFile: String = "phoneTemplates/ru.json" - val ruMobileFormat: PhoneFormat = PhoneFormat( + val phoneFormatsFromFile: String = "phoneTemplates/ru.json" + val ruMobileFormat: PhoneFormat = PhoneFormat( countryCode = "+7", length = 10, areaCodes = Seq("903", "906", "908"), @@ -78,20 +78,20 @@ object Feeders { areaCodes = Seq("495", "495"), format = "X(XXX)XXX-XX-XX", ) - val ruPhoneFormats = List(ruMobileFormat, ruCityPhoneFormat) + val ruPhoneFormats: List[PhoneFormat] = List(ruMobileFormat, ruCityPhoneFormat) - val simplePhoneNumber: Feeder[String] = RandomPhoneFeeder("simplePhoneFeeder") - val randomPhoneNumberFromJson: Feeder[String] = + val simplePhoneNumber: Feeder[String] = RandomPhoneFeeder("simplePhoneFeeder") + val randomPhoneNumberFromJson: Feeder[String] = RandomPhoneFeeder("randomPhoneNumberFile", phoneFormatsFromFile) - val randomPhoneNumber: Feeder[String] = + val randomPhoneNumber: Feeder[String] = RandomPhoneFeeder("randomPhoneNumber", ruPhoneFormats: _*) - val randomE164PhoneNumberFromJson: Feeder[String] = + val randomE164PhoneNumberFromJson: Feeder[String] = RandomPhoneFeeder("randomE164PhoneNumberFile", phoneFormatsFromFile, TypePhone.E164PhoneNumber) - val randomE164PhoneNumber: Feeder[String] = + val randomE164PhoneNumber: Feeder[String] = RandomPhoneFeeder("randomE164PhoneNumber", TypePhone.E164PhoneNumber, ruMobileFormat, ruCityPhoneFormat) val randomTollFreePhoneNumberFromJson: Feeder[String] = RandomPhoneFeeder("randomTollFreePhoneNumberFile", phoneFormatsFromFile, TypePhone.TollFreePhoneNumber) - val randomTollFreePhoneNumber: Feeder[String] = + val randomTollFreePhoneNumber: Feeder[String] = RandomPhoneFeeder("randomTollFreePhoneNumber", TypePhone.TollFreePhoneNumber, ruMobileFormat) // random alphanumeric String with specified length @@ -115,21 +115,21 @@ object Feeders { // custom feeder from provided function val myCustomFeeder: Feeder[String] = CustomFeeder[String]("myParam", myFunction) - private val digitFeeder = RandomDigitFeeder("digit") + private val digitFeeder = RandomDigitFeeder("digit") private val stringFeeder = RandomStringFeeder("string") - private val phoneFeeder = RandomStringFeeder("phone") + private val phoneFeeder = RandomStringFeeder("phone") // Vault HC feeder - private val vaultUrl = System.getenv("vaultUrl") - private val secretPath = System.getenv("secretPath") - private val roleId = System.getenv("roleId") - private val secretId = System.getenv("secretId") - private val keys = List("k1", "k2", "k3") + private val vaultUrl = System.getenv("vaultUrl") + private val secretPath = System.getenv("secretPath") + private val roleId = System.getenv("roleId") + private val secretId = System.getenv("secretId") + private val keys = List("k1", "k2", "k3") val vaultFeeder: FeederBuilderBase[String] = VaultFeeder(vaultUrl, secretPath, roleId, secretId, keys) // Get separated values feeder from the source // SeparatedValuesFeeder will return Vector(Map(HOSTS -> host11), Map(HOSTS -> host12), Map(USERS -> user11), Map(HOSTS -> host21), Map(HOSTS -> host22), Map(USERS -> user21), Map(USERS -> user22), Map(USERS -> user23)) - val vaultData: FeederBuilderBase[String] = Vector( + val vaultData: FeederBuilderBase[String] = Vector( Map( "HOSTS" -> "host11,host12", "USERS" -> "user11", @@ -160,7 +160,7 @@ object Feeders { // random PAN val feederWithoutBinPAN: Feeder[String] = RandomPANFeeder("feederWithoutBinPAN") - val feederPAN: Feeder[String] = RandomPANFeeder("feederPAN", "421345", "541673") + val feederPAN: Feeder[String] = RandomPANFeeder("feederPAN", "421345", "541673") // random ITN val feederNatITN: Feeder[String] = RandomNatITNFeeder("feederNatITN") diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 145c1ad..2642d8d 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -21,26 +21,26 @@ object Dependencies { ).map(_ % "3.11.4" % Test) lazy val json4s: Seq[ModuleID] = Seq( - "org.json4s" %% "json4s-native" % "4.1.0-M5", - "org.json4s" %% "json4s-jackson" % "4.1.0-M5", + "org.json4s" %% "json4s-native" % "4.1.0-M8", + "org.json4s" %% "json4s-jackson" % "4.1.0-M8", ) lazy val pureConfig: Seq[ModuleID] = Seq( - "com.github.pureconfig" %% "pureconfig" % "0.17.7", - "com.github.pureconfig" %% "pureconfig-yaml" % "0.17.7", + "com.github.pureconfig" %% "pureconfig" % "0.17.8", + "com.github.pureconfig" %% "pureconfig-yaml" % "0.17.8", ) lazy val jackson: Seq[ModuleID] = Seq( - "com.fasterxml.jackson.dataformat" % "jackson-dataformat-yaml" % "2.17.0", - "com.fasterxml.jackson.core" % "jackson-core" % "2.17.0", + "com.fasterxml.jackson.dataformat" % "jackson-dataformat-yaml" % "2.18.2", + "com.fasterxml.jackson.core" % "jackson-core" % "2.18.2", ) lazy val scalaTest: Seq[ModuleID] = Seq( - "org.scalatest" %% "scalatest" % "3.2.18" % "test", + "org.scalatest" %% "scalatest" % "3.2.19" % "test", ) lazy val scalaCheck: Seq[ModuleID] = Seq( - "org.scalacheck" %% "scalacheck" % "1.18.0" % "test", + "org.scalacheck" %% "scalacheck" % "1.18.1" % "test", ) lazy val scalaTestPlus: Seq[ModuleID] = Seq( @@ -85,6 +85,6 @@ object Dependencies { ), ) - lazy val junit: Seq[ModuleID] = Seq("org.junit.jupiter" % "junit-jupiter-engine" % "5.10.2" % Test) + lazy val junit: Seq[ModuleID] = Seq("org.junit.jupiter" % "junit-jupiter-engine" % "5.11.3" % Test) } diff --git a/src/main/scala/org/galaxio/gatling/feeders/RandomDigitFeeder.scala b/src/main/scala/org/galaxio/gatling/feeders/RandomDigitFeeder.scala index 1cf7136..a3f6b4d 100644 --- a/src/main/scala/org/galaxio/gatling/feeders/RandomDigitFeeder.scala +++ b/src/main/scala/org/galaxio/gatling/feeders/RandomDigitFeeder.scala @@ -6,10 +6,7 @@ import org.galaxio.gatling.utils.RandomDataGenerators object RandomDigitFeeder { def apply(paramName: String): Feeder[Int] = { - require(paramName.nonEmpty, "paramName must not be empty") - - val randomValue = RandomDataGenerators.randomValue[Int]() - feeder[Int](paramName)(randomValue) + feeder[Int](paramName)(RandomDataGenerators.randomValue[Int]()) } } diff --git a/src/main/scala/org/galaxio/gatling/utils/RandomDataGenerators.scala b/src/main/scala/org/galaxio/gatling/utils/RandomDataGenerators.scala index 9b18f6c..166a5aa 100644 --- a/src/main/scala/org/galaxio/gatling/utils/RandomDataGenerators.scala +++ b/src/main/scala/org/galaxio/gatling/utils/RandomDataGenerators.scala @@ -79,7 +79,7 @@ object RandomDataGenerators { * if `length` is less than or equal to 0 */ def alphanumericString(length: Int): String = - randomString(Random.alphanumeric.mkString)(length) + Random.alphanumeric.take(length).mkString /** Generates a random string of letters with the specified length. * diff --git a/src/test/scala/org/galaxio/gatling/feeders/RandomFeedersSpec.scala b/src/test/scala/org/galaxio/gatling/feeders/RandomFeedersSpec.scala index a8a0ec2..cef8430 100644 --- a/src/test/scala/org/galaxio/gatling/feeders/RandomFeedersSpec.scala +++ b/src/test/scala/org/galaxio/gatling/feeders/RandomFeedersSpec.scala @@ -107,16 +107,18 @@ class RandomFeedersSpec extends AnyFlatSpec with Matchers with ScalaCheckDrivenP } it should "create RandomStringFeeder with specified param length interval" in { - forAll(rndString, positiveInt) { (paramName, length) => - whenever(paramName.nonEmpty) { - RandomStringFeeder(paramName, length) - .take(50) - .foreach(record => - withClue(s"Invalid RandomStringFeeder with specified param length interval: $record, ") { - assert(record(paramName).length == length) - }, - ) - } + forAll(rndString.suchThat(_.nonEmpty), positiveInt.suchThat(_ > 0)) { (paramName, length) => + RandomStringFeeder(paramName, length) + .take(50) + .foreach { record => + withClue(s"Invalid record: ${record.toString}, expected key '$paramName' with length $length, ") { + record + .get(paramName) + .fold( + fail(s"Key '$paramName' is missing in the record."), + )(value => assert(value.length == length)) + } + } } }