make/tests/scripts/features/loadapi
Paul Smith cad3ddd165 Enhance tests to work on different systems
The GNU platform testers reported a number of test errors on
different systems; try to address them.

* tests/thelp.pl: A number of tests timed out with a 4-second
timeout.  Increase the default timeout to 10 seconds.
* tests/run_make_tests.pl: Executing directories on cygwin behaves
differently in Perl than make so skip these tests there.
* tests/scripts/options/symlinks: Check for the symlink feature
in make, rather than whether the system supports them.
* tests/scripts/features/implicit_search: On some systems "false"
exits with a different exit code.  Use the helper instead.
* tests/scripts/features/loadapi: Ditto.
* tests/scripts/features/output-sync: Sleep before make -f bar in
the first test as well as the second one.
* tests/scripts/features/exec: Skip on cygwin, which seems to
be "UNIX" but where scripts don't run normally.
* tests/scripts/misc/fopen-fail: Skip on cygwin, where make
eventually exits with exit code 0 and no error messages.
2022-10-22 22:37:49 -04:00

229 lines
5.3 KiB
Perl

# -*-perl-*-
$description = "Test the shared object load API.";
$details = "Verify the different aspects of the shared object API.";
# Don't do anything if this system doesn't support "load"
exists $FEATURES{load} or return -1;
my $cc = get_config('CC');
if (! $cc) {
$verbose and print "Skipping load test: no CC defined\n";
return -1;
}
# First build a shared object
# Provide both a default and non-default load symbol
unlink(qw(testapi.c testapi.so));
open(my $F, '> testapi.c') or die "open: testapi.c: $!\n";
print $F <<'EOF' ;
#include <string.h>
#include <stdio.h>
#include "gnumake.h"
char *getenv (const char*);
int plugin_is_GPL_compatible;
int testapi_gmk_setup ();
static char *
test_eval (const char *buf)
{
gmk_eval (buf, 0);
return NULL;
}
static char *
test_expand (const char *val)
{
return gmk_expand (val);
}
static char *
test_noexpand (const char *val)
{
char *str = gmk_alloc (strlen (val) + 1);
strcpy (str, val);
return str;
}
static char *
func_test (const char *funcname, unsigned int argc, char **argv)
{
char *mem;
if (strcmp (funcname, "test-expand") == 0)
return test_expand (argv[0]);
if (strcmp (funcname, "test-eval") == 0)
return test_eval (argv[0]);
if (strcmp (funcname, "test-noexpand") == 0)
return test_noexpand (argv[0]);
mem = gmk_alloc (sizeof ("unknown"));
strcpy (mem, "unknown");
return mem;
}
int
testapi_gmk_setup (const gmk_floc *floc)
{
const char *verbose = getenv ("TESTAPI_VERBOSE");
gmk_add_function ("test-expand", func_test, 1, 1, GMK_FUNC_DEFAULT);
gmk_add_function ("test-noexpand", func_test, 1, 1, GMK_FUNC_NOEXPAND);
gmk_add_function ("test-eval", func_test, 1, 1, GMK_FUNC_DEFAULT);
gmk_add_function ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.", func_test, 0, 0, 0);
if (verbose)
{
printf ("testapi_gmk_setup\n");
if (verbose[0] == '2')
printf ("%s:%lu\n", floc->filenm, floc->lineno);
}
if (getenv ("TESTAPI_KEEP"))
return -1;
return 1;
}
EOF
close($F) or die "close: testapi.c: $!\n";
# Make sure we can compile
my $cflags = get_config('CFLAGS');
my $cppflags = get_config('CPPFLAGS');
my $ldflags = get_config('LDFLAGS');
my $sobuild = "$cc ".($srcdir? "-I$srcdir/src":'')." $cppflags $cflags -shared -fPIC $ldflags -o testapi.so testapi.c";
my $clog = `$sobuild 2>&1`;
if ($? != 0) {
$verbose and print "Failed to build testapi.so:\n$sobuild\n$_";
return -1;
}
# TEST 1
# Check the gmk_expand() function
run_make_test(q!
EXPAND = expansion
all: ; @echo $(test-expand $$(EXPAND))
load testapi.so
!,
'', "expansion\n");
# TEST 2
# Check the eval operation. Prove that the argument is expanded only once
run_make_test(q!
load testapi.so
TEST = bye
ASSIGN = VAR = $(TEST) $(shell echo there)
$(test-eval $(value ASSIGN))
TEST = hi
all:;@echo '$(VAR)'
!,
'', "hi there\n");
# TEST 2
# Check the no-expand capability
run_make_test(q!
load testapi.so
TEST = hi
all:;@echo '$(test-noexpand $(TEST))'
!,
'', "\$(TEST)\n");
# During all subsequent tests testapi.so exists.
#
my @loads = ('', q!
load testapi.so
load testapi.so
-load testapi.so
-load testapi.so
$(eval load testapi.so)
$(eval -load testapi.so)
!);
for my $extra_loads (@loads) {
my $n = 5;
if ($extra_loads) {
$n = 12;
}
# sv 63045.
# Test that having unloaded a shared object make loads it again, even if the
# shared object is not updated.
$ENV{TESTAPI_VERBOSE} = 1;
run_make_test("
load testapi.so
$extra_loads
all:; \$(info \$(test-expand hello))
testapi.so: force; \$(info \$@)
force:;
.PHONY: force
", '', "testapi_gmk_setup\ntestapi.so\ntestapi_gmk_setup\nhello\n#MAKE#: 'all' is up to date.\n");
# sv 63045.
# Same as above, but testapi_gmk_setup returned -1.
$ENV{TESTAPI_KEEP} = 1;
$ENV{TESTAPI_VERBOSE} = 1;
run_make_test("
load testapi.so
$extra_loads
all:; \$(info \$(test-expand hello))
testapi.so: force; \$(info \$@)
force:;
.PHONY: force
", '', "testapi_gmk_setup\nhello\n#MAKE#: 'all' is up to date.\n");
# sv 63045.
# Test that make exits, unless make can successfully update an unloaded shared
# object.
$ENV{TESTAPI_VERBOSE} = 1;
run_make_test("
load testapi.so
$extra_loads
all:; \$(info \$(test-expand hello))
testapi.so: force; @#HELPER# fail 1
force:;
.PHONY: force
", '', "testapi_gmk_setup\nfail 1\n#MAKE#: *** [#MAKEFILE#:$n: testapi.so] Error 1\n", 512);
# sv 63045.
# Same as above, but testapi_gmk_setup returned -1.
$ENV{TESTAPI_KEEP} = 1;
$ENV{TESTAPI_VERBOSE} = 1;
run_make_test("
load testapi.so
$extra_loads
all:; \$(info \$(test-expand hello))
testapi.so: force; @#HELPER# fail 1
force:;
.PHONY: force
", '', "testapi_gmk_setup\nhello\n#MAKE#: 'all' is up to date.\n");
# sv 63100.
# Test that make supplies the correct floc when the shared object is loaded
# again.
$ENV{TESTAPI_VERBOSE} = 2;
run_make_test("
load testapi.so
$extra_loads
all:; \$(info \$(test-expand hello))
testapi.so: force; \$(info \$@)
force:;
.PHONY: force
", '', "testapi_gmk_setup\n#MAKEFILE#:2\ntestapi.so\ntestapi_gmk_setup\n#MAKEFILE#:2\nhello\n#MAKE#: 'all' is up to date.\n");
}
unlink(qw(testapi.c testapi.so)) unless $keep;
# This tells the test driver that the perl test script executed properly.
1;