summaryrefslogtreecommitdiff
path: root/usr/src/test/util-tests/tests/sleep/sleeptest.ksh
blob: 555d6ac6f82d830865676353495fdc764cde2469 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#!/bin/ksh
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source.  A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#

#
# Copyright 2019 Robert Mustacchi
# Copyright 2020 Joyent, Inc.
#

#
# Basic tests of sleep(1). sleep is a little hard to test, especially
# for longer running cases. Therefore to test it, we basically take
# advantage of our knowledge of how it is implemented. We see that it
# properly is sleeping for the right amount of time by looking at the
# call to nanosleep in libc and make sure that the structures time is
# what we expect.
#

unalias -a
set -o pipefail

#
# Set the locale for the start of the test to be C.UTF-8 to make sure
# that we have a good starting point and correct fractional
# interpretation.
#
export LC_ALL=C.UTF-8

sleep_arg0="$(basename $0)"
sleep_prog=/usr/bin/sleep
sleep_dir="$(dirname $0)"
sleep_dscript=$sleep_dir/sleep.d
sleep_awk=$sleep_dir/sleep.awk
sleep_exit=0

#
# This is the factor by which we're going to basically say that the slp
# microstate has to complete within. Because the system will usually
# have a bit of additional latency, we will usually be greater than that
# as well. This determines how much we should actually do that by.
#
sleep_factor=1.5

warn()
{
	typeset msg="$*"
	[[ -z "$msg" ]] && msg="failed"
	echo "TEST FAILED: $sleep_arg0: $msg" >&2
}

sleep_bound()
{
	typeset min=$1
	typeset test="sleep $min: bounding"

	ptime -m $sleep_prog $min 2>&1 | nawk -f $sleep_awk min=$min \
	    factor=$sleep_factor
	if [[ $? -ne 42 ]]; then
		warn "$test"
		sleep_exit=1
	else
		printf "TEST PASSED: %s\n" "$test"
	fi
}

sleep_one()
{
	typeset arg=$1
	typeset secs=$2
	typeset nsecs=$3
	typeset test="sleep $arg: $secs secs $nsecs ns"

	if ! dtrace -qws $sleep_dscript -c "$sleep_prog $arg" $secs $nsecs; then
		warn "$test"
		sleep_exit=1
	else
		printf "TEST PASSED: %s\n" "$test"
	fi
}

sleep_err()
{
	typeset test="negative test: sleep $*"

	if $sleep_prog $* 2>/dev/null; then
		warn "$test"
		sleep_exit=1
	else
		printf "TEST PASSED: %s\n" "$test"
	fi
}

if [[ -n $SLEEP ]]; then
	sleep_prog=$SLEEP
fi

#
# First test basic integer values. Both in base 10 and hex.
#
sleep_one 1 1 0
sleep_one 23 23 0
sleep_one 0xff 0xff 0
sleep_one 123456789 123456789 0
sleep_one 1e8 100000000 0

#
# Fractional values.
#
sleep_one 2.5 2 500000000
sleep_one 0.9 0 900000000
sleep_one 34.0051 34 5100000
sleep_one 0x654.100 0x654 62500000

#
# Large values that are basically the same as infinity. The current
# implementation will do a sleep in groups of INT32_MAX at a time. So
# make sure our large values are the same.
#
sleep_one Inf 0x7fffffff 0
sleep_one +Inf 0x7fffffff 0
sleep_one 1e100 0x7fffffff 0
sleep_one 0x123456789abc 0x7fffffff 0

#
# That all of our suffixes for time increments work and make sense.
#
sleep_one 1s 1 0
sleep_one 1m 60 0
sleep_one 1h 3600 0
sleep_one 1d 86400 0
sleep_one 1w 604800 0
sleep_one 1y 31536000 0

sleep_one 3.5s 3 500000000
sleep_one 3.6d 311040 0
sleep_one 2.001y 63103536 0

#
# Now we need to go through and use ptime -m to get the slp time for
# things and make sure it is always greater than what we asked for and
# less than a bound.
#
sleep_bound 0.01
sleep_bound 0.1
sleep_bound 0.25
sleep_bound 0.5
sleep_bound 0.75

#
# The next set of tests are negative tests that make sure that sleep
# does not correctly execute in these cases.
#
sleep_err \"\"
sleep_err 1 2 3
sleep_err 1@23
sleep_err 0,56
sleep_err "hello"
sleep_err s
sleep_err 1z
sleep_err -- -0.3

#
# Test a locale that uses a ',' character (de_DE.UTF-8 is one) as the
# decimal point to make sure that sleep is correctly using LC_NUMERIC.
export LC_ALL=de_DE.UTF-8
sleep_err 21.45
sleep_one 2,5 2 500000000
sleep_one 34,0051 34 5100000
sleep_one 3,6d 311040 0
export LC_ALL=C.UTF-8

exit $sleep_exit