Preliminary version of the C unit tests run-time environment.
Added make rules for building and running C unit tests.
This commit is contained in:
parent
5d5f36f7ce
commit
caa03388bc
|
@ -59,10 +59,6 @@ LINT = @LINT@
|
|||
LINTFLAGS = @LINTFLAGS@
|
||||
ALLLINTFLAGS = $(LINTFLAGS) $(DEFS) $(OPTIONS) $(DIVINCL)
|
||||
WINAPI_CHECK = $(TOPSRCDIR)/tools/winapi_check/winapi_check
|
||||
WINETEST = $(TOPOBJDIR)/programs/winetest/winetest
|
||||
RUNTEST = $(TOPSRCDIR)/programs/winetest/runtest
|
||||
RUNTESTFLAGS = -q -P wine -M $(MODULE) -T $(TOPOBJDIR)
|
||||
TESTRESULTS = $(PLTESTS:.pl=.ok) $(CTESTS:.c=.ok)
|
||||
WINEBUILD = $(TOPOBJDIR)/tools/winebuild/winebuild
|
||||
MAKEDEP = $(TOPOBJDIR)/tools/makedep
|
||||
WRC = $(TOPOBJDIR)/tools/wrc/wrc
|
||||
|
@ -74,6 +70,15 @@ LIBTSX11 = -L$(TOPOBJDIR)/tsx11 -lwine_tsx11
|
|||
LIBUNICODE= -L$(TOPOBJDIR)/unicode -lwine_unicode
|
||||
LIBUUID = -L$(TOPOBJDIR)/ole -lwine_uuid
|
||||
|
||||
WINETEST = $(TOPOBJDIR)/programs/winetest/winetest
|
||||
RUNTEST = $(TOPSRCDIR)/programs/winetest/runtest
|
||||
RUNTESTFLAGS = -q -P wine -M $(MODULE) -T $(TOPOBJDIR)
|
||||
TESTRESULTS = $(PLTESTS:.pl=.ok) $(CTESTS:.c=.ok)
|
||||
TESTPROGRAM = tests/$(MODULE)_test
|
||||
TESTLIST = tests/testlist.c
|
||||
TESTOBJS = $(TESTMAIN) $(TESTLIST:.c=.o) $(CTESTS:.c=.o)
|
||||
TESTMAIN = $(TOPOBJDIR)/programs/winetest/wtmain.o
|
||||
|
||||
@SET_MAKE@
|
||||
|
||||
# Installation infos
|
||||
|
@ -130,6 +135,9 @@ LINTS = $(C_SRCS:.c=.ln)
|
|||
.c.ln:
|
||||
$(LINT) -c $(ALLLINTFLAGS) $< || ( $(RM) $@ && exit 1 )
|
||||
|
||||
.c.ok:
|
||||
$(RUNTEST) $(RUNTESTFLAGS) -p $(TESTPROGRAM) $< && touch $@
|
||||
|
||||
.pl.ok:
|
||||
$(RUNTEST) $(RUNTESTFLAGS) $< && touch $@
|
||||
|
||||
|
@ -217,7 +225,7 @@ $(SUBDIRS:%=%/__depend__): $(MAKEDEP) dummy
|
|||
cd `dirname $@` && $(MAKE) depend
|
||||
|
||||
depend: $(MAKEDEP) $(GEN_C_SRCS) $(SUBDIRS:%=%/__depend__)
|
||||
$(MAKEDEP) $(DIVINCL) -C$(SRCDIR) $(C_SRCS) $(RC_SRCS) $(RC_SRCS16) $(MC_SRCS) $(EXTRA_SRCS) -C. $(GEN_C_SRCS)
|
||||
$(MAKEDEP) $(DIVINCL) -C$(SRCDIR) $(C_SRCS) $(RC_SRCS) $(RC_SRCS16) $(MC_SRCS) $(EXTRA_SRCS) $(CTESTS) -C. $(GEN_C_SRCS)
|
||||
|
||||
# Rules for cleaning
|
||||
|
||||
|
@ -248,11 +256,28 @@ $(SUBDIRS:%=%/__uninstall__): dummy
|
|||
|
||||
test:: $(TESTRESULTS)
|
||||
|
||||
$(TESTRESULTS): $(WINETEST)
|
||||
$(PLTESTS:.c=.ok): $(WINETEST)
|
||||
$(CTESTS:.c=.ok): $(TESTPROGRAM).so
|
||||
|
||||
$(WINETEST):
|
||||
cd $(TOPOBJDIR)/programs/winetest && $(MAKE) winetest
|
||||
|
||||
$(TESTMAIN):
|
||||
cd $(TOPOBJDIR)/programs/winetest && $(MAKE) wtmain.o
|
||||
|
||||
$(TESTLIST): Makefile.in
|
||||
$(TOPSRCDIR)/programs/winetest/make_ctests $(CTESTS) >$(TESTLIST) || $(RM) $(TESTLIST)
|
||||
|
||||
$(TESTPROGRAM).so: $(TESTPROGRAM).spec.o $(TESTOBJS)
|
||||
$(LDSHARED) $(LDDLLFLAGS) $(TESTPROGRAM).spec.o $(TESTOBJS) -o $@ $(LIBWINE) $(LIBS)
|
||||
|
||||
$(TESTPROGRAM).tmp.o: $(TESTOBJS)
|
||||
$(LDCOMBINE) $(TESTOBJS) -o $@
|
||||
-strip --strip-unneeded $@
|
||||
|
||||
$(TESTPROGRAM).spec.c: $(TESTPROGRAM).spec $(TESTPROGRAM).tmp.o $(WINEBUILD)
|
||||
$(LDPATH) $(WINEBUILD) @DLLFLAGS@ -L$(DLLDIR) -sym $(TESTPROGRAM).tmp.o -o $@ -spec $(SRCDIR)/$(TESTPROGRAM).spec
|
||||
|
||||
# Misc. rules
|
||||
|
||||
$(SPEC_SRCS:.spec=.spec.c): $(WINEBUILD)
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
|
||||
DEFS = @DLLFLAGS@ -D__WINE__ $(EXTRADEFS)
|
||||
LIBEXT = @LIBEXT@
|
||||
SONAME = lib$(MODULE).so
|
||||
IMPORTLIBS = $(IMPORTS:%=$(DLLDIR)/lib%.$(LIBEXT))
|
||||
SPEC_SRCS = $(ALTNAMES:%=%.spec)
|
||||
ALL_OBJS = $(MODULE).spec.o $(OBJS)
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Definitions for Wine C unit tests.
|
||||
*
|
||||
* Copyright (C) 2002 Alexandre Julliard
|
||||
*/
|
||||
|
||||
#ifndef __WINE_TEST_H
|
||||
#define __WINE_TEST_H
|
||||
|
||||
/* debug level */
|
||||
extern int winetest_debug;
|
||||
|
||||
/* current platform */
|
||||
extern const char *winetest_platform;
|
||||
|
||||
extern void winetest_ok( int condition, const char *msg, const char *file, int line );
|
||||
|
||||
#define START_TEST(name) void func_##name(void)
|
||||
|
||||
#define ok(test,msg) winetest_ok( (test), (msg), __FILE__, __LINE__ )
|
||||
|
||||
#endif /* __WINE_TEST_H */
|
|
@ -0,0 +1,28 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
|
||||
print "/* Automatically generated file; DO NOT EDIT!! */\n\n";
|
||||
|
||||
my @testlist = @ARGV;
|
||||
foreach (@testlist)
|
||||
{
|
||||
s!.*/([^/]+)\.c$!$1!;
|
||||
printf "extern void func_%s(void);\n", $_;
|
||||
}
|
||||
|
||||
print <<EOF;
|
||||
|
||||
const struct
|
||||
{
|
||||
const char *name;
|
||||
void (*func)(void);
|
||||
} winetest_testlist[] =
|
||||
{
|
||||
EOF
|
||||
|
||||
foreach (@testlist)
|
||||
{
|
||||
printf " { \"%s\", func_%s },\n", $_, $_;
|
||||
}
|
||||
print " { 0, 0 }\n};\n";
|
|
@ -16,6 +16,7 @@ Usage: $0 [options] input_file [perl_args...]
|
|||
Options:
|
||||
-q quiet mode
|
||||
-v verbose mode (can be specified multiple times)
|
||||
-p prog name of the program to run for C tests
|
||||
-I dir prepend dir to Perl include path
|
||||
-P name set the current platform name
|
||||
-M names set the module names to be tested
|
||||
|
@ -31,6 +32,7 @@ $ENV{WINETEST_DEBUG} ||= 1;
|
|||
|
||||
my $topobjdir;
|
||||
my $infile;
|
||||
my $program;
|
||||
my @include_dirs;
|
||||
my @modules;
|
||||
|
||||
|
@ -39,6 +41,7 @@ while ($#ARGV >= 0)
|
|||
{
|
||||
my $arg = shift @ARGV;
|
||||
if ($arg eq "-h") { usage; }
|
||||
if ($arg eq "-p") { $program = shift @ARGV; next; }
|
||||
if ($arg eq "-q") { $ENV{WINETEST_DEBUG} = 0; next; }
|
||||
if ($arg eq "-v") { $ENV{WINETEST_DEBUG}++; next; }
|
||||
if ($arg eq "-P") { $platform = shift @ARGV; next; }
|
||||
|
@ -57,6 +60,12 @@ while ($#ARGV >= 0)
|
|||
# we must have found an input file
|
||||
usage unless defined($infile);
|
||||
|
||||
if ($infile =~ /\.c$/ && !defined($program))
|
||||
{
|
||||
# set program to the .c file base name if not specified otherwise
|
||||
($program = $infile) =~ s/\.c$//;
|
||||
}
|
||||
|
||||
# check/detect topobjdir
|
||||
if (defined($topobjdir))
|
||||
{
|
||||
|
@ -74,20 +83,6 @@ else # try to detect it automatically
|
|||
elsif (-f "../../../server/wineserver") { $topobjdir = "../../.."; }
|
||||
}
|
||||
|
||||
# set environment variables needed for Wine
|
||||
if (defined($topobjdir))
|
||||
{
|
||||
chop($topobjdir = `cd $topobjdir && pwd`);
|
||||
$ENV{LD_LIBRARY_PATH} = $topobjdir . "/dlls:" . $topobjdir . ":" . $ENV{LD_LIBRARY_PATH};
|
||||
$ENV{WINESERVER} ||= $topobjdir . "/server/wineserver";
|
||||
$ENV{WINELOADER} ||= $topobjdir . "/wine";
|
||||
$ENV{WINETEST_PLATFORM} = $platform || "wine";
|
||||
}
|
||||
else
|
||||
{
|
||||
$ENV{WINETEST_PLATFORM} = $platform || "windows";
|
||||
}
|
||||
|
||||
# check for include/ dir in script source directory and append it to search path
|
||||
my $basedir = $0;
|
||||
if ($basedir =~ /\//) { $basedir =~ s!/[^/]+$!!; }
|
||||
|
@ -101,10 +96,25 @@ if (@modules)
|
|||
$ENV{WINEOPTIONS} .= "--dll " . join(',',@modules) . "=b";
|
||||
}
|
||||
|
||||
# and now exec winetest
|
||||
# set environment variables needed for Wine
|
||||
if (defined($topobjdir))
|
||||
{
|
||||
exec $topobjdir . "/programs/winetest/winetest", $infile, @ARGV;
|
||||
chop($topobjdir = `cd $topobjdir && pwd`);
|
||||
$ENV{LD_LIBRARY_PATH} = $topobjdir . "/dlls:" . $topobjdir . ":" . $ENV{LD_LIBRARY_PATH};
|
||||
$ENV{WINESERVER} ||= $topobjdir . "/server/wineserver";
|
||||
$ENV{WINELOADER} ||= $topobjdir . "/wine";
|
||||
$ENV{WINETEST_PLATFORM} = $platform || "wine";
|
||||
$ENV{WINEPRELOAD}=($program || ($topobjdir . "/programs/winetest/winetest")) . ".so";
|
||||
# try to exec the wine loader directly; if it fails continue on to normal exec
|
||||
exec $ENV{WINELOADER}, $infile, @ARGV;
|
||||
}
|
||||
exec "winetest", $infile, @ARGV;
|
||||
print STDERR "Could not exec winetest\n";
|
||||
else
|
||||
{
|
||||
$ENV{WINETEST_PLATFORM} = $platform || "windows";
|
||||
}
|
||||
|
||||
# and now exec the program
|
||||
$program ||= "winetest";
|
||||
exec $program, $infile, @ARGV;
|
||||
print STDERR "Could not exec $program\n";
|
||||
exit 1;
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* Main routine for Wine C unit tests.
|
||||
*
|
||||
* Copyright 2002 Alexandre Julliard
|
||||
* Copyright 2002 Andriy Palamarchuk
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* debug level */
|
||||
int winetest_debug = 1;
|
||||
|
||||
/* current platform */
|
||||
const char *winetest_platform = "windows";
|
||||
|
||||
struct test
|
||||
{
|
||||
const char *name;
|
||||
void (*func)(void);
|
||||
};
|
||||
|
||||
extern const struct test winetest_testlist[];
|
||||
static const struct test *current_test; /* test currently being run */
|
||||
|
||||
static int successes; /* number of successful tests */
|
||||
static int failures; /* number of failures */
|
||||
static int todo_successes; /* number of successful tests inside todo block */
|
||||
static int todo_failures; /* number of failures inside todo block */
|
||||
static int todo_level; /* current todo nesting level */
|
||||
|
||||
/*
|
||||
* Checks condition.
|
||||
* Parameters:
|
||||
* - condition - condition to check;
|
||||
* - msg test description;
|
||||
* - file - test application source code file name of the check
|
||||
* - line - test application source code file line number of the check
|
||||
*/
|
||||
void winetest_ok( int condition, const char *msg, const char *file, int line )
|
||||
{
|
||||
if (todo_level)
|
||||
{
|
||||
if (condition)
|
||||
{
|
||||
fprintf( stderr, "%s:%d: Test succeeded inside todo block", file, line );
|
||||
if (msg && msg[0]) fprintf( stderr, ": %s", msg );
|
||||
fputc( '\n', stderr );
|
||||
todo_failures++;
|
||||
}
|
||||
else todo_successes++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!condition)
|
||||
{
|
||||
fprintf( stderr, "%s:%d: Test failed", file, line );
|
||||
if (msg && msg[0]) fprintf( stderr, ": %s", msg );
|
||||
fputc( '\n', stderr );
|
||||
failures++;
|
||||
}
|
||||
else successes++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Find a test by name */
|
||||
static const struct test *find_test( const char *name )
|
||||
{
|
||||
const struct test *test;
|
||||
const char *p;
|
||||
int len;
|
||||
|
||||
if ((p = strrchr( name, '/' ))) name = p + 1;
|
||||
if ((p = strrchr( name, '\\' ))) name = p + 1;
|
||||
len = strlen(name);
|
||||
if (len > 2 && !strcmp( name + len - 2, ".c" )) len -= 2;
|
||||
|
||||
for (test = winetest_testlist; test->name; test++)
|
||||
{
|
||||
if (!strncmp( test->name, name, len ) && !test->name[len]) break;
|
||||
}
|
||||
return test->name ? test : NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Run a named test, and return exit status */
|
||||
static int run_test( const char *name )
|
||||
{
|
||||
const struct test *test;
|
||||
int status;
|
||||
|
||||
if (!(test = find_test( name )))
|
||||
{
|
||||
fprintf( stderr, "Fatal: test '%s' does not exist.\n", name );
|
||||
exit(1);
|
||||
}
|
||||
successes = failures = todo_successes = todo_failures = 0;
|
||||
todo_level = 0;
|
||||
current_test = test;
|
||||
test->func();
|
||||
|
||||
if (winetest_debug)
|
||||
{
|
||||
fprintf( stderr, "%s: %d tests executed, %d marked as todo, %d %s.\n",
|
||||
name, successes + failures + todo_successes + todo_failures,
|
||||
todo_successes, failures + todo_failures,
|
||||
(failures + todo_failures != 1) ? "failures" : "failure" );
|
||||
}
|
||||
status = (failures + todo_failures < 255) ? failures + todo_failures : 255;
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/* main function */
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
char *p;
|
||||
|
||||
if ((p = getenv( "WINETEST_PLATFORM" ))) winetest_platform = p;
|
||||
if ((p = getenv( "WINETEST_DEBUG" ))) winetest_debug = atoi(p);
|
||||
if (!argv[1])
|
||||
{
|
||||
fprintf( stderr, "Usage: %s test_name\n", argv[0] );
|
||||
exit(1);
|
||||
}
|
||||
exit( run_test(argv[1]) );
|
||||
}
|
Loading…
Reference in New Issue