Better POD
[authen-passphrase-scrypt.git] / scrypt-1.2.1 / tests / shared_test_functions.sh
CommitLineData
0c1f3509
MG
1#!/bin/sh
2
3### Definitions
4#
5# This test suite uses the following terminology:
6# - scenario: a series of commands to test. Each must be in a
7# separate file, and must be completely self-contained
8# (other than the variables listed below).
9# - check: a series of commands that produces an exit code which
10# the test suite should check. A scenario may contain any
11# number of checks.
12#
13### Design
14#
15# The main function is scenario_runner(scenario_filename), which
16# takes a scenario file as the argument, and runs a
17# scenario_cmd()
18# function which was defined in that file.
19#
20### Variables
21#
22# Wherever possible, this suite uses local variables and
23# explicitly-passed arguments, with the following exceptions:
24# - s_basename: this is the basename for the scenario's temporary
25# and log files.
26# - s_val_basename: this is the basename for the scenario's
27# valgrind log files.
28# - s_count: this is the count of the scenario's checks (so that
29# each check can have distinct files).
30# - s_retval: this is the overall exit code of the scenario.
31# - c_exitfile: this contains the exit code of each check.
32# - c_valgrind_min: this is the minimum value of USE_VALGRIND
33# which will enable valgrind checking for this check.
34# - c_valgrind_cmd: this is the valgrind command (including
35# appropriate log file) if necessary, or is "" otherwise.
36
37set -o nounset
38
39### Constants
40out="tests-output"
41out_valgrind="tests-valgrind"
42valgrind_suppressions="${out_valgrind}/suppressions"
43valgrind_suppressions_log="${out_valgrind}/suppressions.pre"
44
45# Keep the user-specified ${USE_VALGRIND}, or initialize to 0.
46USE_VALGRIND=${USE_VALGRIND:-0}
47
48# A non-zero value unlikely to be used as an exit code by the programs being
49# tested.
50valgrind_exit_code=108
51
52## prepare_directories():
53# Delete any old directories, and create new ones as necessary. Must be run
54# after check_optional_valgrind().
55prepare_directories() {
56 # Clean up previous directories.
57 if [ -d "${out}" ]; then
58 rm -rf ${out}
59 fi
60 if [ -d "${out_valgrind}" ]; then
61 rm -rf ${out_valgrind}
62 fi
63
64 # Make new directories.
65 mkdir ${out}
66 if [ "$USE_VALGRIND" -gt 0 ]; then
67 mkdir ${out_valgrind}
68 fi
69}
70
71## find_system (cmd, args...):
72# Looks for ${cmd} in the $PATH, and ensure that it supports ${args}.
73find_system() {
74 cmd=$1
75 cmd_with_args=$@
76 # Look for ${cmd}.
77 system_binary=`command -v ${cmd}`
78 if [ -z "${system_binary}" ]; then
79 system_binary=""
80 printf "System ${cmd} not found.\n" 1>&2
81 # If the command exists, check it ensures the ${args}.
82 elif ${cmd_with_args} 2>&1 >/dev/null | \
83 grep -qE "(invalid|illegal) option"; then
84 system_binary=""
85 printf "Cannot use system ${cmd}; does not" 1>&2
86 printf " support necessary arguments.\n" 1>&2
87 fi
88 echo "${system_binary}"
89}
90
91## check_optional_valgrind ():
92# Return a $USE_VALGRIND variable defined; if it was previously defined and
93# was greater than 0, then check that valgrind is available in the $PATH.
94check_optional_valgrind() {
95 if [ "$USE_VALGRIND" -gt 0 ]; then
96 # Look for valgrind in $PATH.
97 if ! command -v valgrind >/dev/null 2>&1; then
98 printf "valgrind not found\n" 1>&2
99 exit 1
100 fi
101 fi
102}
103
104## ensure_valgrind_suppresssion (potential_memleaks_binary):
105# Runs the ${potential_memleaks_binary} through valgrind, keeping
106# track of any apparent memory leak in order to suppress reporting
107# those leaks when testing other binaries.
108ensure_valgrind_suppression() {
109 potential_memleaks_binary=$1
110
111 # Quit if we're not using valgrind.
112 if [ ! "$USE_VALGRIND" -gt 0 ]; then
113 return
114 fi;
115 printf "Generating valgrind suppressions... "
116
117 # Run valgrind on the binary, sending it a "\n" so that
118 # a test which uses STDIN will not wait for user input.
119 printf "\n" | (valgrind --leak-check=full --show-leak-kinds=all \
120 --gen-suppressions=all \
121 --log-file=${valgrind_suppressions_log} \
122 ${potential_memleaks_binary})
123
124 # Strip out useless parts from the log file, as well as
125 # removing references to the main and "pl_*" ("potential
126 # loss") functions so that the suppressions can apply to
127 # other binaries.
128 (grep -v "^==" ${valgrind_suppressions_log} \
129 | grep -v " fun:pl_" - \
130 | grep -v " fun:main" - \
131 > ${valgrind_suppressions} )
132
133 # Clean up
134 rm -f ${valgrind_suppressions_log}
135 printf "done.\n"
136}
137
138## setup_check_variables ():
139# Set up the "check" variables ${c_exitfile} and ${c_valgrind_cmd}, the
140# latter depending on the previously-defined ${c_valgrind_min}.
141# Advances the number of checks ${s_count} so that the next call to this
142# function will set up new filenames.
143setup_check_variables() {
144 # Set up the "exit" file.
145 c_exitfile="${s_basename}-`printf %02d ${s_count}`.exit"
146
147 # If we don't have a suppressions file, don't try to use it.
148 if [ ! -e ${valgrind_suppressions} ]; then
149 valgrind_suppressions=/dev/null
150 fi
151
152 # Set up the valgrind command if $USE_VALGRIND is greater
153 # than or equal to ${valgrind_min}; otherwise, produce an
154 # empty string. Using --error-exitcode means that if
155 # there is a serious problem (such that scrypt calls
156 # exit(1)) *and* a memory leak, the test suite reports an
157 # exit value of ${valgrind_exit_code}. However, if there
158 # is a serious problem but no memory leak, we still
159 # receive a non-zero exit code. The most important thing
160 # is that we only receive an exit code of 0 if both the
161 # program and valgrind are happy.
162 if [ "$USE_VALGRIND" -ge "${c_valgrind_min}" ]; then
163 val_logfilename=${s_val_basename}-`printf %02d ${s_count}`.log
164 c_valgrind_cmd="valgrind \
165 --log-file=${val_logfilename} \
166 --leak-check=full --show-leak-kinds=all \
167 --errors-for-leak-kinds=all \
168 --suppressions=${valgrind_suppressions} \
169 --error-exitcode=${valgrind_exit_code} "
170 else
171 c_valgrind_cmd=""
172 fi
173
174 # Advances the number of checks.
175 s_count=$((s_count + 1))
176}
177
178## get_val_logfile (val_basename, exitfile):
179# Return the valgrind logfile corresponding to ${exitfile}.
180get_val_logfile() {
181 val_basename=$1
182 exitfile=$2
183 num=`echo "${exitfile}" | rev | cut -c 1-7 | rev | cut -c 1-2 `
184 echo "${val_basename}-${num}.log"
185}
186
187## notify_success_or_fail (log_basename, val_log_basename):
188# Examine all "exit code" files beginning with ${log_basename} and
189# print "SUCCESS!" or "FAILED!" as appropriate. If the test failed
190# with the code ${valgrind_exit_code}, output the appropriate
191# valgrind logfile to stdout.
192notify_success_or_fail() {
193 log_basename=$1
194 val_log_basename=$2
195
196 # Check each exitfile.
197 for exitfile in `ls ${log_basename}-*.exit | sort`; do
198 ret=`cat ${exitfile}`
199 if [ "${ret}" -lt 0 ]; then
200 echo "SKIP!"
201 return
202 fi
203 if [ "${ret}" -gt 0 ]; then
204 echo "FAILED!"
205 retval=${ret}
206 if [ "${ret}" -eq "${valgrind_exit_code}" ]; then
207 val_logfilename=$( get_val_logfile \
208 ${val_log_basename} ${exitfile} )
209 cat ${val_logfilename}
210 fi
211 s_retval=${ret}
212 return
213 fi
214 done
215
216 echo "SUCCESS!"
217}
218
219## scenario_runner (scenario_filename):
220# Runs a test scenario from ${scenario_filename}.
221scenario_runner() {
222 scenario_filename=$1
223 basename=`basename ${scenario_filename} .sh`
224 printf " ${basename}... " 1>&2
225
226 # Initialize "scenario" and "check" variables.
227 s_basename=${out}/${basename}
228 s_val_basename=${out_valgrind}/${basename}
229 s_count=0
230 c_exitfile=/dev/null
231 c_valgrind_min=9
232 c_valgrind_cmd=""
233
234 # Load scenario_cmd() from the scenario file.
235 unset scenario_cmd
236 . ${scenario_filename}
237 if ! command -v scenario_cmd 1>/dev/null ; then
238 printf "ERROR: scenario_cmd() is not defined in\n"
239 printf " ${scenario_filename}\n"
240 exit 1
241 fi
242
243 # Run the scenario command.
244 scenario_cmd
245
246 # Print PASS or FAIL, and return result.
247 s_retval=0
248 notify_success_or_fail ${s_basename} ${s_val_basename}
249
250 return "${s_retval}"
251}
252
253## run_scenarios (scenario_filenames):
254# Runs all scenarios matching ${scenario_filenames}.
255run_scenarios() {
256 printf -- "Running tests\n"
257 printf -- "-------------\n"
258 scenario_filenames=$@
259 for scenario in ${scenario_filenames}; do
260 # We can't call this function with $( ... ) because we
261 # want to allow it to echo values to stdout.
262 scenario_runner ${scenario}
263 retval=$?
264 if [ ${retval} -gt 0 ]; then
265 exit ${retval}
266 fi
267 done
268}
This page took 0.023878 seconds and 4 git commands to generate.