How to dynamically set a port (from a Testcontainers container)

Gatling version: 3.11.5 (must be up to date)
Gatling flavor: java kotlin scala javascript typescript
Gatling build tool: maven gradle sbt bundle npm

I read the guidelines and how to ask a question topics.
I provided a SSCCE (or at least, all information to help the community understand my topic)
I copied output I observe, and explain what I think should be.

I’m creating a gatling simulation in java which I intend to use against an application running in a container. The containerised application is set up with Testcontainers, which is performed in the before method of the Simulation.

The running container will start and is assigned a random port and I can capture it via getMappedPort, but I’m finding it impossible have the running scenario execute against a URL with that port. Is there a way to do this?

Example of the simulation:

@Override
public void before() {
  myTestcontainers.setup();
  // capture application port from getMappedPort by some mechanism, e.g. return it from that call and assign to a variable in the simulation class
}

final HttpProtocolBuilder httpProtocol = http
        .baseUrl("http://localhost:8080") // how to override port when scenario runs?
        .acceptHeader("application/json")
        .userAgentHeader("Gatling");

final ScenarioBuilder getFoo = scenario("get foo")
            .exec(http("Get Foo")
                    .get("/foo")
                    .check(status().is(200)))
            .pause(Duration.ofMillis(500));

{
 
 setUp(getFoo.injectOpen(constantUsersPerSec(10).during(300)).protocols(httpProtocol));
}

I’ve tried a few ways but it seems when the initialiser block runs I can’t modify the protocol baseUrl, and my searching hasn’t found anyone with the same or a similar problem.

Thanks!

It’s a very bad idea to run your load generator and your target application on the same host.

Both applications are going to compete for resources (memory, CPU) and you’ll be using the loopback instead of proper network. Your test results are not going to make much sense.

You should be running load tests with the load generator and the application under test deployed on different hosts.

Thanks for the reply, and I understand the sentiment.

For context, I’m not trying to stress or soak the service but load a single instance of the service such that some useful results might be gleaned further left in the SDLC, rather than needing to wait until deployment to a test environment or production. Running the app in a container allows me to restrict resource allocation to what’s in production, which is a fraction of what it may have on my dev machine. With respect to having test results make sense I understand, but I think have solutions for that. Haven’t fully proven out the methodology of course hence my query.

I’ll take it that this use case isn’t supported in the manner I’m suggesting. Thanks again

Your call.

Regarding coding what you’re trying to do, it’s pretty straightforward.
Just don’t use the before hook and directly place all the code you need in the instance initializer.

{
  myTestcontainers.setup();
  // capture application port from getMappedPort by some mechanism, e.g. return it from that call and assign to a variable in the simulation class
  int myPort = ???;

 HttpProtocolBuilder httpProtocol = http
        .baseUrl("http://localhost:" + myPort)
        .acceptHeader("application/json")
        .userAgentHeader("Gatling");

  ScenarioBuilder getFoo = scenario("get foo")
            .exec(http("Get Foo")
                    .get("/foo")
                    .check(status().is(200)))
            .pause(Duration.ofMillis(500));
 
 setUp(getFoo.injectOpen(constantUsersPerSec(10).during(300)).protocols(httpProtocol));
}

Hah, thanks, I hope I would have bumped into that solution once I let go of trying to force ‘before()’ to behave in a way it can’t.

There’s no way to make it work in before, because instance attributes and instance initializers are executed along with the constructor while before is executed later, after the instance is created.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.