#!/bin/bash
#
# Copyright (C) 2013 Christian Babeux <christian.babeux@efficios.com>
# Copyright (C) 2014, 2016 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
#
# SPDX-License-Identifier: GPL-2.0-only
#

TEST_DESC="Kernel tracer - Clock override plugin"

CURDIR=$(dirname $0)/
TESTDIR=$CURDIR/../..
SESSION_NAME="clock_override"

NUM_TESTS=30
EVENT_NAME="lttng_test_filter_event"

TESTCMD="echo -n 10 > /proc/lttng-test-filter-event"

METADATA_CLOCK_START_TOKEN="clock {"
METADATA_CLOCK_END_TOKEN="};"

METADATA_TOKEN_LIST=(
	"name"
	"uuid"
	"description"
	"freq"
)

CLOCK_TOKEN_VALUE=(
	"lttng_test_clock_override"
	"83c63deb-7aa4-48fb-abda-946f400d76e6"
	"Freeze time with 1KHz for regression test"
	"1000"
)

source $TESTDIR/utils/utils.sh

function signal_cleanup()
{
	diag "*** Exiting ***"
	stop_lttng_sessiond
	modprobe --remove lttng-test lttng-clock-plugin-test lttng-clock
	full_cleanup
}

function extract_clock_metadata()
{
	local metadata_file=$1
	local clock_metadata_file_destination=$2
	cat $metadata_file \
		| sed -n "/$METADATA_CLOCK_START_TOKEN/,/$METADATA_CLOCK_END_TOKEN/p" \
		> $clock_metadata_file_destination
	ok $? "Clock metadata extraction"
}

function extract_clock_metadata_token()
{
	local clock_metadata_file=$1
	local token=$2
	# Look for token and get value between ""
	cat $clock_metadata_file | grep $token | awk -F"= |;" '{print $2}' | tr -d '"'
}

function test_clock_override_metadata()
{
	local ctf_metadata_file=$(mktemp -p $TRACE_PATH ctf-metadata.XXXXXX)
	local clock_metadata_file=$(mktemp -p $TRACE_PATH clock-metadata.XXXXXX)
	local result=""

	diag "Clock override plugin metadata test"

	modprobe lttng-clock-plugin-test
	start_lttng_sessiond
	modprobe lttng-test

	create_lttng_session_ok $SESSION_NAME $TRACE_PATH
	enable_kernel_lttng_event_ok $SESSION_NAME "$EVENT_NAME"
	start_lttng_tracing_ok $SESSION_NAME
	eval ${TESTCMD}
	stop_lttng_tracing_ok $SESSION_NAME
	destroy_lttng_session_ok $SESSION_NAME

	stop_lttng_sessiond
	modprobe --remove lttng-test lttng-clock-plugin-test lttng-clock

	local TRACE_METADATA_FILE_PATH="$(find "$TRACE_PATH" -name metadata -type f)"
	local TRACE_METADATA_DIR="$(dirname "$TRACE_METADATA_FILE_PATH")"

	$BABELTRACE_BIN -o ctf-metadata -w $ctf_metadata_file $TRACE_METADATA_DIR
	ok $? "Metadata extraction from babeltrace"

	extract_clock_metadata $ctf_metadata_file $clock_metadata_file

	test ${#METADATA_TOKEN_LIST[@]} -eq ${#CLOCK_TOKEN_VALUE[@]}
	ok $? "Tokens to check(${#METADATA_TOKEN_LIST[@]}) and provided values(${#CLOCK_TOKEN_VALUE[@]}) count is equal"

	local counter=0
	while [ "$counter" -lt "${#METADATA_TOKEN_LIST[@]}" ]; do
		result=$(extract_clock_metadata_token $clock_metadata_file \
			${METADATA_TOKEN_LIST[$counter]})
		test "$result" == "${CLOCK_TOKEN_VALUE[$counter]}"
		ok $? "Token \"${METADATA_TOKEN_LIST[$counter]}\" expect:${CLOCK_TOKEN_VALUE[$counter]} got:$result"
		let "counter++"
	done
	rm -rf $ctf_metadata_file
	rm -rf $clock_metadata_file
}

function test_clock_override_timestamp()
{
	diag "Clock override test"

	# Test without the plugin
	diag "Plugin disabled"

	start_lttng_sessiond
	modprobe lttng-test

	create_lttng_session_ok $SESSION_NAME $TRACE_PATH
	enable_kernel_lttng_event_ok $SESSION_NAME "$EVENT_NAME"
	start_lttng_tracing_ok $SESSION_NAME
	eval ${TESTCMD}
	stop_lttng_tracing_ok $SESSION_NAME
	destroy_lttng_session_ok $SESSION_NAME

	# Use Babeltrace with "-n all" to give a comma separated list for
	# easy extraction of timestamps.
	unique_timestamps_count=$($BABELTRACE_BIN -n all $TRACE_PATH | \
		cut -d, -f1 | uniq | wc -l)
	test $unique_timestamps_count -gt 1
	ok $? "Unique event timestamps without clock override: $unique_timestamps_count expect >1"
	modprobe --remove lttng-test
	stop_lttng_sessiond

	# Test with clock override plugin.
	diag "Plugin enabled"

	modprobe lttng-clock-plugin-test
	start_lttng_sessiond
	modprobe lttng-test

	start_lttng_sessiond
	create_lttng_session_ok $SESSION_NAME $TRACE_PATH
	enable_kernel_lttng_event_ok $SESSION_NAME "$EVENT_NAME"
	start_lttng_tracing_ok $SESSION_NAME
	eval ${TESTCMD}
	stop_lttng_tracing_ok $SESSION_NAME
	destroy_lttng_session_ok $SESSION_NAME

	stop_lttng_sessiond
	modprobe --remove lttng-clock-plugin-test lttng-clock lttng-test

	# Use Babeltrace with "-n all" to give a comma separated list for
	# easy extraction of timestamps.
	unique_timestamps_count=$($BABELTRACE_BIN -n all $TRACE_PATH | \
		cut -d, -f1 | uniq | wc -l)
	test $unique_timestamps_count -eq 1
	ok $? "Unique event timestamps with clock override: $unique_timestamps_count expect 1"
}

# MUST set TESTDIR before calling those functions
plan_tests $NUM_TESTS

print_test_banner "$TEST_DESC"

TESTS=(
	"test_clock_override_metadata"
	"test_clock_override_timestamp"
)

TEST_COUNT=${#TESTS[@]}
i=0

if [ "$(id -u)" == "0" ]; then
	isroot=1
else
	isroot=0
fi

skip $isroot "Root access is needed. Skipping all tests." $NUM_TESTS ||
{
	trap signal_cleanup SIGTERM SIGINT

	while [ "$i" -lt "$TEST_COUNT" ]; do

		TRACE_PATH=$(mktemp -d)

		# Execute test
		${TESTS[$i]}

		rm -rf $TRACE_PATH

		let "i++"
	done
}
