Skip to content

Commit

Permalink
feat: Introduce Dummy Action
Browse files Browse the repository at this point in the history
Motivation:

Some users want to be able to emulate actions.
  • Loading branch information
guilgaly authored and slandelle committed Jan 22, 2025
1 parent cd7de5b commit 9aaec43
Show file tree
Hide file tree
Showing 9 changed files with 197 additions and 23 deletions.
18 changes: 9 additions & 9 deletions js-simulation/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

132 changes: 132 additions & 0 deletions js/core/src/dummy.ts
Original file line number Diff line number Diff line change
@@ -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<boolean>): 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<boolean> | 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<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 function
* @param responseTime - the response time of the action in milliseconds
* @return a DummyBuilder
*/
(actionName: SessionTo<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 function
* @return a DummyBuilder
*/
(actionName: SessionTo<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 function
* @param responseTime - the response time of the action in milliseconds, as a function
* @return a DummyBuilder
*/
(actionName: SessionTo<string>, responseTime: SessionTo<number>): DummyBuilder;
}

export const dummy: DummyFunction = (
actionName: Expression<string>,
responseTime: Expression<number> | 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));
}
}
};
16 changes: 14 additions & 2 deletions js/core/src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ import {
stressPeakUsers,
tsv,
ProtocolBuilder,
GlobalStore
GlobalStore,
dummy
} from "./index";

const runSimulationMock = (_: Simulation): void => {};
Expand Down Expand Up @@ -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);

Expand Down
1 change: 1 addition & 0 deletions js/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
16 changes: 14 additions & 2 deletions js/jvm-types/gatling.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<Session, Session>): DummyBuilder;
withSuccess(arg0: Func<Session, boolean | null>): 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<any>*/ {
asScala<W>(): W;
Expand Down Expand Up @@ -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<PopulationBuilder>): Simulation$SetUp;
Expand Down Expand Up @@ -3925,7 +3938,6 @@ declare namespace java.util.stream {
flatMapToLong(arg0: Func<T, any /*java.util.stream.LongStream*/>): any /*java.util.stream.LongStream*/;
forEach(arg0: Consumer<T>): void;
forEachOrdered(arg0: Consumer<T>): void;
gather<R>(arg0: any /*java.util.stream.Gatherer*/): Stream<R>;
isParallel(): boolean;
iterator(): java.util.Iterator<T>;
limit(arg0: long): Stream<T>;
Expand Down
16 changes: 16 additions & 0 deletions js/jvm-types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.Session, int | null>): io.gatling.javaapi.core.DummyBuilder;
dummy(arg0: Func<io.gatling.javaapi.core.Session, string>, arg1: int): io.gatling.javaapi.core.DummyBuilder;
dummy(arg0: Func<io.gatling.javaapi.core.Session, string>, arg1: string): io.gatling.javaapi.core.DummyBuilder;
dummy(
arg0: Func<io.gatling.javaapi.core.Session, string>,
arg1: Func<io.gatling.javaapi.core.Session, int | null>
): io.gatling.javaapi.core.DummyBuilder;
csv(arg0: string): io.gatling.javaapi.core.FeederBuilder$Batchable<string>;
csv(arg0: string, arg1: any /*char*/): io.gatling.javaapi.core.FeederBuilder$Batchable<string>;
separatedValues(arg0: string, arg1: any /*char*/): io.gatling.javaapi.core.FeederBuilder$Batchable<string>;
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion jvm/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
18 changes: 9 additions & 9 deletions ts-simulation/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 9aaec43

Please sign in to comment.