#!/bin/bash
#
# SPDX-FileCopyrightText: 2023 Kienan Stewart <kstewart@efficios.com>
# SPDX-FileCopyrightText: 2025 Michael Jeanson <mjeanson@efficios.com>
#
# SPDX-License-Identifier: LGPL-2.1-only
#

TEST_DESC="Verifies that the sessiond starts (or doesn't start) appropriately depending on the combination of path settings in conjuction with LTTNG_UST_ALLOW_BLOCKING and '--blocking-timeout'"

CURDIR="$(dirname "${0}")"
TESTDIR="${CURDIR}/../../.."

# shellcheck source-path=SCRIPTDIR/../../..
source "${TESTDIR}/utils/utils.sh"

TESTAPP="${TESTDIR}/utils/testapp/gen-ust-events"

NR_ITER=100

SESSION_NAME="ust-blocking"
CHANNEL_NAME="ust-blocking"
EVENT_NAMES="tp:tptest"

NUM_TESTS=37

function test_blocking_mode_app_path()
{
	local app_path
	local trace_path
	local env_vars
	local file_testapp_output

	app_path="$(mktemp -d -t "tmp.${FUNCNAME[0]}.app.XXXXXX")"
	trace_path="$(mktemp -d -t "tmp.${FUNCNAME[0]}.trace.XXXXXX")"
	file_testapp_output=$(mktemp -u -t "tmp.${FUNCNAME[0]}_testapp_output.XXXXXX")

	env_vars=(
		LTTNG_UST_ALLOW_BLOCKING=1
		LTTNG_UST_APP_PATH="${app_path}"
	)

	LTTNG_SESSIOND_ENV_VARS="${env_vars[*]}" start_lttng_sessiond
	create_lttng_session_ok "${SESSION_NAME}" "${trace_path}"
	enable_ust_lttng_channel_ok "${SESSION_NAME}" "${CHANNEL_NAME}" "--blocking-timeout=inf"
	enable_ust_lttng_event_ok "${SESSION_NAME}" "--all" "${CHANNEL_NAME}"
	start_lttng_tracing_ok "${SESSION_NAME}"

	run_testapp_ok "$file_testapp_output" "${TESTAPP}" -i $NR_ITER -w 0

	stop_lttng_tracing_ok "${SESSION_NAME}"
	destroy_lttng_session_ok "${SESSION_NAME}" --no-wait

	validate_trace_count "${EVENT_NAMES}" "${trace_path}" $NR_ITER

	stop_lttng_sessiond

	rm -rf "${app_path}" "${trace_path}"
	rm -f "$file_testapp_output"
}

function test_blocking_mode_default_paths()
{
	local env_vars

	diag "Test starting sessiond in blocking with neither LTTNG_UST_APP_PATH nor LTTNG_UST_CTL_PATH set"

	env_vars=(
		LTTNG_UST_ALLOW_BLOCKING=1
	)

	LTTNG_SESSIOND_ENV_VARS="${env_vars[*]}" start_lttng_sessiond_fail
	stop_lttng_sessiond_cleanup
}

function test_blocking_mode_ctl_path()
{
	local ctl_path
	local trace_path
	local file_testapp_output
	local env_vars

	diag "Test starting sessiond in blocking with LTTNG_UST_CTL_PATH set"

	ctl_path="$(mktemp -d -t "tmp.${FUNCNAME[0]}.ctl.XXXXXX")"
	trace_path="$(mktemp -d -t "tmp.${FUNCNAME[0]}.trace.XXXXXX")"
	file_testapp_output=$(mktemp -u -t "tmp.${FUNCNAME[0]}_testapp_output.XXXXXX")

	env_vars=(
		LTTNG_UST_ALLOW_BLOCKING=1
		LTTNG_UST_CTL_PATH="${ctl_path}"
	)

	LTTNG_SESSIOND_ENV_VARS="${env_vars[*]}" start_lttng_sessiond
	create_lttng_session_ok "${SESSION_NAME}" "${trace_path}"
	enable_ust_lttng_channel_ok "${SESSION_NAME}" "${CHANNEL_NAME}" "--blocking-timeout=inf"
	enable_ust_lttng_event_ok "${SESSION_NAME}" "--all" "${CHANNEL_NAME}"
	start_lttng_tracing_ok "${SESSION_NAME}"

	LTTNG_UST_APP_PATH="${ctl_path}" run_testapp_ok "$file_testapp_output" "${TESTAPP}" -i $NR_ITER -w 0

	stop_lttng_tracing_ok "${SESSION_NAME}"
	destroy_lttng_session_ok "${SESSION_NAME}" --no-wait
	validate_trace_count "${EVENT_NAMES}" "${trace_path}" $NR_ITER

	stop_lttng_sessiond

	rm -rf "${ctl_path}" "${trace_path}"
	rm -f "$file_testapp_output"
}

function test_blocking_mode_with_different_paths()
{
	local ctl_path
	local app_path
	local trace_path
	local env_vars
	local file_testapp_output

	diag "Test starting sessiond in blocking with different LTTNG_UST_APP_PATH and LTTNG_UST_CTL_PATHs"

	ctl_path="$(mktemp -d -t "tmp.${FUNCNAME[0]}.ctl.XXXXXX")"
	app_path="$(mktemp -d -t "tmp.${FUNCNAME[0]}.app.XXXXXX")"
	trace_path="$(mktemp -d -t "tmp.${FUNCNAME[0]}.trace.XXXXXX")"
	file_testapp_output=$(mktemp -u -t "tmp.${FUNCNAME[0]}_testapp_output.XXXXXX")

	env_vars=(
		LTTNG_UST_ALLOW_BLOCKING=1
		LTTNG_UST_CTL_PATH="${ctl_path}"
		LTTNG_UST_APP_PATH="${app_path}"
	)

	LTTNG_SESSIOND_ENV_VARS="${env_vars[*]}" start_lttng_sessiond
	create_lttng_session_ok "${SESSION_NAME}" "${trace_path}"
	enable_ust_lttng_channel_ok "${SESSION_NAME}" "${CHANNEL_NAME}" "--blocking-timeout=inf"
	enable_ust_lttng_event_ok "${SESSION_NAME}" "--all" "${CHANNEL_NAME}"
	start_lttng_tracing_ok "${SESSION_NAME}"

	LTTNG_UST_APP_PATH="${ctl_path}" run_testapp_ok "$file_testapp_output" "${TESTAPP}" -i $NR_ITER -w 0

	stop_lttng_tracing_ok "${SESSION_NAME}"
	destroy_lttng_session_ok "${SESSION_NAME}" --no-wait

	validate_trace_count "${EVENT_NAMES}" "${trace_path}" $NR_ITER

	stop_lttng_sessiond

	rm -rf "${ctl_path}" "${trace_path}" "${app_path}"
	rm -f "$file_testapp_output"
}

function test_blocking_mode_with_same_paths()
{
	local same_path
	local env_vars

	diag "Test starting sessiond in blocking with the same LTTNG_UST_APP_PATH and LTTNG_UST_CTL_PATHs"

	same_path="$(mktemp -d -t "tmp.${FUNCNAME[0]}.XXXXXX")"

	env_vars=(
		LTTNG_UST_CTL_PATH="${same_path}"
		LTTNG_UST_APP_PATH="${same_path}"
		LTTNG_UST_ALLOW_BLOCKING=1
	)

	LTTNG_SESSIOND_ENV_VARS="${env_vars[*]}" start_lttng_sessiond_fail
	stop_lttng_sessiond_cleanup

	rm -rf "${same_path}"
}

function test_blocking_mode_app_path_is_default_rundir() {
	local lttng_rundir
	local env_vars

	diag "Test starting sessiond when it's app path happens to match the default rundir"

	lttng_rundir="$(lttng_default_rundir)"

	env_vars=(
		LTTNG_UST_APP_PATH="${lttng_rundir}"
		LTTNG_UST_ALLOW_BLOCKING=1
	)

	LTTNG_SESSIOND_ENV_VARS="${env_vars[*]}" start_lttng_sessiond_fail
	stop_lttng_sessiond_cleanup
}

function test_blocking_mode_ctl_path_is_default_rundir() {
	local lttng_rundir
	local env_vars

	diag "Test starting sessiond when it's ctl path happens to match the default rundir"

	lttng_rundir="$(lttng_default_rundir)"

	env_vars=(
		LTTNG_UST_CTL_PATH="${lttng_rundir}"
		LTTNG_UST_ALLOW_BLOCKING=1
	)

	LTTNG_SESSIOND_ENV_VARS="${env_vars[*]}" start_lttng_sessiond_fail
	stop_lttng_sessiond_cleanup
}

plan_tests "${NUM_TESTS}"

print_test_banner "${TEST_DESC}"

test_blocking_mode_default_paths
test_blocking_mode_app_path
test_blocking_mode_ctl_path
test_blocking_mode_with_same_paths
test_blocking_mode_with_different_paths
test_blocking_mode_app_path_is_default_rundir
test_blocking_mode_ctl_path_is_default_rundir
