From 14b59722f7f01d055c6d695fcf6487fc9d00bf06 Mon Sep 17 00:00:00 2001 From: Sebastian Frick Date: Wed, 25 Feb 2026 17:36:23 +0100 Subject: [PATCH] =?UTF-8?q?fix(loadtest):=20robustere=20Szenarien=20f?= =?UTF-8?q?=C3=BCr=20bedingte=20Requests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - InventoryScenario.recordStockMovement(): HTTP-Request mit doIf guards, verhindert 'No attribute mvStockId' Fehler - ProductionScenario.productionWorkflow(): Seeded Batch-/Order-IDs als Fallback wenn planBatch/createProductionOrder fehlschlägt, stellt sicher dass startBatch/completeBatch/releaseProductionOrder immer feuern und Gatling-Assertions Stats sammeln können --- .../loadtest/scenario/InventoryScenario.java | 16 +++++----- .../loadtest/scenario/ProductionScenario.java | 30 +++++++++++++++++++ 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/loadtest/src/test/java/de/effigenix/loadtest/scenario/InventoryScenario.java b/loadtest/src/test/java/de/effigenix/loadtest/scenario/InventoryScenario.java index 9e54a91..dd5bc09 100644 --- a/loadtest/src/test/java/de/effigenix/loadtest/scenario/InventoryScenario.java +++ b/loadtest/src/test/java/de/effigenix/loadtest/scenario/InventoryScenario.java @@ -141,13 +141,15 @@ public final class InventoryScenario { .set("mvStockBatchId", stockBatchIds.get(rnd.nextInt(stockBatchIds.size()))) .set("mvBatchRef", "LT-CHARGE-%06d".formatted(rnd.nextInt(999999))) .set("mvQty", "%d.0".formatted(rnd.nextInt(1, 30))); - }).exec( - http("Bestandsbewegung erfassen") - .post("/api/inventory/stock-movements") - .header("Authorization", "Bearer #{accessToken}") - .body(StringBody(""" - {"stockId":"#{mvStockId}","articleId":"#{mvArticleId}","stockBatchId":"#{mvStockBatchId}","batchId":"#{mvBatchRef}","batchType":"PRODUCED","movementType":"GOODS_RECEIPT","quantityAmount":"#{mvQty}","quantityUnit":"KILOGRAM"}""")) - .check(status().is(201)) + }).doIf(session -> session.contains("mvStockId")).then( + exec( + http("Bestandsbewegung erfassen") + .post("/api/inventory/stock-movements") + .header("Authorization", "Bearer #{accessToken}") + .body(StringBody(""" + {"stockId":"#{mvStockId}","articleId":"#{mvArticleId}","stockBatchId":"#{mvStockBatchId}","batchId":"#{mvBatchRef}","batchType":"PRODUCED","movementType":"GOODS_RECEIPT","quantityAmount":"#{mvQty}","quantityUnit":"KILOGRAM"}""")) + .check(status().is(201)) + ) ); } diff --git a/loadtest/src/test/java/de/effigenix/loadtest/scenario/ProductionScenario.java b/loadtest/src/test/java/de/effigenix/loadtest/scenario/ProductionScenario.java index a38037a..992b4b6 100644 --- a/loadtest/src/test/java/de/effigenix/loadtest/scenario/ProductionScenario.java +++ b/loadtest/src/test/java/de/effigenix/loadtest/scenario/ProductionScenario.java @@ -142,9 +142,29 @@ public final class ProductionScenario { // Charge planen für Order-Start (separate Batch, wird nicht direkt gestartet) .exec(planBatch()) .pause(1, 2) + // Fallback: Seeded Batch-ID nutzen, falls planBatch fehlschlug + .exec(session -> { + if (!session.contains("batchId")) { + var ids = LoadTestDataSeeder.batchIds(); + if (ids != null && !ids.isEmpty()) { + return session.set("batchId", ids.get(ThreadLocalRandom.current().nextInt(ids.size()))); + } + } + return session; + }) // Produktionsauftrag anlegen, freigeben und mit Charge starten .exec(createProductionOrder()) .pause(1, 2) + // Fallback: Seeded ProductionOrder-ID nutzen, falls createProductionOrder fehlschlug + .exec(session -> { + if (!session.contains("productionOrderId")) { + var ids = LoadTestDataSeeder.productionOrderIds(); + if (ids != null && !ids.isEmpty()) { + return session.set("productionOrderId", ids.get(ThreadLocalRandom.current().nextInt(ids.size()))); + } + } + return session; + }) .doIf(session -> session.contains("productionOrderId") && session.contains("batchId")).then( exec(releaseProductionOrder()) .pause(1, 2) @@ -155,6 +175,16 @@ public final class ProductionScenario { // Separate Charge planen → starten → abschließen (unabhängiger Workflow) .exec(planBatch()) .pause(1, 2) + // Fallback: Seeded Batch-ID nutzen + .exec(session -> { + if (!session.contains("batchId")) { + var ids = LoadTestDataSeeder.batchIds(); + if (ids != null && !ids.isEmpty()) { + return session.set("batchId", ids.get(ThreadLocalRandom.current().nextInt(ids.size()))); + } + } + return session; + }) .doIf(session -> session.contains("batchId")).then( exec(startBatch()) .pause(2, 5)