Merge branch 'testsuite', some bug remain fixed in next commit

Conflicts:

	Makefile.am
	configure.ac
	tests/examples/Makefile.am
This commit is contained in:
Christian Thaeter 2007-08-13 21:40:25 +02:00
commit 8405b42d64
12 changed files with 324 additions and 33 deletions

View file

@ -35,6 +35,7 @@ include $(top_srcdir)/src/lib/Makefile.am
#include $(top_srcdir)/src...
# tests
include $(top_srcdir)/tests/Makefile.am
include $(top_srcdir)/tests/examples/Makefile.am
#EXTRA_DIST += admin debian doc depcomp README.BUILD LICENSE \

View file

@ -7,6 +7,8 @@
# see wiki/index.html#GitNotes%20GitAliases for information
git tag -s -f -m "signature generated by $(git config user.email)" "$(git config user.email)/$(git-symbolic-ref HEAD | cut -d/ -f 3-)_signature"
user_email="$(git config user.email)"
git tag -s -f -m "signature generated by $user_email" "$user_email/$(git-symbolic-ref HEAD | cut -d/ -f 3-)_signature"
git push --all public
git push public "refs/tags/$(git config user.email)/*"
git push public "refs/tags/$user_email/*"

View file

@ -30,7 +30,6 @@ AC_PROG_CC
AC_PROG_CPP
AC_PROG_CXX
AC_PROG_LIBTOOL
AC_PROG_RANLIB
#
# test for headers

View file

@ -19,6 +19,7 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdio.h>
#include <unistd.h>
#include <search.h>
#include <string.h>
#include <dlfcn.h>
@ -33,7 +34,7 @@
TODO move CINELERRA_DIE elsewhere (cinlib.h?)
*/
#define CINELERRA_DIE do{NOBUG_ERROR(NOBUG_ON, LOG_EMERG, "aborting due fatal error"); abort();}while(0)
#define CINELERRA_DIE do{NOBUG_LOG(NOBUG_ON, LOG_EMERG, "aborting due fatal error"); abort();}while(0)
/* TODO should be set by the build system to the actual plugin path */
#define CINELERRA_PLUGIN_PATH "~/.cinelerra3/plugins:/usr/local/lib/cinelerra3/plugins"
@ -43,7 +44,7 @@ NOBUG_DEFINE_FLAG (cinelerra_plugin);
/* errors */
const char* CINELERRA_PLUGIN_SUCCESS = NULL;
const char* CINELERRA_PLUGIN_EDLOPEN = "Could not open plugin";
const char* CINELERRA_PLUGIN_EDHOOK = "Hook function failed";
const char* CINELERRA_PLUGIN_EHOOK = "Hook function failed";
const char* CINELERRA_PLUGIN_ENFOUND = "No such plugin";
const char* CINELERRA_PLUGIN_ENIFACE = "No such interface";
const char* CINELERRA_PLUGIN_EREVISION = "Interface revision too old";
@ -62,15 +63,15 @@ enum cinelerra_plugin_type
static const struct
{
const char* const ext;
enum cinelerra_plugin_type;
enum cinelerra_plugin_type type;
} cinelerra_plugin_extensions [] =
{
"plugin", CINELERRA_PLUGIN_DYNLIB,
"so", CINELERRA_PLUGIN_DYNLIB,
"tcc", CINELERRA_PLUGIN_CSOURCE,
"c", CINELERRA_PLUGIN_CSOURCE,
{"plugin", CINELERRA_PLUGIN_DYNLIB},
{"so", CINELERRA_PLUGIN_DYNLIB},
{"tcc", CINELERRA_PLUGIN_CSOURCE},
{"c", CINELERRA_PLUGIN_CSOURCE},
/* extend here */
NULL, CINELERRA_PLUGIN_NULL
{NULL, CINELERRA_PLUGIN_NULL}
};
@ -153,7 +154,7 @@ cinelerra_plugin_lookup (struct cinelerra_plugin* self, const char* path)
strcpy(tpath, path);
/*for each in path*/
for (char* tok = strtok(tpath, ":", &tmp); tok; tok = strtok(NULL, ":", &tmp))
for (char* tok = strtok_r (tpath, ":", &tmp); tok; tok = strtok_r (NULL, ":", &tmp))
{
/*for each extension*/
for (int i = 0; cinelerra_plugin_extensions[i].ext; ++i)
@ -181,7 +182,7 @@ cinelerra_plugin_lookup (struct cinelerra_plugin* self, const char* path)
struct cinelerra_interface*
cinelerra_interface_open (const char* name, const char* interface, size_t min_revision)
{
REQUIRE (min_revision > sizeof(cinelerra_interface), "try to use an empty interface eh?");
//REQUIRE (min_revision > sizeof(struct cinelerra_interface), "try to use an empty interface eh?");
REQUIRE (interface, "interface name must be given");
pthread_once (&cinelerra_plugin_initialized, cinelerra_plugin_tls_init);
@ -208,7 +209,7 @@ cinelerra_interface_open (const char* name, const char* interface, size_t min_re
{
/*lookup for $CINELERRA_PLUGIN_PATH*/
(*found)->name = strdup (name);
if (!(*found)->name) CINELERA_DIE;
if (!(*found)->name) CINELERRA_DIE;
if (!cinelerra_plugin_lookup (*found, getenv("CINELERRA_PLUGIN_PATH"))
#ifdef CINELERRA_PLUGIN_PATH
@ -225,15 +226,14 @@ cinelerra_interface_open (const char* name, const char* interface, size_t min_re
{
(*found)->name = NULL;
(*found)->pathname = NULL;
(*found)->ext = NULL;
}
(*found)->use_count = 0;
PLANNED("if .so like then dlopen; else if .c like tcc compile");
TODO("factor dlopen and dlsym out")
TODO("factor dlopen and dlsym out");
(*found)->handle = dlopen (pathname, RTLD_NOW|RTLD_LOCAL);
(*found)->handle = dlopen ((*found)->pathname, RTLD_NOW|RTLD_LOCAL);
if (!(*found)->handle)
{
ERROR (cinelerra_plugin, "dlopen failed: %s", dlerror());
@ -304,11 +304,13 @@ cinelerra_interface_open (const char* name, const char* interface, size_t min_re
}
void
cinelerra_interface_close (struct cinelerra_interface* self)
cinelerra_interface_close (void* ptr)
{
if(!self)
if(!ptr)
return;
struct cinelerra_interface* self = (struct cinelerra_interface*) ptr;
pthread_mutex_lock (&cinelerra_plugin_mutex);
struct cinelerra_plugin* plugin = self->plugin;

View file

@ -109,7 +109,7 @@ cinelerra_interface_open (const char* plugin, const char* name, size_t min_revis
* @param self interface to be closed
*/
void
cinelerra_interface_close (struct cinelerra_interface* self);
cinelerra_interface_close (void* self);
/**
* Tries to unload a plugin.

13
tests/00test.tests Normal file
View file

@ -0,0 +1,13 @@
TESTING "test system selftest" cat
TEST "test cat'ing stdin to stdout" <<END
in: foo: bar
out: foo: bar
return: 0
END
TEST "test stderr, cat'ing noonexistant file" ,nonexistent_file <<END
err: cat: ,nonexistent_file: No such file or directory
return: 1
END

23
tests/Makefile.am Normal file
View file

@ -0,0 +1,23 @@
# Copyright (C) CinelerraCV
# 2007, Christian Thaeter <ct@pipapo.org>
# Hermann Vosseler <Ichthyostega@web.de>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
tests_srcdir = $(top_srcdir)/tests
noinst_PROGRAMS +=
TESTS = $(tests_srcdir)/test.sh

View file

@ -28,4 +28,3 @@ noinst_HEADERS += $(examples_srcdir)/hello_interface.h
noinst_LTLIBRARIES += example_plugin.la
example_plugin_la_CPPFLAGS = $(CPPFLAGS) -std=gnu99 -Wall -Werror -I$(top_srcdir)/src/lib/
example_plugin_la_SOURCES = $(examples_srcdir)/example_plugin.c

View file

@ -1,6 +1,6 @@
#include "plugin.h"
CINELERRA_INTERFACE(hello, 1,
CINELERRA_INTERFACE_PROTO(void, hello, (void)),
CINELERRA_INTERFACE_PROTO(void, goodbye, (const char*)),
CINELERRA_INTERFACE_PROTO(void, hello, (void))
CINELERRA_INTERFACE_PROTO(void, goodbye, (const char*))
);

View file

@ -12,20 +12,22 @@ main(int argc, char** argv)
open both try them, close them.
*/
struct hello_interface_1* hello_de =
cinelerra_interface_open ("hello_1", "german_1", sizeof(struct hello_interface_1));
if (!hello_de) CINELERRA_DIE;
TODO("macros, doing casting and typing");
hello_de->say_hello();
CINELERRA_INTERFACE_TYPE(hello, 1)* hello_de = (CINELERRA_INTERFACE_TYPE(hello, 1)*)
cinelerra_interface_open ("hello_1", "german_1", sizeof(CINELERRA_INTERFACE_TYPE(hello, 1)));
TODO("new error handling, when finished if (!hello_de) CINELERRA_DIE");
hello_de->hello();
struct hello_interface_1* hello_en =
cinelerra_interface_open ("hello_1", "english_1", sizeof(struct hello_interface_1));
if (!hello_en) CINELERRA_DIE;
// struct hello_interface_1* hello_en =
// cinelerra_interface_open ("hello_1", "english_1", sizeof(struct hello_interface_1));
// TODO if (!hello_en) CINELERRA_DIE;
hello_en->say_hello();
//hello_en->hello();
cinelerra_interface_close (hello_en);
//cinelerra_interface_close (hello_en);
cinelerra_interface_close (hello_de);
#if 0

214
tests/test.sh Executable file
View file

@ -0,0 +1,214 @@
#!/bin/bash
# Copyright (C) CinelerraCV
# 2007, Christian Thaeter <ct@pipapo.org>
# Hermann Vosseler <Ichthyostega@web.de>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
# TESTMODE=FULL yet unimplemented
# run all tests, PLANNED which fail count as error
#
# TESTMODE=FAST
# run only tests which recently failed
#
# TESTMODE=FIRSTFAIL
# stop testing on the first failure
export LC_ALL=C
arg0="$0"
srcdir=$(dirname "$arg0")
ulimit -S -t 1 -v 524288
valgrind=""
if [ "$VALGRINDFLAGS" = 'DISABLE' ]; then
echo "valgrind explicit disabled"
else
if [ "$(which valgrind)" ]; then
valgrind="$(which valgrind) --leak-check=yes --show-reachable=yes -q $VALGRINDFLAGS"
ulimit -S -t 10
else
echo "no valgrind found, go without it"
fi
fi
echo
echo ================ ${0##*/} ================
TESTCNT=0
SKIPCNT=0
FAILCNT=0
# the old testlog if existing will be used to check for previous test states
if test -f ,testlog; then
mv ,testlog ,testlog.pre
else
touch ,testlog.pre
fi
date >,testlog
function TEST()
{
name="$1"
shift
rm -f ,send_stdin
rm -f ,expect_stdout
rm -f ,expect_stderr
while read -r line; do
cmd="${line%%:*}"
arg="${line#*: }"
expect_return=0
case $cmd in
'in')
echo "$arg" >>,send_stdin
;;
'out')
echo "$arg" >>,expect_stdout
;;
'err')
echo "$arg" >>,expect_stderr
;;
'return')
expect_return=$arg
;;
*)
echo "UNKOWN TEST COMMAND '$cmd'" 1>&2
exit
;;
esac
done
echo -n "TEST $name: "
echo -en "\nTEST $name: $* " >>,testlog
case $TESTMODE in
*FAST*)
if grep "^TEST $name: .* FAILED" ,testlog.pre >&/dev/null; then
MSGOK=" (fixed)"
MSGFAIL=" (still broken)"
elif grep "^TEST $name: .* \\(SKIPPED (ok)\\|OK\\)" ,testlog.pre >&/dev/null; then
echo ".. SKIPPED (ok)"
echo ".. SKIPPED (ok)" >>,testlog
SKIPCNT=$(($SKIPCNT + 1))
TESTCNT=$(($TESTCNT + 1))
return
else
MSGOK=" (new)"
MSGFAIL=" (new)"
fi
;;
*)
MSGOK=""
MSGFAIL=""
;;
esac
TESTCNT=$(($TESTCNT + 1))
fails=0
if test -f ,send_stdin; then
cat ,send_stdin | $valgrind $TESTBIN "$@" 2>,stderr >,stdout
else
$valgrind $TESTBIN "$@" 2>,stderr >,stdout
fi &>/dev/null
return=$?
echo -n >,testtmp
if test -f ,expect_stdout; then
if ! cmp ,expect_stdout ,stdout &>/dev/null; then
echo "unexpected data on stdout" >>,testtmp
grep -v ': \(TRACE\|INFO\|NOTICE\|WARNING\|ERR\):' <,stdout >,tmp
diff -ua ,expect_stdout ,tmp >>,testtmp
rm ,tmp
((fails+=1))
fi
fi
if test -f ,expect_stderr; then
if ! cmp ,expect_stderr ,stderr &>/dev/null; then
echo "unexpected data on stderr" >>,testtmp
grep -v ': \(TRACE\|INFO\|NOTICE\|WARNING\|ERR\):' <,stderr >,tmp
diff -ua ,expect_stderr ,tmp >>,testtmp
rm ,tmp
((fails+=1))
fi
fi
if test $expect_return != $return; then
echo "unexpected return value $return" >>,testtmp
((fails+=1))
fi
if test $fails -eq 0; then
echo ".. OK$MSGOK"
echo ".. OK$MSGOK" >>,testlog
else
echo ".. FAILED$MSGFAIL";
echo ".. FAILED$MSGFAIL" >>,testlog
cat ,testtmp >>,testlog
rm ,testtmp
echo "stderr was:" >>,testlog
cat ,stderr >>,testlog
echo END >>,testlog
FAILCNT=$(($FAILCNT + 1))
case $TESTMODE in
*FIRSTFAIL*)
break 2
;;
esac
fi
}
function PLANNED()
{
echo -n "PLANNED $1: "
echo -en "\nPLANNED $* " >>,testlog
echo ".. SKIPPED (planned)"
echo ".. SKIPPED (planned)" >>,testlog
SKIPCNT=$(($SKIPCNT + 1))
TESTCNT=$(($TESTCNT + 1))
}
function RUNTESTS()
{
for i in $srcdir/*.tests; do
source $i
done
echo
if [ $FAILCNT = 0 ]; then
echo " ... PASSED $(($TESTCNT - $SKIPCNT)) TESTS, $SKIPCNT SKIPPED"
#rm ,testlog
else
echo " ... SUCCEDED $(($TESTCNT - $FAILCNT - $SKIPCNT)) TESTS"
echo " ... FAILED $FAILCNT TESTS"
echo " ... SKIPPED $SKIPCNT TESTS"
echo " see ',testlog' for details"
exit 1
fi
}
function TESTING()
{
echo
echo "$1"
TESTBIN=$2
}
RUNTESTS

View file

@ -795,7 +795,7 @@ This distributed wiki might be used instead the pipapo.org wiki, investigate tha
Wiki works. It is simple to use and just flexible enough to handle the task. I don't go to install any other software for such tasks on my server. While the design progresses I'd propose to move our work into git repositories and eventually phase this wiki pages out anyways. I'd rather like to start out distributed/git right away .. but git gives us only a fine storage layer, for a design process we need some good presentation layer (later when using git and starting the implementation everyones favorite editor serves for that) I have no better ideas yet to solve the presentation problem other than using this wiki (or maybe Bouml).
</pre>
</div>
<div title="Cinelerra3Wiki" modifier="CehTeh" modified="200708120136" created="200706172308" tags="portal" changecount="23">
<div title="Cinelerra3Wiki" modifier="CehTeh" modified="200708131455" created="200706172308" tags="portal" changecount="24">
<pre>This 'index.html' becomes the entry point of some tiddlywikis managed under git. There is a 'empty.html' in the same folder serving as template for generating new wikis. Please refrain from editing it.
* I started a GitNotes where we will collect some information about git, howto and special setups
@ -812,6 +812,7 @@ to get started, we create design drafts emphasizing different aspects and region
* Ichthyo focuses mainly on the Render Engine and its interconnection to the EDL, [[see this separate page|renderengine.html]]
* cehteh works on the data backend draft, see [[this page|backend.html]]
* Some tools which don't fit somewhere else and are used everywhere are put into a [[Support Library|support_library.html]]
* [[Description of the Test System|TestSh]]
!Coding Structures
next we should //start thinking// on how to organize several aspects of the practical coding...
@ -3452,6 +3453,41 @@ Portions written by Luke Blanshard are hereby released into the public domain.
&lt;div macro=&quot;tasksum end&quot;&gt;&lt;/div&gt;
&lt;div class=&quot;tagglyTagging&quot; macro=&quot;tagglyListWithSort&quot;&gt;&lt;/div&gt;
&lt;!--}}}--&gt;
</pre>
</div>
<div title="TestSh" modifier="CehTeh" modified="200708131521" created="200708131509" changecount="5">
<pre>! The Test Script
There is a simple test script in tests which will be used to drive various tests. All tests are run under valgrind control if available unless {{{VALGRINDFLAGS=DISABLE}}} is defined. This test script is integrated in the automake build and will be used when {{{make check}}} is called.
! Options for running the Test Suite
One may define {{{TESTMODE}}} containing any one of the following strings:
* {{{FAST}}} only run tests which failed recently
* {{{FIRSTFAIL}}} abort the tests at the first failure
putting this together a very fast check (when using automake) while hacking on the source would look like:
{{{
VALGRINDFLAGS=DISABLE TESTMODE=FAST+FIRSTFAIL make check
}}}
This doesnt catch all errors, notably not regressions, but is useful to do coarse checks.
Running the testsuite with everything enabled is just:
{{{
make check
}}}
! Writing Tests
Tests are written in files named {{{NNname.tests}}} in the {{{tests}}} dir, where NN is a number defining the order of the various test files, 'name' should be a descriptive name about whats going to be tested.
In a .tests file one has to define following:
* {{{TESTING &lt;description&gt; &lt;binary&gt;}}} set the program binary to be tested to &lt;binary&gt;, &lt;description&gt; should be a string which is displayed as header before running following tests
* {{{TEST &lt;description&gt; [optargs] &lt;&lt;END}}} run the previously set binary with [optargs], &lt;description&gt; is displayed when running this test. A detailed test spec must follow this command and be terminated with {{{END}}} on a single line. Test specs can contain following statements:
** {{{in: &lt;line&gt;}}} send &lt;line&gt; to stdin of the test program
** {{{out: &lt;line&gt;}}} expect &lt;line&gt; at the stdout of the test program
** {{{err: &lt;line&gt;}}} expect &lt;line&gt; at the stderr of the test program
** {{{return: &lt;status&gt;}}} expect &lt;status&gt; as exit status of the program
If no {{{out:}}} or {{{err:}}} is given, stdout and stderr are not considered as part of the test. If no {{{return:}}} is given, then 0 is expected.
</pre>
</div>
<div title="TextAreaPlugin" modifier="Jeremy" created="200601261745" tags="systemConfig" server.type="file" server.host="file:///home/ct/.homepage/home.html" server.page.revision="200601261745">