5 # Script to do automated testing and data collection
6 # for various test files, so that we don't have to do this by hand on
7 # every test file. It attempts to collect some diagnostic info about
8 # size and speed that should be useful in the future as the library
9 # gets tuned for size and speed. In addition, it tests static and
13 # mkcheck [01] (path to build) (path to src) (path to install)
15 if [ $# != 3 ] && [ $# != 4 ]; then
16 echo 'Usage: mkcheck 0 (path to build) (path to src)'
17 echo ' mkcheck 1 (path to build) (path to src) (path to install)'
20 echo "running mkcheck"
25 # WHICH determines if you are testing the installed binary and headers, or
26 # the build binary and headers.
28 if [ $WHICH != "1" ]; then
30 echo "$0: testing the build directory"
31 elif [ $WHICH -eq 1 ]; then
32 echo "$0: testing the install directory $1"
36 if [ ! -d "$BUILD_DIR" ]; then
37 echo "build directory $BUILD_DIR not found, exiting."
42 if [ ! -d "$SRC_DIR" ]; then
43 echo "source directory $SRC_DIR not found, exiting."
47 if [ $WHICH -eq 1 ]; then
49 if [ ! -d "$PREFIX_DIR" ]; then
50 echo "install directory $PREFIX_DIR not found, exiting."
55 # INC_PATH == include path to new headers for use on gcc command-line
56 if [ $WHICH != "1" ]; then
57 INC_PATH
="-I$BUILD_DIR -I$BUILD_DIR/libio -I$SRC_DIR/@ctype_include_dir@ -I$SRC_DIR/@cpu_include_dir@ -I$SRC_DIR/std -I$SRC_DIR -I$SRC_DIR/libio"
58 elif [ $WHICH -eq 1 ]; then
62 #LIB_PATH == where to find the build library binaries.
63 if [ $WHICH != "1" ]; then
64 LIB_PATH
="-L$BUILD_DIR/src/.libs"
65 # BSD seems to want this
66 # LIB_PATH="-L$BUILD_DIR/src/.libs -R$BUILD_DIR/src/.libs"
67 CXX
="../../gcc/g++ -B../../gcc/"
68 elif [ $WHICH -eq 1 ]; then
69 LIB_PATH
="-L$PREFIX_DIR/lib"
70 # BSD seems to want this
71 # LIB_PATH="-L$PREFIX_DIR/lib -R$PREFIX_DIR/lib"
72 CXX
="$PREFIX_DIR/bin/g++"
76 #CXX_FLAG="-fsquangle -fhonor-std -fnew-exceptions -g -O2 -DDEBUG_ASSERT "
77 #CXX_FLAG="-g -O2 -DDEBUG_ASSERT "
78 CXX_FLAG
="-g -DDEBUG_ASSERT "
80 # a specific flag to force the use of shared libraries, if any
83 # a specific flag to force the use of static libraries, if any
86 # Set up the testing directory, which should be in a directory called
87 # "testsuite" in the root level of the build directory.
88 TEST_DIR
="`pwd`/testsuite"
89 if [ ! -d "$TEST_DIR" ]; then
90 echo "making directory $TEST_DIR"
95 # the name of the file that will collect and hold all this useful data:
96 RESULTS_FILE
="$TEST_DIR/$(date +%Y%m%d)-mkcheck.txt"
98 # the name of the log file that will append compiler diagnostics:
99 LOG_FILE
="$TEST_DIR/$(date +%Y%m%d)-mkchecklog.txt"
101 # the names of the specific test files to be run
102 TESTS_FILE
="$TEST_DIR/$(date +%Y%m%d)-mkcheckfiles.txt"
106 # 2: clean, make files, append general test info
108 if [ -f $RESULTS_FILE ]; then
111 if [ -f $LOG_FILE ]; then
115 # Make a list of the files we're going to run, or use an old one if it exists.
116 if [ ! -f "$TESTS_FILE" ]; then
117 echo "making file $TESTS_FILE"
118 for LONG_NAME
in $SRC_DIR/testsuite
/*/*.cc
120 DIR_NAME
=$
(dirname $LONG_NAME)
121 SHORT_NAME
="`basename $DIR_NAME`/`basename $LONG_NAME`"
122 echo "$SHORT_NAME" >> $TESTS_FILE
126 # Nasty solution to replace GNU date(1)'s %s time_t output function.
127 if [ ! -x "$TEST_DIR/printnow" ]; then
128 echo "making utility $TEST_DIR/printnow"
129 gcc
-o "$TEST_DIR/printnow" "$SRC_DIR/testsuite/printnow.c"
130 strip
"$TEST_DIR/printnow"
133 # Remove old executables.
134 rm -rf "$TEST_DIR"/*exe
136 # Remove old core files (which now get left in cwd, not $TEST_DIR).
139 # Copy over the data files for filebufs in read-only mode
140 cp $SRC_DIR/testsuite
/27_io
/*.txt
$TEST_DIR
141 cp $SRC_DIR/testsuite
/27_io
/*.tst
$TEST_DIR
143 # Emit useful info about compiler and platform
144 echo "host: $(uname -mrsv)" >> $RESULTS_FILE
145 echo "compiler: $($CXX --version)" >> $RESULTS_FILE
146 echo "compiler flags: $CXX_FLAG" >> $RESULTS_FILE
147 echo "date: $(date +%Y%m%d)" >> $RESULTS_FILE
148 echo "" >> $RESULTS_FILE
150 echo "p == pass/fail execution test" >> $RESULTS_FILE
151 echo "ctime == time to compile and link" >> $RESULTS_FILE
152 echo "etime == time for executable to run" >> $RESULTS_FILE
153 echo "text == size of the executable text section" >> $RESULTS_FILE
154 echo "data == size of the executable data section" >> $RESULTS_FILE
155 echo "total == size of the executable" >> $RESULTS_FILE
156 echo "(First static, then shared.)" >> $RESULTS_FILE
157 echo "" >> $RESULTS_FILE
159 echo "p" |
awk '{printf("%s ", $1)}' >> $RESULTS_FILE
160 echo "ctime" "etime" |
awk '{printf("%s\t%s\t", $1, $2)}' >> $RESULTS_FILE
161 echo "text" "data" |
awk '{printf("%s\t%s\t", $1, $2)}' >> $RESULTS_FILE
162 echo "total" "name" |
awk '{printf("%s\t%s\t", $1, $2)}' >> $RESULTS_FILE
163 echo "" >> $RESULTS_FILE
167 # 3: compile, link, execute, time
169 # Abstract out the common code for compiling, linking, executing and printing.
172 # NB: S_FLAG has to be last argument because it may be null, and
173 # error checking hasn't been invented yet.
178 # This would be deliciously easy if GNU date's %s were always around.
179 # There are three ways to do this: 1) use the builtin 'time' like we
180 # do later; then getting compiler errors into LOG_FILE is a nightmare.
181 # 2) Grab the output of a formatted date(1) and do the math; harder
182 # and harder as we try compiling at, say, top of the hour; we would
183 # eventually have to calculate time_t anyhow. Or 3) just grab two
184 # time_t's (no more overhead than grabbing two date(1)'s).
185 COMP_TIME_START
=$
($TEST_DIR/printnow
)
186 $CXX $CXX_FLAG $S_FLAG $INC_PATH $LIB_PATH $FILENAME \
187 -o $EXENAME 2>> $LOG_FILE
188 COMP_TIME_END
=$
($TEST_DIR/printnow
)
190 if [ $COMP_TIME_START -lt $COMP_TIME_END ]; then
191 C_TIME
=$
[ $COMP_TIME_END - $COMP_TIME_START ]
196 if [ -f $EXENAME ]; then
199 # These numbers seem to match up to text/data/total,
200 # although their meanings seem to be different. Very
201 # important to not compare these numbers across platforms.
202 ## Get rid of the banner information. I don't recall this
203 ## happening under previous Solarises. Maybe it's an 8 thing.
204 TEXT
="$(size $EXENAME | grep $EXENAME | awk '{print $1}')"
205 DATA
="$(size $EXENAME | grep $EXENAME | awk '{print $3}')"
206 SIZE
="$(size $EXENAME | grep $EXENAME | awk '{print $7}')"
209 # These numbers seem to match up to text/data/total,
210 # although their meanings seem to be different. Very
211 # important to not compare these numbers across platforms.
212 TEXT
="$(size $EXENAME | awk '{print $1}')"
213 DATA
="$(size $EXENAME | awk '{print $3}')"
214 SIZE
="$(size $EXENAME | awk '{print $7}')"
217 TEXT
="$(size -A $EXENAME | grep text | awk '{print $2}')"
218 DATA
="$(size -A $EXENAME | grep data | awk '{print $2}')"
219 SIZE
="$(size -A $EXENAME | grep otal | awk '{print $2}')"
223 # Actually run the executable and time it . . .
224 TIMEFORMAT
='timemark %R'
225 E_TIME_TEXT
="$(exec 2>&1; time $EXENAME)"
226 E_ABNORMAL_TERMINATION
=$?
227 E_TIME
="$(echo $E_TIME_TEXT | awk '{print $2}')"
228 # joining those two commands does not work due to quoting problems:
229 #E_TIME="$(exec 2>&1; time $EXENAME | awk '{print $2}')"
230 # this will work as a fallback on certain systems...?
231 #E_TIME=$(exec 2>&1; time $EXENAME | cut -d ' ' -f 2)
233 if [ "$E_ABNORMAL_TERMINATION" -ne 0 ]; then
236 # sometimes you want to save all core files for review:
237 #mv ./core $EXENAME.core
238 # sometimes the OS names core files as programname.core:
239 #mv ./*core $EXENAME.core
241 # XXX this should probably be a function?
243 # This checks for emitted output files, which is useful
244 # when testing file-related output. The rules for this
245 # working are as follows: the emitted file must have the
246 # ".txt" extension, and be based on the actual *.cc file's
247 # name. For example, 27/filbuf.cc currently outputs files
248 # named 27/filebuf-2.txt and 27/filebuf-3.txt. Also, the first
249 # emitted file must be in the form $NAME-1.txt. The
250 # control file must follow the same constraints, but have
251 # a ".tst" extension. Thus, you have 27/filebuf-2.tst, etc
254 # NAME contains the source name, like 27/filebuf.cc
255 # From that NAME, we want to generate some possible names, using
256 # ls on MATCH, a pattern description generated with sed.
258 # this is the name of the resulting diff file, if any
259 DIFF_FILE
="`echo $PRE_NAME | sed 's/cc$/diff/'`"
260 # construct wildcard names,ie for $NAME=filebuf.cc, makes
262 DATA_FILES
="`echo $NAME | sed 's/\.cc/\*\.tst/g'`"
263 # make sure there is at least one, then go
264 ST_E
="`echo $NAME | sed 's/\.cc/\-1\.tst/g'`"
265 if [ -f $ST_E ]; then
266 # list of actual files that match the wildcard above, ie
268 ST_MATCH_LIST
="`ls $DATA_FILES`"
269 for i
in $ST_MATCH_LIST
271 # ST_OUT_FILE is generated in the build directory.
272 PRE_NAME2
="$TEST_DIR/`basename $i`"
273 ST_OUT_FILE
="`echo $PRE_NAME2 | sed 's/tst$/txt/'`"
274 diff $ST_OUT_FILE $i > $DIFF_FILE
275 if [ -s $DIFF_FILE ]; then
277 echo "$ST_OUT_FILE has some problems, dude"
284 # the file does no output, and didn't abnormally
285 # terminate, so assume passed.
290 # sometimes you want to save all failing exe files for review:
291 #if [ "$RESULT" = "+" ]; then
295 # the file did not compile. Write out compilation info to the log file.
296 echo "$CXX $CXX_FLAG $ST_FLAG $INC_PATH $LIB_PATH $CNAME -o $EXENAME" \
305 echo $RESULT |
awk '{printf("%s\t", $1)}'
306 echo $RESULT |
awk '{printf ("%.1s ", $1)}'>>$RESULTS_FILE
307 echo $C_TIME $E_TIME |
awk '{printf("%d\t%.3f\t", $1, $2)}'>>$RESULTS_FILE
308 echo $TEXT $DATA |
awk '{printf("%s\t%s\t", $1, $2)}'>>$RESULTS_FILE
309 echo $SIZE |
awk '{printf("%s\t", $1)}'>>$RESULTS_FILE
310 echo $NAME |
awk '{printf("%s\n", $1)}'>>$RESULTS_FILE
313 echo "detailed test information in $RESULTS_FILE"
314 echo "------------------------------------------------------------------------"
315 echo "static" |
awk '{printf("%s\t", $1)}'
316 echo "shared" |
awk '{printf("%s\t", $1)}'
317 echo "test" |
awk '{printf("%s\n", $1)}'
318 echo "------------------------------------------------------------------------"
320 TEST_TIME_START
=$
($TEST_DIR/printnow
)
321 for NAME
in `cat $TESTS_FILE`
323 PRE_NAME
="$TEST_DIR/`basename $NAME`"
324 ST_NAME
="`echo $PRE_NAME | sed 's/cc$/st-exe/'`"
325 SH_NAME
="`echo $PRE_NAME | sed 's/cc$/sh-exe/'`"
326 CNAME
="$SRC_DIR/testsuite/$NAME"
328 test_file
$CNAME $ST_NAME $ST_FLAG
329 test_file
$CNAME $SH_NAME $SH_FLAG
330 echo "$NAME" |
awk '{printf("%s\n", $1)}'
332 echo "" >> $RESULTS_FILE
334 TEST_TIME_END
=$
($TEST_DIR/printnow
)
340 # grep can count faster than we can...
341 total_failures
=$
(egrep -c "^\-" $RESULTS_FILE)
342 total_successes
=$
(egrep -c "^\+" $RESULTS_FILE)
343 resultstext
="pass/fail results: ${total_successes}/${total_failures}"
344 if [ $total_failures -eq 0 ]; then
345 resultstext
="${resultstext}, WIN WIN"
348 $resultstext" $RESULTS_FILE > ${RESULTS_FILE}.tmp
349 mv ${RESULTS_FILE}.tmp
$RESULTS_FILE
351 if [ $TEST_TIME_START -lt $TEST_TIME_END ]; then
352 TEST_TIME
=$
[ $TEST_TIME_END - $TEST_TIME_START ]
353 echo "testrun == $TEST_TIME"