Merge Ubuntu/Lucid adjustments. Drop pre 1.0 compatibility
This commit is contained in:
commit
86bc30a10a
15 changed files with 517 additions and 152 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -20,3 +20,4 @@ autom4te.cache
|
|||
semantic.cache
|
||||
wiki/backups/*
|
||||
doc/devel/draw/*.png
|
||||
m4/*
|
||||
|
|
|
|||
87
SConstruct
87
SConstruct
|
|
@ -33,7 +33,7 @@ TESTDIR = 'tests'
|
|||
ICONDIR = 'icons'
|
||||
VERSION = '0.1+pre.01'
|
||||
TOOLDIR = './admin/scons'
|
||||
SVGRENDERER = 'admin/render-icon'
|
||||
SCRIPTDIR = './admin'
|
||||
#-----------------------------------Configuration
|
||||
|
||||
# NOTE: scons -h for help.
|
||||
|
|
@ -47,6 +47,7 @@ import os
|
|||
import sys
|
||||
|
||||
sys.path.append(TOOLDIR)
|
||||
sys.path.append(SCRIPTDIR)
|
||||
|
||||
from Buildhelper import *
|
||||
from LumieraEnvironment import *
|
||||
|
|
@ -58,10 +59,12 @@ def setupBasicEnvironment():
|
|||
""" define cmdline options, build type decisions
|
||||
"""
|
||||
EnsurePythonVersion(2,3)
|
||||
EnsureSConsVersion(0,96,90)
|
||||
EnsureSConsVersion(1,0)
|
||||
|
||||
opts = defineCmdlineOptions()
|
||||
env = LumieraEnvironment(options=opts
|
||||
Decider('MD5-timestamp') # detect changed files by timestamp, then do a MD5
|
||||
|
||||
vars = defineCmdlineVariables()
|
||||
env = LumieraEnvironment(variables=vars
|
||||
,toolpath = [TOOLDIR]
|
||||
,tools = ["default", "BuilderGCH", "BuilderDoxygen"]
|
||||
)
|
||||
|
|
@ -82,7 +85,7 @@ def setupBasicEnvironment():
|
|||
, CCFLAGS='-Wall -Wextra '
|
||||
, CFLAGS='-std=gnu99'
|
||||
)
|
||||
RegisterIcon_Builder(env,SVGRENDERER)
|
||||
RegisterIcon_Builder(env)
|
||||
handleNoBugSwitches(env)
|
||||
|
||||
env.Append(CPPDEFINES = '_GNU_SOURCE')
|
||||
|
|
@ -98,8 +101,8 @@ def setupBasicEnvironment():
|
|||
appendCppDefine(env,'PKGDATADIR','LUMIERA_CONFIG_PATH=\\"$PKGLIBDIR/:.\\"'
|
||||
,'LUMIERA_CONFIG_PATH=\\"$DESTDIR/share/lumiera/:.\\"')
|
||||
|
||||
prepareOptionsHelp(opts,env)
|
||||
opts.Save(OPTIONSCACHEFILE, env)
|
||||
prepareOptionsHelp(vars,env)
|
||||
vars.Save(OPTIONSCACHEFILE, env)
|
||||
return env
|
||||
|
||||
def appendCppDefine(env,var,cppVar, elseVal=''):
|
||||
|
|
@ -139,40 +142,40 @@ def handleVerboseMessages(env):
|
|||
|
||||
|
||||
|
||||
def defineCmdlineOptions():
|
||||
""" current options will be persisted in a options cache file.
|
||||
you may define custom options in a separate file.
|
||||
def defineCmdlineVariables():
|
||||
""" several toggles and configuration variables can be set on the commandline,
|
||||
current settings will be persisted in a options cache file.
|
||||
you may define custom variable settings in a separate file.
|
||||
Commandline will override both.
|
||||
"""
|
||||
opts = Options([OPTIONSCACHEFILE, CUSTOPTIONSFILE])
|
||||
opts.AddOptions(
|
||||
vars = Variables([OPTIONSCACHEFILE, CUSTOPTIONSFILE])
|
||||
vars.AddVariables(
|
||||
('ARCHFLAGS', 'Set architecture-specific compilation flags (passed literally to gcc)','')
|
||||
,('CC', 'Set the C compiler to use.', 'gcc')
|
||||
,('CXX', 'Set the C++ compiler to use.', 'g++')
|
||||
,PathOption('CCACHE', 'Integrate with CCache', '', PathOption.PathAccept)
|
||||
,PathOption('DISTCC', 'Invoke C/C++ compiler commands through DistCC', '', PathOption.PathAccept)
|
||||
,EnumOption('BUILDLEVEL', 'NoBug build level for debugging', 'ALPHA',
|
||||
allowed_values=('ALPHA', 'BETA', 'RELEASE'))
|
||||
,BoolOption('DEBUG', 'Build with debugging information and no optimisations', False)
|
||||
,BoolOption('OPTIMIZE', 'Build with strong optimisation (-O3)', False)
|
||||
,BoolOption('VALGRIND', 'Run Testsuite under valgrind control', True)
|
||||
,BoolOption('VERBOSE', 'Print full build commands', False)
|
||||
,PathVariable('CCACHE', 'Integrate with CCache', '', PathVariable.PathAccept)
|
||||
,PathVariable('DISTCC', 'Invoke C/C++ compiler commands through DistCC', '', PathVariable.PathAccept)
|
||||
,EnumVariable('BUILDLEVEL', 'NoBug build level for debugging', 'ALPHA', allowed_values=('ALPHA', 'BETA', 'RELEASE'))
|
||||
,BoolVariable('DEBUG', 'Build with debugging information and no optimisations', False)
|
||||
,BoolVariable('OPTIMIZE', 'Build with strong optimisation (-O3)', False)
|
||||
,BoolVariable('VALGRIND', 'Run Testsuite under valgrind control', True)
|
||||
,BoolVariable('VERBOSE', 'Print full build commands', False)
|
||||
,('TESTSUITES', 'Run only Testsuites matching the given pattern', '')
|
||||
# ,BoolOption('OPENGL', 'Include support for OpenGL preview rendering', False)
|
||||
# ,EnumOption('DIST_TARGET', 'Build target architecture', 'auto',
|
||||
# ,BoolVariable('OPENGL', 'Include support for OpenGL preview rendering', False)
|
||||
# ,EnumVariable('DIST_TARGET', 'Build target architecture', 'auto',
|
||||
# allowed_values=('auto', 'i386', 'i686', 'x86_64' ), ignorecase=2)
|
||||
,PathOption('DESTDIR', 'Installation dir prefix', '/usr/local')
|
||||
,PathOption('PKGLIBDIR', 'Installation dir for plugins, defaults to DESTDIR/lib/lumiera', '',PathOption.PathAccept)
|
||||
,PathOption('PKGDATADIR', 'Installation dir for default config, usually DESTDIR/share/lumiera', '',PathOption.PathAccept)
|
||||
,PathOption('SRCTAR', 'Create source tarball prior to compiling', '..', PathOption.PathAccept)
|
||||
,PathOption('DOCTAR', 'Create tarball with developer documentation', '..', PathOption.PathAccept)
|
||||
,PathVariable('DESTDIR', 'Installation dir prefix', '/usr/local')
|
||||
,PathVariable('PKGLIBDIR', 'Installation dir for plugins, defaults to DESTDIR/lib/lumiera', '',PathVariable.PathAccept)
|
||||
,PathVariable('PKGDATADIR', 'Installation dir for default config, usually DESTDIR/share/lumiera', '',PathVariable.PathAccept)
|
||||
,PathVariable('SRCTAR', 'Create source tarball prior to compiling', '..', PathVariable.PathAccept)
|
||||
,PathVariable('DOCTAR', 'Create tarball with developer documentation', '..', PathVariable.PathAccept)
|
||||
)
|
||||
|
||||
return opts
|
||||
return vars
|
||||
|
||||
|
||||
|
||||
def prepareOptionsHelp(opts,env):
|
||||
def prepareOptionsHelp(vars,env):
|
||||
prelude = """
|
||||
USAGE: scons [-c] [OPTS] [key=val [key=val...]] [TARGETS]
|
||||
Build and optionally install Lumiera.
|
||||
|
|
@ -191,7 +194,7 @@ Special Targets:
|
|||
|
||||
Configuration Options:
|
||||
"""
|
||||
Help(prelude + opts.GenerateHelpText(env))
|
||||
Help(prelude + vars.GenerateHelpText(env))
|
||||
|
||||
|
||||
|
||||
|
|
@ -215,11 +218,6 @@ def configurePlatform(env):
|
|||
if not conf.CheckLibWithHeader('dl', 'dlfcn.h', 'C'):
|
||||
problems.append('Functions for runtime dynamic loading not available.')
|
||||
|
||||
if not conf.CheckPkgConfig('nobugmt', 200909.1):
|
||||
problems.append('Did not find NoBug [http://www.pipapo.org/pipawiki/NoBug].')
|
||||
else:
|
||||
conf.env.mergeConf('nobugmt')
|
||||
|
||||
if not conf.CheckLibWithHeader('pthread', 'pthread.h', 'C'):
|
||||
problems.append('Did not find the pthread lib or pthread.h.')
|
||||
else:
|
||||
|
|
@ -234,6 +232,11 @@ def configurePlatform(env):
|
|||
else:
|
||||
print 'Valgrind not found. The use of Valgrind is optional; building without.'
|
||||
|
||||
if not conf.CheckPkgConfig('nobugmt', 201005.1):
|
||||
problems.append('Did not find NoBug [http://www.lumiera.org/nobug_manual.html].')
|
||||
else:
|
||||
conf.env.mergeConf('nobugmt')
|
||||
|
||||
if not conf.CheckCXXHeader('tr1/memory'):
|
||||
problems.append('We rely on the std::tr1 proposed standard extension for shared_ptr.')
|
||||
|
||||
|
|
@ -248,6 +251,12 @@ def configurePlatform(env):
|
|||
problems.append('We need the boost regular expression lib (incl. binary lib for linking).')
|
||||
|
||||
|
||||
if conf.CheckLib(symbol='clock_gettime'):
|
||||
print 'Using function clock_gettime() as defined in the C-lib...'
|
||||
else:
|
||||
if not conf.CheckLib(symbol='clock_gettime', library='rt'):
|
||||
problems.append('No library known to provide the clock_gettime() function.')
|
||||
|
||||
if not conf.CheckPkgConfig('gavl', 1.0):
|
||||
problems.append('Did not find Gmerlin Audio Video Lib [http://gmerlin.sourceforge.net/gavl.html].')
|
||||
else:
|
||||
|
|
@ -280,9 +289,6 @@ def configurePlatform(env):
|
|||
|
||||
if not conf.CheckPkgConfig('xv') : problems.append('Need libXv...')
|
||||
if not conf.CheckPkgConfig('xext'): problems.append('Need libXext.')
|
||||
# if not conf.CheckPkgConfig('sm'): Exit(1)
|
||||
#
|
||||
# obviously not needed?
|
||||
|
||||
|
||||
# report missing dependencies
|
||||
|
|
@ -323,7 +329,8 @@ def defineBuildTargets(env, artifacts):
|
|||
setup sub-environments with special build options if necessary.
|
||||
We use a custom function to declare a whole tree of srcfiles.
|
||||
"""
|
||||
# use PCH to speed up building
|
||||
|
||||
# use PCH to speed up building // disabled for now due to strange failures
|
||||
# env['GCH'] = ( env.PrecompiledHeader('$SRCDIR/pre.hpp')
|
||||
# + env.PrecompiledHeader('$SRCDIR/pre_a.hpp')
|
||||
# )
|
||||
|
|
@ -355,7 +362,7 @@ def defineBuildTargets(env, artifacts):
|
|||
|
||||
# the Lumiera GTK GUI
|
||||
envGtk = env.Clone()
|
||||
envGtk.mergeConf(['gtkmm-2.4','cairomm-1.0','gdl','gthread-2.0','xv','xext','sm'])
|
||||
envGtk.mergeConf(['gtkmm-2.4','gthread-2.0','cairomm-1.0','gdl','xv','xext','sm'])
|
||||
envGtk.Append(CPPDEFINES='LUMIERA_PLUGIN', LIBS=core)
|
||||
|
||||
objgui = srcSubtree(envGtk,'$SRCDIR/gui')
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#!/usr/bin/python
|
||||
#
|
||||
# render-icons.py - Icon rendering utility script
|
||||
# render_icons.py - Icon rendering utility script
|
||||
#
|
||||
# Copyright (C) Lumiera.org
|
||||
# 2008, Joel Holdsworth <joel@airwebreathe.org.uk>
|
||||
|
|
@ -196,12 +196,13 @@ def checkCommandOption(env, optID, val=None, cmdName=None):
|
|||
|
||||
|
||||
|
||||
def RegisterIcon_Builder(env, renderer):
|
||||
def RegisterIcon_Builder(env):
|
||||
""" Registers Custom Builders for generating and installing Icons.
|
||||
Additionally you need to build the tool (rsvg-convert.c)
|
||||
used to generate png from the svg source using librsvg.
|
||||
"""
|
||||
renderer = __import__(renderer) # load python script for invoking the render
|
||||
|
||||
import render_icon as renderer # load Joel's python script for invoking the rsvg-convert (SVG render)
|
||||
renderer.rsvgPath = env.subst("$BINDIR/rsvg-convert")
|
||||
|
||||
def invokeRenderer(target, source, env):
|
||||
|
|
|
|||
|
|
@ -74,32 +74,19 @@ class LumieraEnvironment(Environment):
|
|||
return False
|
||||
|
||||
self.libInfo[libID] = libInfo = LumieraEnvironment()
|
||||
libInfo["ENV"]["PKG_CONFIG_PATH"] = os.environ.get("PKG_CONFIG_PATH")
|
||||
libInfo.ParseConfig ('pkg-config --cflags --libs '+ libID )
|
||||
if alias:
|
||||
self.libInfo[alias] = libInfo
|
||||
return libInfo
|
||||
|
||||
def Glob (self, pattern):
|
||||
""" temporary workaround; newer versions of SCons provide this as a global function """
|
||||
pattern = self.subst(pattern)
|
||||
return glob.glob(pattern)
|
||||
|
||||
def AddMethod (self, function):
|
||||
""" temporary workaround; newer versions of SCons provide this as a global function """
|
||||
self.__dict__[function.__name__] = function.__get__(self)
|
||||
|
||||
|
||||
#### temporary pre 1.0 SCons compatibility hack ####
|
||||
_ver = map(int, SCons.__version__.split('.')[:2])
|
||||
_old = (_ver[0]<1 and _ver[1]<97)
|
||||
if _old:
|
||||
ConfigBase = SCons.SConf.SConf
|
||||
else:
|
||||
ConfigBase = SCons.SConf.SConfBase
|
||||
del LumieraEnvironment.Glob
|
||||
del LumieraEnvironment.AddMethod
|
||||
# use the official impl present since SCons 0.98
|
||||
# use the new name of the config context base class
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# extending the 'Configure' functionality of SCons,
|
||||
# especially for library dependency checking
|
||||
ConfigBase = SCons.SConf.SConfBase
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
46
admin/vg-run.sh
Normal file
46
admin/vg-run.sh
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# vg-run.sh - convenience wrapper script to run an executable with valgrind
|
||||
# using "typical options"; output goes to a logfile, which is
|
||||
# fed to less afterwards.
|
||||
#
|
||||
# a valgrind suppression file is generated automatically, in
|
||||
# case there is an executable "vgsuppression" located in the same
|
||||
# directory as the target executable
|
||||
#
|
||||
# Ichthyo 8/2007
|
||||
#
|
||||
LOGFILE=,valgrind.log
|
||||
SUPPRESS=vgsuppression
|
||||
VALGRINDFLAGS=${VALGRINDFLAGS:---leak-check=yes --show-reachable=yes --demangle=yes}
|
||||
|
||||
EXECUTABLE=$1
|
||||
if [[ ! -x $EXECUTABLE ]]; then
|
||||
echo -e "ERROR: executable \"$EXECUTABLE\" not found.\n\n"
|
||||
exit -1
|
||||
fi
|
||||
|
||||
|
||||
PATHPREFIX=${EXECUTABLE%/*}
|
||||
SUPPRESS="$PATHPREFIX/$SUPPRESS"
|
||||
|
||||
if [[ -x $SUPPRESS ]]; then
|
||||
if [[ $SUPPRESS -nt $SUPPRESS.supp ]]; then
|
||||
echo 'generating valgrind supression file...'
|
||||
|
||||
valgrind $VALGRINDFLAGS -q --gen-suppressions=all $SUPPRESS 2>&1 \
|
||||
| awk '/^{/ {i = 1;} /^}/ {i = 0; print $0;} {if (i == 1) print $0;}' >$SUPPRESS.supp
|
||||
echo 'done.'
|
||||
fi
|
||||
SUPPRESSIONFLAG="--suppressions=$SUPPRESS.supp"
|
||||
else
|
||||
echo 'no suppression.'
|
||||
fi
|
||||
|
||||
echo "running......$@"
|
||||
|
||||
valgrind $VALGRINDFLAGS --log-file=$LOGFILE.%p $SUPPRESSIONFLAG $@ &
|
||||
PID=$!
|
||||
wait $PID
|
||||
less $LOGFILE.$PID
|
||||
|
||||
|
|
@ -1 +0,0 @@
|
|||
Cinelerra2 sources, added per case when needed
|
||||
|
|
@ -37,11 +37,11 @@ namespace lumiera {
|
|||
{
|
||||
NOBUG_INIT;
|
||||
|
||||
#ifdef DEBUG
|
||||
#if NOBUG_MODE_ALPHA
|
||||
static uint callCount = 0;
|
||||
ASSERT ( 0 == callCount++ );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -129,8 +129,6 @@ main (int argc, char **argv)
|
|||
/* Set the locale so that UTF-8 filenames work */
|
||||
setlocale(LC_ALL, "");
|
||||
|
||||
g_thread_init(NULL);
|
||||
|
||||
g_option_context = g_option_context_new (_("- SVG Converter"));
|
||||
g_option_context_add_main_entries (g_option_context, options_table, NULL);
|
||||
g_option_context_set_help_enabled (g_option_context, TRUE);
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@
|
|||
// 7/08 - combining partial specialisation and subclasses
|
||||
// 10/8 - abusing the STL containers to hold noncopyable values
|
||||
// 6/09 - investigating how to build a mixin template providing an operator bool()
|
||||
// 12/9 - tracking down a strange "warning: type qualifiers ignored on function return type"
|
||||
// 1/10 - can we determine at compile time the presence of a certain function (for duck-typing)?
|
||||
|
||||
|
||||
#include "include/nobugcfg.h"
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
just place any problematic calls where valgrind whines about in main (with comments please)
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
int
|
||||
|
|
|
|||
|
|
@ -90,6 +90,10 @@ if testsuites:
|
|||
pluginpath = os.environ.get('LUMIERA_PLUGIN_PATH')
|
||||
if testsuites:
|
||||
testEnv['ENV']['LUMIERA_PLUGIN_PATH'] = pluginpath
|
||||
|
||||
# specify path to test.conf
|
||||
testEnv['ENV']['TEST_CONF'] = env.File("test.conf").abspath
|
||||
|
||||
|
||||
testDir = env.Dir('#$BINDIR')
|
||||
runTest = env.File("test.sh").abspath
|
||||
|
|
|
|||
1
tests/test.conf
Executable file
1
tests/test.conf
Executable file
|
|
@ -0,0 +1 @@
|
|||
LOGSUPPRESS='^\(\*\*[0-9]*\*\* \)\?[0-9]\{10,\}[:!] \(TRACE\|INFO\|NOTICE\|WARNING\|ERR\|TODO\|PLANNED\|FIXME\|DEPRECATED\|UNIMPLEMENTED\|RESOURCE_ANNOUNCE\|RESOURCE_ENTER\|RESOURCE_STATE\|RESOURCE_LEAVE\):'
|
||||
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
#include <stdio.h>
|
||||
|
||||
NOBUG_DEFINE_FLAG (tests);
|
||||
NOBUG_DEFINE_FLAG (TESTS);
|
||||
LUMIERA_ERROR_DEFINE (TEST, "test error");
|
||||
|
||||
#define TESTS_BEGIN \
|
||||
|
|
@ -36,7 +36,7 @@ int \
|
|||
main (int argc, const char** argv) \
|
||||
{ \
|
||||
NOBUG_INIT; \
|
||||
NOBUG_INIT_FLAG (tests); \
|
||||
NOBUG_INIT_FLAG (TESTS); \
|
||||
\
|
||||
if (argc == 1) \
|
||||
{ \
|
||||
|
|
|
|||
476
tests/test.sh
476
tests/test.sh
|
|
@ -1,6 +1,6 @@
|
|||
#!/usr/bin/env bash
|
||||
# Copyright (C) Lumiera.org
|
||||
# 2007 - 2008, Christian Thaeter <ct@pipapo.org>
|
||||
# Copyright (C) Lumiera.org
|
||||
# 2007, 2008, 2009, 2010, Christian Thaeter <ct@pipapo.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
|
|
@ -25,35 +25,134 @@
|
|||
# TESTMODE=FIRSTFAIL
|
||||
# stop testing on the first failure
|
||||
|
||||
export LC_ALL=C
|
||||
NOBUG_LOGREGEX='^\(\*\*[0-9]*\*\* \)\?[0-9]\{10,\}: \(TRACE\|INFO\|NOTICE\|WARNING\|ERR\|TODO\|PLANNED\|FIXME\|DEPRECATED\|UNIMPLEMENTED\):'
|
||||
#intro Test.sh
|
||||
#intro =======
|
||||
#intro Christian Thäter
|
||||
#intro
|
||||
#intro A shell script driving software tests.
|
||||
#intro
|
||||
|
||||
#=intro
|
||||
#=tests Writing tests
|
||||
# =run
|
||||
#=config
|
||||
#=configf
|
||||
# =make
|
||||
# =control
|
||||
#=valgrind
|
||||
#=libtool
|
||||
#_
|
||||
#_ Index
|
||||
#_ -----
|
||||
#_
|
||||
#=index
|
||||
#_
|
||||
|
||||
LC_ALL=C
|
||||
|
||||
#config HEAD- Configuration; configuration; configure tests
|
||||
#config
|
||||
#config PARA LOGSUPPRESS; LOGSUPPRESS; suppress certain lines from stderr
|
||||
#config LOGSUPPRESS='^\(\*\*[0-9]*\*\* \)\?[0-9]\{10,\}: \(TRACE\|INFO\|NOTICE\|WARNING\|ERR\):'
|
||||
#config
|
||||
#config Programms sometimes emit additional diagnostics on stderr which is volatile and not necessary for
|
||||
#config validating the output the `LOGSUPRESS` variable can be set to a regex to filter this things out.
|
||||
#config The default as shown above filters some NoBug annotations and non fatal logging out.
|
||||
#config
|
||||
LOGSUPPRESS='^\(\*\*[0-9]*\*\* \)\?[0-9]\{10,\}[:!] \(TRACE\|INFO\|NOTICE\|WARNING\|ERR\):'
|
||||
|
||||
#config PARA Resource Limits; ulimit; constrain resource limits
|
||||
#config It is possible to set some limits for tests to protect the system against really broken cases.
|
||||
#config Since running under valgrind takes consinderable more resources there are separate variants for
|
||||
#config limits when running under valgrind.
|
||||
#config
|
||||
#config LIMIT_CPU=5
|
||||
#config Maximal CPU time the test may take after it will be killed with SIGXCPU. This protects agaist Lifelocks.
|
||||
#config
|
||||
#config LIMIT_TIME=10
|
||||
#config Maximal wall-time a test may take after this it will be killed with SIGKILL. Protects against Deadlocks.
|
||||
#config
|
||||
#config LIMIT_VSZ=524288
|
||||
#config Maximal virtual memory size the process may map, allocations/mappings will fail when this limit is reached.
|
||||
#config Protects against memory leaks.
|
||||
#config
|
||||
#config LIMIT_VG_CPU=20
|
||||
#config LIMIT_VG_TIME=30
|
||||
#config LIMIT_VG_VSZ=524288
|
||||
#config Same variables again with limits when running under valgrind.
|
||||
#config
|
||||
LIMIT_CPU=5
|
||||
LIMIT_TIME=10
|
||||
LIMIT_VSZ=524288
|
||||
LIMIT_VG_CPU=20
|
||||
LIMIT_VG_TIME=30
|
||||
LIMIT_VG_VSZ=524288
|
||||
|
||||
|
||||
#configf HEAD~ Configuration Files; configuration files; define variables to configure the test
|
||||
#configf
|
||||
#configf `test.sh` reads config files from the following location if they are exist
|
||||
#configf * 'test.conf' from the current directory
|
||||
#configf * '$srcdir/test.conf' `$srcdir` is set by autotools
|
||||
#configf * '$srcdir/tests/test.conf' `tests/` is suspected as default directory for tests
|
||||
#configf * '$TEST_CONF' a user defineable variable to point to a config file
|
||||
#configf
|
||||
test -f 'test.conf' && source test.conf
|
||||
test -n "$srcdir" -a -e "$srcdir/test.conf" && source "$srcdir/test.conf"
|
||||
test -n "$srcdir" -a -e "$srcdir/tests/test.conf" && source "$srcdir/tests/test.conf"
|
||||
test -n "$TEST_CONF" -a -e "$TEST_CONF" && source "$TEST_CONF"
|
||||
|
||||
|
||||
|
||||
arg0="$0"
|
||||
srcdir="$(dirname "$arg0")"
|
||||
vgsuppression_mangle='/^\(\(==\)\|\(\*\*\)[0-9]*\(==\)\|\(\*\*\)\)\|\(\(\*\*[0-9]*\*\* \)\?[0-9]\{10,\}: ECHO:\)/d;'
|
||||
TESTDIR="$(dirname "$arg0")"
|
||||
|
||||
ulimit -S -t 5 -v 524288
|
||||
|
||||
#libtool HEAD Libtool; libtool; support for libtool
|
||||
#libtool When test.sh detects the presence of './libtool' it runs all tests with
|
||||
#libtool `./libtool --mode=execute`.
|
||||
#libtool
|
||||
LIBTOOL_EX=
|
||||
if test -x ./libtool; then
|
||||
LIBTOOL_EX="./libtool --mode=execute"
|
||||
fi
|
||||
|
||||
#valgrind HEAD- Valgrind; valgrind; valgrind support
|
||||
#valgrind Test are run under valgrind supervision by default, if not disabled.
|
||||
#valgrind
|
||||
#valgrind PARA VALGRINDFLAGS; VALGRINDFLAGS; control valgrind options
|
||||
#valgrind VALGRINDFLAGS="--leak-check=yes --show-reachable=yes"
|
||||
#valgrind
|
||||
#valgrind `VALGRINDFLAGS` define the options which are passed to valgrind. This can be used to override
|
||||
#valgrind the defaults or switching the valgrind tool. The special case `VALGRINDFLAGS=DISABLE` will disable
|
||||
#valgrind valgrind for the tests.
|
||||
#valgrind
|
||||
#valgrind HEAD~ Generating Valgrind Suppression Files; vgsuppression; ignore false positives
|
||||
#valgrind When there is a 'vgsuppression' executable in the current dir (build by something external) then
|
||||
#valgrind test.sh uses this to generate a local 'vgsuppression.supp' file and uses that to suppress
|
||||
#valgrind all errors generated by 'vgsuppression'. The Idea here is that one adds code which triggers known
|
||||
#valgrind false positives in 'vgsuppression'. Care must be taken that this file is simple and does
|
||||
#valgrind not generate true positives.
|
||||
#valgrind
|
||||
ulimit -S -t ${LIMIT_CPU:-5} -v ${LIMIT_VSZ:-524288}
|
||||
valgrind=""
|
||||
LIMIT_TIME_REAL="$LIMIT_TIME"
|
||||
if [ "$VALGRINDFLAGS" = 'DISABLE' ]; then
|
||||
echo "valgrind explicit disabled"
|
||||
else
|
||||
if [ "$(which valgrind)" ]; then
|
||||
ulimit -S -t 20
|
||||
ulimit -S -t ${ULIMIT_VG_CPU:-20} -v ${ULIMIT_VG_VSZ:-524288}
|
||||
LIMIT_TIME_REAL="$LIMIT_VG_TIME"
|
||||
if [[ -x 'vgsuppression' ]]; then
|
||||
if [[ 'vgsuppression' -nt 'vgsuppression.supp' ]]; then
|
||||
echo 'generating valgrind supression file'
|
||||
|
||||
if [[ -x ".libs/vgsuppression" ]]; then
|
||||
./libtool --mode=execute valgrind --leak-check=yes --show-reachable=yes -q --gen-suppressions=all vgsuppression 2>&1 \
|
||||
| sed -e "$vgsuppression_mangle" >vgsuppression.supp
|
||||
else
|
||||
valgrind --leak-check=yes --show-reachable=yes -q --gen-suppressions=all ./vgsuppression 2>&1 \
|
||||
| sed -e "$vgsuppression_mangle" >vgsuppression.supp
|
||||
fi
|
||||
$LIBTOOL_EX $(which valgrind) ${VALGRINDFLAGS:---leak-check=yes --show-reachable=yes} -q --gen-suppressions=all vgsuppression 2>&1 \
|
||||
| awk '/^{/ {i = 1;} /^}/ {i = 0; print $0;} {if (i == 1) print $0;}' >vgsuppression.supp
|
||||
fi
|
||||
valgrind="$(which valgrind) --leak-check=yes --show-reachable=no --suppressions=vgsuppression.supp -q $VALGRINDFLAGS"
|
||||
valgrind="$(which valgrind) ${VALGRINDFLAGS:---leak-check=yes --show-reachable=no} --suppressions=vgsuppression.supp -q"
|
||||
else
|
||||
valgrind="$(which valgrind) --leak-check=yes --show-reachable=no -q $VALGRINDFLAGS"
|
||||
valgrind="$(which valgrind) ${VALGRINDFLAGS:---leak-check=yes --show-reachable=no -q}"
|
||||
fi
|
||||
else
|
||||
echo "no valgrind found, go without it"
|
||||
|
|
@ -77,40 +176,193 @@ fi
|
|||
|
||||
date >,testlog
|
||||
|
||||
function compare_regex() # rxfile plainfile
|
||||
function compare_template() # template plainfile
|
||||
{
|
||||
local regex
|
||||
local template
|
||||
local line
|
||||
local miss
|
||||
local lineno=1
|
||||
local regexno=1
|
||||
local templateno=1
|
||||
{
|
||||
IFS='' read -u 3 -r regex || return 0
|
||||
IFS='' read -u 3 -r template || return 0
|
||||
IFS='' read -u 4 -r line || { echo "no output"; return 1; }
|
||||
while true; do
|
||||
if [[ $line =~ $regex ]]; then
|
||||
IFS='' read -u 4 -r line ||
|
||||
if IFS='' read -u 3 -r regex; then
|
||||
echo "premature end in output, expecting: '$regex':$regexno"
|
||||
return 1
|
||||
local cmd="${template%%:*}:"
|
||||
local arg="${template#*: }"
|
||||
|
||||
case $cmd in
|
||||
'regex_cont:')
|
||||
if [[ $line =~ $arg ]]; then
|
||||
IFS='' read -u 4 -r line ||
|
||||
if IFS='' read -u 3 -r template; then
|
||||
echo "premature end in output, expecting $template:$templateno"
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
: $((++lineno))
|
||||
miss=0
|
||||
else
|
||||
return 0
|
||||
if [[ $((++miss)) -gt 1 ]]; then
|
||||
echo -e "'$line':$lineno\ndoes not match\n$template:$templateno"
|
||||
return 1
|
||||
fi
|
||||
IFS='' read -u 3 -r template || { echo "more output than expected: '$line':$lineno"; return 1; }
|
||||
: $((++templateno))
|
||||
fi
|
||||
: $((++lineno))
|
||||
miss=0
|
||||
else
|
||||
if [[ $((++miss)) -gt 1 ]]; then
|
||||
echo -e "'$line':$lineno\ndoes not match\n'$regex':$regexno"
|
||||
;;
|
||||
'literal:')
|
||||
if [[ "$line" = "$arg" ]]; then
|
||||
IFS='' read -u 3 -r template && IFS='' read -u 4 -r line || {
|
||||
return 0
|
||||
}
|
||||
else
|
||||
echo -e "'$line':$lineno\ndoes not match\n$template:$templateno"
|
||||
return 1
|
||||
fi
|
||||
IFS='' read -u 3 -r regex || { echo "more output than expected: '$line':$lineno"; return 1; }
|
||||
: $((++regexno))
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo "UNKOWN MATCH COMMAND '$cmd'" 1>&2
|
||||
exit
|
||||
;;
|
||||
esac
|
||||
done
|
||||
} 3<"$1" 4<"$2"
|
||||
}
|
||||
|
||||
#tests HEAD- Writing Tests; tests; how to write testsuites
|
||||
#tests Tests are nothing more than bash scripts with some functions from the test.sh
|
||||
#tests framework defined. Test.sh looks in the current directory for all files which ending in .test
|
||||
#tests and runs them in alphabetical order. The selection of this tests can be constrained with the
|
||||
#tests `TESTSUITES` environment variable.
|
||||
#tests
|
||||
#tests HEAD~ Testsuites; test files; writing tests
|
||||
#tests It is common to start the name of the '.test' files with a 2 digi number to give them a proper
|
||||
#tests order: '10foo.test', '20bar.test' and so on. Each such test should only test a certain aspect of
|
||||
#tests the system. You have to select the testing binary with the `TESTING` function and then write
|
||||
#tests certain TEST's defining how the test should react. Since tests are shell scripts it is possible
|
||||
#tests to add some supplemental commands there to set and clean up the given test environment.
|
||||
#tests
|
||||
#tests HEAD^ TESTING; TESTING; set the test binary
|
||||
#tests TESTING "message" test_program
|
||||
#tests
|
||||
#tests Selects the test binary for the follwing tests, prints an informal message.
|
||||
#tests
|
||||
#tests `message`::
|
||||
#tests message to be printed
|
||||
#tests `test_program`::
|
||||
#tests an existing program to drive the tests or a shell function
|
||||
#tests
|
||||
#tests ----
|
||||
#tests TESTING "Testing a.out" ./a.out
|
||||
#tests ----
|
||||
#tests
|
||||
function TESTING()
|
||||
{
|
||||
echo
|
||||
echo "$1"
|
||||
echo -e "\n#### $1, $TESTFILE, $2" >>,testlog
|
||||
|
||||
TESTBIN="$2"
|
||||
}
|
||||
|
||||
#tests HEAD^ TEST; TEST; single test
|
||||
#tests TEST "title" arguments.. <<END
|
||||
#tests
|
||||
#tests Runs a single test
|
||||
#tests
|
||||
#tests `title`::
|
||||
#tests describes this test and is also used as identifier for this test,
|
||||
#tests must be unique for all your tests
|
||||
#tests `arguments`::
|
||||
#tests the following arguments are passed to the test program
|
||||
#tests `<<END .. END`::
|
||||
#tests a list of control commands expected in and outputs is given as 'heredoc'.
|
||||
#tests
|
||||
#tests Each line of the test specification in the heredoc starts with an arbitary number of spaces
|
||||
#tests followed by a command, followed by a colon and a space, followed by additional arguments or
|
||||
#tests being an empty or comment line.
|
||||
#tests
|
||||
#tests
|
||||
#tests HEAD+ Test Commands; commands; define expected in and outputs
|
||||
#tests
|
||||
#tests PARA in; in; stdin data for a test
|
||||
#tests in: text
|
||||
#tests
|
||||
#tests Send `text` to stdin of the test binary. If no `in:` commands are given, nothing is send to the
|
||||
#tests tests input.
|
||||
#tests
|
||||
#tests PARA out; out; expected stdout (regex) from a test
|
||||
#tests out: regex
|
||||
#tests
|
||||
#tests Expect `regex` on stdout. This regexes have a 'triggering' semantic. That means it is tried to match
|
||||
#tests a given regex on as much lines as possible (`.*` will match any remaining output), if the match fails,
|
||||
#tests the next expected output line is tried. When that fails too the test is aborted and counted as failure.
|
||||
#tests
|
||||
#tests When no `out:` or `out-lit:` commands are given, then stdout is not checked, any output is ignored.
|
||||
#tests
|
||||
#tests PARA err; err; expected stderr (regex) from a test
|
||||
#tests out: regex
|
||||
#tests
|
||||
#tests Same as 'out:' but expects data on stderr. When no `err:` or `err-lit:` commands are given, then stdout is
|
||||
#tests not checked, any output there is ignored.
|
||||
#tests
|
||||
#tests PARA out-lit; out-lit; expected stdout (literal) from a test
|
||||
#tests out-lit: text
|
||||
#tests
|
||||
#tests Expect `text` on stdout, must match exactly or will fail.
|
||||
#tests
|
||||
#tests PARA err-lit; err-lit; expected stderr (literal) from a test
|
||||
#tests err-lit: text
|
||||
#tests
|
||||
#tests Same as 'out-lit:' but expects data on stderr.
|
||||
#tests
|
||||
#tests PARA return; return; expected exit value of a test
|
||||
#tests return: value
|
||||
#tests
|
||||
#tests Expects `value` as exit code of the tested program. The check can be negated by prepending the value with
|
||||
#tests an exclamation mark, `return: !0` expects any exist code except zero.
|
||||
#tests
|
||||
#tests If no `return:` command is given then a zero (success) return from the test program is expected.
|
||||
#tests
|
||||
#tests HEAD+ Conditional Tests; conditional tests; switch tests on conditions
|
||||
#tests Sometimes tests need to be adapted to the environment/platform they are running on. This can be archived
|
||||
#tests with common if-else-elseif-endif statements. This statements can be nested.
|
||||
#tests
|
||||
#tests PARA if; if; conditional test
|
||||
#tests if: check
|
||||
#tests
|
||||
#tests Executes `check` as shell command, if its return is zero (success) then the following test parts are used.
|
||||
#tests
|
||||
#tests PARA else; else; conditional alternative
|
||||
#tests else:
|
||||
#tests
|
||||
#tests If the previous `if` failed then the following test parts are included in the test, otherwise they
|
||||
#tests are excluded.
|
||||
#tests
|
||||
#tests PARA elseif; elseif; conditional alternative with test
|
||||
#tests elseif: check
|
||||
#tests
|
||||
#tests Composition of else and if, only includes the following test parts if the if's and elseif's before failed
|
||||
#tests and `check` succeeded.
|
||||
#tests
|
||||
#tests PARA endif; endif; end of conditonal test part
|
||||
#tests endif:
|
||||
#tests
|
||||
#tests Ends an `if` statement.
|
||||
#tests
|
||||
#tests HEAD+ Other Elements;;
|
||||
#tests
|
||||
#tests PARA msg; msg; print a diagnostic message
|
||||
#tests msg: message..
|
||||
#tests
|
||||
#tests Prints `message` while processing the test suite.
|
||||
#tests
|
||||
#tests PARA comments; comments; adding comments to tests
|
||||
#tests # anything
|
||||
#tests
|
||||
#tests Lines starting with the hash mark and empty lines count as comment and are not used.
|
||||
#tests
|
||||
function TEST()
|
||||
{
|
||||
name="$1"
|
||||
|
|
@ -120,33 +372,82 @@ function TEST()
|
|||
rm -f ,expect_stderr
|
||||
expect_return=0
|
||||
|
||||
local valgrind="$valgrind"
|
||||
if [ "$VALGRINDFLAGS" = 'DISABLE' ]; then
|
||||
valgrind=
|
||||
fi
|
||||
|
||||
local condstack="1"
|
||||
while read -r line; do
|
||||
cmd="${line%%:*}"
|
||||
arg="${line#*:}"
|
||||
arg="${arg:1}"
|
||||
local cmd="${line%%:*}:"
|
||||
local arg="${line#*: }"
|
||||
|
||||
if [[ ! "$arg" ]]; then
|
||||
arg='^$'
|
||||
fi
|
||||
|
||||
case $cmd in
|
||||
'in')
|
||||
echo "$arg" >>,send_stdin
|
||||
'if:')
|
||||
if $arg; then
|
||||
condstack="1$condstack"
|
||||
else
|
||||
condstack="0$condstack"
|
||||
fi
|
||||
;;
|
||||
'out')
|
||||
echo "$arg" >>,expect_stdout
|
||||
'elseif:')
|
||||
if [[ "${condstack:0:1}" = "0" ]]; then
|
||||
if $arg; then
|
||||
condstack="1${condstack:1}"
|
||||
else
|
||||
condstack="0${condstack:1}"
|
||||
fi
|
||||
else
|
||||
condstack="2${condstack:1}"
|
||||
fi
|
||||
;;
|
||||
'err')
|
||||
echo "$arg" >>,expect_stderr
|
||||
'else:')
|
||||
if [[ "${condstack:0:1}" != "0" ]]; then
|
||||
condstack="0${condstack:1}"
|
||||
else
|
||||
condstack="1${condstack:1}"
|
||||
fi
|
||||
;;
|
||||
'return')
|
||||
expect_return="$arg"
|
||||
;;
|
||||
'#'*|'')
|
||||
:
|
||||
'endif:')
|
||||
condstack="${condstack:1}"
|
||||
;;
|
||||
*)
|
||||
echo "UNKOWN TEST COMMAND '$cmd'" 1>&2
|
||||
exit
|
||||
if [[ "${condstack:0:1}" = "1" ]]; then
|
||||
case $cmd in
|
||||
'msg:')
|
||||
echo "MSG $arg"
|
||||
;;
|
||||
'in:')
|
||||
echo "$arg" >>,send_stdin
|
||||
;;
|
||||
'out:')
|
||||
echo "regex_cont: $arg" >>,expect_stdout
|
||||
;;
|
||||
'err:')
|
||||
echo "regex_cont: $arg" >>,expect_stderr
|
||||
;;
|
||||
'out-lit:')
|
||||
echo "literal: $arg" >>,expect_stdout
|
||||
;;
|
||||
'err-lit:')
|
||||
echo "literal: $arg" >>,expect_stderr
|
||||
;;
|
||||
'return:')
|
||||
expect_return="$arg"
|
||||
;;
|
||||
'#'*|':')
|
||||
:
|
||||
;;
|
||||
*)
|
||||
echo "UNKOWN TEST COMMAND '$cmd'" 1>&2
|
||||
exit
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
|
@ -185,7 +486,7 @@ function TEST()
|
|||
if declare -F | grep $TESTBIN >&/dev/null; then
|
||||
CALL=
|
||||
elif test -x $TESTBIN; then
|
||||
CALL="env $TESTBIN_PREFIX"
|
||||
CALL="env $LIBTOOL_EX $valgrind"
|
||||
else
|
||||
CALL='-'
|
||||
echo -n >,stdout
|
||||
|
|
@ -194,17 +495,31 @@ function TEST()
|
|||
fi
|
||||
|
||||
if test "$CALL" != '-'; then
|
||||
|
||||
if test -f ,send_stdin; then
|
||||
$CALL $TESTBIN "$@" <,send_stdin 2>,stderr >,stdout
|
||||
(
|
||||
$CALL $TESTBIN "$@" <,send_stdin 2>,stderr >,stdout
|
||||
echo $? >,return
|
||||
) &
|
||||
else
|
||||
$CALL $TESTBIN "$@" 2>,stderr >,stdout
|
||||
(
|
||||
$CALL $TESTBIN "$@" 2>,stderr >,stdout
|
||||
echo $? >,return
|
||||
) &
|
||||
fi &>/dev/null
|
||||
return=$?
|
||||
pid=$!
|
||||
|
||||
# watchdog
|
||||
( sleep $LIMIT_TIME_REAL && kill -KILL $pid ) &>/dev/null &
|
||||
wpid=$!
|
||||
wait $pid
|
||||
return=$(<,return)
|
||||
if [[ "$return" -le 128 ]]; then
|
||||
kill -INT $wpid >&/dev/null
|
||||
fi
|
||||
|
||||
if test -f ,expect_stdout; then
|
||||
grep -v "$NOBUG_LOGREGEX" <,stdout >,tmp
|
||||
if ! compare_regex ,expect_stdout ,tmp >>,cmptmp; then
|
||||
grep -v "$LOGSUPPRESS" <,stdout >,tmp
|
||||
if ! compare_template ,expect_stdout ,tmp >>,cmptmp; then
|
||||
echo "unexpected data on stdout" >>,testtmp
|
||||
cat ,cmptmp >>,testtmp
|
||||
((fails+=1))
|
||||
|
|
@ -213,9 +528,9 @@ function TEST()
|
|||
fi
|
||||
|
||||
if test -f ,expect_stderr; then
|
||||
grep -v "$NOBUG_LOGREGEX" <,stderr >,tmp
|
||||
grep -v "$LOGSUPPRESS" <,stderr >,tmp
|
||||
cat ,tmp >>,testtmp
|
||||
if ! compare_regex ,expect_stderr ,tmp >>,cmptmp; then
|
||||
if ! compare_template ,expect_stderr ,tmp >>,cmptmp; then
|
||||
echo "unexpected data on stderr" >>,testtmp
|
||||
cat ,cmptmp >>,testtmp
|
||||
((fails+=1))
|
||||
|
|
@ -256,6 +571,23 @@ function TEST()
|
|||
fi
|
||||
}
|
||||
|
||||
#tests HEAD^ PLANNED; PLANNED; deactivated test
|
||||
#tests PLANNED "title" arguments.. <<END
|
||||
#tests
|
||||
#tests Skip a single test.
|
||||
#tests
|
||||
#tests `title`::
|
||||
#tests describes this test and is also used as identifier for this test,
|
||||
#tests must be unique for all your tests
|
||||
#tests `arguments`::
|
||||
#tests the following arguments are passed to the test program
|
||||
#tests `<<END .. END`::
|
||||
#tests a list of control commands expected in and outputs is given as 'heredoc'.
|
||||
#tests
|
||||
#tests `PLANNED` acts as dropin replacement for `TEST`. Each such test is skipped (and counted as skipped)
|
||||
#tests This can be used to specify tests in advance and activate them as soon development goes on or
|
||||
#tests deactivate intentional broken tests to be fixed later.
|
||||
#tests
|
||||
function PLANNED()
|
||||
{
|
||||
echo -n "PLANNED $1: "
|
||||
|
|
@ -271,14 +603,14 @@ function RUNTESTS()
|
|||
if test \( ! "${TESTSUITES/*,*/}" \) -a "$TESTSUITES"; then
|
||||
TESTSUITES="{$TESTSUITES}"
|
||||
fi
|
||||
for t in $(eval echo "$srcdir/*$TESTSUITES*.tests"); do
|
||||
for t in $(eval echo "$TESTDIR/*$TESTSUITES*.tests"); do
|
||||
echo "$t"
|
||||
done | sort | uniq | {
|
||||
while read i; do
|
||||
while read TESTFILE; do
|
||||
echo
|
||||
echo "### $i" >&2
|
||||
if test -f $i; then
|
||||
source $i
|
||||
echo "### $TESTFILE" >&2
|
||||
if test -f $TESTFILE; then
|
||||
source $TESTFILE
|
||||
fi
|
||||
done
|
||||
echo
|
||||
|
|
@ -295,20 +627,6 @@ function RUNTESTS()
|
|||
}
|
||||
}
|
||||
|
||||
function TESTING()
|
||||
{
|
||||
echo
|
||||
echo "$1"
|
||||
echo -e "\n#### $1" >>,testlog
|
||||
|
||||
if [[ -x ".libs/$2" ]]; then
|
||||
TESTBIN_PREFIX="./libtool --mode=execute $valgrind"
|
||||
else
|
||||
TESTBIN_PREFIX="$valgrind"
|
||||
fi
|
||||
TESTBIN="$2"
|
||||
}
|
||||
|
||||
TESTSUITES="${TESTSUITES}${1:+${TESTSUITES:+,}$1}"
|
||||
|
||||
RUNTESTS
|
||||
|
|
|
|||
Loading…
Reference in a new issue