#!/bin/bash
#
# Oracle Linux DTrace.
# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
# Licensed under the Universal Permissive License v 1.0 as shown at
# http://oss.oracle.com/licenses/upl.

# This test covers all stapsdt probes fired by the STAP_PROBEn macros.
# Arguments values are checked only for first 10 arguments because
# there is support for arg0 ... arg9 only at this moment.

if [ $# != 1 ]; then
	echo expected one argument: '<'dtrace-path'>'
	exit 2
fi

dtrace=$1
CC=/usr/bin/gcc
CFLAGS="-I${PWD}/test/unittest/usdt"

DIRNAME="$tmpdir/usdt-notes.$$.$RANDOM"
mkdir -p $DIRNAME
cd $DIRNAME

cat > libstapsdttest.c <<EOF
#include <sdt_notes.h>

void
libfn(int argc, char **argv)
{
	if (argc == 0 && argv == 0)
		return;
	STAP_PROBE(test_prov, zero);
	STAP_PROBE1(test_prov, one, argc);
	STAP_PROBE2(test_prov, two, 2, 3);
	STAP_PROBE3(test_prov, three, 4, 5, 7);
	STAP_PROBE4(test_prov, four, 7, 8, 9, 10);
	STAP_PROBE5(test_prov, five, 11, 12, 13, 14, 15);
	STAP_PROBE6(test_prov, six, 16, 17, 18, 19, 20, 21);
	STAP_PROBE7(test_prov, seven, 22, 23, 24, 25, 26, 27, 28);
	STAP_PROBE8(test_prov, eight, 29, 30, 31, 32, 33, 34, 35, 36);
	STAP_PROBE9(test_prov, nine, 37, 38, 39, 40, 41, 42, 43, 44, 45);
	STAP_PROBE10(test_prov, ten, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55);
	STAP_PROBE11(test_prov, eleven, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66);
	STAP_PROBE12(test_prov, twelve, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78);
}
EOF

cat > test.c <<EOF

#include <unistd.h>

extern void libfn(int argc, char **argv);

int
main(int argc, char **argv)
{
	libfn(0, 0);
	sleep(10);
	libfn(argc, argv);
	return 0;
}
EOF

${CC} ${CFLAGS} -c -fpic libstapsdttest.c
${CC} -shared -o libstapsdttest.so libstapsdttest.o
${CC} -L. ${CFLAGS} -o test test.c -lstapsdttest
if [ $? -ne 0 ]; then
	echo "failed to compile test.c" >& 2
	exit 1
fi

export LD_LIBRARY_PATH=.:${LD_LIBRARY_PATH}
LD_LIBRARY_PATH=.:${LD_LIBRARY_PATH} ./test &
PID=$!
sleep 5
$dtrace -p $PID -qs /dev/stdin <<EOF
test_prov\$target:::zero
{
	printf("%s:%s:%s\n", probemod, probefunc, probename);
}

test_prov\$target:::one
{
	printf("%s:%s:%s:%li\n", probemod, probefunc, probename, arg0);
}

test_prov\$target:::two
{
	printf("%s:%s:%s:%li:%li\n", probemod, probefunc, probename, arg0, arg1);
}

test_prov\$target:::three
{
	printf("%s:%s:%s:%li:%li:%li\n", probemod, probefunc, probename, arg0, arg1,
	       arg2);
}

test_prov\$target:::four
{
	printf("%s:%s:%s:%li:%li:%li:%li\n", probemod, probefunc, probename, arg0, arg1,
	       arg2, arg3);
}

test_prov\$target:::five
{
	printf("%s:%s:%s:%li:%li:%li:%li:%li\n", probemod, probefunc, probename,
	       arg0, arg1, arg2, arg3, arg4);
}

test_prov\$target:::six
{
	printf("%s:%s:%s:%li:%li:%li:%li:%li:%li\n", probemod, probefunc, probename,
	       arg0, arg1, arg2, arg3, arg4, arg5);
}

test_prov\$target:::seven
{
	printf("%s:%s:%s:%li:%li:%li:%li:%li:%li:%li\n", probemod, probefunc, probename,
	       arg0, arg1, arg2, arg3, arg4, arg5, arg6);
}

test_prov\$target:::eight
{
	printf("%s:%s:%s:%li:%li:%li:%li:%li:%li:%li:%li\n", probemod, probefunc, probename,
	       arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
}

test_prov\$target:::nine
{
	printf("%s:%s:%s:%li:%li:%li:%li:%li:%li:%li:%li:%li\n", probemod, probefunc, probename,
	       arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
}

test_prov\$target:::ten,
test_prov\$target:::eleven,
test_prov\$target:::twelve
{
	printf("%s:%s:%s:%li:%li:%li:%li:%li:%li:%li:%li:%li:%li\n", probemod, probefunc, probename,
	       arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
}
EOF
status=$?

exit $status
