]> git.proxmox.com Git - mirror_ovs.git/blob - tests/ovs-macros.at
ovs-macros: Make tests log how long they waited when they succeed.
[mirror_ovs.git] / tests / ovs-macros.at
1 AT_TESTED([ovs-vswitchd])
2 AT_TESTED([ovs-vsctl])
3
4 m4_include([m4/compat.m4])
5
6 dnl Make AT_SETUP automatically run the ovs_init() shell function
7 dnl as the first step in every test.
8 m4_rename([AT_SETUP], [OVS_AT_SETUP])
9 m4_define([AT_SETUP], [OVS_AT_SETUP($@)
10 ovs_init
11 ])
12
13 dnl OVS_START_SHELL_HELPERS...OVS_END_SHELL_HELPERS may bracket shell
14 dnl function definitions that invoke AT_CHECK and other Autotest macros
15 dnl that can ordinarily be run only within AT_SETUP...AT_CLEANUP.
16 m4_define([OVS_START_SHELL_HELPERS],
17 [m4_ifdef([AT_ingroup], [m4_fatal([$0: AT_SETUP and OVS_DEFINE_SHELL_HELPERS may not nest])])
18 m4_define([AT_ingroup])
19 m4_divert_push([PREPARE_TESTS])])
20 m4_define([OVS_END_SHELL_HELPERS], [
21 m4_divert_pop([PREPARE_TESTS])
22 m4_undefine([AT_ingroup])])
23
24 m4_divert_push([PREPARE_TESTS])
25 [
26 # Set ovs_base to the base directory in which the test is running and
27 # initialize the OVS_*DIR environment variables to point to this
28 # directory.
29 ovs_init() {
30 ovs_base=`pwd`
31 trap '. "$ovs_base/cleanup"' 0
32 : > cleanup
33 ovs_setenv
34 }
35
36 # With no parameter or an empty parameter, sets the OVS_*DIR
37 # environment variables to point to $ovs_base, the base directory in
38 # which the test is running.
39 #
40 # With a parameter, sets them to $ovs_base/$1.
41 ovs_setenv() {
42 sandbox=$1
43 ovs_dir=$ovs_base${1:+/$1}
44 OVS_RUNDIR=$ovs_dir; export OVS_RUNDIR
45 OVS_LOGDIR=$ovs_dir; export OVS_LOGDIR
46 OVS_DBDIR=$ovs_dir; export OVS_DBDIR
47 OVS_SYSCONFDIR=$ovs_dir; export OVS_SYSCONFDIR
48 OVS_PKGDATADIR=$ovs_dir; export OVS_PKGDATADIR
49 }
50
51 # Prints the integers from $1 to $2, increasing by $3 (default 1) on stdout.
52 seq () {
53 if test $# = 1; then
54 set 1 $1
55 fi
56 while test $1 -le $2; do
57 echo $1
58 set `expr $1 + ${3-1}` $2 $3
59 done
60 }
61
62 if test "$IS_WIN32" = "yes"; then
63 pwd () {
64 command pwd -W "$@"
65 }
66
67 diff () {
68 command diff --strip-trailing-cr "$@"
69 }
70
71 # tskill is more effective than taskkill but it isn't always installed.
72 if (tskill //?) >/dev/null 2>&1; then :; else
73 tskill () { taskkill //F //PID $1 >/dev/null; }
74 fi
75
76 kill () {
77 signal=
78 retval=0
79 for arg; do
80 case $arg in
81 -*) signal=$arg ;;
82 [1-9][0-9]*)
83 # tasklist always returns 0.
84 # If pid does exist, there will be a line with the pid.
85 if tasklist //fi "PID eq $arg" | grep $arg >/dev/null; then
86 if test "X$signal" != "X-0"; then
87 tskill $arg
88 fi
89 else
90 retval=1
91 fi
92 ;;
93 esac
94 done
95 return $retval
96 }
97 fi
98
99 # parent_pid PID
100 #
101 # Prints the PID of the parent of process PID.
102 parent_pid () {
103 # Using "ps" is portable to any POSIX system, but busybox "ps" (used in
104 # e.g. Alpine Linux) is noncompliant, so we use a Linux-specific approach
105 # when it's available. We check the format of the status file to avoid
106 # the NetBSD file with the same name but different contents.
107 if egrep '^PPid:[[:space:]]*[0-9]*$' /proc/$1/status > /dev/null 2>&1; then
108 sed -n 's/^PPid: \([0-9]*\)/\1/p' /proc/$1/status
109 else
110 ps -o ppid= -p $1
111 fi
112 }
113
114 # kill_ovs_vswitchd [PID]
115 #
116 # Signal the ovs-vswitchd daemon to exit gracefully and wait for it to
117 # terminate or kill it if that takes too long.
118 #
119 # It is used to cleanup all sorts of tests and results. It can't assume
120 # any state, including the availability of PID file which can be provided.
121 kill_ovs_vswitchd () {
122 # Use provided PID or save the current PID if available.
123 TMPPID=$1
124 if test -z "$TMPPID"; then
125 TMPPID=$(cat $OVS_RUNDIR/ovs-vswitchd.pid 2>/dev/null)
126 fi
127
128 # Tell the daemon to terminate gracefully
129 ovs-appctl --timeout=10 -t ovs-vswitchd exit --cleanup 2>/dev/null
130
131 # Nothing else to be done if there is no PID
132 test -z "$TMPPID" && return
133
134 for i in 1 2 3 4 5 6 7 8 9; do
135 # Check if the daemon is alive.
136 kill -0 $TMPPID 2>/dev/null || return
137
138 # Fallback to whole number since POSIX doesn't require
139 # fractional times to work.
140 sleep 0.1 || sleep 1
141 done
142
143 # Make sure it is terminated.
144 kill $TMPPID
145 }
146
147 # Normalize the output of 'wc' to match POSIX.
148 # POSIX says 'wc' should print "%d %d %d", but GNU prints "%7d %7d %7d".
149 # POSIX says 'wc -l' should print "%d %s", but BSD prints "%8d".
150 #
151 # This fixes all of those (it will screw up filenames that contain
152 # multiple sequential spaces, but that doesn't really matter).
153 wc () {
154 command wc "$@" | tr -s ' ' ' ' | sed 's/^ *//'
155 }
156
157 uuidfilt () {
158 $PYTHON "$top_srcdir"/tests/uuidfilt.py "$@"
159 }
160
161 # run_as PROGRAM_NAME COMMAND [ARG...]
162 #
163 # Runs a command with argv[0] set to PROGRAM_NAME, if possible, in a
164 # subshell. Most utilities print argc[0] as part of their messages,
165 # so this makes it easier to figure out which particular utility
166 # prints a message if a bunch of identical processes are running.
167 #
168 # Not all shells support "exec -a NAME", so test for it.
169 if (exec -a myname true); then
170 run_as () {
171 (exec -a "$@")
172 }
173 else
174 run_as () {
175 shift
176 (exec "$@")
177 }
178 fi
179 ]
180 m4_divert_pop([PREPARE_TESTS])
181
182 OVS_START_SHELL_HELPERS
183 ovs_wait () {
184 echo "$1: waiting $2..." >&AS_MESSAGE_LOG_FD
185
186 # First try the condition without waiting.
187 if ovs_wait_cond; then echo "$1: wait succeeded immediately" >&AS_MESSAGE_LOG_FD; return 0; fi
188
189 # Try a quick sleep, so that the test completes very quickly
190 # in the normal case. POSIX doesn't require fractional times to
191 # work, so this might not work.
192 sleep 0.1
193 if ovs_wait_cond; then echo "$1: wait succeeded quickly" >&AS_MESSAGE_LOG_FD; return 0; fi
194
195 # Then wait up to 10 seconds.
196 local d
197 for d in 1 2 3 4 5 6 7 8 9 10; do
198 sleep 1
199 if ovs_wait_cond; then echo "$1: wait succeeded after $d seconds" >&AS_MESSAGE_LOG_FD; return 0; fi
200 done
201
202 echo "$1: wait failed after $d seconds" >&AS_MESSAGE_LOG_FD
203 ovs_wait_failed
204 AT_FAIL_IF([:])
205 }
206 OVS_END_SHELL_HELPERS
207 m4_define([OVS_WAIT], [dnl
208 ovs_wait_cond () {
209 $1
210 }
211 ovs_wait_failed () {
212 :
213 $2
214 }
215 ovs_wait "AS_ESCAPE([$3])" "AS_ESCAPE([$4])"
216 ])
217
218 dnl OVS_WAIT_UNTIL(COMMAND)
219 dnl
220 dnl Executes shell COMMAND in a loop until it returns
221 dnl zero return code. If COMMAND did not return
222 dnl zero code within reasonable time limit, then
223 dnl the test fails.
224 m4_define([OVS_WAIT_UNTIL],
225 [OVS_WAIT([$1], [$2], [AT_LINE], [until $1])])
226
227 dnl OVS_WAIT_WHILE(COMMAND)
228 dnl
229 dnl Executes shell COMMAND in a loop until it returns
230 dnl non-zero return code. If COMMAND did not return
231 dnl non-zero code within reasonable time limit, then
232 dnl the test fails.
233 m4_define([OVS_WAIT_WHILE],
234 [OVS_WAIT([if $1; then return 1; else return 0; fi], [$2],
235 [AT_LINE], [while $1])])
236
237 dnl OVS_APP_EXIT_AND_WAIT(DAEMON)
238 dnl
239 dnl Ask the daemon named DAEMON to exit, via ovs-appctl, and then wait for it
240 dnl to exit.
241 m4_define([OVS_APP_EXIT_AND_WAIT],
242 [AT_CHECK([test -e $OVS_RUNDIR/$1.pid])
243 TMPPID=$(cat $OVS_RUNDIR/$1.pid)
244 AT_CHECK(m4_if([$1],[ovs-vswitchd],
245 [ovs-appctl --timeout=10 -t $1 exit --cleanup],
246 [ovs-appctl --timeout=10 -t $1 exit]))
247 OVS_WAIT_WHILE([kill -0 $TMPPID 2>/dev/null])])
248
249 dnl OVS_APP_EXIT_AND_WAIT_BY_TARGET(TARGET, PIDFILE)
250 dnl
251 dnl Ask the daemon identified by TARGET to exit, via ovs-appctl (using the target
252 dnl argument), and then wait for it to exit.
253 m4_define([OVS_APP_EXIT_AND_WAIT_BY_TARGET],
254 [AT_CHECK([test -e $2])
255 TMPPID=$(cat $2)
256 AT_CHECK([ovs-appctl --timeout=10 --target=$1 exit])
257 OVS_WAIT_WHILE([kill -0 $TMPPID 2>/dev/null])])
258
259 dnl on_exit "COMMAND"
260 dnl
261 dnl Add the shell COMMAND to a collection executed when the current test
262 dnl completes, as a cleanup action. (The most common use is to kill a
263 dnl daemon started by the test. This is important to prevent tests that
264 dnl start daemons from hanging at exit.)
265 dnl
266 dnl Cleanup commands are executed in the reverse order of calls to this
267 dnl function.
268 m4_divert_text([PREPARE_TESTS], [dnl
269 on_exit () {
270 (echo "$1"; cat cleanup) > cleanup.tmp
271 mv cleanup.tmp cleanup
272 }
273 ])
274
275 dnl Autoconf 2.63 compatibility verison of macro introduced in Autoconf 2.64:
276 m4_ifndef([AS_VAR_APPEND],
277 [m4_divert_text([PREPARE_TESTS],
278 [as_var_append () {
279 eval $1=\$$1\$2
280 }
281 ])
282 m4_define([AS_VAR_APPEND], [as_var_append $1 $2])])
283
284 dnl Autoconf 2.63 compatibility verison of macro introduced in Autoconf 2.64:
285 m4_ifndef([AT_CHECK_UNQUOTED],
286 [m4_define([AT_CHECK_UNQUOTED],
287 [_AT_CHECK([$1], [$2], AS_ESCAPE(m4_dquote(m4_expand([$3])), [""]),
288 AS_ESCAPE(m4_dquote(m4_expand([$4])),[""]), [$5], [$6])])])
289
290 dnl Autoconf 2.63 compatibility verison of macro introduced in Autoconf 2.64:
291 m4_ifndef([AT_SKIP_IF],
292 [m4_define([AT_SKIP_IF],
293 [AT_CHECK([($1) \
294 && exit 77 || exit 0], [0], [ignore], [ignore])])])
295
296 dnl Autoconf 2.63 compatibility verison of macro introduced in Autoconf 2.64:
297 m4_ifndef([AT_FAIL_IF],
298 [m4_define([AT_FAIL_IF],
299 [AT_CHECK([($1) \
300 && exit 99 || exit 0], [0], [ignore], [ignore])])])