This is an automated email from the ASF dual-hosted git repository.

hubcio pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iggy.git


The following commit(s) were added to refs/heads/master by this push:
     new ab7825f05 fix(bdd): make ./scripts/run-bdd-tests.sh actually support 
FEATURE flag (#3384)
ab7825f05 is described below

commit ab7825f05a55ab4d68e39f9a717aad5ba59a842c
Author: Chengxi Luo <[email protected]>
AuthorDate: Mon Jun 15 08:42:33 2026 -0400

    fix(bdd): make ./scripts/run-bdd-tests.sh actually support FEATURE flag 
(#3384)
---
 .github/config/components.yml            |   2 +
 bdd/README.md                            |  40 ++++--
 bdd/docker-compose.cluster.yml           | 125 ++++++++++++++++
 bdd/docker-compose.coverage.yml          |  33 +++--
 bdd/docker-compose.server.yml            |  89 ++++++++++++
 bdd/docker-compose.yml                   | 240 ++++---------------------------
 bdd/go/Dockerfile                        |   1 -
 bdd/go/tests/suite_test.go               |  47 ++++--
 bdd/scenarios/basic_messaging.feature    |   1 +
 bdd/scenarios/leader_redirection.feature |   1 -
 scripts/run-bdd-tests.sh                 |  88 +++++++++---
 11 files changed, 398 insertions(+), 269 deletions(-)

diff --git a/.github/config/components.yml b/.github/config/components.yml
index 66b0acc0e..3e2ca285e 100644
--- a/.github/config/components.yml
+++ b/.github/config/components.yml
@@ -281,6 +281,8 @@ components:
     paths:
       - "scripts/run-bdd-tests.sh"
       - "bdd/docker-compose.yml"
+      - "bdd/docker-compose.server.yml"
+      - "bdd/docker-compose.cluster.yml"
       - "bdd/docker-compose.coverage.yml"
 
   # Individual BDD tests per SDK - only run when specific SDK changes
diff --git a/bdd/README.md b/bdd/README.md
index d348d68d1..a17bbc950 100644
--- a/bdd/README.md
+++ b/bdd/README.md
@@ -7,7 +7,8 @@ This directory contains cross-SDK Behavior-Driven Development 
(BDD) tests for Ap
 ```bash
 bdd/
 ├── scenarios/                  # Shared Gherkin feature files
-│   └── basic_messaging.feature
+│   ├── basic_messaging.feature
+│   └── leader_redirection.feature
 ├── rust/                       # Rust SDK BDD implementation
 │   ├── Dockerfile              # Rust BDD test container
 │   ├── tests/
@@ -17,11 +18,13 @@ bdd/
 │   ├── tests/
 │   ├── pyproject.toml
 │   └── uv.lock
-├── node/                       # Node SDK BDD implementation
-│   └── Dockerfile              # Node BDD test container
 ├── go/                         # Go SDK BDD implementation
 │   ├── Dockerfile              # Go BDD test container
-│   └── tests/
+│   ├── tests/
+│   ├── go.mod
+│   └── go.sum
+├── node/                       # Node SDK BDD implementation
+│   └── Dockerfile              # Node BDD test container
 ├── csharp/                     # csharp SDK BDD implementation
 │   └── Dockerfile              # csharp BDD test container
 ├── java/                       # Java SDK BDD implementation
@@ -32,7 +35,10 @@ bdd/
 │   ├── Dockerfile              # PHP BDD test container
 │   ├── phpunit.xml.dist
 │   └── tests/
-├── docker-compose.yml          # Orchestrates server + SDK containers
+├── docker-compose.yml          # Base: SDK test clients (always included)
+├── docker-compose.server.yml   # Single iggy-server test setup
+├── docker-compose.cluster.yml  # Leader + follower test setup
+├── docker-compose.coverage.yml # Coverage collection overlay
 ├── Dockerfile                  # Debug build of Iggy server
 └── README.md
 ```
@@ -42,10 +48,14 @@ bdd/
 ### Quick Start
 
 ```bash
-# Run all SDK tests
+# Usage: ../scripts/run-bdd-tests.sh [--coverage] <sdk> [feature]
+#   sdk:     rust | python | php | go | go-race | node | csharp | java | all | 
clean  (default: all)
+#   feature: basic_messaging | leader_redirection | all  (default: all)
+
+# Run all features for all SDKs
 ../scripts/run-bdd-tests.sh all
 
-# Run specific SDK tests
+# Run specific SDK tests (all features)
 ../scripts/run-bdd-tests.sh rust
 ../scripts/run-bdd-tests.sh python
 ../scripts/run-bdd-tests.sh go
@@ -54,6 +64,12 @@ bdd/
 ../scripts/run-bdd-tests.sh java
 ../scripts/run-bdd-tests.sh php
 
+# Run only basic_messaging feature for Rust SDK
+../scripts/run-bdd-tests.sh rust basic_messaging
+
+# Run only leader_redirection
+../scripts/run-bdd-tests.sh all leader_redirection
+
 # Clean up Docker resources
 ../scripts/run-bdd-tests.sh clean
 ```
@@ -65,7 +81,7 @@ bdd/
 
 ### How it Works
 
-1. **Server Container**: Builds and runs the latest Iggy server in debug mode
+1. **Server Containers**: `docker-compose.server.yml` runs a single Iggy 
server; `docker-compose.cluster.yml` adds a leader + follower pair for cluster 
scenarios
 2. **SDK Containers**: Each SDK has its own container with the appropriate 
runtime and dependencies
 3. **Shared Features**: All SDKs test against the same `.feature` files for 
consistency
 4. **Health Checks**: Containers wait for the server to be healthy before 
running tests
@@ -79,7 +95,7 @@ To add a new SDK (e.g., Node.js):
 3. Create `node/tests/` directory with BDD implementation
 4. Add `node-bdd` service to `docker-compose.yml`
 5. Update `../scripts/run-bdd-tests.sh` script
-6. Update 
[changed-files-config.json](https://github.com/apache/iggy/blob/master/.github/changed-files-config.json)
 file to include the new SDK files
+6. Update 
[components.yml](https://github.com/apache/iggy/blob/master/.github/config/components.yml)
 file to include the new SDK files
 
 ### CI/CD Integration
 
@@ -89,12 +105,16 @@ GitHub Actions workflow: 
[ci-test-bdd.yml](https://github.com/apache/iggy/blob/m
 
 ### For Rust SDK
 
-The Rust implementation is located in `core/bdd/` and linked via Docker 
volumes.
+The Rust implementation is located in `bdd/rust/` and linked via Docker 
volumes.
 
 ### For Python SDK
 
 The Python implementation is in `bdd/python/tests/` and needs to be updated as 
the Python SDK API evolves.
 
+### For Go SDK
+
+The Go implementation is located in `bdd/go/tests/`.
+
 ### For Node SDK
 
 The node.js BDD test are run by cucumber-js, bdd test code is located at 
[foreign/node/src/bdd](../foreign/node/src/bdd/)
diff --git a/bdd/docker-compose.cluster.yml b/bdd/docker-compose.cluster.yml
new file mode 100644
index 000000000..7f6279621
--- /dev/null
+++ b/bdd/docker-compose.cluster.yml
@@ -0,0 +1,125 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# Iggy leader + follower cluster test setup.
+# Activated by: ./scripts/run-bdd-tests.sh <sdk> leader_redirection
+#               ./scripts/run-bdd-tests.sh <sdk> all
+
+x-cluster-node: &cluster-node
+  image: iggy-bdd-server
+  platform: linux/amd64
+  build:
+    context: ..
+    dockerfile: core/server/Dockerfile
+    target: runtime-prebuilt
+    args:
+      PREBUILT_IGGY_SERVER: ${IGGY_SERVER_PATH:-target/debug/iggy-server}
+      PREBUILT_IGGY_CLI: ${IGGY_CLI_PATH:-target/debug/iggy}
+      LIBC: glibc
+      PROFILE: debug
+  cap_add:
+    - SYS_NICE
+  security_opt:
+    - seccomp:unconfined
+  ulimits:
+    memlock:
+      soft: -1
+      hard: -1
+  networks:
+    - iggy-bdd-network
+
+x-cluster-topology: &cluster-topology
+  IGGY_CLUSTER_ENABLED: "true"
+  IGGY_CLUSTER_NAME: test-cluster
+  IGGY_CLUSTER_NODES_0_NAME: leader-node
+  IGGY_CLUSTER_NODES_0_IP: iggy-leader
+  IGGY_CLUSTER_NODES_0_REPLICA_ID: "0"
+  IGGY_CLUSTER_NODES_0_PORTS_TCP: "8091"
+  IGGY_CLUSTER_NODES_0_PORTS_QUIC: "8081"
+  IGGY_CLUSTER_NODES_0_PORTS_HTTP: "3001"
+  IGGY_CLUSTER_NODES_0_PORTS_WEBSOCKET: "8071"
+  IGGY_CLUSTER_NODES_1_NAME: follower-node
+  IGGY_CLUSTER_NODES_1_IP: iggy-follower
+  IGGY_CLUSTER_NODES_1_REPLICA_ID: "1"
+  IGGY_CLUSTER_NODES_1_PORTS_TCP: "8092"
+  IGGY_CLUSTER_NODES_1_PORTS_QUIC: "8082"
+  IGGY_CLUSTER_NODES_1_PORTS_HTTP: "3002"
+  IGGY_CLUSTER_NODES_1_PORTS_WEBSOCKET: "8072"
+
+x-cluster-bdd-deps: &cluster-bdd-deps
+  depends_on:
+    iggy-leader:
+      condition: service_healthy
+    iggy-follower:
+      condition: service_healthy
+  environment:
+    - IGGY_TCP_ADDRESS_LEADER=iggy-leader:8091
+    - IGGY_TCP_ADDRESS_FOLLOWER=iggy-follower:8092
+
+services:
+  iggy-leader:
+    <<: *cluster-node
+    command: [ "--fresh", "--with-default-root-credentials", "--replica-id", 
"0" ]
+    healthcheck:
+      test: [ "CMD", "/usr/local/bin/iggy", "--tcp-server-address", 
"127.0.0.1:8091", "ping" ]
+      interval: 5s
+      timeout: 3s
+      retries: 30
+      start_period: 2s
+    environment:
+      <<: *cluster-topology
+      RUST_LOG: info
+      IGGY_SYSTEM_PATH: local_data_leader
+      IGGY_TCP_ADDRESS: 0.0.0.0:8091
+      IGGY_HTTP_ADDRESS: 0.0.0.0:3001
+      IGGY_QUIC_ADDRESS: 0.0.0.0:8081
+      IGGY_WEBSOCKET_ADDRESS: 0.0.0.0:8071
+    volumes:
+      - iggy_leader_data:/app/local_data_leader
+
+  iggy-follower:
+    <<: *cluster-node
+    command: [ "--fresh", "--with-default-root-credentials", "--follower", 
"--replica-id", "1" ]
+    healthcheck:
+      test: [ "CMD", "/usr/local/bin/iggy", "--tcp-server-address", 
"127.0.0.1:8092", "ping" ]
+      interval: 5s
+      timeout: 3s
+      retries: 30
+      start_period: 2s
+    environment:
+      <<: *cluster-topology
+      RUST_LOG: info
+      IGGY_SYSTEM_PATH: local_data_follower
+      IGGY_TCP_ADDRESS: 0.0.0.0:8092
+      IGGY_HTTP_ADDRESS: 0.0.0.0:3002
+      IGGY_QUIC_ADDRESS: 0.0.0.0:8082
+      IGGY_WEBSOCKET_ADDRESS: 0.0.0.0:8072
+    volumes:
+      - iggy_follower_data:/app/local_data_follower
+
+  rust-bdd:
+    <<: *cluster-bdd-deps
+
+  go-bdd:
+    <<: *cluster-bdd-deps
+
+  csharp-bdd:
+    <<: *cluster-bdd-deps
+
+volumes:
+  iggy_leader_data:
+  iggy_follower_data:
diff --git a/bdd/docker-compose.coverage.yml b/bdd/docker-compose.coverage.yml
index 7f742440e..dfc47984a 100644
--- a/bdd/docker-compose.coverage.yml
+++ b/bdd/docker-compose.coverage.yml
@@ -28,11 +28,14 @@ services:
     command:
       - sh
       - -c
-      - >-
-        rustup component add llvm-tools-preview
-        && cargo install cargo-llvm-cov
-        && cargo llvm-cov test -p bdd --features bdd
-        --lcov --output-path /reports/rust-bdd-coverage.lcov
+      - |
+        rustup component add llvm-tools-preview \
+        && cargo install cargo-llvm-cov \
+        && case "$$BDD_FEATURE" in
+          basic_messaging)    cargo llvm-cov test -p bdd --features bdd --test 
basic_messaging --lcov --output-path /reports/rust-bdd-coverage.lcov ;;
+          leader_redirection) cargo llvm-cov test -p bdd --features bdd --test 
leader_redirection --lcov --output-path /reports/rust-bdd-coverage.lcov ;;
+          *)                  cargo llvm-cov test -p bdd --features bdd --lcov 
--output-path /reports/rust-bdd-coverage.lcov ;;
+        esac
 
   python-bdd:
     volumes:
@@ -69,7 +72,7 @@ services:
       - sh
       - -c
       - >-
-        go test -v ${GO_TEST_EXTRA_FLAGS}
+        go test -v
         -coverpkg=github.com/apache/iggy/foreign/go/...
         -coverprofile=/reports/go-bdd-coverage.out
         ./...
@@ -87,15 +90,15 @@ services:
     volumes:
       - ../reports:/reports
     command:
-      - dotnet
-      - test
-      - --coverage
-      - --coverage-output-format
-      - cobertura
-      - --coverage-output
-      - csharp-bdd-coverage.cobertura.xml
-      - --results-directory
-      - /reports
+      - sh
+      - -c
+      - |
+        FILTER=""
+        case "$$BDD_FEATURE" in
+          basic_messaging)    FILTER='--filter-trait Category=basic-messaging' 
;;
+          leader_redirection) FILTER='--filter-trait 
Category=requires-leader-awareness' ;;
+        esac
+        dotnet test $$FILTER --coverage --coverage-output-format cobertura 
--coverage-output csharp-bdd-coverage.cobertura.xml --results-directory /reports
 
   java-bdd:
     volumes:
diff --git a/bdd/docker-compose.server.yml b/bdd/docker-compose.server.yml
new file mode 100644
index 000000000..f1a1e25e7
--- /dev/null
+++ b/bdd/docker-compose.server.yml
@@ -0,0 +1,89 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# Single Iggy server test setup.
+# Activated by: ./scripts/run-bdd-tests.sh <sdk> basic_messaging
+#               ./scripts/run-bdd-tests.sh <sdk> leader_redirection
+#               ./scripts/run-bdd-tests.sh <sdk> all
+
+x-server-bdd-deps: &server-bdd-deps
+  depends_on:
+    iggy-server:
+      condition: service_healthy
+  environment:
+    - IGGY_TCP_ADDRESS=iggy-server:8090
+
+services:
+  iggy-server:
+    image: iggy-bdd-server
+    platform: linux/amd64
+    build:
+      context: ..
+      dockerfile: core/server/Dockerfile
+      target: runtime-prebuilt
+      args:
+        PREBUILT_IGGY_SERVER: ${IGGY_SERVER_PATH:-target/debug/iggy-server}
+        PREBUILT_IGGY_CLI: ${IGGY_CLI_PATH:-target/debug/iggy}
+        LIBC: glibc
+        PROFILE: debug
+    command: [ "--fresh", "--with-default-root-credentials" ]
+    cap_add:
+      - SYS_NICE
+    security_opt:
+      - seccomp:unconfined
+    ulimits:
+      memlock:
+        soft: -1
+        hard: -1
+    healthcheck:
+      test: [ "CMD", "/usr/local/bin/iggy", "--tcp-server-address", 
"127.0.0.1:8090", "ping" ]
+      interval: 5s
+      timeout: 3s
+      retries: 30
+      start_period: 2s
+    environment:
+      - RUST_LOG=info
+      - IGGY_SYSTEM_PATH=local_data
+      - IGGY_TCP_ADDRESS=0.0.0.0:8090
+      - IGGY_HTTP_ADDRESS=0.0.0.0:3000
+      - IGGY_QUIC_ADDRESS=0.0.0.0:8080
+      - IGGY_WEBSOCKET_ADDRESS=0.0.0.0:8070
+    volumes:
+      - iggy_data:/app/local_data
+    networks:
+      - iggy-bdd-network
+
+  rust-bdd:
+    <<: *server-bdd-deps
+
+  python-bdd:
+    <<: *server-bdd-deps
+
+  go-bdd:
+    <<: *server-bdd-deps
+
+  node-bdd:
+    <<: *server-bdd-deps
+
+  csharp-bdd:
+    <<: *server-bdd-deps
+
+  java-bdd:
+    <<: *server-bdd-deps
+
+volumes:
+  iggy_data:
diff --git a/bdd/docker-compose.yml b/bdd/docker-compose.yml
index e466312e1..6774a9464 100644
--- a/bdd/docker-compose.yml
+++ b/bdd/docker-compose.yml
@@ -16,204 +16,40 @@
 # under the License.
 
 services:
-  # Original single server for backward compatibility
-  iggy-server:
-    platform: linux/amd64
-    build:
-      context: ..
-      dockerfile: core/server/Dockerfile
-      target: runtime-prebuilt
-      args:
-        PREBUILT_IGGY_SERVER: ${IGGY_SERVER_PATH:-target/debug/iggy-server}
-        PREBUILT_IGGY_CLI: ${IGGY_CLI_PATH:-target/debug/iggy}
-        LIBC: glibc
-        PROFILE: debug
-    command: [ "--fresh", "--with-default-root-credentials" ]
-    cap_add:
-      - SYS_NICE
-    security_opt:
-      - seccomp:unconfined
-    ulimits:
-      memlock:
-        soft: -1
-        hard: -1
-    healthcheck:
-      test: [ "CMD", "/usr/local/bin/iggy", "--tcp-server-address", 
"127.0.0.1:8090", "ping" ]
-      interval: 20s
-      timeout: 3s
-      retries: 30
-      start_period: 2s
-    environment:
-      - RUST_LOG=info
-      - IGGY_SYSTEM_PATH=local_data
-      - IGGY_TCP_ADDRESS=0.0.0.0:8090
-      - IGGY_HTTP_ADDRESS=0.0.0.0:3000
-      - IGGY_QUIC_ADDRESS=0.0.0.0:8080
-      - IGGY_WEBSOCKET_ADDRESS=0.0.0.0:8070
-    volumes:
-      - iggy_data:/app/local_data
-    networks:
-      - iggy-bdd-network
-
-  # Leader server for cluster testing
-  iggy-leader:
-    platform: linux/amd64
-    build:
-      context: ..
-      dockerfile: core/server/Dockerfile
-      target: runtime-prebuilt
-      args:
-        PREBUILT_IGGY_SERVER: ${IGGY_SERVER_PATH:-target/debug/iggy-server}
-        PREBUILT_IGGY_CLI: ${IGGY_CLI_PATH:-target/debug/iggy}
-        LIBC: glibc
-        PROFILE: debug
-    # Leader runs without --follower flag; --replica-id selects this node's
-    # entry (replica_id=0) from the shared cluster.nodes roster below.
-    command: [ "--fresh", "--with-default-root-credentials", "--replica-id", 
"0" ]
-    cap_add:
-      - SYS_NICE
-    security_opt:
-      - seccomp:unconfined
-    ulimits:
-      memlock:
-        soft: -1
-        hard: -1
-    healthcheck:
-      test: [ "CMD", "/usr/local/bin/iggy", "--tcp-server-address", 
"127.0.0.1:8091", "ping" ]
-      interval: 20s
-      timeout: 3s
-      retries: 30
-      start_period: 2s
-    environment:
-      - RUST_LOG=info
-      - IGGY_SYSTEM_PATH=local_data_leader
-      # Server bind addresses for this container.
-      - IGGY_TCP_ADDRESS=0.0.0.0:8091
-      - IGGY_HTTP_ADDRESS=0.0.0.0:3001
-      - IGGY_QUIC_ADDRESS=0.0.0.0:8081
-      - IGGY_WEBSOCKET_ADDRESS=0.0.0.0:8071
-      # Cluster configuration. The block below is byte-identical on the
-      # follower container; the only runtime difference is --replica-id,
-      # passed via the command above.
-      - IGGY_CLUSTER_ENABLED=true
-      - IGGY_CLUSTER_NAME=test-cluster
-      - IGGY_CLUSTER_NODES_0_NAME=leader-node
-      - IGGY_CLUSTER_NODES_0_IP=iggy-leader
-      - IGGY_CLUSTER_NODES_0_REPLICA_ID=0
-      - IGGY_CLUSTER_NODES_0_PORTS_TCP=8091
-      - IGGY_CLUSTER_NODES_0_PORTS_QUIC=8081
-      - IGGY_CLUSTER_NODES_0_PORTS_HTTP=3001
-      - IGGY_CLUSTER_NODES_0_PORTS_WEBSOCKET=8071
-      - IGGY_CLUSTER_NODES_1_NAME=follower-node
-      - IGGY_CLUSTER_NODES_1_IP=iggy-follower
-      - IGGY_CLUSTER_NODES_1_REPLICA_ID=1
-      - IGGY_CLUSTER_NODES_1_PORTS_TCP=8092
-      - IGGY_CLUSTER_NODES_1_PORTS_QUIC=8082
-      - IGGY_CLUSTER_NODES_1_PORTS_HTTP=3002
-      - IGGY_CLUSTER_NODES_1_PORTS_WEBSOCKET=8072
-    volumes:
-      - iggy_leader_data:/app/local_data_leader
-    networks:
-      - iggy-bdd-network
-
-  # Follower server for cluster testing
-  iggy-follower:
-    platform: linux/amd64
-    build:
-      context: ..
-      dockerfile: core/server/Dockerfile
-      target: runtime-prebuilt
-      args:
-        PREBUILT_IGGY_SERVER: ${IGGY_SERVER_PATH:-target/debug/iggy-server}
-        PREBUILT_IGGY_CLI: ${IGGY_CLI_PATH:-target/debug/iggy}
-        LIBC: glibc
-        PROFILE: debug
-    # Follower runs with --follower flag; --replica-id selects this node's
-    # entry (replica_id=1) from the shared cluster.nodes roster below.
-    command: [ "--fresh", "--with-default-root-credentials", "--follower", 
"--replica-id", "1" ]
-    cap_add:
-      - SYS_NICE
-    security_opt:
-      - seccomp:unconfined
-    ulimits:
-      memlock:
-        soft: -1
-        hard: -1
-    healthcheck:
-      test: [ "CMD", "/usr/local/bin/iggy", "--tcp-server-address", 
"127.0.0.1:8092", "ping" ]
-      interval: 20s
-      timeout: 3s
-      retries: 30
-      start_period: 2s
-    environment:
-      - RUST_LOG=info
-      - IGGY_SYSTEM_PATH=local_data_follower
-      # Server bind addresses for this container.
-      - IGGY_TCP_ADDRESS=0.0.0.0:8092
-      - IGGY_HTTP_ADDRESS=0.0.0.0:3002
-      - IGGY_QUIC_ADDRESS=0.0.0.0:8082
-      - IGGY_WEBSOCKET_ADDRESS=0.0.0.0:8072
-      # Cluster configuration. The block below is byte-identical on the
-      # leader container; the only runtime difference is --replica-id,
-      # passed via the command above.
-      - IGGY_CLUSTER_ENABLED=true
-      - IGGY_CLUSTER_NAME=test-cluster
-      - IGGY_CLUSTER_NODES_0_NAME=leader-node
-      - IGGY_CLUSTER_NODES_0_IP=iggy-leader
-      - IGGY_CLUSTER_NODES_0_REPLICA_ID=0
-      - IGGY_CLUSTER_NODES_0_PORTS_TCP=8091
-      - IGGY_CLUSTER_NODES_0_PORTS_QUIC=8081
-      - IGGY_CLUSTER_NODES_0_PORTS_HTTP=3001
-      - IGGY_CLUSTER_NODES_0_PORTS_WEBSOCKET=8071
-      - IGGY_CLUSTER_NODES_1_NAME=follower-node
-      - IGGY_CLUSTER_NODES_1_IP=iggy-follower
-      - IGGY_CLUSTER_NODES_1_REPLICA_ID=1
-      - IGGY_CLUSTER_NODES_1_PORTS_TCP=8092
-      - IGGY_CLUSTER_NODES_1_PORTS_QUIC=8082
-      - IGGY_CLUSTER_NODES_1_PORTS_HTTP=3002
-      - IGGY_CLUSTER_NODES_1_PORTS_WEBSOCKET=8072
-    volumes:
-      - iggy_follower_data:/app/local_data_follower
-    networks:
-      - iggy-bdd-network
-
   rust-bdd:
+    image: iggy-bdd-rust
     build:
       context: ..
       dockerfile: bdd/rust/Dockerfile
-    depends_on:
-      iggy-server:
-        condition: service_healthy
-      iggy-leader:
-        condition: service_healthy
-      iggy-follower:
-        condition: service_healthy
     environment:
       - IGGY_ROOT_USERNAME=iggy
       - IGGY_ROOT_PASSWORD=iggy
-      - IGGY_TCP_ADDRESS=iggy-server:8090
-      # Additional addresses for leader redirection tests
-      - IGGY_TCP_ADDRESS_LEADER=iggy-leader:8091
-      - IGGY_TCP_ADDRESS_FOLLOWER=iggy-follower:8092
+      - BDD_FEATURE=${BDD_FEATURE:-all}
       - RUST_LOG=debug
       - RUSTFLAGS=-C linker=gcc
     volumes:
       - 
./scenarios/basic_messaging.feature:/app/features/basic_messaging.feature
       - 
./scenarios/leader_redirection.feature:/app/features/leader_redirection.feature
-    command: [ "cargo", "test", "-p", "bdd", "--features", "bdd" ]
+    command:
+      - sh
+      - -c
+      - |
+        case "$$BDD_FEATURE" in
+          basic_messaging)    cargo test -p bdd --features bdd --test 
basic_messaging ;;
+          leader_redirection) cargo test -p bdd --features bdd --test 
leader_redirection ;;
+          *)                  cargo test -p bdd --features bdd ;;
+        esac
     networks:
       - iggy-bdd-network
 
   python-bdd:
+    image: iggy-bdd-python
     build:
       context: ..
       dockerfile: bdd/python/Dockerfile
-    depends_on:
-      - iggy-server
     environment:
       - IGGY_ROOT_USERNAME=iggy
       - IGGY_ROOT_PASSWORD=iggy
-      - IGGY_TCP_ADDRESS=iggy-server:8090
     volumes:
       - 
./scenarios/basic_messaging.feature:/app/features/basic_messaging.feature
     working_dir: /app
@@ -241,74 +77,61 @@ services:
       - iggy-bdd-network
 
   go-bdd:
+    image: iggy-bdd-go
     build:
       context: ..
       dockerfile: bdd/go/Dockerfile
-    depends_on:
-      iggy-server:
-        condition: service_healthy
-      iggy-leader:
-        condition: service_healthy
-      iggy-follower:
-        condition: service_healthy
     environment:
       - IGGY_ROOT_USERNAME=iggy
       - IGGY_ROOT_PASSWORD=iggy
-      - IGGY_TCP_ADDRESS=iggy-server:8090
+      - BDD_FEATURE=${BDD_FEATURE:-all}
       - GO_TEST_EXTRA_FLAGS=${GO_TEST_EXTRA_FLAGS:-}
-    volumes:
-      - 
./scenarios/basic_messaging.feature:/app/features/basic_messaging.feature
-    command: [ "sh", "-c", "go test -v ${GO_TEST_EXTRA_FLAGS} ./..." ]
+    command: [ "sh", "-c", "go test -v ${GO_TEST_EXTRA_FLAGS:-} ./..." ]
     networks:
       - iggy-bdd-network
 
   node-bdd:
+    image: iggy-bdd-node
     build:
       context: ..
       dockerfile: bdd/node/Dockerfile
-    depends_on:
-      iggy-server:
-        condition: service_healthy
     environment:
       - IGGY_ROOT_USERNAME=iggy
       - IGGY_ROOT_PASSWORD=iggy
-      - IGGY_TCP_ADDRESS=iggy-server:8090
     command: [ "npm", "run", "test:bdd" ]
     networks:
       - iggy-bdd-network
 
   csharp-bdd:
+    image: iggy-bdd-csharp
     build:
       context: ..
       dockerfile: bdd/csharp/Dockerfile
-    depends_on:
-      iggy-server:
-        condition: service_healthy
-      iggy-leader:
-        condition: service_healthy
-      iggy-follower:
-        condition: service_healthy
     environment:
       - IGGY_ROOT_USERNAME=iggy
       - IGGY_ROOT_PASSWORD=iggy
-      - IGGY_TCP_ADDRESS=iggy-server:8090
-      - IGGY_TCP_ADDRESS_LEADER=iggy-leader:8091
-      - IGGY_TCP_ADDRESS_FOLLOWER=iggy-follower:8092
-    command: [ "dotnet", "test" ]
+      - BDD_FEATURE=${BDD_FEATURE:-all}
+    command:
+      - sh
+      - -c
+      - |
+        FILTER=""
+        case "$$BDD_FEATURE" in
+          basic_messaging)    FILTER='--filter-trait Category=basic-messaging' 
;;
+          leader_redirection) FILTER='--filter-trait 
Category=requires-leader-awareness' ;;
+        esac
+        dotnet test $$FILTER
     networks:
       - iggy-bdd-network
 
   java-bdd:
+    image: iggy-bdd-java
     build:
       context: ..
       dockerfile: bdd/java/Dockerfile
-    depends_on:
-      iggy-server:
-        condition: service_healthy
     environment:
       - IGGY_ROOT_USERNAME=iggy
       - IGGY_ROOT_PASSWORD=iggy
-      - IGGY_TCP_ADDRESS=iggy-server:8090
     volumes:
       - 
./scenarios/basic_messaging.feature:/app/features/basic_messaging.feature
     command: [ "gradle", "--no-daemon", "test" ]
@@ -318,8 +141,3 @@ services:
 networks:
   iggy-bdd-network:
     driver: bridge
-
-volumes:
-  iggy_data:
-  iggy_leader_data:
-  iggy_follower_data:
diff --git a/bdd/go/Dockerfile b/bdd/go/Dockerfile
index 02a6a1c24..ab7f2e779 100644
--- a/bdd/go/Dockerfile
+++ b/bdd/go/Dockerfile
@@ -53,5 +53,4 @@ COPY bdd/scenarios ./bdd/scenarios
 # Change workdir to bdd/go
 WORKDIR /app/bdd/go
 
-# Default command (GO_TEST_EXTRA_FLAGS can inject -race)
 CMD ["sh", "-c", "go test -v ${GO_TEST_EXTRA_FLAGS:-} ./..."]
diff --git a/bdd/go/tests/suite_test.go b/bdd/go/tests/suite_test.go
index cf1f478bb..15d951b44 100644
--- a/bdd/go/tests/suite_test.go
+++ b/bdd/go/tests/suite_test.go
@@ -18,27 +18,44 @@
 package tests
 
 import (
+       "os"
        "testing"
 
        "github.com/cucumber/godog"
 )
 
 func TestFeatures(t *testing.T) {
-       suites := []godog.TestSuite{{
-               ScenarioInitializer: initBasicMessagingScenario,
-               Options: &godog.Options{
-                       Format:   "pretty",
-                       Paths:    
[]string{"../../scenarios/basic_messaging.feature"},
-                       TestingT: t,
-               },
-       }, {
-               ScenarioInitializer: initLeaderRedirectionScenario,
-               Options: &godog.Options{
-                       Format:   "pretty",
-                       Paths:    
[]string{"../../scenarios/leader_redirection.feature"},
-                       TestingT: t,
-               },
-       }}
+       feature := os.Getenv("BDD_FEATURE")
+       if feature == "" {
+               feature = "all"
+       }
+
+       var suites []godog.TestSuite
+       if feature == "all" || feature == "basic_messaging" {
+               suites = append(suites, godog.TestSuite{
+                       ScenarioInitializer: initBasicMessagingScenario,
+                       Options: &godog.Options{
+                               Format:   "pretty",
+                               Paths:    
[]string{"../../scenarios/basic_messaging.feature"},
+                               TestingT: t,
+                       },
+               })
+       }
+       if feature == "all" || feature == "leader_redirection" {
+               suites = append(suites, godog.TestSuite{
+                       ScenarioInitializer: initLeaderRedirectionScenario,
+                       Options: &godog.Options{
+                               Format:   "pretty",
+                               Paths:    
[]string{"../../scenarios/leader_redirection.feature"},
+                               TestingT: t,
+                       },
+               })
+       }
+
+       if len(suites) == 0 {
+               t.Fatalf("unknown BDD_FEATURE=%q", feature)
+       }
+
        for _, s := range suites {
                if s.Run() != 0 {
                        t.Fatal("failing feature tests")
diff --git a/bdd/scenarios/basic_messaging.feature 
b/bdd/scenarios/basic_messaging.feature
index e31eea599..a0daf2463 100644
--- a/bdd/scenarios/basic_messaging.feature
+++ b/bdd/scenarios/basic_messaging.feature
@@ -15,6 +15,7 @@
 # specific language governing permissions and limitations
 # under the License.
 
+@basic-messaging
 Feature: Basic Messaging Operations
   As a developer using Apache Iggy
   I want to perform basic messaging operations
diff --git a/bdd/scenarios/leader_redirection.feature 
b/bdd/scenarios/leader_redirection.feature
index fee32c6d9..35d141f11 100644
--- a/bdd/scenarios/leader_redirection.feature
+++ b/bdd/scenarios/leader_redirection.feature
@@ -16,7 +16,6 @@
 # under the License.
 
 @requires-leader-awareness
-@rust
 Feature: Leader-Aware Client Connections
   As a developer using Apache Iggy with clustering
   I want my SDK clients to automatically connect to the leader node
diff --git a/scripts/run-bdd-tests.sh b/scripts/run-bdd-tests.sh
index cf99c8b1a..24b8449f7 100755
--- a/scripts/run-bdd-tests.sh
+++ b/scripts/run-bdd-tests.sh
@@ -28,23 +28,59 @@ for arg in "$@"; do
 done
 
 SDK="${ARGS[0]:-all}"
-FEATURE="${ARGS[1]:-scenarios/basic_messaging.feature}"
+FEATURE="${ARGS[1]:-all}"
 
-export DOCKER_BUILDKIT=1 FEATURE GO_TEST_EXTRA_FLAGS="${GO_TEST_EXTRA_FLAGS:-}"
+log(){ printf "%b\n" "$*"; }
+
+usage(){
+  log "Usage: $0 [--coverage] <sdk> [feature]"
+  log ""
+  log "  sdk:     rust | python | php | go | go-race | node | csharp | java | 
all | clean (default: all)"
+  log "  feature: basic_messaging | leader_redirection | all  (default: all)"
+  log ""
+  log "Examples:"
+  log "  $0 rust                         # run all features for Rust"
+  log "  $0 rust basic_messaging         # run only basic_messaging for Rust"
+  log "  $0 all leader_redirection       # run leader_redirection for all 
supporting SDKs"
+  log "  $0 --coverage go basic_messaging"
+}
+
+case "$FEATURE" in
+  basic_messaging|leader_redirection|all) ;;
+  *)
+    log "Unknown feature: ${FEATURE}"
+    usage
+    exit 2 ;;
+esac
+
+export DOCKER_BUILDKIT=1 BDD_FEATURE="$FEATURE" 
GO_TEST_EXTRA_FLAGS="${GO_TEST_EXTRA_FLAGS:-}"
 
 cd "$(dirname "$0")/../bdd"
 
-COMPOSE_CMD=(docker compose -f docker-compose.yml)
+ALL_COMPOSE_FILES=(
+  -f docker-compose.yml
+  -f docker-compose.server.yml
+  -f docker-compose.cluster.yml
+  -f docker-compose.coverage.yml
+)
+
+COMPOSE_FILES=(-f docker-compose.yml)
+case "$FEATURE" in
+  basic_messaging|leader_redirection|all)
+    COMPOSE_FILES+=(-f docker-compose.server.yml) ;;
+esac
+case "$FEATURE" in
+  leader_redirection|all)
+    COMPOSE_FILES+=(-f docker-compose.cluster.yml) ;;
+esac
 if [ "$COVERAGE" = "1" ]; then
-  COMPOSE_CMD+=(-f docker-compose.coverage.yml)
+  COMPOSE_FILES+=(-f docker-compose.coverage.yml)
   mkdir -p ../reports
 fi
 
-log(){ printf "%b\n" "$*"; }
-
 cleanup(){
   log "🧹  cleaning up containers & volumes…"
-  "${COMPOSE_CMD[@]}" down -v --remove-orphans >/dev/null 2>&1 || true
+  docker compose "${ALL_COMPOSE_FILES[@]}" down -v --remove-orphans >/dev/null 
2>&1 || true
 }
 trap cleanup EXIT INT TERM
 
@@ -56,12 +92,28 @@ fi
 
 run_suite(){
   local svc="$1" emoji="$2" label="$3"
-  log "${emoji}  ${label}…"
-  set +e
-  "${COMPOSE_CMD[@]}" up --build --abort-on-container-exit --exit-code-from 
"$svc" "$svc"
-  local code=$?
-  set -e
-  "${COMPOSE_CMD[@]}" down -v --remove-orphans >/dev/null 2>&1 || true
+  if [ "$FEATURE" = "leader_redirection" ]; then
+    case "$svc" in
+      rust-bdd|go-bdd|csharp-bdd) ;;
+      *)
+        if [ "$SDK" = "all" ]; then
+          log "⚠️ skipping ${svc%-bdd} (does not support ${FEATURE})"
+          return 0
+        else
+          log "❌ ${SDK} does not support feature '${FEATURE}'"
+          return 1
+        fi
+        ;;
+    esac
+  fi
+
+  log "${emoji} ${label}..."
+  local code=0
+  docker compose "${COMPOSE_FILES[@]}" \
+    up --build --exit-code-from "$svc" "$svc" \
+    || code=$?
+  docker compose "${COMPOSE_FILES[@]}" \
+    down -v --remove-orphans >/dev/null 2>&1 || true
   return "$code"
 }
 
@@ -71,6 +123,9 @@ case "$SDK" in
   php)      run_suite php-bdd    "🐘"   "Running PHP BDD tests"    ;;
   go)       run_suite go-bdd     "🐹"   "Running Go BDD tests"     ;;
   go-race)
+    if [ "$COVERAGE" = "1" ]; then
+      log "⚠️ coverage collection automatically drops -race flag as coverage 
does not need -race"
+    fi
     export GO_TEST_EXTRA_FLAGS="-race"
     run_suite go-bdd "🐹⚡" "Running Go BDD tests with data race detector"
     ;;
@@ -89,11 +144,12 @@ case "$SDK" in
     run_suite java-bdd   "☕"   "Running Java BDD tests"                       
|| exit $?
     ;;
   clean)
-    cleanup; exit 0 ;;
+    cleanup
+    exit 0 ;;
   *)
     log "❌ Unknown SDK: ${SDK}"
-    log "📖 Usage: $0 [--coverage] 
[rust|python|php|go|go-race|node|csharp|java|all|clean] [feature_file]"
+    usage
     exit 2 ;;
 esac
 
-log "✅ BDD tests completed for: ${SDK}"
+log "✅ BDD tests completed for: sdk=${SDK}  feature=${FEATURE}"

Reply via email to