33b6692003-06-01Martin Nilsson #! /usr/bin/env pike
06983f1996-09-22Fredrik Hübinette (Hubbe) 
29c1f62007-06-07Henrik Grubbström (Grubba) /* $Id: test_pike.pike,v 1.110 2007/06/07 13:51:23 grubba Exp $ */
e9361f1995-11-06Fredrik Hübinette (Hubbe) 
6657a51999-10-21Fredrik Hübinette (Hubbe) #if !constant(_verify_internals)
c7dbb61996-06-09Fredrik Hübinette (Hubbe) #define _verify_internals() #endif
6657a51999-10-21Fredrik Hübinette (Hubbe) #if !constant(_dmalloc_set_name) void _dmalloc_set_name(mixed ... args) {} #endif
73b75f1998-02-24Fredrik Hübinette (Hubbe) int foo(string opt) { if(opt=="" || !opt) return 1; return (int)opt; }
dddccc1998-04-15Fredrik Hübinette (Hubbe) 
fa34962003-06-02Martin Stjernholm int maybe_tty = 1;
619f882000-01-30Fredrik Hübinette (Hubbe) 
dddccc1998-04-15Fredrik Hübinette (Hubbe) mapping(string:int) cond_cache=([]);
bd227a1999-01-21Fredrik Hübinette (Hubbe) #if constant(thread_create) #define HAVE_DEBUG #endif
d125f32003-06-26Martin Nilsson void print_code(string test)
394d7d1999-04-08Fredrik Hübinette (Hubbe) {
1e03b62003-08-14Henrik Grubbström (Grubba)  array lines = Locale.Charset.encoder("iso-8859-1", 0, lambda(string s) {
c904132003-08-14Henrik Grubbström (Grubba)  return sprintf("\\%o", s[0]);
1e03b62003-08-14Henrik Grubbström (Grubba)  })->feed(test)->drain()/"\n";
a696742002-08-06Martin Nilsson  foreach(lines; int r; string line) {
1e03b62003-08-14Henrik Grubbström (Grubba)  werror("%3d: %s\n", r+1, line);
a696742002-08-06Martin Nilsson  } werror("\n"); return;
394d7d1999-04-08Fredrik Hübinette (Hubbe) }
a1aa642004-07-15Henrik Grubbström (Grubba) void report_size() { #if 0 werror("\n"); Process.system(sprintf("/usr/proc/bin/pmap %d|tail -1", getpid())); #endif }
ada13c1999-06-19Fredrik Hübinette (Hubbe) array find_testsuites(string dir) { array(string) ret=({}); if(array(string) s=get_dir(dir||".")) {
f52ca12004-02-29Martin Nilsson  if(has_value(s,"no_testsuites")) return ret;
ada13c1999-06-19Fredrik Hübinette (Hubbe)  foreach(s, string file)
a1aa642004-07-15Henrik Grubbström (Grubba)  { string name=combine_path(dir||"",file); if(Stdio.is_dir(name)) { ret+=find_testsuites(name); continue;
ada13c1999-06-19Fredrik Hübinette (Hubbe)  }
a1aa642004-07-15Henrik Grubbström (Grubba)  switch(file)
1da4a12001-01-01Mirar (Pontus Hagland)  {
a1aa642004-07-15Henrik Grubbström (Grubba)  case "testsuite": case "module_testsuite": ret+=({ combine_path(dir||"",file) });
1da4a12001-01-01Mirar (Pontus Hagland)  }
a1aa642004-07-15Henrik Grubbström (Grubba)  }
ada13c1999-06-19Fredrik Hübinette (Hubbe)  } return ret; }
d5d01e2002-05-02Martin Nilsson array(string) read_tests( string fn ) {
d125f32003-06-26Martin Nilsson  string|array(string) tests = Stdio.read_file( fn );
d5d01e2002-05-02Martin Nilsson  if(!tests) { werror("Failed to read test file %O, errno=%d.\n", fn, errno()); exit(1); }
7c690f2002-07-31Martin Nilsson 
3ad3be2004-05-02Martin Nilsson  if(has_prefix(tests, "START")) { tests = tests[6..]; if(!has_suffix(tests, "END\n")) werror("%s: Missing end marker.\n", fn); else tests = tests[..sizeof(tests)-1-4]; }
d5d01e2002-05-02Martin Nilsson  tests = tests/"\n....\n"; return tests[0..sizeof(tests)-2]; }
2bfdd42006-06-16Henrik Grubbström (Grubba) mapping(string:int) pushed_warnings = ([]);
218e4b2002-05-24Martin Nilsson class WarningFlag { int(0..1) warning;
27d7702004-01-15Martin Nilsson  array(string) warnings = ({});
218e4b2002-05-24Martin Nilsson 
27d7702004-01-15Martin Nilsson  void compile_warning(string file, int line, string text) {
2bfdd42006-06-16Henrik Grubbström (Grubba)  if (pushed_warnings[text]) return;
27d7702004-01-15Martin Nilsson  warnings += ({ line+": "+text });
218e4b2002-05-24Martin Nilsson  warning = 1; }
27d7702004-01-15Martin Nilsson  void compile_error(string file, int line, string text) { werror("%s:%d: %s\n", file,line,text); }
218e4b2002-05-24Martin Nilsson }
d5d01e2002-05-02Martin Nilsson  // // Watchdog stuff //
c749142000-03-28Fredrik Hübinette (Hubbe) // 20 minutes should be enough..
379e452001-06-27Fredrik Hübinette (Hubbe) #if !constant(_reset_dmalloc)
c749142000-03-28Fredrik Hübinette (Hubbe) #define WATCHDOG_TIMEOUT 60*20
379e452001-06-27Fredrik Hübinette (Hubbe) #else // ... unless we're running dmalloc #define WATCHDOG_TIMEOUT 60*80 #endif
c749142000-03-28Fredrik Hübinette (Hubbe) 
8240052000-02-22Fredrik Hübinette (Hubbe) #if constant(thread_create) #define WATCHDOG #define WATCHDOG_PIPE
d3027a2000-03-07Fredrik Hübinette (Hubbe) object watchdog_pipe;
8240052000-02-22Fredrik Hübinette (Hubbe) #else
0d985b2002-10-01Martin Nilsson #if constant(kill)
8240052000-02-22Fredrik Hübinette (Hubbe) #define WATCHDOG #define WATCHDOG_SIGNAL #endif
0d985b2002-10-01Martin Nilsson #endif
8240052000-02-22Fredrik Hübinette (Hubbe) 
d3027a2000-03-07Fredrik Hübinette (Hubbe) #ifdef WATCHDOG
aebd8f2000-03-25Fredrik Hübinette (Hubbe) object watchdog;
d3027a2000-03-07Fredrik Hübinette (Hubbe) int use_watchdog=1;
c749142000-03-28Fredrik Hübinette (Hubbe) int watchdog_time; void signal_watchdog() { #ifdef WATCHDOG if(use_watchdog && time() - watchdog_time > 30) { watchdog_time=time(); #ifdef WATCHDOG_PIPE watchdog_pipe->write("x",1); #endif
7c690f2002-07-31Martin Nilsson 
c749142000-03-28Fredrik Hübinette (Hubbe) #ifdef WATCHDOG_SIGNAL watchdog->kill(signum("SIGQUIT")); #endif } #endif }
d3027a2000-03-07Fredrik Hübinette (Hubbe) #endif
d5d01e2002-05-02Martin Nilsson void run_watchdog(int pid) { #ifdef WATCHDOG int cnt=0; int last_time=time(); int exit_quietly; #ifdef WATCHDOG_PIPE thread_create(lambda() { object o=Stdio.File("stdin");
ead9722003-01-20Martin Nilsson  while(sizeof(o->read(1) || ""))
d5d01e2002-05-02Martin Nilsson  { last_time=time(); } exit_quietly=1; });
0d985b2002-10-01Martin Nilsson #endif // WATCHDOG_PIPE
d5d01e2002-05-02Martin Nilsson  #ifdef WATCHDOG_SIGNAL werror("Setting signal (1)\n"); if(signum("SIGQUIT")>=0) { werror("Setting signal (2)\n"); signal( signum("SIGQUIT"), lambda() { last_time=time(); }); } else { exit(1); }
0d985b2002-10-01Martin Nilsson #endif // WATCHDOG_SIGNAL
d5d01e2002-05-02Martin Nilsson  while(1) { sleep(10); if(exit_quietly) _exit(0); #ifndef __NT__ if(!kill(pid, 0)) _exit(0); #endif /* I hope 30 minutes per test is enough for everybody */ if(time() - last_time > WATCHDOG_TIMEOUT) { werror("\n[WATCHDOG] Pike testsuite timeout, sending SIGABRT.\n"); kill(pid, signum("SIGABRT")); for(int q=0;q<60;q++) if(!kill(pid,0)) _exit(0); else sleep(1); werror("\n" "[WATCHDOG] This is your friendly watchdog again...\n" "[WATCHDOG] testsuite failed to die from SIGABRT, sending SIGKILL\n"); kill(pid, signum("SIGKILL")); for(int q=0;q<60;q++) if(!kill(pid,0)) _exit(0); else sleep(1); werror("\n" "[WATCHDOG] This is your friendly watchdog AGAIN...\n" "[WATCHDOG] SIGKILL, SIGKILL, SIGKILL, DIE!\n"); kill(pid, signum("SIGKILL")); kill(pid, signum("SIGKILL")); kill(pid, signum("SIGKILL")); kill(pid, signum("SIGKILL")); for(int q=0;q<60;q++) if(!kill(pid,0)) _exit(0); else sleep(1); werror("\n" "[WATCHDOG] Giving up, must be a device wait.. :(\n"); _exit(0); } } #else _exit(1);
0d985b2002-10-01Martin Nilsson #endif // else WATCHDOG
d5d01e2002-05-02Martin Nilsson }
218e4b2002-05-24Martin Nilsson // // Main program //
d5d01e2002-05-02Martin Nilsson 
c83fb62000-03-30Henrik Grubbström (Grubba) int main(int argc, array(string) argv)
a9679f1995-11-13David Hedbor {
1c0c612002-11-14Marcus Comstedt  int e, verbose, prompt, successes, errors, t, check, asmdebug;
1fba802002-07-29Martin Nilsson  int skipped;
c83fb62000-03-30Henrik Grubbström (Grubba)  array(string) tests;
f07dba2004-04-23Henrik Grubbström (Grubba)  array(string) forked;
a9679f1995-11-13David Hedbor  program testprogram;
c3c7031996-12-04Fredrik Hübinette (Hubbe)  int start, fail, mem;
f07dba2004-04-23Henrik Grubbström (Grubba)  int loop=1;
0073821998-04-05Fredrik Hübinette (Hubbe)  int end=0x7fffffff;
bd227a1999-01-21Fredrik Hübinette (Hubbe)  string extra_info="";
1869a91999-02-28Fredrik Hübinette (Hubbe)  int shift;
bd227a1999-01-21Fredrik Hübinette (Hubbe) 
5f25b52003-10-13Henrik Grubbström (Grubba) #if constant(System.getrlimit) // Attempt to enable coredumps. // Many Linux distributions default to having coredumps disabled. catch { [ int current, int max ] = System.getrlimit("core"); if ((current != -1) && ((current < max) || (max == -1))) { // Not unlimited, and less than max. // Attempt to raise. System.setrlimit("core", max, max); } }; #endif /* constant(System.getrlimit) */
bd227a1999-01-21Fredrik Hübinette (Hubbe)  if(signum("SIGQUIT")>=0) { signal(signum("SIGQUIT"),lambda() { master()->handle_error( ({"\nSIGQUIT recived, printing backtrace and continuing.\n",backtrace() }) );
9b03192001-11-08Fredrik Hübinette (Hubbe)  mapping x=_memory_usage(); foreach(sort(indices(x)),string p) { if(sscanf(p,"%s_bytes",p)) { werror("%20ss: %8d %8d Kb\n",p, x["num_"+p+"s"], x[p+"_bytes"]/1024); } }
bd227a1999-01-21Fredrik Hübinette (Hubbe)  }); }
a9679f1995-11-13David Hedbor 
c83fb62000-03-30Henrik Grubbström (Grubba)  array(string) args=backtrace()[0][3];
ada13c1999-06-19Fredrik Hübinette (Hubbe)  array(string) testsuites=({});
086bfa1998-04-09Fredrik Hübinette (Hubbe)  args=args[..sizeof(args)-1-argc];
b66f132003-05-17Henrik Grubbström (Grubba)  add_constant("RUNPIKE_ARRAY", args);
0d985b2002-10-01Martin Nilsson  add_constant("RUNPIKE", map(args, Process.sh_quote)*" ");
086bfa1998-04-09Fredrik Hübinette (Hubbe) 
73b75f1998-02-24Fredrik Hübinette (Hubbe)  foreach(Getopt.find_all_options(argv,aggregate(
d3027a2000-03-07Fredrik Hübinette (Hubbe)  ({"no-watchdog",Getopt.NO_ARG,({"--no-watchdog"})}),
8240052000-02-22Fredrik Hübinette (Hubbe)  ({"watchdog",Getopt.HAS_ARG,({"--watchdog"})}),
73b75f1998-02-24Fredrik Hübinette (Hubbe)  ({"help",Getopt.NO_ARG,({"-h","--help"})}),
97c35b2000-03-31Fredrik Hübinette (Hubbe)  ({"verbose",Getopt.MAY_HAVE_ARG,({"-v","--verbose"})}),
50a34a2001-11-14Jonas Wallden  ({"prompt",Getopt.NO_ARG,({"-p","--prompt"})}),
73b75f1998-02-24Fredrik Hübinette (Hubbe)  ({"start",Getopt.HAS_ARG,({"-s","--start-test"})}),
9b03192001-11-08Fredrik Hübinette (Hubbe)  ({"end",Getopt.HAS_ARG,({"-e","--end-after"})}),
d5d01e2002-05-02Martin Nilsson  ({"fail",Getopt.NO_ARG,({"-f","--fail"})}),
e0b3fe2004-04-23Henrik Grubbström (Grubba)  ({"forked",Getopt.NO_ARG,({"-F","--forked"})}),
d5d01e2002-05-02Martin Nilsson  ({"loop",Getopt.HAS_ARG,({"-l","--loop"})}), ({"trace",Getopt.HAS_ARG,({"-t","--trace"})}),
73b75f1998-02-24Fredrik Hübinette (Hubbe)  ({"check",Getopt.MAY_HAVE_ARG,({"-c","--check"})}),
1c0c612002-11-14Marcus Comstedt #if constant(_assembler_debug) ({"asm",Getopt.MAY_HAVE_ARG,({"--assembler-debug"})}), #endif
d5d01e2002-05-02Martin Nilsson  ({"mem",Getopt.NO_ARG,({"-m","--mem","--memory"})}),
d125f32003-06-26Martin Nilsson  ({"auto",Getopt.MAY_HAVE_ARG,({"-a","--auto"})}),
4faea62000-07-26Martin Nilsson  ({"notty",Getopt.NO_ARG,({"-T","--notty"})}),
bd227a1999-01-21Fredrik Hübinette (Hubbe) #ifdef HAVE_DEBUG ({"debug",Getopt.MAY_HAVE_ARG,({"-d","--debug"})}), #endif
218e4b2002-05-24Martin Nilsson  ({"regression",Getopt.NO_ARG,({"-r","--regression"})}),
73b75f1998-02-24Fredrik Hübinette (Hubbe)  )),array opt)
a9679f1995-11-13David Hedbor  {
73b75f1998-02-24Fredrik Hübinette (Hubbe)  switch(opt[0]) {
d3027a2000-03-07Fredrik Hübinette (Hubbe)  case "no-watchdog": use_watchdog=0; break;
8240052000-02-22Fredrik Hübinette (Hubbe)  case "watchdog":
d5d01e2002-05-02Martin Nilsson  run_watchdog( (int)opt[1] );
8240052000-02-22Fredrik Hübinette (Hubbe)  break;
7c690f2002-07-31Martin Nilsson 
619f882000-01-30Fredrik Hübinette (Hubbe)  case "notty":
fa34962003-06-02Martin Stjernholm  maybe_tty = 0;
619f882000-01-30Fredrik Hübinette (Hubbe)  break;
73b75f1998-02-24Fredrik Hübinette (Hubbe)  case "help":
40b5bb2004-08-31Henrik Grubbström (Grubba)  write(doc);
73b75f1998-02-24Fredrik Hübinette (Hubbe)  return 0; case "verbose": verbose+=foo(opt[1]); break;
50a34a2001-11-14Jonas Wallden  case "prompt": prompt+=foo(opt[1]); break;
73b75f1998-02-24Fredrik Hübinette (Hubbe)  case "start": start=foo(opt[1]); start--; break;
0073821998-04-05Fredrik Hübinette (Hubbe)  case "end": end=foo(opt[1]); break;
d5d01e2002-05-02Martin Nilsson  case "fail": fail=1; break;
f07dba2004-04-23Henrik Grubbström (Grubba)  case "forked": { array(string) orig_argv = backtrace()[0][3]; int i = search(orig_argv, argv[0]); if (i < 0) { werror("Forked operation failed: Failed to find %O in %O\n", argv[0], orig_argv); break; } forked = orig_argv[..i]; break; }
d5d01e2002-05-02Martin Nilsson  case "loop": loop=foo(opt[1]); break;
73b75f1998-02-24Fredrik Hübinette (Hubbe)  case "trace": t+=foo(opt[1]); break; case "check": check+=foo(opt[1]); break;
1c0c612002-11-14Marcus Comstedt  case "asm": asmdebug+=foo(opt[1]); break;
d5d01e2002-05-02Martin Nilsson  case "mem": mem=1; break;
bd227a1999-01-21Fredrik Hübinette (Hubbe) 
ada13c1999-06-19Fredrik Hübinette (Hubbe)  case "auto":
d125f32003-06-26Martin Nilsson  if(stringp(opt[1])) testsuites=find_testsuites(opt[1]); else testsuites=find_testsuites(".");
ada13c1999-06-19Fredrik Hübinette (Hubbe)  break;
218e4b2002-05-24Martin Nilsson  case "regression": add_constant("regression", 1); break;
bd227a1999-01-21Fredrik Hübinette (Hubbe) #ifdef HAVE_DEBUG case "debug": { object p=Stdio.Port(); p->bind(0); werror("Debug port is: %s\n",p->query_address()); sscanf(p->query_address(),"%*s %d",int portno); extra_info+=sprintf(" dport:%d",portno); thread_create(lambda(object p){ while(p) { if(object o=p->accept()) { object q=Stdio.FILE(); q->assign(o); destruct(o); Tools.Hilfe.GenericHilfe(q,q); } } },p); } #endif
73b75f1998-02-24Fredrik Hübinette (Hubbe)  }
a9679f1995-11-13David Hedbor  }
f07dba2004-04-23Henrik Grubbström (Grubba)  if (forked) { if (!use_watchdog) forked += ({ "--no-watchdog" }); if (!maybe_tty) forked += ({ "--notty" }); if (verbose) forked += ({ "--verbose=" + verbose }); if (prompt) forked += ({ "--prompt=" + prompt }); if (start) forked += ({ "--start-test=" + (start+1) }); // FIXME: end handling is not quite correct. if (end != 0x7fffffff) forked += ({ "--end-after=" + end }); if (fail) forked += ({ "--fail" }); // forked is handled here. // loop is handled here. if (t) forked += ({ "--trace=" + t }); if (check) forked += ({ "--check=" + check }); if (asmdebug) forked += ({ "--asm=" + asmdebug }); if (mem) forked += ({ "--memory" }); // auto already handled. if (all_constants()->regression) forked += ({ "--regression" }); // debug port not propagated. //werror("forked:%O\n", forked); }
bcbc422004-08-31Henrik Grubbström (Grubba)  // Move stdout to a higher fd, so that close on exec works. // This makes sure the original stdout gets closed even if // some subprocess hangs.
55f0802004-08-31Henrik Grubbström (Grubba)  Stdio.File stdout = Stdio.File(); Stdio.stdout->dup2(stdout); //stdout->assign(Stdio.stdout->_fd->dup());
bcbc422004-08-31Henrik Grubbström (Grubba)  Stdio.stderr->dup2(Stdio.stdout); stdout->set_close_on_exec(1);
8240052000-02-22Fredrik Hübinette (Hubbe) #ifdef WATCHDOG int watchdog_time=time();
e0b3fe2004-04-23Henrik Grubbström (Grubba)  if(use_watchdog && !forked)
d3027a2000-03-07Fredrik Hübinette (Hubbe)  {
29c1f62007-06-07Henrik Grubbström (Grubba)  object watchdog_tmp;
8240052000-02-22Fredrik Hübinette (Hubbe) #ifdef WATCHDOG_PIPE
29c1f62007-06-07Henrik Grubbström (Grubba)  watchdog_tmp = Stdio.File(); watchdog_pipe = watchdog_tmp->pipe(Stdio.PROP_IPC); add_constant("__signal_watchdog",lambda(){});
8240052000-02-22Fredrik Hübinette (Hubbe) #endif
d3027a2000-03-07Fredrik Hübinette (Hubbe)  watchdog=Process.create_process(
29c1f62007-06-07Henrik Grubbström (Grubba)  backtrace()[0][3] + ({ "--watchdog="+getpid() }), ([ "stdin" :watchdog_tmp || Stdio.stdin, "stdout":Stdio.stderr, "stderr":Stdio.stderr, ])); if (watchdog_tmp) destruct(watchdog_tmp);
d3027a2000-03-07Fredrik Hübinette (Hubbe)  }
29c1f62007-06-07Henrik Grubbström (Grubba) #endif #if defined(WATCHDOG_SIGNAL) && defined(WATCHDOG)
c749142000-03-28Fredrik Hübinette (Hubbe)  add_constant("__signal_watchdog",signal_watchdog);
29c1f62007-06-07Henrik Grubbström (Grubba) #else // WATCHDOG_PIPE or !WATCHDOG add_constant("__signal_watchdog",lambda(){}); #endif // WATCHDOG_SIGNAL && WATCHDOG
8240052000-02-22Fredrik Hübinette (Hubbe) 
55f0802004-08-31Henrik Grubbström (Grubba)  add_constant("_verbose", verbose); if(verbose) stdout->write("Begin tests at "+ctime(time()));
d5d01e2002-05-02Martin Nilsson  testsuites += Getopt.get_args(argv, 1)[1..];
9053bf2004-05-23Martin Nilsson  foreach(testsuites; int pos; string ts) { if(Stdio.is_dir(ts)) testsuites[pos] = ts = combine_path(ts, "testsuite"); if(!file_stat(ts)) exit(1, "Could not find test %O.\n", ts);
06983f1996-09-22Fredrik Hübinette (Hubbe)  }
9053bf2004-05-23Martin Nilsson  if(!sizeof(testsuites)) exit(1, "No tests found. Use --help for more information.\n");
4cd6692002-11-26Martin Nilsson #if 1 // Store the name of all constants so that we can see // if any constant has been leaked from the testsuite. array const_names = indices(all_constants()); #endif
1c0c612002-11-14Marcus Comstedt #if constant(_assembler_debug) if(asmdebug) _assembler_debug(asmdebug); #endif
c3c7031996-12-04Fredrik Hübinette (Hubbe)  while(loop--) { successes=errors=0;
e0b3fe2004-04-23Henrik Grubbström (Grubba)  if (forked) { foreach(testsuites, string testsuite) { Stdio.File p = Stdio.File();
df20a92004-04-23Henrik Grubbström (Grubba)  Stdio.File p2 = p->pipe();
69b5bf2005-04-09Martin Nilsson  if(!p2) { werror("Failed to create pipe.\n"); if(fail) exit(1); errors++; continue; }
e0b3fe2004-04-23Henrik Grubbström (Grubba)  object pid =
f07dba2004-04-23Henrik Grubbström (Grubba)  Process.create_process(forked + ({ testsuite }),
df20a92004-04-23Henrik Grubbström (Grubba)  ([ "stdout":p2 ])); p2->close();
e0b3fe2004-04-23Henrik Grubbström (Grubba)  string raw_results; string results = lower_case(raw_results = p->read()); int err = pid->wait(); int total = 0; int failed = 0; int skip = 0; if (((sscanf(results, "%*sfailed tests:%d", failed) != 2) + (sscanf(results, "%*stotal tests:%d", total) != 2) + (sscanf(results, "%*s(%d tests skipped)", skip) != 2)) == 3) { // Failed to parse the result totally.
3b201d2004-10-22Henrik Grubbström (Grubba)  if (err == -1) { werror("Failed to parse subresult for testsuite %O " "(died of signal %d).\n" "%O", testsuite, pid->last_signal(), raw_results); } else { werror("Failed to parse subresult for testsuite %O " "(exitcode:%d):\n" "%O", testsuite, err, raw_results); }
e0b3fe2004-04-23Henrik Grubbström (Grubba)  errors++; } else { werror("Subresult: %d tests, %d failed, %d skipped\n", total, failed, skip); errors += failed; successes += total - failed; skipped += skip;
3b201d2004-10-22Henrik Grubbström (Grubba)  werror("Accumulated: %d tests, %d failed, %d skipped\n", successes + errors, errors, skipped);
e0b3fe2004-04-23Henrik Grubbström (Grubba)  }
3d12992004-04-23Henrik Grubbström (Grubba)  if (fail && errors) { exit(1); }
e0b3fe2004-04-23Henrik Grubbström (Grubba)  } } else {
d5d01e2002-05-02Martin Nilsson  testloop: foreach(testsuites, string testsuite)
a9679f1995-11-13David Hedbor  {
d5d01e2002-05-02Martin Nilsson  tests = read_tests( testsuite ); werror("Doing tests in %s (%d tests)\n", testsuite, sizeof(tests));
9ac7792000-07-28Martin Nilsson  int qmade, qskipped, qmadep, qskipp;
7c690f2002-07-31Martin Nilsson 
bcbc092004-03-06Martin Nilsson  int testno, testline;
d5d01e2002-05-02Martin Nilsson  for(e=start;e<sizeof(tests);e++) { signal_watchdog();
8240052000-02-22Fredrik Hübinette (Hubbe) 
a1aa642004-07-15Henrik Grubbström (Grubba)  if (!((e-start) % 10)) report_size();
8cd2e32002-05-05Martin Stjernholm  int skip=0, prev_errors = errors;
d5d01e2002-05-02Martin Nilsson  object o; mixed a,b;
ee7e3c2002-08-21Martin Nilsson  // Extra consistency checks?
d5d01e2002-05-02Martin Nilsson  if(check) { if(check>0 || (e % -check)==0 )
a571702000-04-14Fredrik Hübinette (Hubbe)  _verify_internals();
d5d01e2002-05-02Martin Nilsson  } if(check>3) { gc(); _verify_internals(); }
ee7e3c2002-08-21Martin Nilsson  string test = tests[e]; // Is there a condition for this test? string condition;
d5d01e2002-05-02Martin Nilsson  if( sscanf(test, "COND %s\n%s", condition, test)==2 ) { int tmp; if(!(tmp=cond_cache[condition]))
dddccc1998-04-15Fredrik Hübinette (Hubbe)  {
d5d01e2002-05-02Martin Nilsson  mixed err = catch { tmp=!!(compile_string("mixed c() { return "+condition+"; }", "Cond "+(e+1))()->c()); }; if(err) {
bcbc092004-03-06Martin Nilsson  werror( "\nConditional %d %s failed:\n" "%s\n", e+1, testline?"(line "+testline+")":"", describe_backtrace(err) );
d5d01e2002-05-02Martin Nilsson  errors++; tmp = -1;
1869a91999-02-28Fredrik Hübinette (Hubbe)  }
d5d01e2002-05-02Martin Nilsson  if(!tmp) tmp=-1; cond_cache[condition]=tmp; }
a696742002-08-06Martin Nilsson 
d5d01e2002-05-02Martin Nilsson  if(tmp==-1) {
1fba802002-07-29Martin Nilsson  if(verbose>1)
d5d01e2002-05-02Martin Nilsson  werror("Not doing test "+(e+1)+"\n"); successes++; skipped++; skip=1;
8240052000-02-22Fredrik Hübinette (Hubbe)  }
d5d01e2002-05-02Martin Nilsson  }
8240052000-02-22Fredrik Hübinette (Hubbe) 
ee7e3c2002-08-21Martin Nilsson  string|int type;
8cd2e32002-05-05Martin Stjernholm  sscanf(test, "%s\n%s", type, test);
ee7e3c2002-08-21Martin Nilsson  string testfile; sscanf(type, "%s: test %d, expected result: %s", testfile, testno, type);
8cd2e32002-05-05Martin Stjernholm  if (testfile) { array split = testfile / ":"; testline = (int) split[-1]; testfile = split[..sizeof (split) - 2] * ":"; } string pad_on_error = "\n";
d125f32003-06-26Martin Nilsson  if(maybe_tty && Stdio.Terminfo.is_tty())
d5d01e2002-05-02Martin Nilsson  {
0d985b2002-10-01Martin Nilsson  if(verbose<2) {
8cd2e32002-05-05Martin Stjernholm  werror("test %d, line %d\r", e+1, testline); pad_on_error = " \r"; }
d5d01e2002-05-02Martin Nilsson  }
1fba802002-07-29Martin Nilsson  else if(verbose){
d5d01e2002-05-02Martin Nilsson  if(skip) { if(qmade) werror(" Made %d test%s.\n", qmade, qmade==1?"":"s"); qmade=0; qskipp=1; qskipped++; } else { if(qskipped) werror(" Skipped %d test%s.\n", qskipped, qskipped==1?"":"s"); qskipped=0; qmadep=1; qmade++; } } else { /* Use + instead of . so that sendmail and * cron will not cut us off... :( */ switch( (e-start) % 50)
8240052000-02-22Fredrik Hübinette (Hubbe)  {
d5d01e2002-05-02Martin Nilsson  case 0:
ee7e3c2002-08-21Martin Nilsson  werror("%5d: ", e); // fallthrough
d5d01e2002-05-02Martin Nilsson 
ee7e3c2002-08-21Martin Nilsson  default: werror(skip?"-":"+"); break;
d5d01e2002-05-02Martin Nilsson  case 9: case 19: case 29: case 39: werror(skip?"- ":"+ "); break;
ee7e3c2002-08-21Martin Nilsson 
d5d01e2002-05-02Martin Nilsson  case 49: werror(skip?"-\n":"+\n");
73b75f1998-02-24Fredrik Hübinette (Hubbe)  }
d5d01e2002-05-02Martin Nilsson  } if(skip) continue;
8240052000-02-22Fredrik Hübinette (Hubbe) 
8cd2e32002-05-05Martin Stjernholm  if (!testfile || !testno || !type) { werror ("%sInvalid format in test file: %O\n", pad_on_error, type); errors++; continue; }
d5d01e2002-05-02Martin Nilsson  if (prompt) { if (Stdio.Readline()-> read(sprintf("About to run test: %d. [<RETURN>/'quit']: ",
69807c2002-05-02Martin Nilsson  testno)) == "quit") {
d5d01e2002-05-02Martin Nilsson  break testloop;
1869a91999-02-28Fredrik Hübinette (Hubbe)  }
d5d01e2002-05-02Martin Nilsson  }
475a841999-02-20Henrik Grubbström (Grubba) 
1fba802002-07-29Martin Nilsson  if(verbose>1)
d5d01e2002-05-02Martin Nilsson  {
8cd2e32002-05-05Martin Stjernholm  werror("Doing test %d (%d total) at %s:%d%s\n", testno, successes+errors+1, testfile, testline, extra_info);
d125f32003-06-26Martin Nilsson  if(verbose>2) print_code(test);
d5d01e2002-05-02Martin Nilsson  } if(check > 1) _verify_internals();
c3c7031996-12-04Fredrik Hübinette (Hubbe) 
d5d01e2002-05-02Martin Nilsson  shift++;
8cd2e32002-05-05Martin Stjernholm  string fname = testfile + ":" + testline + ": Test " + testno +
d5d01e2002-05-02Martin Nilsson  " (shift " + (shift%3) + ")";
475a841999-02-20Henrik Grubbström (Grubba) 
d5d01e2002-05-02Martin Nilsson  string widener = ([ 0:"",
475a841999-02-20Henrik Grubbström (Grubba)  1:"\nint \x30c6\x30b9\x30c8=0;\n",
1869a91999-02-28Fredrik Hübinette (Hubbe)  2:"\nint \x10001=0;\n" ])[shift%3];
a2c6f41999-12-10Henrik Grubbström (Grubba) 
d5d01e2002-05-02Martin Nilsson  // widener += "#pragma strict_types\n";
a2c6f41999-12-10Henrik Grubbström (Grubba) 
d5d01e2002-05-02Martin Nilsson  if(test[-1]!='\n') test+="\n";
53db3a1999-10-28Fredrik Hübinette (Hubbe) 
d5d01e2002-05-02Martin Nilsson  int computed_line=sizeof(test/"\n"); array gnapp= test/"#"; for(int e=1;e<sizeof(gnapp);e++) { if(sscanf(gnapp[e],"%*d"))
53db3a1999-10-28Fredrik Hübinette (Hubbe)  {
d5d01e2002-05-02Martin Nilsson  computed_line=0; break;
53db3a1999-10-28Fredrik Hübinette (Hubbe)  }
d5d01e2002-05-02Martin Nilsson  } string linetester="int __cpp_line=__LINE__; int __rtl_line=[int]backtrace()[-1][1];\n";
32a6ac1998-04-11Henrik Grubbström (Grubba) 
d5d01e2002-05-02Martin Nilsson  string to_compile = test + linetester + widener;
a4db192000-02-27Fredrik Hübinette (Hubbe) 
d5d01e2002-05-02Martin Nilsson  if((shift/6)&1) { if(search("don't save parent",to_compile) != -1)
a4db192000-02-27Fredrik Hübinette (Hubbe)  {
d5d01e2002-05-02Martin Nilsson  fname+=" (save parent)"; to_compile= "#pragma save_parent\n" "# 1\n" +to_compile;
a4db192000-02-27Fredrik Hübinette (Hubbe)  }
d5d01e2002-05-02Martin Nilsson  }
1ab6792000-10-08Henrik Grubbström (Grubba) 
d5d01e2002-05-02Martin Nilsson  if((shift/3)&1) { fname+=" (CRNL)"; to_compile=replace(to_compile,"\n","\r\n"); }
82ad8d2001-06-23Fredrik Hübinette (Hubbe) 
d5d01e2002-05-02Martin Nilsson  // _optimizer_debug(5);
7c690f2002-07-31Martin Nilsson 
d125f32003-06-26Martin Nilsson  if(verbose>9) print_code(to_compile);
27d7702004-01-15Martin Nilsson  WarningFlag wf;
d5d01e2002-05-02Martin Nilsson  switch(type) { mixed at,bt; mixed err; case "COMPILE":
27d7702004-01-15Martin Nilsson  wf = WarningFlag(); master()->set_inhibit_compile_errors(wf);
d5d01e2002-05-02Martin Nilsson  _dmalloc_set_name(fname,0);
8cd2e32002-05-05Martin Stjernholm  if(catch(compile_string(to_compile, testsuite)))
1869a91999-02-28Fredrik Hübinette (Hubbe)  {
d5d01e2002-05-02Martin Nilsson  _dmalloc_set_name();
27d7702004-01-15Martin Nilsson  master()->set_inhibit_compile_errors(0);
8cd2e32002-05-05Martin Stjernholm  werror(pad_on_error + fname + " failed.\n");
d125f32003-06-26Martin Nilsson  print_code(test);
d5d01e2002-05-02Martin Nilsson  errors++; } else { _dmalloc_set_name();
27d7702004-01-15Martin Nilsson  master()->set_inhibit_compile_errors(0); if(wf->warning) { werror(pad_on_error + fname + " produced warning.\n"); werror("%{%s\n%}", wf->warnings); print_code(test); errors++; break; }
d5d01e2002-05-02Martin Nilsson  successes++; } break;
7c690f2002-07-31Martin Nilsson 
d5d01e2002-05-02Martin Nilsson  case "COMPILE_ERROR": master()->set_inhibit_compile_errors(1); _dmalloc_set_name(fname,0);
8cd2e32002-05-05Martin Stjernholm  if(catch(compile_string(to_compile, testsuite)))
d5d01e2002-05-02Martin Nilsson  { _dmalloc_set_name(); successes++; } else { _dmalloc_set_name();
8cd2e32002-05-05Martin Stjernholm  werror(pad_on_error + fname + " failed (expected compile error).\n");
d125f32003-06-26Martin Nilsson  print_code(test);
d5d01e2002-05-02Martin Nilsson  errors++; } master()->set_inhibit_compile_errors(0); break;
218e4b2002-05-24Martin Nilsson  case "COMPILE_WARNING":
27d7702004-01-15Martin Nilsson  wf = WarningFlag();
218e4b2002-05-24Martin Nilsson  master()->set_inhibit_compile_errors(wf); _dmalloc_set_name(fname,0); if(catch(compile_string(to_compile, testsuite))) { _dmalloc_set_name(); werror(pad_on_error + fname + " failed.\n");
d125f32003-06-26Martin Nilsson  print_code(test);
218e4b2002-05-24Martin Nilsson  errors++; } else { _dmalloc_set_name(); if( wf->warning ) successes++; else { werror(pad_on_error + fname + " failed (expected compile warning).\n");
d125f32003-06-26Martin Nilsson  print_code(test);
218e4b2002-05-24Martin Nilsson  errors++; } } master()->set_inhibit_compile_errors(0); break;
d5d01e2002-05-02Martin Nilsson  case "EVAL_ERROR": master()->set_inhibit_compile_errors(1); _dmalloc_set_name(fname,0); at = gauge { err=catch {
4cd6692002-11-26Martin Nilsson  a = compile_string(to_compile, testsuite)()->a();
d5d01e2002-05-02Martin Nilsson  }; }; if(err) { _dmalloc_set_name(); successes++;
1fba802002-07-29Martin Nilsson  if(verbose>3)
d5d01e2002-05-02Martin Nilsson  werror("Time in a(): %f\n",at); } else { _dmalloc_set_name();
8cd2e32002-05-05Martin Stjernholm  werror(pad_on_error + fname + " failed (expected eval error).\n");
4cd6692002-11-26Martin Nilsson  werror("Got %O\n", a);
d125f32003-06-26Martin Nilsson  print_code(test);
d5d01e2002-05-02Martin Nilsson  errors++; } master()->set_inhibit_compile_errors(0); break;
7c690f2002-07-31Martin Nilsson 
d5d01e2002-05-02Martin Nilsson  default: if (err = catch{
27d7702004-01-15Martin Nilsson  wf = WarningFlag(); master()->set_inhibit_compile_errors(wf);
d5d01e2002-05-02Martin Nilsson  _dmalloc_set_name(fname,0);
4cd6692002-11-26Martin Nilsson  o=compile_string(to_compile,testsuite)();
d5d01e2002-05-02Martin Nilsson  _dmalloc_set_name();
27d7702004-01-15Martin Nilsson 
d5d01e2002-05-02Martin Nilsson  if(check > 1) _verify_internals();
7c690f2002-07-31Martin Nilsson 
d5d01e2002-05-02Martin Nilsson  a=b=0; if(t) trace(t); _dmalloc_set_name(fname,1); if(functionp(o->a)) { // trace(10); at = gauge { a=o->a(); }; // trace(0); } if(functionp(o->b)) { bt = gauge { b=o->b(); }; }
7c690f2002-07-31Martin Nilsson 
d5d01e2002-05-02Martin Nilsson  _dmalloc_set_name();
53db3a1999-10-28Fredrik Hübinette (Hubbe) 
d5d01e2002-05-02Martin Nilsson  if(t) trace(0); if(check > 1) _verify_internals();
06fe872000-05-16Fredrik Hübinette (Hubbe) 
27d7702004-01-15Martin Nilsson  if(wf->warning) { werror(pad_on_error + fname + " produced warning.\n"); werror("%{%s\n%}", wf->warnings); print_code(test); errors++; break; } master()->set_inhibit_compile_errors(0);
d5d01e2002-05-02Martin Nilsson  }) {
27d7702004-01-15Martin Nilsson  if(t) trace(0); master()->set_inhibit_compile_errors(0);
8cd2e32002-05-05Martin Stjernholm  werror(pad_on_error + fname + " failed.\n");
d125f32003-06-26Martin Nilsson  print_code(test);
d5d01e2002-05-02Martin Nilsson  if (arrayp(err) && sizeof(err) && stringp(err[0])) { werror("Error: " + master()->describe_backtrace(err)); } if (objectp(err)) { werror("Error: " + master()->describe_backtrace(err)); } errors++; break; } if( o->__cpp_line != o->__rtl_line || ( computed_line && computed_line!=o->__cpp_line)) {
8cd2e32002-05-05Martin Stjernholm  werror(pad_on_error + fname + " Line numbering failed.\n");
29eda12004-04-22Henrik Grubbström (Grubba)  print_code(to_compile); werror(" Preprocessed:\n"); print_code(cpp(to_compile, fname));
d5d01e2002-05-02Martin Nilsson  werror(" CPP lines: %d\n",o->__cpp_line); werror(" RTL lines: %d\n",o->__rtl_line); if(computed_line) werror("Actual lines: %d\n",computed_line); errors++; } if(verbose>2) werror("Time in a(): %f, Time in b(): %O\n",at,bt);
7c690f2002-07-31Martin Nilsson 
d5d01e2002-05-02Martin Nilsson  switch(type) { case "FALSE": if(a) {
8cd2e32002-05-05Martin Stjernholm  werror(pad_on_error + fname + " failed.\n");
d125f32003-06-26Martin Nilsson  print_code(test);
d5d01e2002-05-02Martin Nilsson  werror(sprintf("o->a(): %O\n",a)); errors++; } else { successes++; } break;
1869a91999-02-28Fredrik Hübinette (Hubbe) 
d5d01e2002-05-02Martin Nilsson  case "TRUE": if(!a) {
8cd2e32002-05-05Martin Stjernholm  werror(pad_on_error + fname + " failed.\n");
d125f32003-06-26Martin Nilsson  print_code(test);
d5d01e2002-05-02Martin Nilsson  werror(sprintf("o->a(): %O\n",a)); errors++; } else { successes++; } break;
2bfdd42006-06-16Henrik Grubbström (Grubba)  case "PUSH_WARNING": if (!stringp(a)) { werror(pad_on_error + fname + " failed.\n"); print_code(test); werror(sprintf("o->a(): %O\n", a)); } else { pushed_warnings[a]++; } break; case "POP_WARNING": if (!stringp(a)) { werror(pad_on_error + fname + " failed.\n"); print_code(test); werror(sprintf("o->a(): %O\n", a)); } else if (pushed_warnings[a]) { if (!--pushed_warnings[a]) { m_delete(pushed_warnings, a); } } else { werror(pad_on_error + fname + " failed.\n"); print_code(test); werror(sprintf("o->a(): %O not pushed!\n", a)); } break;
73b75f1998-02-24Fredrik Hübinette (Hubbe) 
d5d01e2002-05-02Martin Nilsson  case "RUN": successes++; break; case "RUNCT": if(!a || !arrayp(a) || sizeof(a)!=2 || !intp(a[0]) || !intp(a[1])) {
8cd2e32002-05-05Martin Stjernholm  werror(pad_on_error + fname + " failed to return proper results.\n");
d125f32003-06-26Martin Nilsson  print_code(test);
d5d01e2002-05-02Martin Nilsson  werror(sprintf("o->a(): %O\n",a)); errors++; } else { successes += a[0]; errors += a[1];
1fba802002-07-29Martin Nilsson  if (verbose>1)
8cd2e32002-05-05Martin Stjernholm  if(a[1]) werror("%d/%d tests failed.\n", a[1], a[0]+a[1]); else werror("Did %d tests in %s.\n", a[0], fname);
d5d01e2002-05-02Martin Nilsson  } break; case "EQ": if(a!=b) {
8cd2e32002-05-05Martin Stjernholm  werror(pad_on_error + fname + " failed.\n");
d125f32003-06-26Martin Nilsson  print_code(test);
d5d01e2002-05-02Martin Nilsson  werror(sprintf("o->a(): %O\n",a)); werror(sprintf("o->b(): %O\n",b)); errors++;
1590d02003-06-05Henrik Grubbström (Grubba)  if (stringp(a) && stringp(b) && (sizeof(a) == sizeof(b)) && (sizeof(a) > 20)) { werror("Differences at:\n"); int i; for(i = 0; i < sizeof(a); i++) { if (a[i] != b[i]) { werror(" %4d: 0x%04x != 0x%04x\n", i, a[i], b[i]); } } }
d5d01e2002-05-02Martin Nilsson  } else { successes++; } break;
73b75f1998-02-24Fredrik Hübinette (Hubbe) 
d5d01e2002-05-02Martin Nilsson  case "EQUAL": if(!equal(a,b)) {
8cd2e32002-05-05Martin Stjernholm  werror(pad_on_error + fname + " failed.\n");
d125f32003-06-26Martin Nilsson  print_code(test);
d5d01e2002-05-02Martin Nilsson  werror(sprintf("o->a(): %O\n",a)); werror(sprintf("o->b(): %O\n",b)); errors++;
1590d02003-06-05Henrik Grubbström (Grubba)  if (stringp(a) && stringp(b) && (sizeof(a) == sizeof(b)) && (sizeof(a) > 20)) { werror("Differences at:\n"); int i; for(i = 0; i < sizeof(a); i++) { if (a[i] != b[i]) { werror(" %4d: 0x%04x != 0x%04x\n", i, a[i], b[i]); } } }
d5d01e2002-05-02Martin Nilsson  } else { successes++; } break;
73b75f1998-02-24Fredrik Hübinette (Hubbe) 
d5d01e2002-05-02Martin Nilsson  default: werror(sprintf("\n%s: Unknown test type (%O).\n", fname, type)); errors++;
1869a91999-02-28Fredrik Hübinette (Hubbe)  }
d5d01e2002-05-02Martin Nilsson  }
8cd2e32002-05-05Martin Stjernholm  if (errors > prev_errors) werror ("\n");
d5d01e2002-05-02Martin Nilsson  if(check > 2) _verify_internals();
73b75f1998-02-24Fredrik Hübinette (Hubbe) 
d5d01e2002-05-02Martin Nilsson  if(fail && errors) exit(1);
619f882000-01-30Fredrik Hübinette (Hubbe) 
d5d01e2002-05-02Martin Nilsson  if(successes+errors > end)
619f882000-01-30Fredrik Hübinette (Hubbe)  {
d5d01e2002-05-02Martin Nilsson  break testloop;
619f882000-01-30Fredrik Hübinette (Hubbe)  }
d5d01e2002-05-02Martin Nilsson  a=b=0; }
d125f32003-06-26Martin Nilsson  if(maybe_tty && Stdio.Terminfo.is_tty())
d5d01e2002-05-02Martin Nilsson  {
8cd2e32002-05-05Martin Stjernholm  werror(" \r");
d5d01e2002-05-02Martin Nilsson  }
1fba802002-07-29Martin Nilsson  else if(verbose) {
d5d01e2002-05-02Martin Nilsson  if(!qskipp && !qmadep); else if(!qskipp) werror("Made all tests\n"); else if(!qmadep) werror("Skipped all tests\n"); else if(qmade) werror(" Made %d test%s.\n", qmade, qmade==1?"":"s"); else if(qskipped) werror(" Skipped %d test%s.\n", qskipped, qskipped==1?"":"s"); } else { werror("\n"); }
c3c7031996-12-04Fredrik Hübinette (Hubbe)  }
e0b3fe2004-04-23Henrik Grubbström (Grubba)  }
a1aa642004-07-15Henrik Grubbström (Grubba)  report_size();
73b75f1998-02-24Fredrik Hübinette (Hubbe)  if(mem)
c3c7031996-12-04Fredrik Hübinette (Hubbe)  {
73b75f1998-02-24Fredrik Hübinette (Hubbe)  int total; tests=0; gc(); mapping tmp=_memory_usage();
e0b3fe2004-04-23Henrik Grubbström (Grubba)  werror(sprintf("%-10s: %6s %10s\n","Category","num","bytes"));
73b75f1998-02-24Fredrik Hübinette (Hubbe)  foreach(sort(indices(tmp)),string foo)
d5d01e2002-05-02Martin Nilsson  { if(sscanf(foo,"%s_bytes",foo))
73b75f1998-02-24Fredrik Hübinette (Hubbe)  {
e0b3fe2004-04-23Henrik Grubbström (Grubba)  werror(sprintf("%-10s: %6d %10d\n",
d5d01e2002-05-02Martin Nilsson  foo+"s", tmp["num_"+foo+"s"], tmp[foo+"_bytes"])); total+=tmp[foo+"_bytes"];
73b75f1998-02-24Fredrik Hübinette (Hubbe)  }
d5d01e2002-05-02Martin Nilsson  }
e0b3fe2004-04-23Henrik Grubbström (Grubba)  werror( "%-10s: %6s %10d\n",
a1aa642004-07-15Henrik Grubbström (Grubba)  "Total", "", total );
c3c7031996-12-04Fredrik Hübinette (Hubbe)  }
a9679f1995-11-13David Hedbor  }
1fba802002-07-29Martin Nilsson  if(errors || verbose>1)
b455c81998-03-20Fredrik Hübinette (Hubbe)  {
bcbc422004-08-31Henrik Grubbström (Grubba)  stdout->write("Failed tests: "+errors+".\n");
b455c81998-03-20Fredrik Hübinette (Hubbe)  }
7c690f2002-07-31Martin Nilsson 
bcbc422004-08-31Henrik Grubbström (Grubba)  stdout->write(sprintf("Total tests: %d (%d tests skipped)\n", successes+errors, skipped));
4cd6692002-11-26Martin Nilsson  if(verbose)
bcbc422004-08-31Henrik Grubbström (Grubba)  stdout->write("Finished tests at "+ctime(time()));
4cd6692002-11-26Martin Nilsson  #if 1 if(verbose && sizeof(all_constants())!=sizeof(const_names)) { multiset const_names = (multiset)const_names; foreach(indices(all_constants()), string const) if( !const_names[const] ) werror("Leaked constant %O\n", const); } #endif
a9679f1995-11-13David Hedbor 
4a156f2002-12-29Martin Nilsson  add_constant("regression"); add_constant("_verbose");
b66f132003-05-17Henrik Grubbström (Grubba)  add_constant("__signal_watchdog");
4a156f2002-12-29Martin Nilsson  add_constant("RUNPIKE");
0e221a2004-04-23Henrik Grubbström (Grubba) #if defined(WATCHDOG_SIGNAL) || defined(WATCHDOG_PIPE) if(watchdog)
03f5dc2000-03-20Fredrik Hübinette (Hubbe)  { #ifdef WATCHDOG_PIPE destruct(watchdog_pipe);
0e221a2004-04-23Henrik Grubbström (Grubba) #endif
03f5dc2000-03-20Fredrik Hübinette (Hubbe)  catch { watchdog->kill(signum("SIGKILL")); }; watchdog->wait(); }
8240052000-02-22Fredrik Hübinette (Hubbe) #endif
a9679f1995-11-13David Hedbor  return errors; }
d5d01e2002-05-02Martin Nilsson  constant doc = #" Usage: test_pike [args] [testfiles] --no-watchdog Watchdog will not be used.
3d75d62004-10-22Henrik Grubbström (Grubba) --watchdog=pid Run only the watchdog and monitor the process with the given pid.
d5d01e2002-05-02Martin Nilsson -h, --help Prints this message. -v[level],
3d75d62004-10-22Henrik Grubbström (Grubba) --verbose[=level] Select the level of verbosity. Every verbosity level includes the printouts from the levels below.
d5d01e2002-05-02Martin Nilsson  0 No extra printouts.
1fba802002-07-29Martin Nilsson  1 Some additional information printed out after every finished block of tests.
3d75d62004-10-22Henrik Grubbström (Grubba)  2 Some extra information about tests that will or won't be
e6114d2002-05-27Martin Nilsson  run.
1fba802002-07-29Martin Nilsson  3 Every test is printed out.
3d75d62004-10-22Henrik Grubbström (Grubba)  4 Time spent in individual tests is printed out.
ee7e3c2002-08-21Martin Nilsson  10 The actual Pike code compiled, including wrappers, is
e6114d2002-05-27Martin Nilsson  printed.
d5d01e2002-05-02Martin Nilsson -p, --prompt The user will be asked before every test is run.
3d75d62004-10-22Henrik Grubbström (Grubba) -sX, --start-test=X Where in the testsuite testing should start, i.e. ignores X
e6114d2002-05-27Martin Nilsson  tests in every testsuite.
95824f2002-05-27Johan Sundström -eX, --end-after=X How many tests should be run.
e2fa6b2002-12-30Martin Nilsson -f, --fail If set, the test program exits on first failure.
3d12992004-04-23Henrik Grubbström (Grubba) -F, --forking If set, each testsuite will run in a separate process.
e6114d2002-05-27Martin Nilsson -lX, --loop=X The number of times the testsuite should be run. Default is 1.
d5d01e2002-05-02Martin Nilsson -tX, --trace=X Run tests with trace level X.
ee7e3c2002-08-21Martin Nilsson -c[X], --check[=X] The level of extra Pike consistency checks performed.
d5d01e2002-05-02Martin Nilsson  1 _verify_internals is run before every test. 2 _verify_internals is run after every compilation. 3 _verify_internals is run after every test. 4 An extra gc and _verify_internals is run before every test.
e6114d2002-05-27Martin Nilsson  X<0 For values below zero, _verify_internals will be run before every n:th test, where n=abs(X).
d5d01e2002-05-02Martin Nilsson -m, --mem, --memory Print out memory allocations after the tests.
3d75d62004-10-22Henrik Grubbström (Grubba) -a, --auto[=dir] Let the test program find the testsuites automatically.
d5d01e2002-05-02Martin Nilsson -T, --notty Format output for non-tty. -d, --debug Opens a debug port. ";