
atf_test_case basic
basic_head()
{
	atf_set "descr" "Basic tests on pwait(1) utility"
}

basic_body()
{
	sleep 1 &
	p1=$!

	sleep 5 &
	p5=$!

	sleep 10 &
	p10=$!

	atf_check \
		-o empty \
		-e empty \
		-s exit:0 \
		timeout --preserve-status 15 pwait $p1 $p5 $p10

	atf_check \
		-o empty \
		-e inline:"kill: $p1: No such process\n" \
		-s exit:1 \
		kill -0 $p1

	atf_check \
		-o empty \
		-e inline:"kill: $p5: No such process\n" \
		-s exit:1 \
		kill -0 $p5

	atf_check \
		-o empty \
		-e inline:"kill: $p10: No such process\n" \
		-s exit:1 \
		kill -0 $p10

}

basic_cleanup()
{
	kill $p1 $p5 $p10 >/dev/null 2>&1
	wait $p1 $p5 $p10 >/dev/null 2>&1
}

atf_test_case time_unit
time_unit_head()
{
	atf_set "descr" "Test parsing the timeout unit and value"
}

time_unit_body()
{
	atf_check \
		-o empty \
		-e inline:"pwait: timeout unit\n" \
		-s exit:65 \
		timeout --preserve-status 2 pwait -t 1d $$

	atf_check \
		-o empty \
		-e inline:"pwait: timeout unit\n" \
		-s exit:65 \
		timeout --preserve-status 2 pwait -t 1d $$

	atf_check \
		-o empty \
		-e inline:"pwait: timeout value\n" \
		-s exit:65 \
		timeout --preserve-status 2 pwait -t -1 $$

	atf_check \
		-o empty \
		-e inline:"pwait: timeout value\n" \
		-s exit:65 \
		timeout --preserve-status 2 pwait -t 100000001 $$

	# These long duration cases are expected to timeout from the
	# timeout utility rather than pwait -t.
	atf_check \
		-o empty \
		-e empty \
		-s signal:15 \
		timeout --preserve-status 2 pwait -t 100000000 $$

	atf_check \
		-o empty \
		-e empty \
		-s signal:15 \
		timeout --preserve-status 2 pwait -t 1h $$

	atf_check \
		-o empty \
		-e empty \
		-s signal:15 \
		timeout --preserve-status 2 pwait -t 1.5h $$

	atf_check \
		-o empty \
		-e empty \
		-s signal:15 \
		timeout --preserve-status 2 pwait -t 1m $$

	atf_check \
		-o empty \
		-e empty \
		-s signal:15 \
		timeout --preserve-status 2 pwait -t 1.5m $$

	atf_check \
		-o empty \
		-e empty \
		-s signal:15 \
		timeout --preserve-status 2 pwait -t 0 $$

	# The rest are fast enough that pwait -t is expected to trigger
	# the timeout.
	atf_check \
		-o empty \
		-e empty \
		-s exit:124 \
		timeout --preserve-status 2 pwait -t 1s $$

	atf_check \
		-o empty \
		-e empty \
		-s exit:124 \
		timeout --preserve-status 2 pwait -t 1.5s $$

	atf_check \
		-o empty \
		-e empty \
		-s exit:124 \
		timeout --preserve-status 2 pwait -t 1 $$

	atf_check \
		-o empty \
		-e empty \
		-s exit:124 \
		timeout --preserve-status 2 pwait -t 1.5 $$

	atf_check \
		-o empty \
		-e empty \
		-s exit:124 \
		timeout --preserve-status 2 pwait -t 0.5 $$
}

atf_test_case timeout_trigger_timeout
timeout_trigger_timeout_head()
{
	atf_set "descr" "Test that exceeding the timeout is detected"
}

timeout_trigger_timeout_body()
{
	sleep 10 &
	p10=$!

	atf_check \
		-o empty \
		-e empty \
		-s exit:124 \
		timeout --preserve-status 6.5 pwait -t 5 $p10
}

timeout_trigger_timeout_cleanup()
{
	kill $p10 >/dev/null 2>&1
	wait $p10 >/dev/null 2>&1
}

atf_test_case timeout_no_timeout
timeout_no_timeout_head()
{
	atf_set "descr" "Test that not exceeding the timeout continues to wait"
}

timeout_no_timeout_body()
{
	sleep 10 &
	p10=$!

	atf_check \
		-o empty \
		-e empty \
		-s exit:0 \
		timeout --preserve-status 11.5 pwait -t 12 $p10
}

timeout_no_timeout_cleanup()
{
	kill $p10 >/dev/null 2>&1
	wait $p10 >/dev/null 2>&1
}

atf_test_case timeout_many
timeout_many_head()
{
	atf_set "descr" "Test timeout on many processes"
}

timeout_many_body()
{
	sleep 1 &
	p1=$!

	sleep 5 &
	p5=$!

	sleep 10 &
	p10=$!

	atf_check \
		-o empty \
		-e empty \
		-s exit:124 \
		timeout --preserve-status 7.5 pwait -t 6 $p1 $p5 $p10
}

timeout_many_cleanup()
{
	kill $p1 $p5 $p10 >/dev/null 2>&1
	wait $p1 $p5 $p10 >/dev/null 2>&1
}

atf_test_case or_flag
or_flag_head()
{
	atf_set "descr" "Test OR flag"
}

or_flag_body()
{
	sleep 2 &
	p2=$!

	sleep 4 &
	p4=$!

	sleep 6 &
	p6=$!

	atf_check \
		-o inline:"$p2: exited with status 0.\n" \
		-e empty \
		-s exit:0 \
		timeout --preserve-status 15 pwait -o -v $p2 $p4 $p6

	atf_check \
		-o empty \
		-e inline:"pwait: $p2: No such process\n" \
		-s exit:0 \
		timeout --preserve-status 15 pwait -o $p2 $p4 $p6

	atf_check \
		-o empty \
		-e empty \
		-s exit:0 \
		timeout --preserve-status 15 pwait -o $p4 $p6

	atf_check \
		-o empty \
		-e inline:"pwait: $p4: No such process\n" \
		-s exit:0 \
		timeout --preserve-status 15 pwait -o $p4 $p6

	atf_check \
		-o inline:"$p6: exited with status 0.\n" \
		-e empty \
		-s exit:0 \
		timeout --preserve-status 15 pwait -o -v $p6

	atf_check \
		-o empty \
		-e inline:"pwait: $p6: No such process\n" \
		-s exit:0 \
		timeout --preserve-status 15 pwait -o $p6

	atf_check \
		-o empty \
		-e inline:"kill: $p2: No such process\n" \
		-s exit:1 \
		kill -0 $p2

	atf_check \
		-o empty \
		-e inline:"kill: $p4: No such process\n" \
		-s exit:1 \
		kill -0 $p4

	atf_check \
		-o empty \
		-e inline:"kill: $p6: No such process\n" \
		-s exit:1 \
		kill -0 $p6

}

or_flag_cleanup()
{
	kill $p2 $p4 $p6 >/dev/null 2>&1
	wait $p2 $p4 $p6 >/dev/null 2>&1
}

atf_test_case print
print_head()
{
	atf_set "descr" "Test the -p flag"
}

print_body()
{
	sleep 1 &
	p1=$!

	sleep 5 &
	p5=$!

	sleep 10 &
	p10=$!

	atf_check \
		-o inline:"$p5\n$p10\n" \
		-s exit:124 \
		pwait -t 2 -p $p10 $p5 $p1 $p5 $p10

	atf_check \
		-e inline:"kill: $p1: No such process\n" \
		-s exit:1 \
		kill -0 $p1

	atf_check kill -0 $p5
	atf_check kill -0 $p10
}

print_cleanup()
{
	kill $p1 $p5 $p10 >/dev/null 2>&1
	wait $p1 $p5 $p10 >/dev/null 2>&1
}

atf_init_test_cases()
{
	atf_add_test_case basic
	atf_add_test_case time_unit
	atf_add_test_case timeout_trigger_timeout
	atf_add_test_case timeout_no_timeout
	atf_add_test_case timeout_many
	atf_add_test_case or_flag
	atf_add_test_case print
}
