Add initial stress test (#2364)

We need to make a test that runs longer than the tests we had before to check
some problems that might happen after running for some time (e.g. memory
corruption or something else).
This commit is contained in:
Maks Litskevich 2023-08-01 10:38:37 +01:00 committed by GitHub
parent 4b1f027690
commit b88f2c06c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 161 additions and 14 deletions

View File

@ -527,7 +527,7 @@ jobs:
working-directory: ./core/iwasm/libraries/lib-socket/test/
- name: run tests
timeout-minutes: 10
timeout-minutes: 20
run: ./test_wamr.sh ${{ matrix.test_option }} -t ${{ matrix.running_mode }}
working-directory: ./tests/wamr-test-suites
@ -543,7 +543,7 @@ jobs:
sudo apt install -y g++-multilib lib32gcc-9-dev
- name: run tests x86_32
timeout-minutes: 10
timeout-minutes: 20
if: env.TEST_ON_X86_32 == 'true'
run: ./test_wamr.sh ${{ env.X86_32_TARGET_TEST_OPTIONS }} ${{ matrix.test_option }} -t ${{ matrix.running_mode }}
working-directory: ./tests/wamr-test-suites

View File

@ -595,7 +595,7 @@ jobs:
working-directory: ./core/iwasm/libraries/lib-socket/test/
- name: run tests
timeout-minutes: 10
timeout-minutes: 20
run: ./test_wamr.sh ${{ matrix.test_option }} -t ${{ matrix.running_mode }}
working-directory: ./tests/wamr-test-suites
@ -611,7 +611,7 @@ jobs:
sudo apt install -y g++-multilib lib32gcc-9-dev
- name: run tests x86_32
timeout-minutes: 10
timeout-minutes: 20
if: env.TEST_ON_X86_32 == 'true'
run: ./test_wamr.sh ${{ env.X86_32_TARGET_TEST_OPTIONS }} ${{ matrix.test_option }} -t ${{ matrix.running_mode }}
working-directory: ./tests/wamr-test-suites

View File

@ -9,10 +9,13 @@ set -eo pipefail
CC=${CC:=/opt/wasi-sdk/bin/clang}
WAMR_DIR=../../../../..
# Stress tests names
thread_start_file_exclusions=("spawn_stress_test.wasm" "linear_memory_size_update.wasm")
for test_c in *.c; do
test_wasm="$(basename $test_c .c).wasm"
if [ $test_wasm = "linear_memory_size_update.wasm" ]; then
if [[ " ${thread_start_file_exclusions[@]} " =~ " ${test_wasm} " ]] ; then
thread_start_file=""
else
thread_start_file=$WAMR_DIR/samples/wasi-threads/wasm-apps/wasi_thread_start.S

View File

@ -0,0 +1,3 @@
{
"name": "lib-wasi-threads tests"
}

View File

@ -0,0 +1,5 @@
{
"lib-wasi-threads tests": {
"spawn_stress_test": "Stress tests are incompatible with the other part and executed differently"
}
}

View File

@ -0,0 +1,114 @@
/*
* Copyright (C) 2023 Amazon.com Inc. or its affiliates. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#ifndef __wasi__
#error This example only compiles to WASM/WASI target
#endif
#include <assert.h>
#include <errno.h>
#include <math.h>
#include <pthread.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
enum CONSTANTS {
NUM_ITER = 100000,
NUM_RETRY = 5,
MAX_NUM_THREADS = 8,
};
unsigned prime_numbers_count = 0;
bool
is_prime(unsigned int num)
{
for (unsigned int i = 2; i <= (unsigned int)(sqrt(num)); ++i) {
if (num % i == 0) {
return false;
}
}
return true;
}
void *
check_if_prime(void *value)
{
unsigned int *num = (unsigned int *)(value);
usleep(10000);
if (is_prime(*num)) {
__atomic_fetch_add(&prime_numbers_count, 1, __ATOMIC_SEQ_CST);
}
return NULL;
}
unsigned int
validate()
{
unsigned int counter = 0;
for (unsigned int i = 2; i <= NUM_ITER; ++i) {
counter += is_prime(i);
}
return counter;
}
void
spawn_thread(pthread_t *thread, unsigned int *arg)
{
int status_code = -1;
for (int tries = 0; status_code != 0 && tries < NUM_RETRY; ++tries) {
status_code = pthread_create(thread, NULL, &check_if_prime, arg);
assert(status_code == 0 || status_code == EAGAIN);
if (status_code == EAGAIN) {
usleep(2000);
}
}
assert(status_code == 0 && "Thread creation should succeed");
}
int
main(int argc, char **argv)
{
pthread_t threads[MAX_NUM_THREADS];
unsigned int args[MAX_NUM_THREADS];
double percentage = 0.1;
for (unsigned int factorised_number = 2; factorised_number < NUM_ITER;
++factorised_number) {
if (factorised_number > NUM_ITER * percentage) {
fprintf(stderr, "Stress test is %d%% finished\n",
(unsigned int)(percentage * 100));
percentage += 0.1;
}
unsigned int thread_num = factorised_number % MAX_NUM_THREADS;
if (threads[thread_num] != 0) {
assert(pthread_join(threads[thread_num], NULL) == 0);
}
args[thread_num] = factorised_number;
usleep(2000);
spawn_thread(&threads[thread_num], &args[thread_num]);
assert(threads[thread_num] != 0);
}
for (int i = 0; i < MAX_NUM_THREADS; ++i) {
assert(threads[i] == 0 || pthread_join(threads[i], NULL) == 0);
}
// Check the test results
assert(
prime_numbers_count == validate()
&& "Answer mismatch between tested code and reference implementation");
fprintf(stderr, "Stress test finished successfully\n");
return 0;
}

View File

@ -14,6 +14,7 @@ readonly WAMR_DIR="${WORK_DIR}/../../../.."
readonly IWASM_CMD="${WORK_DIR}/../../../../product-mini/platforms/${PLATFORM}/build/iwasm \
--allow-resolve=google-public-dns-a.google.com \
--addr-pool=::1/128,127.0.0.1/32"
readonly IWASM_CMD_STRESS="${IWASM_CMD} --max-threads=8"
readonly WAMRC_CMD="${WORK_DIR}/../../../../wamr-compiler/build/wamrc"
readonly C_TESTS="tests/c/testsuite/"
readonly ASSEMBLYSCRIPT_TESTS="tests/assemblyscript/testsuite/"
@ -24,6 +25,11 @@ readonly LIB_SOCKET_TESTS="${WAMR_DIR}/core/iwasm/libraries/lib-socket/test/"
run_aot_tests () {
local tests=("$@")
for test_wasm in ${tests[@]}; do
local extra_stress_flags=""
if [[ "$test_wasm" =~ "stress" ]]; then
extra_stress_flags="--max-threads=8"
fi
test_aot="${test_wasm%.wasm}.aot"
test_json="${test_wasm%.wasm}.json"
@ -41,7 +47,7 @@ run_aot_tests () {
expected=$(jq .exit_code ${test_json})
fi
${IWASM_CMD} $test_aot
${IWASM_CMD} $extra_stress_flags $test_aot
ret=${PIPESTATUS[0]}
@ -55,15 +61,31 @@ run_aot_tests () {
if [[ $MODE != "aot" ]];then
python3 -m venv wasi-env && source wasi-env/bin/activate
python3 -m pip install -r test-runner/requirements.txt
# Stress test requires max-threads=8 so it's run separately
if [[ -e "${THREAD_INTERNAL_TESTS}spawn_stress_test.wasm" ]]; then
${IWASM_CMD_STRESS} ${THREAD_INTERNAL_TESTS}spawn_stress_test.wasm
ret=${PIPESTATUS[0]}
if [ "${ret}" -ne 0 ]; then
echo "Stress test spawn_stress_test FAILED with code " ${ret}
exit_code=${ret}
fi
fi
TEST_RUNTIME_EXE="${IWASM_CMD}" python3 test-runner/wasi_test_runner.py \
-r adapters/wasm-micro-runtime.py \
-t \
${C_TESTS} \
${ASSEMBLYSCRIPT_TESTS} \
${THREAD_PROPOSAL_TESTS} \
${THREAD_INTERNAL_TESTS} \
${LIB_SOCKET_TESTS}
exit_code=${PIPESTATUS[0]}
-r adapters/wasm-micro-runtime.py \
-t \
${C_TESTS} \
${ASSEMBLYSCRIPT_TESTS} \
${THREAD_PROPOSAL_TESTS} \
${THREAD_INTERNAL_TESTS} \
${LIB_SOCKET_TESTS} \
--exclude-filter "${THREAD_INTERNAL_TESTS}skip.json"
ret=${PIPESTATUS[0]}
if [ "${ret}" -ne 0 ]; then
exit_code=${ret}
fi
deactivate
else
target_option=""