-
Notifications
You must be signed in to change notification settings - Fork 21
handle more scenarios #1212
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
handle more scenarios #1212
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -9,6 +9,7 @@ | |||||||||||||||||||||||||||||||||||||||||||||
| import static io.gatling.javaapi.core.CoreDsl.jsonPath; | ||||||||||||||||||||||||||||||||||||||||||||||
| import static io.gatling.javaapi.core.CoreDsl.nothingFor; | ||||||||||||||||||||||||||||||||||||||||||||||
| import static io.gatling.javaapi.core.CoreDsl.rampUsers; | ||||||||||||||||||||||||||||||||||||||||||||||
| import static io.gatling.javaapi.core.CoreDsl.rampUsersPerSec; | ||||||||||||||||||||||||||||||||||||||||||||||
| import static io.gatling.javaapi.core.CoreDsl.scenario; | ||||||||||||||||||||||||||||||||||||||||||||||
| import static io.gatling.javaapi.http.HttpDsl.header; | ||||||||||||||||||||||||||||||||||||||||||||||
| import static io.gatling.javaapi.http.HttpDsl.http; | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -18,7 +19,6 @@ | |||||||||||||||||||||||||||||||||||||||||||||
| import io.gatling.javaapi.core.ChainBuilder; | ||||||||||||||||||||||||||||||||||||||||||||||
| import io.gatling.javaapi.core.ScenarioBuilder; | ||||||||||||||||||||||||||||||||||||||||||||||
| import java.time.Duration; | ||||||||||||||||||||||||||||||||||||||||||||||
| import java.util.Objects; | ||||||||||||||||||||||||||||||||||||||||||||||
| import java.util.concurrent.ThreadLocalRandom; | ||||||||||||||||||||||||||||||||||||||||||||||
| import org.slf4j.Logger; | ||||||||||||||||||||||||||||||||||||||||||||||
| import org.slf4j.LoggerFactory; | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -33,13 +33,13 @@ public class CreateProductSimulation extends BaseSimulation { | |||||||||||||||||||||||||||||||||||||||||||||
| private static final Logger LOGGER = LoggerFactory.getLogger(CreateProductSimulation.class); | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| // Configuration parameters - can be externalized to properties | ||||||||||||||||||||||||||||||||||||||||||||||
| private static final int RAMP_USERS = Integer.parseInt(System.getProperty("rampUsers", "3")); | ||||||||||||||||||||||||||||||||||||||||||||||
| private static final int RAMP_USERS = Integer.parseInt(System.getProperty("rampUsers", "50")); | ||||||||||||||||||||||||||||||||||||||||||||||
| private static final int CONSTANT_USERS = | ||||||||||||||||||||||||||||||||||||||||||||||
| Integer.parseInt(System.getProperty("constantUsers", "15")); | ||||||||||||||||||||||||||||||||||||||||||||||
| Integer.parseInt(System.getProperty("constantUsers", "100")); | ||||||||||||||||||||||||||||||||||||||||||||||
| private static final int RAMP_DURATION_SECONDS = | ||||||||||||||||||||||||||||||||||||||||||||||
| Integer.parseInt(System.getProperty("rampDuration", "30")); | ||||||||||||||||||||||||||||||||||||||||||||||
| private static final int TEST_DURATION_SECONDS = | ||||||||||||||||||||||||||||||||||||||||||||||
| Integer.parseInt(System.getProperty("testDuration", "60")); | ||||||||||||||||||||||||||||||||||||||||||||||
| Integer.parseInt(System.getProperty("testDuration", "180")); | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| // Breaking down the test flow into reusable components for better readability and | ||||||||||||||||||||||||||||||||||||||||||||||
| // maintainability | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -173,34 +173,39 @@ public class CreateProductSimulation extends BaseSimulation { | |||||||||||||||||||||||||||||||||||||||||||||
| private final ScenarioBuilder productWorkflow = | ||||||||||||||||||||||||||||||||||||||||||||||
| scenario("E2E Product Creation Workflow") | ||||||||||||||||||||||||||||||||||||||||||||||
| .feed(enhancedProductFeeder()) | ||||||||||||||||||||||||||||||||||||||||||||||
| .exec(createProduct) | ||||||||||||||||||||||||||||||||||||||||||||||
| .pause(Duration.ofMillis(10)) // Add pause to reduce load | ||||||||||||||||||||||||||||||||||||||||||||||
| .exec(getProduct) | ||||||||||||||||||||||||||||||||||||||||||||||
| .pause(Duration.ofMillis(10)) // Add pause to reduce load | ||||||||||||||||||||||||||||||||||||||||||||||
| .exec(getInventory) | ||||||||||||||||||||||||||||||||||||||||||||||
| .pause(Duration.ofMillis(20)) // More pause before the critical update | ||||||||||||||||||||||||||||||||||||||||||||||
| // Simplified workflow to avoid syntax issues | ||||||||||||||||||||||||||||||||||||||||||||||
| .exec( | ||||||||||||||||||||||||||||||||||||||||||||||
| session -> { | ||||||||||||||||||||||||||||||||||||||||||||||
| // Add safeguard to skip inventory update if inventory info is | ||||||||||||||||||||||||||||||||||||||||||||||
| // missing or invalid | ||||||||||||||||||||||||||||||||||||||||||||||
| if (session.contains("inventoryResponseBody") | ||||||||||||||||||||||||||||||||||||||||||||||
| && session.getString("inventoryResponseBody") != null | ||||||||||||||||||||||||||||||||||||||||||||||
| && !Objects.requireNonNull( | ||||||||||||||||||||||||||||||||||||||||||||||
| session.getString("inventoryResponseBody")) | ||||||||||||||||||||||||||||||||||||||||||||||
| .trim() | ||||||||||||||||||||||||||||||||||||||||||||||
| .isEmpty()) { | ||||||||||||||||||||||||||||||||||||||||||||||
| return session; | ||||||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||||||
| LOGGER.warn( | ||||||||||||||||||||||||||||||||||||||||||||||
| "Skipping inventory update due to missing inventory data"); | ||||||||||||||||||||||||||||||||||||||||||||||
| // Return marked as failed so we don't attempt to create an | ||||||||||||||||||||||||||||||||||||||||||||||
| // order based on invalid inventory | ||||||||||||||||||||||||||||||||||||||||||||||
| return session.markAsFailed(); | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||
| .exec(updateInventory) | ||||||||||||||||||||||||||||||||||||||||||||||
| .pause(Duration.ofMillis(10)) // Add pause to reduce load | ||||||||||||||||||||||||||||||||||||||||||||||
| .exec(createOrder); | ||||||||||||||||||||||||||||||||||||||||||||||
| exec(createProduct) | ||||||||||||||||||||||||||||||||||||||||||||||
| .exec( | ||||||||||||||||||||||||||||||||||||||||||||||
| session -> { | ||||||||||||||||||||||||||||||||||||||||||||||
| logRequestTime( | ||||||||||||||||||||||||||||||||||||||||||||||
| "Create Product Complete", | ||||||||||||||||||||||||||||||||||||||||||||||
| System.currentTimeMillis()); | ||||||||||||||||||||||||||||||||||||||||||||||
| return session; | ||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||
| .pause(200) // Reduced pause time from 500 to 200 ms | ||||||||||||||||||||||||||||||||||||||||||||||
| .exec(getProduct) | ||||||||||||||||||||||||||||||||||||||||||||||
| .pause(100) // Reduced pause time from 300 to 100 ms | ||||||||||||||||||||||||||||||||||||||||||||||
| // .exec(getInventory) | ||||||||||||||||||||||||||||||||||||||||||||||
| .pause(100) // Reduced pause time | ||||||||||||||||||||||||||||||||||||||||||||||
| .exec( | ||||||||||||||||||||||||||||||||||||||||||||||
| session -> { | ||||||||||||||||||||||||||||||||||||||||||||||
| // Add safeguard to skip inventory update if | ||||||||||||||||||||||||||||||||||||||||||||||
| // inventory info is missing or invalid | ||||||||||||||||||||||||||||||||||||||||||||||
| if (session.contains("inventoryResponseBody") | ||||||||||||||||||||||||||||||||||||||||||||||
| && session.getString( | ||||||||||||||||||||||||||||||||||||||||||||||
| "inventoryResponseBody") | ||||||||||||||||||||||||||||||||||||||||||||||
| != null) { | ||||||||||||||||||||||||||||||||||||||||||||||
| return session; | ||||||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||||||
| LOGGER.warn( | ||||||||||||||||||||||||||||||||||||||||||||||
| "Skipping inventory update due to missing inventory data"); | ||||||||||||||||||||||||||||||||||||||||||||||
| return session.markAsFailed(); | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||
| .exec(updateInventory) | ||||||||||||||||||||||||||||||||||||||||||||||
| .pause(300) | ||||||||||||||||||||||||||||||||||||||||||||||
| .exec(createOrder)); | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||
| * Prepares the inventory update request by generating a new inventory quantity | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -323,29 +328,39 @@ public CreateProductSimulation() { | |||||||||||||||||||||||||||||||||||||||||||||
| runHealthChecks(); | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| LOGGER.info( | ||||||||||||||||||||||||||||||||||||||||||||||
| "Running with warm-up phase of {} seconds with a single user to initialize Kafka", | ||||||||||||||||||||||||||||||||||||||||||||||
| "Running with warm-up phase of {} seconds with multiple users to initialize Kafka", | ||||||||||||||||||||||||||||||||||||||||||||||
| KAFKA_INIT_DELAY_SECONDS); | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| // Global assertions to validate overall service performance | ||||||||||||||||||||||||||||||||||||||||||||||
| this.setUp( | ||||||||||||||||||||||||||||||||||||||||||||||
| productWorkflow | ||||||||||||||||||||||||||||||||||||||||||||||
| // Small pause between steps to simulate realistic user behavior | ||||||||||||||||||||||||||||||||||||||||||||||
| .pause(Duration.ofMillis(500)) | ||||||||||||||||||||||||||||||||||||||||||||||
| .injectOpen( | ||||||||||||||||||||||||||||||||||||||||||||||
| // Initial single user for Kafka initialization | ||||||||||||||||||||||||||||||||||||||||||||||
| atOnceUsers(1), | ||||||||||||||||||||||||||||||||||||||||||||||
| // Wait for Kafka initialization to complete | ||||||||||||||||||||||||||||||||||||||||||||||
| nothingFor(Duration.ofSeconds(KAFKA_INIT_DELAY_SECONDS)), | ||||||||||||||||||||||||||||||||||||||||||||||
| // Ramp up users phase for gradual load increase | ||||||||||||||||||||||||||||||||||||||||||||||
| rampUsers(RAMP_USERS) | ||||||||||||||||||||||||||||||||||||||||||||||
| .during(Duration.ofSeconds(RAMP_DURATION_SECONDS)), | ||||||||||||||||||||||||||||||||||||||||||||||
| // Constant load phase to test system stability | ||||||||||||||||||||||||||||||||||||||||||||||
| constantUsersPerSec(CONSTANT_USERS) | ||||||||||||||||||||||||||||||||||||||||||||||
| .during(Duration.ofSeconds(TEST_DURATION_SECONDS)))) | ||||||||||||||||||||||||||||||||||||||||||||||
| // Configure simulation with robust load profile | ||||||||||||||||||||||||||||||||||||||||||||||
| setUp( | ||||||||||||||||||||||||||||||||||||||||||||||
| productWorkflow.injectOpen( | ||||||||||||||||||||||||||||||||||||||||||||||
| // Initial users for Kafka initialization and baseline - increased | ||||||||||||||||||||||||||||||||||||||||||||||
| // from 3 to 10 | ||||||||||||||||||||||||||||||||||||||||||||||
| atOnceUsers(10), | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| // Wait for Kafka initialization to complete | ||||||||||||||||||||||||||||||||||||||||||||||
| nothingFor(Duration.ofSeconds(KAFKA_INIT_DELAY_SECONDS)), | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| // Initial ramp using users - increased for more load | ||||||||||||||||||||||||||||||||||||||||||||||
| rampUsers(RAMP_USERS) | ||||||||||||||||||||||||||||||||||||||||||||||
| .during(Duration.ofSeconds(RAMP_DURATION_SECONDS)), | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| // Constant load phase with shorter duration but higher throughput | ||||||||||||||||||||||||||||||||||||||||||||||
| constantUsersPerSec(CONSTANT_USERS / 2) | ||||||||||||||||||||||||||||||||||||||||||||||
| .during(Duration.ofSeconds(TEST_DURATION_SECONDS / 4)), | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| // Ramp up to peak load more quickly | ||||||||||||||||||||||||||||||||||||||||||||||
| rampUsersPerSec(CONSTANT_USERS / 2) | ||||||||||||||||||||||||||||||||||||||||||||||
| .to(CONSTANT_USERS) | ||||||||||||||||||||||||||||||||||||||||||||||
| .during(Duration.ofSeconds(TEST_DURATION_SECONDS / 4)), | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| // Sustained peak load phase | ||||||||||||||||||||||||||||||||||||||||||||||
| constantUsersPerSec(CONSTANT_USERS) | ||||||||||||||||||||||||||||||||||||||||||||||
| .during(Duration.ofSeconds(TEST_DURATION_SECONDS / 2)))) | ||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+348
to
+358
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Prevent zero-rate injection when halving constantUsers Line 348 currently divides the user rate with integer math, so a legitimate override like - constantUsersPerSec(CONSTANT_USERS / 2)
+ constantUsersPerSec(CONSTANT_USERS / 2.0)
...
- rampUsersPerSec(CONSTANT_USERS / 2)
+ rampUsersPerSec(CONSTANT_USERS / 2.0)📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||
| .protocols(httpProtocol) | ||||||||||||||||||||||||||||||||||||||||||||||
| .assertions( | ||||||||||||||||||||||||||||||||||||||||||||||
| // Add global performance SLA assertions | ||||||||||||||||||||||||||||||||||||||||||||||
| global().responseTime().mean().lt(1500), // Mean response time under 1.5s | ||||||||||||||||||||||||||||||||||||||||||||||
| global().responseTime().mean().lt(2000), // Mean response time under 2s | ||||||||||||||||||||||||||||||||||||||||||||||
| global().responseTime() | ||||||||||||||||||||||||||||||||||||||||||||||
| .percentile(95) | ||||||||||||||||||||||||||||||||||||||||||||||
| .lt(5000), // 95% of responses under 5s | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.