From 0d0888a448871bda6dc2203ee1c093d83be9d461 Mon Sep 17 00:00:00 2001 From: Tomas Halman Date: Tue, 2 Apr 2024 17:27:45 +0200 Subject: [PATCH] Add gating tests configuration --- .fmf/version | 1 + gating.yaml | 6 ++ plans/all.fmf | 18 ++++ tests/performance/jqspeed.sh | 20 +++++ tests/performance/main.fmf | 6 ++ tests/pkgs-yum4.yml | 0 tests/provision.fmf | 5 ++ tests/segfault/jqsegfault.sh | 19 ++++ tests/segfault/main.fmf | 8 ++ .../test_segfault_with_multithreaded_env.c | 90 +++++++++++++++++++ tests/tests.yml | 27 ++++++ tests/upstream/jqtests.sh | 48 ++++++++++ tests/upstream/main.fmf | 11 +++ 13 files changed, 259 insertions(+) create mode 100644 .fmf/version create mode 100644 gating.yaml create mode 100644 plans/all.fmf create mode 100755 tests/performance/jqspeed.sh create mode 100644 tests/performance/main.fmf create mode 100644 tests/pkgs-yum4.yml create mode 100644 tests/provision.fmf create mode 100755 tests/segfault/jqsegfault.sh create mode 100644 tests/segfault/main.fmf create mode 100644 tests/segfault/test_segfault_with_multithreaded_env.c create mode 100644 tests/tests.yml create mode 100755 tests/upstream/jqtests.sh create mode 100644 tests/upstream/main.fmf diff --git a/.fmf/version b/.fmf/version new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/.fmf/version @@ -0,0 +1 @@ +1 diff --git a/gating.yaml b/gating.yaml new file mode 100644 index 0000000..4ca9235 --- /dev/null +++ b/gating.yaml @@ -0,0 +1,6 @@ +--- !Policy +product_versions: + - rhel-10 +decision_context: osci_compose_gate +rules: + - !PassingTestCaseRule {test_case_name: osci.brew-build.tier0.functional} diff --git a/plans/all.fmf b/plans/all.fmf new file mode 100644 index 0000000..d36f996 --- /dev/null +++ b/plans/all.fmf @@ -0,0 +1,18 @@ +summary: Run gating tests +discover: + how: fmf + dist-git-source: true + dist-git-type: centos +prepare: + - how: install + package: + - dnf-plugins-core + - how: install + package: + - jq + - jq-devel + - gcc + - wget + +execute: + how: tmt diff --git a/tests/performance/jqspeed.sh b/tests/performance/jqspeed.sh new file mode 100755 index 0000000..9840c2d --- /dev/null +++ b/tests/performance/jqspeed.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +export LC_ALL=C + +stress_jq() { + `which time` -p -f '%e\n' bash -c 'for i in `seq 1 1000` ; do echo '"'"'{"foo":"bar"}'"'"' | jq '"'"'has("bar")'"'"' > /dev/null ; done' 2>&1 | cut -d. -f1 +} + +FAIL=0 +TIME=`stress_jq` +echo -n "Test jqspeed ... " +if [ $TIME -gt 8 ] ; then + echo "failed" + FAIL=1 +else + echo "ok" +fi + +echo "Runtime: ${TIME}s " +exit $FAIL diff --git a/tests/performance/main.fmf b/tests/performance/main.fmf new file mode 100644 index 0000000..b1a8e27 --- /dev/null +++ b/tests/performance/main.fmf @@ -0,0 +1,6 @@ +summary: Run jq performance/speed test +require: + - jq + - which + - time +test: ./jqspeed.sh diff --git a/tests/pkgs-yum4.yml b/tests/pkgs-yum4.yml new file mode 100644 index 0000000..e69de29 diff --git a/tests/provision.fmf b/tests/provision.fmf new file mode 100644 index 0000000..62a6eba --- /dev/null +++ b/tests/provision.fmf @@ -0,0 +1,5 @@ +--- + +standard-inventory-qcow2: + qemu: + m: 2G diff --git a/tests/segfault/jqsegfault.sh b/tests/segfault/jqsegfault.sh new file mode 100755 index 0000000..96369c9 --- /dev/null +++ b/tests/segfault/jqsegfault.sh @@ -0,0 +1,19 @@ +#!/bin/sh + +FAIL=0 + +# Test for segfault in multithreaded environment +gcc -o test_segfault test_segfault_with_multithreaded_env.c -lpthread -ljq && \ +./test_segfault +RET=$? + +echo -n "Test jqsegfault ... " + +if [ $RET != 0 ]; then + echo "failed" + FAIL=1 +else + echo "ok" +fi + +exit $FAIL diff --git a/tests/segfault/main.fmf b/tests/segfault/main.fmf new file mode 100644 index 0000000..9b2850d --- /dev/null +++ b/tests/segfault/main.fmf @@ -0,0 +1,8 @@ +summary: Run segfault threads test +require: + - wget + - dnf-utils + - gcc + - jq + - jq-devel +test: ./jqsegfault.sh diff --git a/tests/segfault/test_segfault_with_multithreaded_env.c b/tests/segfault/test_segfault_with_multithreaded_env.c new file mode 100644 index 0000000..c8e2622 --- /dev/null +++ b/tests/segfault/test_segfault_with_multithreaded_env.c @@ -0,0 +1,90 @@ +#include +#include +#include +#include +#include +#include + +int my_jq_parse(jq_state *jq, struct jv_parser *parser) +{ + int rv = 0; + jv value; + + value = jv_parser_next(parser); + while (jv_is_valid(value)) { + jq_start(jq, value, 0); + jv result; + + while (jv_is_valid(result = jq_next(jq))) { + jv dumped = jv_dump_string(result, 0); + const char *str = jv_string_value(dumped); + printf("dumped: %s\n", str); + } + + jv_free(result); + value = jv_parser_next(parser); + } + + if (jv_invalid_has_msg(jv_copy(value))) { + jv msg = jv_invalid_get_msg(value); + printf("invalid: %s\n", jv_string_value(msg)); + jv_free(msg); + rv = 1; + } else { + jv_free(value); + } + + return rv; +} + +void *run(void *not_used) { + int rv; + jq_state *jq; + const char *prg = ".data"; + + jq = jq_init(); + printf("jq_init jq: %p prg: %s\n", jq, prg); + if (jq_compile(jq, prg) == 0) { + jq_teardown(&jq); + return NULL; + } + printf("compiled\n"); + + struct jv_parser *parser = jv_parser_new(0); + const char *buf = "{ \"data\": 1 }"; + jv_parser_set_buf(parser, buf, strlen(buf), 0); + rv = my_jq_parse(jq, parser); + if (rv != 0) { + printf("my_jq_parse failed!\n"); + } + + jv_parser_free(parser); + jq_teardown(&jq); + return NULL; +} + +#define THREADS 2 +/* calling run() twice works fine */ +/* calling them in threads causes core-dump */ +int main (int argc, char *argv[]) +{ + pthread_t threads[THREADS]; + int createerror; + int a; + + memset(&threads, 0, sizeof(threads)); + for (a = 0; a < THREADS; ++a) { + // sleep(1); // < if you want to run threads sequentionally + createerror = pthread_create(&threads[a], NULL, run, NULL); + if (createerror) { + printf("create thread error %d\n", a); + } + } + for(a = 0; a < THREADS; ++a) { + if (threads[a] != 0) { + pthread_join(threads[a], NULL); + } + } + + return 0; +} diff --git a/tests/tests.yml b/tests/tests.yml new file mode 100644 index 0000000..f2f5ccc --- /dev/null +++ b/tests/tests.yml @@ -0,0 +1,27 @@ +--- +- hosts: localhost + roles: + - role: standard-test-source + tags: + - always + + - role: standard-test-basic + tags: + - classic + required_packages: + - jq + - gcc + - wget + - jq-devel + - valgrind + - rubygem-rake + tests: + - upstream: + dir: upstream + run: ./jqtests.sh + - segfault: + dir: segfault + run: ./jqsegfault.sh + - performance: + dir: performance + run: ./jqspeed.sh diff --git a/tests/upstream/jqtests.sh b/tests/upstream/jqtests.sh new file mode 100755 index 0000000..3c859f5 --- /dev/null +++ b/tests/upstream/jqtests.sh @@ -0,0 +1,48 @@ +#!/bin/sh + +die () { + echo "$1" >&2 + exit 1 +} + +# If source not found, download it with dnf +if [ ! -d ./source ]; then + # Extract source from srpm + dnf download --source jq && \ + rpm2cpio jq*.rpm|cpio -id && \ + mkdir source && \ + tar -zxf jq-*.tar.gz -C source --strip-components=1 + if [ $? != 0 ]; then + echo "Failed to download upstream tests" + exit 1 + fi +fi + +pushd ./source || die "missing source directory" +rm -f jq tests/*.log 2>/dev/null +ln -s /usr/bin/jq || die "failed to link jq binary" + +FAIL=0 + +# run the tests +# List of tests is taken from Makefile +TESTS="tests/optionaltest tests/mantest tests/jqtest tests/onigtest tests/shtest tests/utf8test tests/base64test" + +for t in $TESTS; do + echo -n "Test $t ... " + ./${t} >"${t}.log" 2>&1 + RET=$? + if [ $RET = 0 ]; then + echo "ok" + else + echo "failed" + echo "-------------------- ${t}.log start -----------------------------" + cat "${t}.log" + echo "-------------------- ${t}.log end -----------------------------" + FAIL=1 + fi +done + +popd # exit SOURCE_DIR + +exit $FAIL diff --git a/tests/upstream/main.fmf b/tests/upstream/main.fmf new file mode 100644 index 0000000..bed862c --- /dev/null +++ b/tests/upstream/main.fmf @@ -0,0 +1,11 @@ +summary: Run jq gating tests +require: + - wget + - dnf-utils + - gcc + - jq + - jq-devel + - valgrind + - diffutils +test: ./jqtests.sh +duration: 30m