506 lines
12 KiB
C
506 lines
12 KiB
C
#define DEFAULT_NUMBER_OF_PROCESSES 4
|
|
|
|
static const char *usage =
|
|
"usage: tissat [<option> ... ] [ <pattern> ... ]\n"
|
|
"\n"
|
|
"where '<option>' is one of the following:\n"
|
|
"\n"
|
|
"-h prints this command line option information\n"
|
|
"-v increase verbosity and force sequential testing\n"
|
|
#if defined(LOGGING) && !defined(QUIET)
|
|
"-l increase logging level for solver instances\n"
|
|
"-s non-parallel sequential testing"
|
|
"(implied by '-v' and '-l')\n"
|
|
"-p print progress "
|
|
"(can not be combined with '-v' or '-l')\n"
|
|
#else
|
|
"-p print progress (can not be combined with '-v')\n"
|
|
"-s non-parallel sequential testing (implied by '-v')\n"
|
|
#endif
|
|
"-j[<processes>] number of processes (infinite '-j', default '-j%d')\n"
|
|
"-b thorough big tests and all options\n"
|
|
"\n"
|
|
"The list of patterns is matched to the function names of the tests.\n"
|
|
"If no pattern is given at all then all test cases are executed.\n"
|
|
"\n"
|
|
"Otherwise only those tests are executed for which at least one\n"
|
|
"pattern matches its function name (contains the pattern).\n";
|
|
|
|
#include "build.h"
|
|
|
|
#include "../src/allocate.h"
|
|
#include "../src/application.h"
|
|
#include "../src/check.h"
|
|
#include "../src/clause.h"
|
|
#include "../src/colors.h"
|
|
#include "../src/file.h"
|
|
#include "../src/handle.h"
|
|
#include "../src/internal.h"
|
|
#include "../src/literal.h"
|
|
#include "../src/parse.h"
|
|
#include "../src/print.h"
|
|
#include "../src/resize.h"
|
|
#include "../src/resources.h"
|
|
#include "../src/stack.h"
|
|
#include "../src/utilities.h"
|
|
#include "../src/vector.h"
|
|
|
|
#include <ctype.h>
|
|
#include <stdarg.h>
|
|
#include <sys/stat.h>
|
|
#include <unistd.h>
|
|
|
|
#include "test.h"
|
|
|
|
bool tissat_big;
|
|
bool tissat_found_test_directory;
|
|
bool tissat_sequential;
|
|
bool tissat_progress;
|
|
|
|
int tissat_processes;
|
|
|
|
#ifndef NPROOFS
|
|
|
|
bool tissat_found_drabt;
|
|
bool tissat_found_drat_trim;
|
|
|
|
#endif
|
|
|
|
const char *tissat_root = DIR;
|
|
|
|
#ifdef _POSIX_C_SOURCE
|
|
|
|
bool tissat_found_bzip2;
|
|
bool tissat_found_gzip;
|
|
bool tissat_found_lzma;
|
|
bool tissat_found_xz;
|
|
bool tissat_found_7z;
|
|
|
|
#endif
|
|
|
|
#if defined(LOGGING) && !defined(QUIET)
|
|
static int tissat_logging;
|
|
#endif
|
|
|
|
void
|
|
tissat_init_solver (kissat * solver)
|
|
{
|
|
#if !defined(NOPTIONS) && !defined(QUIET)
|
|
#ifdef LOGGING
|
|
if (tissat_logging)
|
|
solver->options.log = tissat_logging;
|
|
#endif
|
|
if (tissat_verbosity > 1)
|
|
solver->options.verbose = tissat_verbosity - 1;
|
|
#else
|
|
(void) solver;
|
|
#endif
|
|
solver->watching = true;
|
|
}
|
|
|
|
static bool
|
|
find_test_directory (void)
|
|
{
|
|
struct stat buf;
|
|
return !stat ("../test", &buf);
|
|
}
|
|
|
|
static bool
|
|
match (const char *str, const char *pattern)
|
|
{
|
|
for (const char *s = str; *s; s++)
|
|
{
|
|
const char *p = pattern;
|
|
for (const char *q = s; *p && *p == *q; p++, q++)
|
|
;
|
|
if (!*p)
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
static int patterns;
|
|
|
|
static void
|
|
schedule (const char *name, void (*scheduler) (void), int argc, char **argv)
|
|
{
|
|
bool execute = !patterns || argc < 2;
|
|
for (int i = 1; !execute && i < argc; i++)
|
|
execute = match (name, argv[i]);
|
|
if (patterns && !execute)
|
|
return;
|
|
const unsigned before = tissat_scheduled;
|
|
scheduler ();
|
|
const unsigned jobs = tissat_scheduled - before;
|
|
tissat_message ("Scheduled %u jobs through '%s'.", jobs, name);
|
|
}
|
|
|
|
static int
|
|
get_number_of_cores (void)
|
|
{
|
|
int res = -1;
|
|
#ifdef _POSIX_C_SOURCE
|
|
res = sysconf (_SC_NPROCESSORS_ONLN);
|
|
#endif
|
|
return res;
|
|
}
|
|
|
|
static int
|
|
default_number_of_processes (void)
|
|
{
|
|
int res = get_number_of_cores ();
|
|
return res <= 0 ? DEFAULT_NUMBER_OF_PROCESSES : res;
|
|
}
|
|
|
|
int
|
|
main (int argc, char **argv)
|
|
{
|
|
const double start = kissat_wall_clock_time ();
|
|
const char *sequential_option = 0;
|
|
const char *processes_option = 0;
|
|
const char *verbose_option = 0;
|
|
|
|
if (chdir (DIR))
|
|
FATAL ("could not change to build director '%s'", DIR);
|
|
|
|
for (int i = 1; i < argc; i++)
|
|
if (!strcmp (argv[i], "-h"))
|
|
printf (usage, default_number_of_processes ()), exit (0);
|
|
else if (!strcmp (argv[i], "-v"))
|
|
{
|
|
if (tissat_progress)
|
|
tissat_error ("can not combine '-p' and '-v'");
|
|
|
|
if (processes_option)
|
|
tissat_error ("can not combine '%s' and '-v'", processes_option);
|
|
|
|
if (!verbose_option)
|
|
verbose_option = argv[i];
|
|
|
|
tissat_verbosity++;
|
|
}
|
|
else if (!strcmp (argv[i], "-s"))
|
|
{
|
|
if (sequential_option)
|
|
tissat_error ("multiple '-s' options");
|
|
|
|
if (processes_option)
|
|
tissat_error ("can not combine '%s' and '-s'", processes_option);
|
|
|
|
if (!tissat_sequential)
|
|
{
|
|
tissat_sequential = true;
|
|
sequential_option = "-s";
|
|
}
|
|
}
|
|
else if (!strcmp (argv[i], "-p"))
|
|
{
|
|
if (verbose_option)
|
|
tissat_error ("can not combine '%s' and '-p'", verbose_option);
|
|
|
|
tissat_progress = true;
|
|
}
|
|
else if (!strcmp (argv[i], "-j"))
|
|
{
|
|
if (verbose_option)
|
|
tissat_error ("can not combine '%s' and '-j'", verbose_option);
|
|
|
|
if (tissat_sequential)
|
|
tissat_error ("can not combine '-s' and '-j'");
|
|
|
|
if (processes_option)
|
|
{
|
|
if (!strcmp (processes_option, "-j"))
|
|
tissat_error ("multiple '-j' options");
|
|
else
|
|
tissat_error ("multiple '%s' and '-j'", processes_option);
|
|
}
|
|
else
|
|
assert (!tissat_processes);
|
|
|
|
processes_option = argv[i];
|
|
tissat_processes = -1;
|
|
}
|
|
else if (argv[i][0] == '-' && argv[i][1] == 'j' && argv[i][2])
|
|
{
|
|
if (processes_option)
|
|
{
|
|
if (!strcmp (processes_option, argv[i]))
|
|
tissat_error ("multiple '%s' options", argv[i]);
|
|
else
|
|
tissat_error ("multiple '%s' and '%s'",
|
|
processes_option, argv[i]);
|
|
}
|
|
else
|
|
assert (!tissat_processes);
|
|
|
|
int tmp = 0;
|
|
char ch;
|
|
for (const char *p = argv[i] + 2; (ch = *p); p++)
|
|
{
|
|
if (!isdigit (ch))
|
|
tissat_error ("expected digit in '%s' (try '-h')", argv[i]);
|
|
if (INT_MAX / 10 < tmp)
|
|
tissat_error ("number in '%s' way too large (try '-h')",
|
|
argv[i]);
|
|
tmp *= 10;
|
|
int digit = ch - '0';
|
|
if (INT_MAX - digit <= tmp)
|
|
tissat_error ("number in '%s' too large (try '-h')", argv[i]);
|
|
tmp += digit;
|
|
}
|
|
if (!tmp)
|
|
tissat_error ("invalid zero argument in '%s' (try '-h')", argv[i]);
|
|
|
|
if (verbose_option)
|
|
tissat_error ("can not combine '%s' and '%s'",
|
|
verbose_option, argv[i]);
|
|
|
|
if (tissat_sequential)
|
|
tissat_error ("can not combine '-s' and '%s'", argv[i]);
|
|
|
|
processes_option = argv[i];
|
|
tissat_processes = tmp;
|
|
}
|
|
#if defined(LOGGING) && !defined(QUIET)
|
|
else if (!strcmp (argv[i], "-l"))
|
|
{
|
|
if (tissat_progress)
|
|
tissat_error ("can not combine '-p' and '-l");
|
|
if (processes_option)
|
|
tissat_error ("can not combine '%s' and '-v'", processes_option);
|
|
if (!verbose_option)
|
|
verbose_option = argv[i];
|
|
tissat_logging++;
|
|
tissat_verbosity = 4;
|
|
}
|
|
#endif
|
|
else if (!strcmp (argv[i], "-b"))
|
|
tissat_big = true;
|
|
else if (argv[i][0] == '-')
|
|
tissat_error ("invalid option '%s' (try '-h')", argv[i]);
|
|
else
|
|
patterns++;
|
|
|
|
if (tissat_verbosity && !tissat_sequential)
|
|
{
|
|
if (!tissat_sequential)
|
|
{
|
|
tissat_sequential = true;
|
|
sequential_option = "-v";
|
|
}
|
|
}
|
|
|
|
#if defined(LOGGING)
|
|
if (tissat_logging && !tissat_sequential)
|
|
{
|
|
if (!tissat_sequential)
|
|
{
|
|
tissat_sequential = true;
|
|
sequential_option = "-l";
|
|
}
|
|
}
|
|
#endif
|
|
|
|
if (!tissat_sequential && !tissat_processes)
|
|
tissat_processes = default_number_of_processes ();
|
|
|
|
#ifndef QUIET
|
|
kissat_banner ("", "TISSAT Tester for KISSAT");
|
|
tissat_line ();
|
|
tissat_message ("Use '-h' to print usage (i.e., how to use patterns).");
|
|
#else
|
|
tissat_message ("TISSAT Tester for KISSAT");
|
|
#endif
|
|
tissat_message ("Changed to '%s' directory.", DIR);
|
|
|
|
if (tissat_sequential)
|
|
tissat_message ("Forced sequential non-parallel execution "
|
|
"(due to '-s').");
|
|
else if (tissat_processes < 0)
|
|
{
|
|
if (processes_option)
|
|
tissat_message ("Parallel execution "
|
|
"using an arbitrary number of processes "
|
|
"(due to '-j').");
|
|
else
|
|
{
|
|
assert (DEFAULT_NUMBER_OF_PROCESSES < 0);
|
|
tissat_message ("Parallel execution "
|
|
"using an arbitrary number of processes "
|
|
"(by default).");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (processes_option)
|
|
tissat_message ("Parallel execution "
|
|
"using at most %d processes (due to '%s').",
|
|
tissat_processes, processes_option);
|
|
else
|
|
{
|
|
tissat_message ("Parallel execution "
|
|
"using at most %d processes (by default).",
|
|
tissat_processes);
|
|
}
|
|
}
|
|
|
|
if (tissat_progress)
|
|
tissat_message ("Job execution progress reporting " "(due to '-p').");
|
|
else if (verbose_option)
|
|
tissat_message ("Job execution progress reporting disabled "
|
|
"(due to '%s').", verbose_option);
|
|
else
|
|
tissat_message ("Job execution progress reporting disabled "
|
|
"(enable with '-p').");
|
|
|
|
tissat_found_test_directory = find_test_directory ();
|
|
|
|
if (!tissat_found_test_directory)
|
|
{
|
|
tissat_line ();
|
|
tissat_message ("Could not find '../test/' directory.");
|
|
tissat_message ("Skipping test cases that rely on '../test' .");
|
|
}
|
|
else
|
|
{
|
|
tissat_line ();
|
|
tissat_message ("Found '../test' directory "
|
|
"(running test cases that need '../test' too).");
|
|
}
|
|
|
|
#ifndef NPROOFS
|
|
bool found_proof_checker = false;
|
|
#define FIND(EXECUTABLE,FLAG) \
|
|
do { \
|
|
if ((tissat_found_ ## FLAG = kissat_find_executable (#EXECUTABLE))) \
|
|
{ \
|
|
tissat_message ("Found '%s' executable (will check proofs with it).", \
|
|
#EXECUTABLE); \
|
|
found_proof_checker = true; \
|
|
} \
|
|
else \
|
|
tissat_warning ("Did not find '%s' executable.", #EXECUTABLE); \
|
|
} while (0)
|
|
|
|
// *INDENT-OFF*
|
|
|
|
FIND (drabt, drabt);
|
|
FIND (drat-trim, drat_trim);
|
|
|
|
// *INDENT-ON*
|
|
|
|
if (!found_proof_checker)
|
|
{
|
|
tissat_line ();
|
|
tissat_bold_message ("Install either 'drat-trim' or "
|
|
"'drabt' to check proofs too!");
|
|
tissat_line ();
|
|
}
|
|
#undef FIND
|
|
#endif
|
|
|
|
#ifdef _POSIX_C_SOURCE
|
|
bool found_compression_utility;
|
|
#define FIND(EXECUTABLE) \
|
|
do { \
|
|
if ((tissat_found_ ## EXECUTABLE = kissat_find_executable (#EXECUTABLE))) \
|
|
{ \
|
|
tissat_message ("Found '%s' executable for testing compression.", \
|
|
#EXECUTABLE); \
|
|
found_compression_utility = true; \
|
|
} \
|
|
else \
|
|
tissat_warning ("Did not find '%s' executable for testing compression.", \
|
|
#EXECUTABLE); \
|
|
} while (0)
|
|
|
|
// *INDENT-OFF*
|
|
|
|
FIND (bzip2);
|
|
FIND (gzip);
|
|
FIND (lzma);
|
|
FIND (xz);
|
|
FIND (7z);
|
|
|
|
// *INDENT-ON*
|
|
|
|
if (!found_compression_utility)
|
|
tissat_message
|
|
("Not testing compression (no compression utility found).");
|
|
|
|
#else
|
|
tissat_message ("No compression tests for non POSIX configuration.");
|
|
#endif
|
|
|
|
tissat_line ();
|
|
|
|
#define SCHEDULE(NAME) \
|
|
do { \
|
|
void tissat_schedule_ ## NAME (void); \
|
|
schedule ("tissat_schedule_" #NAME, \
|
|
tissat_schedule_ ## NAME, argc, argv); \
|
|
} while (0)
|
|
|
|
SCHEDULE (error);
|
|
SCHEDULE (endianess);
|
|
SCHEDULE (format);
|
|
SCHEDULE (references);
|
|
SCHEDULE (reluctant);
|
|
SCHEDULE (random);
|
|
SCHEDULE (queue);
|
|
SCHEDULE (allocate);
|
|
SCHEDULE (stack);
|
|
SCHEDULE (arena);
|
|
SCHEDULE (heap);
|
|
SCHEDULE (vector);
|
|
SCHEDULE (rank);
|
|
SCHEDULE (sort);
|
|
SCHEDULE (bump);
|
|
SCHEDULE (options);
|
|
SCHEDULE (init);
|
|
SCHEDULE (add);
|
|
SCHEDULE (file);
|
|
SCHEDULE (parse);
|
|
SCHEDULE (usage);
|
|
SCHEDULE (main);
|
|
SCHEDULE (collect);
|
|
SCHEDULE (solve);
|
|
SCHEDULE (coverage);
|
|
SCHEDULE (terminate);
|
|
|
|
#ifndef NPROOFS
|
|
if (tissat_found_drabt || tissat_found_drat_trim)
|
|
SCHEDULE (prove);
|
|
#endif
|
|
|
|
#ifndef NDEBUG
|
|
SCHEDULE (dump);
|
|
#endif
|
|
|
|
if (tissat_scheduled)
|
|
{
|
|
tissat_line ();
|
|
|
|
if (tissat_sequential)
|
|
tissat_run_jobs (0);
|
|
else
|
|
tissat_run_jobs (tissat_processes);
|
|
|
|
if (tissat_verbosity)
|
|
tissat_section ("Finished");
|
|
else
|
|
tissat_line ();
|
|
tissat_message ("All %u test jobs %ssucceeded%s in %.2f seconds.",
|
|
tissat_scheduled,
|
|
kissat_bold_green_color_code (1),
|
|
kissat_normal_color_code (1),
|
|
kissat_wall_clock_time () - start);
|
|
tissat_release_jobs ();
|
|
}
|
|
else
|
|
tissat_warning ("No job scheduled.");
|
|
|
|
return 0;
|
|
}
|