Simple continuous test solution via make
Perl hacker gugod demoed Test::Continuous in OSDC.tw 2008 lightning talk. This is a great idea that breaks the code/build/debug cycle so we can continuously focus on the code we're writing and let the build/debug stuffs go background (mentally). But Test::Continuous is a perl module that best suite for perl hacking. I'm a C/C++ programmer now and cannot benefit from his work. So I wrote a little script that brute forced the idea with the help of make.
The most complex part of Test::Continuous is to detect whether we should build and test, or just waiting for source file changes. I'm not sure how gugod did that in Perl, but this is absolutely what make(1) good at. The -q argument for GNU make will return an exit status indicating whether specified targets are already up to date or not. So we may write an infinite loop and ask GNU make to check whether depended source is changed or not, and really do the build/test if make -q returns nonzero.
And, with the help of gnome-cli-notify.py, it is easy to show a notification popup when build/test failed or vice versa.
So, here comes the script. Enjoy.
#!/usr/bin/env bash
# ---------------------------------------------------------------------------
# Amarganth Development Environment
# Copyright (c) 2007, Jeff Hung
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# - Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# - Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# - Neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# ---------------------------------------------------------------------------
# $Date: 2009-07-27 10:18:22 +0800 (Mon, 27 Jul 2009) $
# $Rev: 489 $
# $Author: jeffhung $
# ----------------------------------------------------------------------------
# revid: "@(#) $Id: scm.old 489 2009-07-27 02:18:22Z jeffhung $"
# ----------------------------------------------------------------------------
__exe_name__=`basename $0`;
__revision__=`echo '$Rev: 560 $' | cut -d' ' -f2`;
__rev_date__=`echo '$Date: 2007-07-19 11:07:45 +0800 (星期四, 19 七月 2007) $' | cut -d' ' -f2`;
continuous_timeout=5
error_stop_timeout=30
if [ $# -lt 3 ]; then
echo "\
Usage: continuous-test <build-target> <test-target> <notify-cmd> ...
The continuous-test script make(1) your <test-target> continuously while we
developing. The script repeatedly asking GNU make(1) to determine whether
<build-target> need to be built or not. If it needs to be built, build it
and then <test-target>. If any of <build-target> or <test-target> failed,
run <notify-cmd> to notify we developer. If build successed, <build-target>
no longer need to be built, and this script go back to check continuously.
This script requires GNU make(1) and bash(1).
Example:
$ continuous-test all test \\
\"gnome-cli-notify.py 'Test Failed...' 'Check error console please.'\" \\
;
Revision: r$__revision__ ($__rev_date__)";
exit;
fi;
build_target="$1"; shift;
test_target="$1"; shift;
notify_cmd="$1"; shift;
while [ $# -gt 0 ]; do
notify_cmd="$notify_cmd '$1'";
shift;
done;
#echo "$notify_cmd";
while [ -z '' ]; do
make -q "$build_target";
if [ $? -ne 0 ]; then
echo "Change detected, build and test!!";
rm -f "$temp_file";
make "$build_target" && make "$test_target";
if [ $? -ne 0 ]; then
echo ">>> TEST FAILED!!";
if [ -n "$notify_cmd" ]; then
eval $notify_cmd;
fi;
read -n 1 -t $error_stop_timeout \
-p "(`date '+%H:%M:%S'`+$error_stop_timeout) Stop continuous test (y/N)? " \
ans;
# if [ \( $? -ne 0 \) -o \( "$ans" = 'y' \) ]; then
if [ \( $? -eq 0 \) -a \( "$ans" = 'y' \) ]; then
echo;
break; # while
fi;
fi;
fi;
printf "\r";
read -n 1 -t $continuous_timeout \
-p "(`date '+%H:%M:%S'`+$continuous_timeout) Stop continuous test (y/N)? " \
ans;
if [ \( $? -eq 0 \) -a \( "$ans" = 'y' \) ]; then
echo;
break; # while
fi;
done;
echo 'End.';
This script is written in Bash for the read builtin, cooperate with GNU make.



2 Comments
不好意思,找個小碴:
1. "a infinite" -> "an infinite".
2. "whether depended source changed or not" -> "whether depended source is changed or not"
感謝,菜英文被你抓到了。
Post a Comment