pw stress tests
diff --git a/.bazelrc b/.bazelrc index dd92fd3..ab8b222 100644 --- a/.bazelrc +++ b/.bazelrc
@@ -83,4 +83,20 @@ # Mirrors k_common's test_tag_filters and adds -hardware (physical-board-only tests). # Combined into one flag to avoid the Bazel 'expanded from multiple configs' warning # that fires when --test_tag_filters is set by both k_common and this config. -test:virt_ast10x0 --test_tag_filters=-integration,-do_not_build,-do_not_run_test,-kernel_doc_test,-hardware \ No newline at end of file +test:virt_ast10x0 --test_tag_filters=-integration,-do_not_build,-do_not_run_test,-kernel_doc_test,-hardware + +# Stress test configs — identical to the base configs but with --no-timeout in +# --run_under and +stress in test_tag_filters so only stress targets are run. +common:stress_virt_ast10x0 --platforms=//target/ast10x0 +common:stress_virt_ast10x0 --//target/ast10x0:qemu=true +build:stress_virt_ast10x0 --build_tag_filters=-do_not_build,-kernel_doc_test +run:stress_virt_ast10x0 --run_under="//target/ast10x0/harness:qemu_runner \ + --no-timeout --cpu cortex-m4 --machine ast1030-evb --image " +test:stress_virt_ast10x0 --run_under="//target/ast10x0/harness:qemu_runner \ + --no-timeout --cpu cortex-m4 --machine ast1030-evb --image " +common:stress_k_ast1060_evb --platforms=//target/ast10x0 +build:stress_k_ast1060_evb --build_tag_filters=-do_not_build,-kernel_doc_test +test:stress_k_ast1060_evb --local_test_jobs=1 +test:stress_k_ast1060_evb --run_under="//target/ast10x0/harness:test_runner \ + --timeout 0 " +test:stress_k_ast1060_evb --test_env=AST1060_EVB_PI_HOST
diff --git a/target/ast10x0/harness/qemu_runner.py b/target/ast10x0/harness/qemu_runner.py index 10fe61c..0ea4e46 100644 --- a/target/ast10x0/harness/qemu_runner.py +++ b/target/ast10x0/harness/qemu_runner.py
@@ -55,6 +55,11 @@ parser.add_argument( "--qemu-args", nargs="*", help="Extra arguments to pass to qemu" ) + parser.add_argument( + "--no-timeout", + action="store_true", + help="Run indefinitely; for stress tests that never emit PASS", + ) return parser.parse_args() @@ -138,7 +143,7 @@ result = [None] # 0 = pass, 1 = fail, None = no sentinel found with tempfile.NamedTemporaryFile() as f: - with subprocess.Popen(args=qemu_args, stdout=f) as proc: + with subprocess.Popen(args=qemu_args, stdout=f, stdin=subprocess.DEVNULL) as proc: qemu_finished = threading.Event() sentinel_thread = threading.Thread( target=_sentinel_watcher, @@ -154,7 +159,13 @@ stdout_thread.start() try: - proc.wait(timeout=TIMEOUT_SECONDS) + if args.no_timeout: + proc.wait() + else: + proc.wait(timeout=TIMEOUT_SECONDS) + except KeyboardInterrupt: + proc.kill() + proc.wait() except subprocess.TimeoutExpired: _LOG.error( "Test timed out after %ds — no sentinel detected",
diff --git a/target/ast10x0/harness/stress_image_test.bzl b/target/ast10x0/harness/stress_image_test.bzl new file mode 100644 index 0000000..0e60d76 --- /dev/null +++ b/target/ast10x0/harness/stress_image_test.bzl
@@ -0,0 +1,40 @@ +# Licensed under the Apache-2.0 license +# SPDX-License-Identifier: Apache-2.0 +"""Bazel rule for stress test images. + +Stress tests loop forever and only exit on TEST_RESULT:FAIL. This rule +produces a test target that relies on --run_under to supply the runner, +exactly like system_image_test. Use the stress_virt_ast10x0 or +stress_k_ast1060_evb configs which pass --no-timeout to the runner. +""" + +load("@pigweed//pw_kernel/tooling:system_image.bzl", "SystemImageInfo") + +def _stress_image_test_impl(ctx): + executable_symlink = ctx.actions.declare_file(ctx.label.name) + ctx.actions.symlink( + output = executable_symlink, + target_file = ctx.attr.image[SystemImageInfo].elf, + ) + + return [ + DefaultInfo( + executable = executable_symlink, + runfiles = ctx.attr.image[DefaultInfo].default_runfiles, + ), + ] + +stress_image_test = rule( + implementation = _stress_image_test_impl, + test = True, + attrs = { + "image": attr.label( + doc = "The system_image target to test.", + mandatory = True, + providers = [DefaultInfo, SystemImageInfo], + executable = True, + cfg = "target", + ), + }, + doc = "Defines a stress test for a system_image. Use with stress_virt_ast10x0 or stress_k_ast1060_evb config.", +)
diff --git a/target/ast10x0/tests/stress/README.md b/target/ast10x0/tests/stress/README.md new file mode 100644 index 0000000..510e3bf --- /dev/null +++ b/target/ast10x0/tests/stress/README.md
@@ -0,0 +1,37 @@ +# AST10x0 Stress Tests + +Stress tests run forever and only exit on `TEST_RESULT:FAIL`. They are excluded +from CI and must be run manually using one of the configs below. + +## Tests + +| Target | What it stresses | +|---|---| +| `stress/mutex/kernel:mutex_stress_test` | Mutex contention across three kernel threads | +| `stress/ipc/user:ipc_stress_test` | IPC channel between initiator and handler processes | +| `stress/process_termination/user:process_termination_stress_test` | Repeated process termination and restart | + +## Running on QEMU + +``` +# Open-ended soak — runs until Ctrl-C or FAIL, no timeout. +# Target the system_image directly, not the _stress_test rule. +bazel run --config=stress_virt_ast10x0 //target/ast10x0/tests/stress/mutex/kernel:mutex + +# Timed run — Bazel kills after 3600s if no FAIL detected. +bazel test --config=stress_virt_ast10x0 //target/ast10x0/tests/stress/<test>:*_stress_test +``` + +Use `bazel run` on the `system_image` target (`:mutex`, `:ipc`, `:process_termination`) +for open-ended soak testing — this runs QEMU directly with no wrappers. +`bazel test` targets the `_stress_test` rule and is bounded by Bazel's 3600s ceiling. + +## Running on hardware (EVB via Pi fixture) + +``` +AST1060_EVB_PI_HOST=<pi-hostname> bazel test --config=stress_k_ast1060_evb //target/ast10x0/tests/stress/<test> +``` + +`bazel run` is not supported for EVB — the Pi fixture is only wired into +`bazel test`. Tests run one at a time (`--local_test_jobs=1` is inherited from +`k_ast1060_evb`) and have no runner timeout.
diff --git a/target/ast10x0/tests/stress/ipc/user/BUILD.bazel b/target/ast10x0/tests/stress/ipc/user/BUILD.bazel index 2510ac1..8d8b284 100644 --- a/target/ast10x0/tests/stress/ipc/user/BUILD.bazel +++ b/target/ast10x0/tests/stress/ipc/user/BUILD.bazel
@@ -7,6 +7,7 @@ load("@pigweed//pw_kernel/tooling/panic_detector:rust_binary_no_panics_test.bzl", "rust_binary_no_panics_test") load("@rules_rust//rust:defs.bzl", "rust_binary") load("//target/ast10x0:defs.bzl", "TARGET_COMPATIBLE_WITH") +load("//target/ast10x0/harness:stress_image_test.bzl", "stress_image_test") system_image( name = "ipc", @@ -27,6 +28,17 @@ tags = ["kernel"], ) +stress_image_test( + name = "ipc_stress_test", + image = ":ipc", + tags = [ + "kernel", + "do_not_run_test", + ], + target_compatible_with = TARGET_COMPATIBLE_WITH, + timeout = "eternal", +) + filegroup( name = "system_config", srcs = ["system.json5"],
diff --git a/target/ast10x0/tests/stress/mutex/kernel/BUILD.bazel b/target/ast10x0/tests/stress/mutex/kernel/BUILD.bazel index adc3068..a0bddda 100644 --- a/target/ast10x0/tests/stress/mutex/kernel/BUILD.bazel +++ b/target/ast10x0/tests/stress/mutex/kernel/BUILD.bazel
@@ -6,6 +6,7 @@ load("@pigweed//pw_kernel/tooling/panic_detector:rust_binary_no_panics_test.bzl", "rust_binary_no_panics_test") load("@rules_rust//rust:defs.bzl", "rust_binary") load("//target/ast10x0:defs.bzl", "TARGET_COMPATIBLE_WITH") +load("//target/ast10x0/harness:stress_image_test.bzl", "stress_image_test") system_image( name = "mutex", @@ -23,6 +24,17 @@ tags = ["kernel"], ) +stress_image_test( + name = "mutex_stress_test", + image = ":mutex", + tags = [ + "kernel", + "do_not_run_test", + ], + target_compatible_with = TARGET_COMPATIBLE_WITH, + timeout = "eternal", +) + filegroup( name = "system_config", srcs = ["system.json5"],
diff --git a/target/ast10x0/tests/stress/process_termination/user/BUILD.bazel b/target/ast10x0/tests/stress/process_termination/user/BUILD.bazel index 0a30fba..d32e72a 100644 --- a/target/ast10x0/tests/stress/process_termination/user/BUILD.bazel +++ b/target/ast10x0/tests/stress/process_termination/user/BUILD.bazel
@@ -7,6 +7,7 @@ load("@pigweed//pw_kernel/tooling/panic_detector:rust_binary_no_panics_test.bzl", "rust_binary_no_panics_test") load("@rules_rust//rust:defs.bzl", "rust_binary") load("//target/ast10x0:defs.bzl", "TARGET_COMPATIBLE_WITH") +load("//target/ast10x0/harness:stress_image_test.bzl", "stress_image_test") system_image( name = "process_termination", @@ -27,6 +28,17 @@ tags = ["kernel"], ) +stress_image_test( + name = "process_termination_stress_test", + image = ":process_termination", + tags = [ + "kernel", + "do_not_run_test", + ], + target_compatible_with = TARGET_COMPATIBLE_WITH, + timeout = "eternal", +) + filegroup( name = "system_config", srcs = ["system.json5"],
diff --git a/workflows.json b/workflows.json index d1f1919..5d9ca2a 100644 --- a/workflows.json +++ b/workflows.json
@@ -129,7 +129,7 @@ "args": [ "--keep_going", "--config=virt_ast10x0", - "--test_tag_filters=-hardware", + "--test_tag_filters=-hardware,-do_not_run_test", "--test_output=streamed" ], "driver_options": {