t_ps.sh revision 1.1.4.1 1 1.1.4.1 tls # $NetBSD: t_ps.sh,v 1.1.4.1 2014/08/20 00:04:45 tls Exp $
2 1.1 jruoho #
3 1.1 jruoho # Copyright (c) 2007 The NetBSD Foundation, Inc.
4 1.1 jruoho # All rights reserved.
5 1.1 jruoho #
6 1.1 jruoho # Redistribution and use in source and binary forms, with or without
7 1.1 jruoho # modification, are permitted provided that the following conditions
8 1.1 jruoho # are met:
9 1.1 jruoho # 1. Redistributions of source code must retain the above copyright
10 1.1 jruoho # notice, this list of conditions and the following disclaimer.
11 1.1 jruoho # 2. Redistributions in binary form must reproduce the above copyright
12 1.1 jruoho # notice, this list of conditions and the following disclaimer in the
13 1.1 jruoho # documentation and/or other materials provided with the distribution.
14 1.1 jruoho #
15 1.1 jruoho # THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
16 1.1 jruoho # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17 1.1 jruoho # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 1.1 jruoho # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
19 1.1 jruoho # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 1.1 jruoho # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 1.1 jruoho # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 1.1 jruoho # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 1.1 jruoho # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 1.1 jruoho # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 1.1 jruoho # POSSIBILITY OF SUCH DAMAGE.
26 1.1 jruoho #
27 1.1 jruoho
28 1.1 jruoho # the implementation of "ps" to test
29 1.1 jruoho : ${TEST_PS:="ps"}
30 1.1 jruoho # tab and newline characters
31 1.1 jruoho tab="$(printf '\t')"
32 1.1 jruoho # nl="$(printf '\n')" doesn't work
33 1.1 jruoho nl='
34 1.1 jruoho '
35 1.1 jruoho
36 1.1 jruoho #
37 1.1 jruoho # Parse the "keywords" file into a load of shell variables
38 1.1 jruoho #
39 1.1 jruoho setup_keywords()
40 1.1 jruoho {
41 1.1 jruoho # Set variables representing the header text
42 1.1 jruoho # for all normal keywords (except aliases), and
43 1.1 jruoho # for regular expressions to match the text in left- or
44 1.1 jruoho # right-justified columns.
45 1.1 jruoho # For example, head_text_p_cpu="%CPU" head_regexp_p_cpu=" *%CPU".
46 1.1 jruoho while read keyword heading flag
47 1.1 jruoho do
48 1.1 jruoho case "$keyword" in
49 1.1 jruoho ''|\#*) continue
50 1.1 jruoho ;;
51 1.1 jruoho esac
52 1.1 jruoho [ x"$flag" = x"ALIAS" ] && continue
53 1.1 jruoho kvar="${keyword}"
54 1.1 jruoho case "${keyword}" in
55 1.1 jruoho %*) kvar="p_${keyword#%}"
56 1.1 jruoho ;;
57 1.1 jruoho esac
58 1.1 jruoho eval head_text_${kvar}=\'"${heading}"\'
59 1.1 jruoho case "${flag}" in
60 1.1 jruoho '') # right justified
61 1.1 jruoho eval head_regexp_${kvar}=\'" *${heading}"\'
62 1.1 jruoho ;;
63 1.1 jruoho LJUST) # left justified
64 1.1 jruoho eval head_regexp_${kvar}=\'"${heading} *"\'
65 1.1 jruoho ;;
66 1.1 jruoho *) atf_fail "unknown flag in keywords"
67 1.1 jruoho ;;
68 1.1 jruoho esac
69 1.1 jruoho done <"$(atf_get_srcdir)/keywords"
70 1.1 jruoho
71 1.1 jruoho # Now do the aliases.
72 1.1 jruoho while read keyword heading flag
73 1.1 jruoho do
74 1.1 jruoho case "$keyword" in
75 1.1 jruoho ''|\#*) continue
76 1.1 jruoho ;;
77 1.1 jruoho esac
78 1.1 jruoho [ x"$flag" != x"ALIAS" ] && continue
79 1.1 jruoho kvar="${keyword}"
80 1.1 jruoho avar="${heading}"
81 1.1 jruoho case "${keyword}" in
82 1.1 jruoho %*) kvar="p_${keyword#%}"
83 1.1 jruoho ;;
84 1.1 jruoho esac
85 1.1 jruoho case "${heading}" in
86 1.1 jruoho %*) avar="p_${heading#%}"
87 1.1 jruoho ;;
88 1.1 jruoho esac
89 1.1 jruoho eval head_text_${kvar}=\"\$head_text_${avar}\"
90 1.1 jruoho eval head_regexp_${kvar}=\"\$head_regexp_${avar}\"
91 1.1 jruoho done <"$(atf_get_srcdir)/keywords"
92 1.1 jruoho
93 1.1 jruoho # default sets of keywords
94 1.1 jruoho default_keywords='pid tty stat time command'
95 1.1 jruoho j_keywords='user pid ppid pgid sess jobc state tt time command'
96 1.1 jruoho l_keywords='uid pid ppid cpu pri nice vsz rss wchan state tt time command'
97 1.1.4.1 tls s_keywords='uid pid ppid cpu lid nlwp pri nice vsz rss wchan lstate tt ltime command'
98 1.1 jruoho u_keywords='user pid %cpu %mem vsz rss tt state start time command'
99 1.1 jruoho v_keywords='pid state time sl re pagein vsz rss lim tsiz %cpu %mem command'
100 1.1 jruoho }
101 1.1 jruoho
102 1.1 jruoho # Convert a list of keywords like "pid comm" to a regexp
103 1.1 jruoho # like " *PID COMMAND *"
104 1.1 jruoho heading_keywords_to_regexp()
105 1.1 jruoho {
106 1.1 jruoho local keywords="$1"
107 1.1 jruoho local regexp
108 1.1 jruoho regexp="$(echo "$keywords" | \
109 1.1 jruoho sed -E -e 's/\%/p_/g' -e 's/(^| )/\1\$head_regexp_/g')"
110 1.1 jruoho eval regexp=\""${regexp}"\"
111 1.1 jruoho regexp="^${regexp}\$"
112 1.1 jruoho echo "$regexp"
113 1.1 jruoho }
114 1.1 jruoho
115 1.1 jruoho #
116 1.1 jruoho # Check that a string matches a regexp; use the specified id
117 1.1 jruoho # in error or success messages.
118 1.1 jruoho #
119 1.1 jruoho check_regexp() {
120 1.1 jruoho local id="$1" string="$2" regexp="$3"
121 1.1 jruoho if ! expr "$string" : "$regexp" >/dev/null
122 1.1 jruoho then
123 1.1 jruoho atf_fail "${id}: expected [${regexp}], got [${string}]"
124 1.1 jruoho false
125 1.1 jruoho fi
126 1.1 jruoho }
127 1.1 jruoho
128 1.1 jruoho #
129 1.1 jruoho # Run "ps $args -p $$"; check that only one line is printed,
130 1.1 jruoho # without a preceding header line.
131 1.1 jruoho #
132 1.1 jruoho check_no_heading_line()
133 1.1 jruoho {
134 1.1 jruoho local args="$1"
135 1.1 jruoho local output="$(eval "${TEST_PS} $args -p $$")"
136 1.1 jruoho case "$output" in
137 1.1 jruoho *"$nl"*)
138 1.1 jruoho local firstline="${output%%${nl}*}"
139 1.1 jruoho atf_fail "check_no_heading_line [$args] got [$firstline]"
140 1.1 jruoho ;;
141 1.1 jruoho *)
142 1.1 jruoho ;;
143 1.1 jruoho esac
144 1.1 jruoho }
145 1.1 jruoho
146 1.1 jruoho #
147 1.1 jruoho # Run "ps $args"; check that the heading matches the expected regexp.
148 1.1 jruoho #
149 1.1 jruoho check_heading_regexp()
150 1.1 jruoho {
151 1.1 jruoho args="$1"
152 1.1 jruoho regexp="$2"
153 1.1 jruoho actual="$( eval "${TEST_PS} $args" | sed -e 1q )"
154 1.1 jruoho check_regexp "heading [$args]" "${actual}" "${regexp}"
155 1.1 jruoho }
156 1.1 jruoho
157 1.1 jruoho #
158 1.1 jruoho # Run "ps $args"; check that the heading matches a regexp constructed
159 1.1 jruoho # from the specified keywords.
160 1.1 jruoho #
161 1.1 jruoho check_heading_keywords()
162 1.1 jruoho {
163 1.1 jruoho args="$1"
164 1.1 jruoho keywords="$2"
165 1.1 jruoho check_heading_regexp "$args" "$(heading_keywords_to_regexp "$keywords")"
166 1.1 jruoho }
167 1.1 jruoho
168 1.1 jruoho #
169 1.1 jruoho # Try several variations on "ps $flag", "ps -$flag", etc.,
170 1.1 jruoho # and check that the heading always has the correct keywords.
171 1.1 jruoho #
172 1.1 jruoho check_heading_variations()
173 1.1 jruoho {
174 1.1 jruoho flag="$1"
175 1.1 jruoho keywords="$2"
176 1.1 jruoho for args in "$flag" "-$flag" "-$flag$flag -$flag"; do
177 1.1 jruoho check_heading_keywords "$args" "$keywords"
178 1.1 jruoho done
179 1.1 jruoho }
180 1.1 jruoho
181 1.1 jruoho atf_test_case default_columns
182 1.1 jruoho default_columns_head()
183 1.1 jruoho {
184 1.1 jruoho atf_set "descr" "Checks that the default set of columns is correct" \
185 1.1 jruoho "and also check that the columns printed by the -j," \
186 1.1 jruoho "-l, -s, -u and -v flags alone are correct"
187 1.1 jruoho }
188 1.1 jruoho default_columns_body()
189 1.1 jruoho {
190 1.1 jruoho setup_keywords
191 1.1 jruoho check_heading_keywords '' "$default_keywords"
192 1.1 jruoho check_heading_variations 'j' "$j_keywords"
193 1.1 jruoho check_heading_variations 'l' "$l_keywords"
194 1.1 jruoho check_heading_variations 's' "$s_keywords"
195 1.1 jruoho check_heading_variations 'u' "$u_keywords"
196 1.1 jruoho check_heading_variations 'v' "$v_keywords"
197 1.1 jruoho }
198 1.1 jruoho
199 1.1 jruoho atf_test_case minus_O
200 1.1 jruoho minus_O_head()
201 1.1 jruoho {
202 1.1 jruoho atf_set "descr" "Checks that 'ps -O foo' inserts columns just after" \
203 1.1 jruoho "the pid column"
204 1.1 jruoho }
205 1.1 jruoho minus_O_body()
206 1.1 jruoho {
207 1.1 jruoho setup_keywords
208 1.1 jruoho check_heading_keywords '-O %cpu,%mem' \
209 1.1 jruoho "$(echo "${default_keywords}" | sed -e 's/pid/pid %cpu %mem/')"
210 1.1 jruoho check_heading_keywords '-O %cpu -O %mem' \
211 1.1 jruoho "$(echo "${default_keywords}" | sed -e 's/pid/pid %cpu %mem/')"
212 1.1 jruoho check_heading_keywords '-O%cpu -O%mem' \
213 1.1 jruoho "$(echo "${default_keywords}" | sed -e 's/pid/pid %cpu %mem/')"
214 1.1 jruoho }
215 1.1 jruoho
216 1.1 jruoho atf_test_case minus_o
217 1.1 jruoho minus_o_head()
218 1.1 jruoho {
219 1.1 jruoho atf_set "descr" "Checks simple cases of 'ps -o foo' to control which" \
220 1.1 jruoho "columns are printed; this does not test header" \
221 1.1 jruoho "overriding via 'ps -o foo=BAR'"
222 1.1 jruoho }
223 1.1 jruoho minus_o_body()
224 1.1 jruoho {
225 1.1 jruoho setup_keywords
226 1.1 jruoho # Keywords for "-o name" override the default display
227 1.1 jruoho check_heading_keywords '-o pid,%cpu,%mem' \
228 1.1 jruoho "pid %cpu %mem"
229 1.1 jruoho check_heading_keywords '-o pid -o %cpu,%mem' \
230 1.1 jruoho "pid %cpu %mem"
231 1.1 jruoho check_heading_keywords '-opid -o %cpu,%mem' \
232 1.1 jruoho "pid %cpu %mem"
233 1.1 jruoho # Space works like comma
234 1.1 jruoho check_heading_keywords '-opid -o "%cpu %mem"' \
235 1.1 jruoho "pid %cpu %mem"
236 1.1 jruoho # Check missing pid
237 1.1 jruoho check_heading_keywords '-o comm' \
238 1.1 jruoho "comm"
239 1.1 jruoho # Check pid present but not first
240 1.1 jruoho check_heading_keywords '-o comm,pid' \
241 1.1 jruoho "comm pid"
242 1.1 jruoho }
243 1.1 jruoho
244 1.1 jruoho atf_test_case override_heading_simple
245 1.1 jruoho override_heading_simple_head()
246 1.1 jruoho {
247 1.1 jruoho atf_set "descr" "Tests simple uses of header overriding via" \
248 1.1 jruoho "'ps -o foo=BAR'. This does not test columns " \
249 1.1 jruoho "with null headings, or headings with embedded" \
250 1.1 jruoho "space, ',' or '='."
251 1.1 jruoho }
252 1.1 jruoho override_heading_simple_body()
253 1.1 jruoho {
254 1.1 jruoho setup_keywords
255 1.1 jruoho check_heading_regexp '-o pid=PPP -o comm' \
256 1.1 jruoho '^ *PPP '"${head_text_comm}"'$' # no trailing space
257 1.1 jruoho check_heading_regexp '-o pid=PPP -o comm=CCC' \
258 1.1 jruoho '^ *PPP CCC$'
259 1.1 jruoho check_heading_regexp '-o pid,comm=CCC' \
260 1.1 jruoho '^'"${head_regexp_pid}"' CCC$'
261 1.1 jruoho check_heading_regexp '-o pid -o comm=CCC' \
262 1.1 jruoho '^'"${head_regexp_pid}"' CCC$'
263 1.1 jruoho # Check missing pid
264 1.1 jruoho check_heading_regexp '-o comm=CCC' \
265 1.1 jruoho '^CCC$'
266 1.1 jruoho # Check pid present but not first
267 1.1 jruoho check_heading_regexp '-o comm=CCC -o pid=PPP' \
268 1.1 jruoho '^CCC *PPP$'
269 1.1 jruoho check_heading_regexp '-o comm,pid=PPP' \
270 1.1 jruoho '^'"${head_regexp_comm}"' *PPP$'
271 1.1 jruoho }
272 1.1 jruoho
273 1.1 jruoho atf_test_case override_heading_embedded_specials
274 1.1 jruoho override_heading_embedded_specials_head()
275 1.1 jruoho {
276 1.1 jruoho atf_set "descr" "Tests header overriding with embedded space," \
277 1.1 jruoho "',' or '='. Everything after the first '='" \
278 1.1 jruoho "is part of the heading."
279 1.1 jruoho }
280 1.1 jruoho override_heading_embedded_specials_body()
281 1.1 jruoho {
282 1.1 jruoho setup_keywords
283 1.1 jruoho # Check embedded "," or "=" in override header.
284 1.1 jruoho check_heading_regexp '-o comm,pid==' \
285 1.1 jruoho '^'"${head_regexp_comm}"' *=$'
286 1.1 jruoho check_heading_regexp '-o comm,pid=,' \
287 1.1 jruoho '^'"${head_regexp_comm}"' *,$'
288 1.1 jruoho check_heading_regexp '-o pid=PPP,comm' \
289 1.1 jruoho '^ *PPP,comm$' # not like '-o pid=PPP -o comm'
290 1.1 jruoho check_heading_regexp '-o pid=PPP,comm=CCC' \
291 1.1 jruoho '^ *PPP,comm=CCC$' # not like '-o pid=PPP -o comm=CCC'
292 1.1 jruoho check_heading_regexp '-o comm,pid=PPP,QQQ' \
293 1.1 jruoho '^'"${head_regexp_comm}"' *PPP,QQQ$'
294 1.1 jruoho check_heading_regexp '-o comm,pid=ppid,tty=state' \
295 1.1 jruoho '^'"${head_regexp_comm}"' *ppid,tty=state$'
296 1.1 jruoho # Check embedded space or tab in override header.
297 1.1 jruoho check_heading_regexp '-o comm,pid="PPP QQQ"' \
298 1.1 jruoho '^'"${head_regexp_comm}"' *PPP QQQ$'
299 1.1 jruoho check_heading_regexp '-o comm,pid="PPP${tab}QQQ"' \
300 1.1 jruoho '^'"${head_regexp_comm}"' *PPP'"${tab}"'QQQ$'
301 1.1 jruoho }
302 1.1 jruoho
303 1.1 jruoho atf_test_case override_heading_some_null
304 1.1 jruoho override_heading_some_null_head()
305 1.1 jruoho {
306 1.1 jruoho atf_set "descr" "Tests simple uses of null column headings" \
307 1.1 jruoho "overriding via 'ps -o foo=BAR -o baz='. This" \
308 1.1 jruoho "does not test the case where all columns have" \
309 1.1 jruoho "null headings."
310 1.1 jruoho }
311 1.1 jruoho override_heading_some_null_body()
312 1.1 jruoho {
313 1.1 jruoho setup_keywords
314 1.1 jruoho check_heading_regexp '-o pid=PPP -o comm=' \
315 1.1 jruoho '^ *PPP *$'
316 1.1 jruoho check_heading_regexp '-o pid= -o comm=CCC' \
317 1.1 jruoho '^ * CCC$'
318 1.1 jruoho check_heading_regexp '-o pid -o comm=' \
319 1.1 jruoho '^'"${head_regexp_pid}"' *$'
320 1.1 jruoho # Check missing pid
321 1.1 jruoho check_heading_regexp '-o ppid= -o comm=CCC' \
322 1.1 jruoho '^ * CCC$'
323 1.1 jruoho check_heading_regexp '-o ppid=PPP -o comm=' \
324 1.1 jruoho '^ *PPP *$'
325 1.1 jruoho # Check pid present but not first
326 1.1 jruoho check_heading_regexp '-o comm= -o pid=PPP' \
327 1.1 jruoho '^ * PPP$'
328 1.1 jruoho check_heading_regexp '-o comm,pid=' \
329 1.1 jruoho '^'"${head_regexp_comm}"' *$'
330 1.1 jruoho # A field with a null custom heading retains a minimum width
331 1.1 jruoho # derived from the default heading. This does not apply
332 1.1 jruoho # to a field with a very short (non-null) custom heading.
333 1.1 jruoho #
334 1.1 jruoho # We choose "holdcnt" as a column whose width is likely to be
335 1.1 jruoho # determined entirely by the header width, because the values
336 1.1 jruoho # are likely to be very small.
337 1.1 jruoho check_heading_regexp '-o holdcnt -o holdcnt -o holdcnt' \
338 1.1 jruoho '^HOLDCNT HOLDCNT HOLDCNT$'
339 1.1 jruoho check_heading_regexp '-o holdcnt -o holdcnt= -o holdcnt' \
340 1.1 jruoho '^HOLDCNT HOLDCNT$'
341 1.1 jruoho check_heading_regexp '-o holdcnt -o holdcnt=HH -o holdcnt' \
342 1.1 jruoho '^HOLDCNT HH HOLDCNT$'
343 1.1 jruoho }
344 1.1 jruoho
345 1.1 jruoho atf_test_case override_heading_all_null
346 1.1 jruoho override_heading_all_null_head()
347 1.1 jruoho {
348 1.1 jruoho atf_set "descr" "Tests the use of 'ps -o foo= -o bar=' (with a" \
349 1.1 jruoho "null heading for every column). The heading" \
350 1.1 jruoho "should not be printed at all in this case."
351 1.1 jruoho }
352 1.1 jruoho override_heading_all_null_body()
353 1.1 jruoho {
354 1.1 jruoho setup_keywords
355 1.1 jruoho # A heading with a space is not a null heading,
356 1.1 jruoho # so should not be suppressed
357 1.1 jruoho check_heading_regexp '-o comm=" "' \
358 1.1 jruoho '^ *$'
359 1.1 jruoho # Null headings should be suppressed
360 1.1 jruoho check_no_heading_line '-o pid= -o comm='
361 1.1 jruoho check_no_heading_line '-o pid= -o comm='
362 1.1 jruoho # Check missing pid
363 1.1 jruoho check_no_heading_line '-o ppid='
364 1.1 jruoho check_no_heading_line '-o comm='
365 1.1 jruoho check_no_heading_line '-o command='
366 1.1 jruoho check_no_heading_line '-o ppid= -o comm='
367 1.1 jruoho check_no_heading_line '-o comm= -o ppid='
368 1.1 jruoho # Check pid present but not first
369 1.1 jruoho check_no_heading_line '-o comm= -o pid='
370 1.1 jruoho check_no_heading_line '-o ppid= -o pid= -o command='
371 1.1 jruoho }
372 1.1 jruoho
373 1.1 jruoho atf_test_case duplicate_column
374 1.1 jruoho duplicate_column_head()
375 1.1 jruoho {
376 1.1 jruoho atf_set "descr" "Tests the use of -o options to display the" \
377 1.1 jruoho "same column more than once"
378 1.1 jruoho }
379 1.1 jruoho duplicate_column_body()
380 1.1 jruoho {
381 1.1 jruoho setup_keywords
382 1.1 jruoho # two custom headers
383 1.1 jruoho check_heading_regexp '-o pid=PPP -o pid=QQQ' \
384 1.1 jruoho '^ *PPP *QQQ$'
385 1.1 jruoho # one custom header, before and after default header
386 1.1 jruoho check_heading_regexp '-o pid=PPP -o pid' \
387 1.1 jruoho '^ *PPP '"${head_regexp_pid}"'$'
388 1.1 jruoho check_heading_regexp '-o pid -o pid=QQQ' \
389 1.1 jruoho '^'"${head_regexp_pid}"' *QQQ$'
390 1.1 jruoho # custom headers both before and after default header
391 1.1 jruoho check_heading_regexp '-o pid=PPP -o pid -o pid=QQQ' \
392 1.1 jruoho '^ *PPP '"${head_regexp_pid}"' *QQQ$'
393 1.1 jruoho }
394 1.1 jruoho
395 1.1 jruoho atf_init_test_cases() {
396 1.1 jruoho atf_add_test_case default_columns
397 1.1 jruoho atf_add_test_case minus_O
398 1.1 jruoho atf_add_test_case minus_o
399 1.1 jruoho atf_add_test_case override_heading_simple
400 1.1 jruoho atf_add_test_case override_heading_embedded_specials
401 1.1 jruoho atf_add_test_case override_heading_some_null
402 1.1 jruoho atf_add_test_case override_heading_all_null
403 1.1 jruoho atf_add_test_case duplicate_column
404 1.1 jruoho }
405