diff --git a/js-simulation/package-lock.json b/js-simulation/package-lock.json index c7d098e..74b2337 100644 --- a/js-simulation/package-lock.json +++ b/js-simulation/package-lock.json @@ -26,7 +26,7 @@ "@jspm/core": "2.1.0", "archiver": "7.0.1", "commander": "12.1.0", - "esbuild": "0.24.0", + "esbuild": "0.24.2", "esbuild-plugin-tsc": "0.4.0", "import-meta-resolve": "4.1.0", "make-fetch-happen": "14.0.3", @@ -39,11 +39,11 @@ "devDependencies": { "@types/archiver": "6.0.3", "@types/make-fetch-happen": "10.0.4", - "@types/node": "18.19.67", + "@types/node": "18.19.71", "@types/readline-sync": "1.4.8", - "prettier": "3.4.1", + "prettier": "3.4.2", "rimraf": "6.0.1", - "typescript": "5.7.2" + "typescript": "5.7.3" } }, "../tmp/cli/package/node_modules/@esbuild/darwin-arm64": { @@ -625,11 +625,11 @@ "devDependencies": { "@types/jest": "29.5.14", "jest": "29.7.0", - "prettier": "3.4.1", + "prettier": "3.4.2", "rimraf": "6.0.1", "ts-jest": "29.2.5", "ts-node": "10.9.2", - "typescript": "5.7.2" + "typescript": "5.7.3" } }, "../tmp/core/package/node_modules/@ampproject/remapping": { @@ -4423,11 +4423,11 @@ "devDependencies": { "@types/jest": "29.5.14", "jest": "29.7.0", - "prettier": "3.4.1", + "prettier": "3.4.2", "rimraf": "6.0.1", "ts-jest": "29.2.5", "ts-node": "10.9.2", - "typescript": "5.7.2" + "typescript": "5.7.3" } }, "../tmp/http/package/node_modules/@ampproject/remapping": { @@ -8219,7 +8219,7 @@ "version": "0.0.0", "license": "Apache-2.0", "devDependencies": { - "typescript": "5.7.2" + "typescript": "5.7.3" } }, "../tmp/jvm-types/package/node_modules/typescript": { diff --git a/js/core/src/dummy.ts b/js/core/src/dummy.ts new file mode 100644 index 0000000..43d1919 --- /dev/null +++ b/js/core/src/dummy.ts @@ -0,0 +1,132 @@ +import { CoreDsl as JvmCoreDsl } from "@gatling.io/jvm-types"; +import JvmDummyBuilder = io.gatling.javaapi.core.DummyBuilder; + +import { Expression, SessionTo, SessionTransform, underlyingSessionTo, underlyingSessionTransform } from "./session"; +import { ActionBuilder } from "./structure"; + +export interface DummyBuilder extends ActionBuilder { + /** + * Set the successful outcome of the dummy action. If undefined, the outcome is a success. + * + * @param newSuccess - if the outcome of the dummy action must be a success + * @return a new DummyBuilder with the success outcome defined + */ + withSuccess(newSuccess: boolean): DummyBuilder; + + /** + * Set the successful outcome of the dummy action. If undefined, the outcome is a success. + * + * @param newSuccess - if the outcome of the dummy action must be a success, as a Gatling EL String + * @return a new DummyBuilder with the success outcome defined + */ + withSuccess(newSuccess: string): DummyBuilder; + + /** + * Set the successful outcome of the dummy action. If undefined, the outcome is a success. + * + * @param newSuccess - if the outcome of the dummy action must be a success, as a function + * @return a new DummyBuilder with the success outcome defined + */ + withSuccess(newSuccess: SessionTo): DummyBuilder; + + /** + * Modify the Session like an exec(f) block would, as part of this dummy action + * + * @param f - a function to return an updated Session + * @return a new DummyBuilder with the Session function defined + */ + withSessionUpdate(f: SessionTransform): DummyBuilder; +} + +const wrapDummyBuilder = (_underlying: JvmDummyBuilder): DummyBuilder => ({ + _underlying, + withSuccess: (newSuccess: Expression | string) => + wrapDummyBuilder( + typeof newSuccess === "function" + ? _underlying.withSuccess(underlyingSessionTo(newSuccess)) + : typeof newSuccess === "string" + ? _underlying.withSuccess(newSuccess) + : _underlying.withSuccess(newSuccess) + ), + withSessionUpdate: (f: SessionTransform) => + wrapDummyBuilder(_underlying.withSessionUpdate(underlyingSessionTransform(f))) +}); + +export interface DummyFunction { + /** + * Bootstrap a builder for performing a dummy action that emulates a network remote call + * + * @param actionName - the name of the action, as a Gatling EL String + * @param responseTime - the response time of the action in milliseconds + * @return a DummyBuilder + */ + (actionName: string, responseTime: number): DummyBuilder; + + /** + * Bootstrap a builder for performing a dummy action that emulates a network remote call + * + * @param actionName - the name of the action, as a Gatling EL String + * @param responseTime - the response time of the action in milliseconds, as a Gatling EL String + * @return a DummyBuilder + */ + (actionName: string, responseTime: string): DummyBuilder; + + /** + * Bootstrap a builder for performing a dummy action that emulates a network remote call + * + * @param actionName - the name of the action, as a Gatling EL String + * @param responseTime - the response time of the action in milliseconds, as a function + * @return a DummyBuilder + */ + (actionName: string, responseTime: SessionTo): DummyBuilder; + + /** + * Bootstrap a builder for performing a dummy action that emulates a network remote call + * + * @param actionName - the name of the action, as a function + * @param responseTime - the response time of the action in milliseconds + * @return a DummyBuilder + */ + (actionName: SessionTo, responseTime: number): DummyBuilder; + + /** + * Bootstrap a builder for performing a dummy action that emulates a network remote call + * + * @param actionName - the name of the action, as a Gatling EL String + * @param responseTime - the response time of the action in milliseconds, as function + * @return a DummyBuilder + */ + (actionName: SessionTo, responseTime: string): DummyBuilder; + + /** + * Bootstrap a builder for performing a dummy action that emulates a network remote call + * + * @param actionName - the name of the action, as a function + * @param responseTime - the response time of the action in milliseconds, as a function + * @return a DummyBuilder + */ + (actionName: SessionTo, responseTime: SessionTo): DummyBuilder; +} + +export const dummy: DummyFunction = ( + actionName: Expression, + responseTime: Expression | string +): DummyBuilder => { + if (typeof actionName === "function") { + if (typeof responseTime === "function") { + return wrapDummyBuilder(JvmCoreDsl.dummy(underlyingSessionTo(actionName), underlyingSessionTo(responseTime))); + } else if (typeof responseTime === "string") { + return wrapDummyBuilder(JvmCoreDsl.dummy(underlyingSessionTo(actionName), responseTime)); + } else { + return wrapDummyBuilder(JvmCoreDsl.dummy(underlyingSessionTo(actionName), responseTime)); + } + } else { + if (typeof responseTime === "function") { + return wrapDummyBuilder(JvmCoreDsl.dummy(actionName, underlyingSessionTo(responseTime))); + } else if (typeof responseTime === "string") { + return wrapDummyBuilder(JvmCoreDsl.dummy(actionName, responseTime)); + } else { + return wrapDummyBuilder(JvmCoreDsl.dummy(actionName, responseTime)); + } + } +}; diff --git a/js/core/src/index.test.ts b/js/core/src/index.test.ts index e125a7f..87a6b01 100644 --- a/js/core/src/index.test.ts +++ b/js/core/src/index.test.ts @@ -38,7 +38,8 @@ import { stressPeakUsers, tsv, ProtocolBuilder, - GlobalStore + GlobalStore, + dummy } from "./index"; const runSimulationMock = (_: Simulation): void => {}; @@ -453,7 +454,18 @@ const scn = scenario("scenario") (session) => true ) .crashLoadGeneratorIf("#{message}", (session) => true) - .crashLoadGeneratorIf((session) => "message", "#{condition}"); + .crashLoadGeneratorIf((session) => "message", "#{condition}") + .exec( + dummy("Dummy action 1", 500), + dummy("Dummy action 2", "#{dummy_response_time}"), + dummy("Dummy action 3", (session) => 500), + dummy((session) => "Dummy action 4", 500), + dummy((session) => "Dummy action 5", "#{dummy_response_time}"), + dummy( + (session) => "Dummy action 6", + (session) => 500 + ) + ); //registerPebbleExtensions((io.pebbletemplates.pebble.extension.Extension) null); diff --git a/js/core/src/index.ts b/js/core/src/index.ts index 86bf014..12241d3 100644 --- a/js/core/src/index.ts +++ b/js/core/src/index.ts @@ -20,6 +20,7 @@ export * from "./body"; export * from "./checks"; export * from "./closedInjection"; export * from "./common"; +export { dummy, DummyBuilder, DummyFunction } from "./dummy"; export * from "./feeders"; export * from "./filters"; export { GlobalStore } from "./globalStore"; diff --git a/js/jvm-types/gatling.d.ts b/js/jvm-types/gatling.d.ts index 1f859d2..8506d99 100644 --- a/js/jvm-types/gatling.d.ts +++ b/js/jvm-types/gatling.d.ts @@ -746,6 +746,18 @@ declare namespace io.gatling.javaapi.core { toString(): string; } // end CoreDsl } // end namespace io.gatling.javaapi.core +declare namespace io.gatling.javaapi.core { + class DummyBuilder /* extends java.lang.Object implements ActionBuilder*/ { + asScala(): any /*io.gatling.core.action.builder.ActionBuilder*/; + equals(arg0: any /*java.lang.Object*/): boolean; + toChainBuilder(): ChainBuilder; + toString(): string; + withSessionUpdate(arg0: Func): DummyBuilder; + withSuccess(arg0: Func): DummyBuilder; + withSuccess(arg0: boolean): DummyBuilder; + withSuccess(arg0: string): DummyBuilder; + } // end DummyBuilder +} // end namespace io.gatling.javaapi.core declare namespace io.gatling.javaapi.core { class Filter$AllowList /* extends Filter*/ { asScala(): W; @@ -1384,7 +1396,8 @@ declare namespace io.gatling.javaapi.core { before(): void; equals(arg0: any /*java.lang.Object*/): boolean; params( - arg0: any /*io.gatling.core.config.GatlingConfiguration*/ + arg0: any /*io.gatling.core.config.GatlingConfiguration*/, + arg1: string ): any /*io.gatling.core.scenario.SimulationParams*/; setUp(...arg0: PopulationBuilder[]): Simulation$SetUp; setUp(arg0: java.util.List): Simulation$SetUp; @@ -3925,7 +3938,6 @@ declare namespace java.util.stream { flatMapToLong(arg0: Func): any /*java.util.stream.LongStream*/; forEach(arg0: Consumer): void; forEachOrdered(arg0: Consumer): void; - gather(arg0: any /*java.util.stream.Gatherer*/): Stream; isParallel(): boolean; iterator(): java.util.Iterator; limit(arg0: long): Stream; diff --git a/js/jvm-types/index.ts b/js/jvm-types/index.ts index f671eb7..58cf71b 100644 --- a/js/jvm-types/index.ts +++ b/js/jvm-types/index.ts @@ -588,6 +588,15 @@ interface CoreDslStatic { constantConcurrentUsers(arg0: int): io.gatling.javaapi.core.ClosedInjectionStep$Constant; rampConcurrentUsers(arg0: int): io.gatling.javaapi.core.ClosedInjectionStep$Ramp; incrementConcurrentUsers(arg0: int): io.gatling.javaapi.core.ClosedInjectionStep$Stairs; + dummy(arg0: string, arg1: int): io.gatling.javaapi.core.DummyBuilder; + dummy(arg0: string, arg1: string): io.gatling.javaapi.core.DummyBuilder; + dummy(arg0: string, arg1: Func): io.gatling.javaapi.core.DummyBuilder; + dummy(arg0: Func, arg1: int): io.gatling.javaapi.core.DummyBuilder; + dummy(arg0: Func, arg1: string): io.gatling.javaapi.core.DummyBuilder; + dummy( + arg0: Func, + arg1: Func + ): io.gatling.javaapi.core.DummyBuilder; csv(arg0: string): io.gatling.javaapi.core.FeederBuilder$Batchable; csv(arg0: string, arg1: any /*char*/): io.gatling.javaapi.core.FeederBuilder$Batchable; separatedValues(arg0: string, arg1: any /*char*/): io.gatling.javaapi.core.FeederBuilder$Batchable; @@ -1234,6 +1243,13 @@ interface DoWhileStatic { export const DoWhile: DoWhileStatic = Java.type("io.gatling.javaapi.core.loop.DoWhile"); +interface DummyBuilderStatic { + readonly class: any; + new (arg0: any /*scala.Function1*/, arg1: any /*scala.Function1*/): io.gatling.javaapi.core.DummyBuilder; +} + +export const DummyBuilder: DummyBuilderStatic = Java.type("io.gatling.javaapi.core.DummyBuilder"); + interface DurationStatic { readonly class: any; between(arg0: any /*java.time.temporal.Temporal*/, arg1: any /*java.time.temporal.Temporal*/): java.time.Duration; diff --git a/jvm/build.sbt b/jvm/build.sbt index e7e4bc6..ad18214 100644 --- a/jvm/build.sbt +++ b/jvm/build.sbt @@ -16,7 +16,7 @@ Global / gatlingDevelopers := Seq( val compilerRelease = 21 val graalvmJdkVersion = "23.0.1" val graalvmJsVersion = "24.1.1" -val gatlingVersion = "3.13.1" +val gatlingVersion = "3.13.2" // bit weird cause this is not a dependency of this project val gatlingEnterpriseComponentPluginVersion = "1.11.0" diff --git a/jvm/java2ts/src/main/java/io/gatling/javaapi/package-info.java b/jvm/java2ts/src/main/java/io/gatling/javaapi/package-info.java index 296cd4e..2b62bc5 100644 --- a/jvm/java2ts/src/main/java/io/gatling/javaapi/package-info.java +++ b/jvm/java2ts/src/main/java/io/gatling/javaapi/package-info.java @@ -54,6 +54,7 @@ @Type(value = io.gatling.javaapi.core.ClosedInjectionStep.Stairs.class, export = true), @Type(value = io.gatling.javaapi.core.ClosedInjectionStep.StairsWithTime.class, export = true), @Type(value = io.gatling.javaapi.core.ClosedInjectionStep.Composite.class, export = true), + @Type(value = io.gatling.javaapi.core.DummyBuilder.class, export = true), @Type(value = io.gatling.javaapi.core.FeederBuilder.class, export = true), @Type(value = io.gatling.javaapi.core.FeederBuilder.FileBased.class, export = true), @Type(value = io.gatling.javaapi.core.FeederBuilder.Batchable.class, export = true), diff --git a/ts-simulation/package-lock.json b/ts-simulation/package-lock.json index 319401b..5040e37 100644 --- a/ts-simulation/package-lock.json +++ b/ts-simulation/package-lock.json @@ -27,7 +27,7 @@ "@jspm/core": "2.1.0", "archiver": "7.0.1", "commander": "12.1.0", - "esbuild": "0.24.0", + "esbuild": "0.24.2", "esbuild-plugin-tsc": "0.4.0", "import-meta-resolve": "4.1.0", "make-fetch-happen": "14.0.3", @@ -40,11 +40,11 @@ "devDependencies": { "@types/archiver": "6.0.3", "@types/make-fetch-happen": "10.0.4", - "@types/node": "18.19.67", + "@types/node": "18.19.71", "@types/readline-sync": "1.4.8", - "prettier": "3.4.1", + "prettier": "3.4.2", "rimraf": "6.0.1", - "typescript": "5.7.2" + "typescript": "5.7.3" } }, "../tmp/cli/package/node_modules/@esbuild/darwin-arm64": { @@ -626,11 +626,11 @@ "devDependencies": { "@types/jest": "29.5.14", "jest": "29.7.0", - "prettier": "3.4.1", + "prettier": "3.4.2", "rimraf": "6.0.1", "ts-jest": "29.2.5", "ts-node": "10.9.2", - "typescript": "5.7.2" + "typescript": "5.7.3" } }, "../tmp/core/package/node_modules/@ampproject/remapping": { @@ -4424,11 +4424,11 @@ "devDependencies": { "@types/jest": "29.5.14", "jest": "29.7.0", - "prettier": "3.4.1", + "prettier": "3.4.2", "rimraf": "6.0.1", "ts-jest": "29.2.5", "ts-node": "10.9.2", - "typescript": "5.7.2" + "typescript": "5.7.3" } }, "../tmp/http/package/node_modules/@ampproject/remapping": { @@ -8220,7 +8220,7 @@ "version": "0.0.0", "license": "Apache-2.0", "devDependencies": { - "typescript": "5.7.2" + "typescript": "5.7.3" } }, "../tmp/jvm-types/package/node_modules/typescript": {