#!/bin/sh
# PCP QA Test No. 1606
# malloc/free integrity on pmDupContext error paths
#
# non-valgrind variant, see qa/1607 for the valgrind variant
#
# Copyright (c) 2025 Ken McDonell.  All Rights Reserved.
#

if [ $# -eq 0 ]
then
    seq=`basename $0`
    echo "QA output created by $seq"
else
    # use $seq from caller, unless not set
    [ -n "$seq" ] || seq=`basename $0`
    echo "QA output created by `basename $0` $*"
fi

# get standard environment, filters and checks
. ./common.product
. ./common.filter
. ./common.check

src/check_fault_injection >/dev/null 2>&1 || \
    _notrun "libpcp not built with fault injection enabled"

do_valgrind=false
if [ "$1" = "--valgrind" ]
then
    _check_valgrind
    do_valgrind=true
elif which valgrind >/dev/null 2>&1
then
    [ "$PCPQA_VALGRIND" = both ] || \
        _notrun "valgrind variant qa/1607 will be run"
fi

_cleanup()
{
    cd $here
    $sudo rm -rf $tmp $tmp.*
}

status=0	# success is the default!
trap "_cleanup; exit \$status" 0 1 2 3 15

_filter()
{
    sed \
	-e "s@$tmp@TMP@g" \
    # end
}

_do_arch()
{
    if $do_valgrind
    then
	_run_valgrind src/context_test -I -i2 "$@"
    else
	src/context_test -I -i2 "$@" 2>&1
    fi \
    | _filter
}

# avoid derived metrics
export PCP_DERIVED_CONFIG=

# setup mutiarchive dir
# - pmlogrewrite to "fix" hostname and timezone
#
mkdir $tmp || exit 1
cat >$tmp.rewrite <<End-of-File
global {
    hostname -> pcp.qa.com
    timezone -> "UTC"
}
End-of-File
for arch in archives/ok-bigbin archives/ok-mv-bigbin archives/ok-foo
do
    if pmlogrewrite -c $tmp.rewrite $arch `echo $arch | sed -e "s@^archives/@$tmp/@"`
    then
	:
    else
	echo "Arrggh ... rewrite failed"
	status=1
	exit
    fi
done

# setup using libpcp_fault
export PM_FAULT_CONTROL=$tmp.control
export LD_PRELOAD=$PCP_LIB_DIR/libpcp_fault.so

# real QA test starts here

echo "== initial profile malloc fails"
cat >$tmp.control <<End-of-File
libpcp/context.c:0	== 1
End-of-File
_do_arch -h local:

echo
echo "== profile instances malloc fails"
cat >$tmp.control <<End-of-File
libpcp/context.c:1	== 1
End-of-File
_do_arch -h local:

echo
echo "== clone c_archctl malloc fails"
cat >$tmp.control <<End-of-File
libpcp/context.c:2	== 1
End-of-File
_do_arch -a tmparch/foo

echo
echo "== c_archctl->ac_log_list malloc fails"
cat >$tmp.control <<End-of-File
libpcp/context.c:3	== 1
End-of-File
_do_arch -a tmparch/foo

echo
echo "== c_archctl->ac_log_list[0] malloc fails"
cat >$tmp.control <<End-of-File
libpcp/context.c:4	== 1
End-of-File
_do_arch -a $tmp

echo
echo "== c_archctl->ac_log_list[2] malloc fails"
cat >$tmp.control <<End-of-File
libpcp/context.c:4	== 3
End-of-File
_do_arch -a $tmp

echo
echo "== c_archctl->ac_log_list[0]->name strdup fails"
cat >$tmp.control <<End-of-File
libpcp/context.c:5	== 1
End-of-File
_do_arch -a $tmp

echo
echo "== c_archctl->ac_log_list[1]->hostname strdup fails"
cat >$tmp.control <<End-of-File
libpcp/context.c:6	== 2
End-of-File
_do_arch -a $tmp

echo
echo "== c_archctl->ac_log_list[2]->timezone strdup fails"
cat >$tmp.control <<End-of-File
libpcp/context.c:7	== 3
End-of-File
_do_arch -a $tmp

echo
echo "== c_archctl->ac_log_list[0]->zoneinfo strdup fails"
cat >$tmp.control <<End-of-File
libpcp/context.c:8	== 1
End-of-File
_do_arch -a tmparch/foo

echo
echo "== map_handle() fails"
cat >$tmp.control <<End-of-File
libpcp/context.c:9	== 1
End-of-File
_do_arch -h local:

# success, all done
exit
