xref: /illumos-gate/usr/src/test/util-tests/tests/sleep/sleeptest.ksh (revision 176a9270a1856e0e2fddcbc3c7d35aa1f750c6b9)
1#!/bin/ksh
2#
3# This file and its contents are supplied under the terms of the
4# Common Development and Distribution License ("CDDL"), version 1.0.
5# You may only use this file in accordance with the terms of version
6# 1.0 of the CDDL.
7#
8# A full copy of the text of the CDDL should have accompanied this
9# source.  A copy of the CDDL is also available via the Internet at
10# http://www.illumos.org/license/CDDL.
11#
12
13#
14# Copyright 2019 Robert Mustacchi
15#
16
17#
18# Basic tests of sleep(1). sleep is a little hard to test, especially
19# for longer running cases. Therefore to test it, we basically take
20# advantage of our knowledge of how it is implemented. We see that it
21# properly is sleeping for the right amount of time by looking at the
22# call to nanosleep in libc and make sure that the structures time is
23# what we expect.
24#
25
26unalias -a
27set -o pipefail
28
29#
30# Set the locale for the start of the test to be C.UTF-8 to make sure
31# that we have a good starting point and correct fractional
32# interpretation.
33#
34export LC_ALL=C.UTF-8
35
36sleep_arg0="$(basename $0)"
37sleep_prog=/usr/bin/sleep
38sleep_dir="$(dirname $0)"
39sleep_dscript=$sleep_dir/sleep.d
40sleep_awk=$sleep_dir/sleep.awk
41sleep_exit=0
42
43#
44# This is the factor by which we're going to basically say that the slp
45# microstate has to complete within. Because the system will usually
46# have a bit of additional latency, we will usually be greater than that
47# as well. This determines how much we should actually do that by.
48#
49sleep_factor=1.5
50
51warn()
52{
53	typeset msg="$*"
54	[[ -z "$msg" ]] && msg="failed"
55	echo "TEST FAILED: $sleep_arg0: $msg" >&2
56}
57
58sleep_bound()
59{
60	typeset min=$1
61	typeset test="sleep $min: bounding"
62
63	ptime -m $sleep_prog $min 2>&1 | nawk -f $sleep_awk min=$min \
64	    factor=$sleep_factor
65	if [[ $? -ne 42 ]]; then
66		warn "$test"
67		sleep_exit=1
68	else
69		printf "TEST PASSED: %s\n" "$test"
70	fi
71}
72
73sleep_one()
74{
75	typeset arg=$1
76	typeset secs=$2
77	typeset nsecs=$3
78	typeset test="sleep $arg: $secs secs $nsecs ns"
79
80	if ! dtrace -qws $sleep_dscript -c "$sleep_prog $arg" $secs $nsecs; then
81		warn "$test"
82		sleep_exit=1
83	else
84		printf "TEST PASSED: %s\n" "$test"
85	fi
86}
87
88sleep_err()
89{
90	typeset test="negative test: sleep $*"
91
92	if $sleep_prog $* 2>/dev/null; then
93		warn "$test"
94		sleep_exit=1
95	else
96		printf "TEST PASSED: %s\n" "$test"
97	fi
98}
99
100if [[ -n $SLEEP ]]; then
101	sleep_prog=$SLEEP
102fi
103
104#
105# First test basic integer values. Both in base 10 and hex.
106#
107sleep_one 1 1 0
108sleep_one 23 23 0
109sleep_one 0xff 0xff 0
110sleep_one 123456789 123456789 0
111sleep_one 1e8 100000000 0
112
113#
114# Fractional values.
115#
116sleep_one 2.5 2 500000000
117sleep_one 0.9 0 900000000
118sleep_one 34.0051 34 5100000
119sleep_one 0x654.100 0x654 62500000
120
121#
122# Large values that are basically the same as infinity. The current
123# implementation will do a sleep in groups of INT32_MAX at a time. So
124# make sure our large values are the same.
125#
126sleep_one Inf 0x7fffffff 0
127sleep_one +Inf 0x7fffffff 0
128sleep_one 1e100 0x7fffffff 0
129sleep_one 0x123456789abc 0x7fffffff 0
130
131#
132# That all of our suffixes for time increments work and make sense.
133#
134sleep_one 1s 1 0
135sleep_one 1m 60 0
136sleep_one 1h 3600 0
137sleep_one 1d 86400 0
138sleep_one 1w 604800 0
139sleep_one 1y 31536000 0
140
141sleep_one 3.5s 3 500000000
142sleep_one 3.6d 311040 0
143sleep_one 2.001y 63103536 0
144
145#
146# Now we need to go through and use ptime -m to get the slp time for
147# things and make sure it is always greater than what we asked for and
148# less than a bound.
149#
150sleep_bound 0.01
151sleep_bound 0.1
152sleep_bound 0.25
153sleep_bound 0.5
154sleep_bound 0.75
155
156#
157# The next set of tests are negative tests that make sure that sleep
158# does not correctly execute in these cases.
159#
160sleep_err \"\"
161sleep_err 1 2 3
162sleep_err 1@23
163sleep_err 0,56
164sleep_err "hello"
165sleep_err s
166sleep_err 1z
167sleep_err -- -0.3
168
169#
170# Test a locale that uses a ',' character (de_DE.UTF-8 is one) as the
171# decimal point to make sure that sleep correctly is using LC_NUMERIC.
172#
173export LANG=de_DE.UTF-8
174sleep_err 21.45
175sleep_one 2,5 2 500000000
176sleep_one 34,0051 34 5100000
177sleep_one 3,6d 311040 0
178export LANG=C.UTF-8
179
180exit $sleep_exit
181