Update gating to tmt, add segfault test

Moving gating to use tmt format for finding/running tests.

Also adding test to cover segfault bug.

Adding perf test script from Thomas Halman for jqspeed.sh.

Dropping log collection in favor of printing on failure for upstream
tests.

Related: RHEL-12897
Related: RHEL-5052
(cherry picked from commit 771c857cf5)
This commit is contained in:
Scott Poore 2023-09-28 11:03:19 -05:00
parent 6ac733a7d9
commit 9c974c6015
13 changed files with 242 additions and 33 deletions

1
.fmf/version Normal file
View File

@ -0,0 +1 @@
1

23
plans/all.fmf Normal file
View File

@ -0,0 +1,23 @@
summary: Run gating tests
discover:
how: fmf
dist-git-source: true
dist-git-type: centos
prepare:
- how: install
package:
- dnf-plugins-core
- https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
- how: shell
script: /usr/bin/crb enable
- how: install
package:
- jq
- jq-devel
- gcc
- wget
- how: shell
script: dnf config-manager --disable epel*
execute:
how: tmt

View File

@ -1,30 +0,0 @@
#!/bin/sh
die () {
echo "$1" >&2
exit 1
}
# link jq binary. This make the tests to use
# installed binary instead of compiled one
cd source || die "missing source directory"
rm -f jq tests/*.log 2>/dev/null
ln -s /usr/bin/jq || die "failed to link jq binary"
# 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"
cat "${t}.log"
die "Test ${t} failed"
fi
done
exit 0

20
tests/performance/jqspeed.sh Executable file
View File

@ -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

View File

@ -0,0 +1,6 @@
summary: Run jq performance/speed test
require:
- jq
- which
- time
test: ./jqspeed.sh

0
tests/pkgs-yum4.yml Normal file
View File

5
tests/provision.fmf Normal file
View File

@ -0,0 +1,5 @@
---
standard-inventory-qcow2:
qemu:
m: 2G

19
tests/segfault/jqsegfault.sh Executable file
View File

@ -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

8
tests/segfault/main.fmf Normal file
View File

@ -0,0 +1,8 @@
summary: Run segfault threads test
require:
- wget
- dnf-utils
- gcc
- jq
- jq-devel
test: ./jqsegfault.sh

View File

@ -0,0 +1,90 @@
#include <stdlib.h>
#include <jq.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
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;
}

View File

@ -10,10 +10,18 @@
- classic
required_packages:
- jq
- gcc
- wget
- jq-devel
- valgrind
- rubygem-rake
tests:
- jqtests:
dir: .
- upstream:
dir: upstream
run: ./jqtests.sh
save-files: ["source/tests/*.log"]
- segfault:
dir: segfault
run: ./jqsegfault.sh
- performance:
dir: performance
run: ./jqspeed.sh

48
tests/upstream/jqtests.sh Executable file
View File

@ -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

11
tests/upstream/main.fmf Normal file
View File

@ -0,0 +1,11 @@
summary: Run jq gating tests
require:
- wget
- dnf-utils
- gcc
- jq
- jq-devel
- valgrind
- diffutils
test: ./jqtests.sh
duration: 30m