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-12896 Related: RHEL-13431
This commit is contained in:
parent
ae78ba56c6
commit
771c857cf5
1
.fmf/version
Normal file
1
.fmf/version
Normal file
@ -0,0 +1 @@
|
|||||||
|
1
|
23
plans/all.fmf
Normal file
23
plans/all.fmf
Normal 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-9.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
|
@ -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
20
tests/performance/jqspeed.sh
Executable 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
|
6
tests/performance/main.fmf
Normal file
6
tests/performance/main.fmf
Normal 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
0
tests/pkgs-yum4.yml
Normal file
5
tests/provision.fmf
Normal file
5
tests/provision.fmf
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
standard-inventory-qcow2:
|
||||||
|
qemu:
|
||||||
|
m: 2G
|
19
tests/segfault/jqsegfault.sh
Executable file
19
tests/segfault/jqsegfault.sh
Executable 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
8
tests/segfault/main.fmf
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
summary: Run segfault threads test
|
||||||
|
require:
|
||||||
|
- wget
|
||||||
|
- dnf-utils
|
||||||
|
- gcc
|
||||||
|
- jq
|
||||||
|
- jq-devel
|
||||||
|
test: ./jqsegfault.sh
|
90
tests/segfault/test_segfault_with_multithreaded_env.c
Normal file
90
tests/segfault/test_segfault_with_multithreaded_env.c
Normal 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;
|
||||||
|
}
|
@ -10,10 +10,18 @@
|
|||||||
- classic
|
- classic
|
||||||
required_packages:
|
required_packages:
|
||||||
- jq
|
- jq
|
||||||
|
- gcc
|
||||||
|
- wget
|
||||||
|
- jq-devel
|
||||||
- valgrind
|
- valgrind
|
||||||
- rubygem-rake
|
- rubygem-rake
|
||||||
tests:
|
tests:
|
||||||
- jqtests:
|
- upstream:
|
||||||
dir: .
|
dir: upstream
|
||||||
run: ./jqtests.sh
|
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
48
tests/upstream/jqtests.sh
Executable 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
11
tests/upstream/main.fmf
Normal 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
|
Loading…
Reference in New Issue
Block a user