Branch: Tag:

2002-05-02

2002-05-02 00:29:29 by Martin Nilsson <mani@lysator.liu.se>

Done a lot of stuff. The functional differences are support for RUNCT and --help.

Rev: bin/test_pike.pike:1.62

1:   #!/usr/local/bin/pike    - /* $Id: test_pike.pike,v 1.61 2001/11/14 16:44:58 jonasw Exp $ */ + /* $Id: test_pike.pike,v 1.62 2002/05/02 00:29:29 nilsson Exp $ */      import Stdio;   
83:    return ret;   }    + array(string) read_tests( string fn ) { +  string|array(string) tests = read_bytes( fn ); +  if(!tests) { +  werror("Failed to read test file %O, errno=%d.\n", +  fn, errno()); +  exit(1); +  } +  +  tests = tests/"\n....\n"; +  return tests[0..sizeof(tests)-2]; + } +  +  + // + // Watchdog stuff + // +    // 20 minutes should be enough..   #if !constant(_reset_dmalloc)   #define WATCHDOG_TIMEOUT 60*20
102:   #endif   #endif    -  +    #ifdef WATCHDOG   object watchdog;   int use_watchdog=1;
114: Inside #if defined(WATCHDOG) and #if defined(WATCHDOG)
   if(use_watchdog && time() - watchdog_time > 30)    {    watchdog_time=time(); - // werror("{WATCHDOG} Ping!\n"); +    #ifdef WATCHDOG_PIPE    watchdog_pipe->write("x",1);   #endif
127:   }   #endif    - int main(int argc, array(string) argv) - { -  int e, verbose, prompt, successes, errors, t, check; -  int skipped, quiet; -  array(string) tests; -  string tmp; -  program testprogram; -  int start, fail, mem; -  int loop=1; -  int end=0x7fffffff; -  string extra_info=""; -  int shift; -  - #if constant(signal) && constant(signum) -  if(signum("SIGQUIT")>=0) -  { -  signal(signum("SIGQUIT"),lambda() -  { -  master()->handle_error( ({"\nSIGQUIT recived, printing backtrace and continuing.\n",backtrace() }) ); -  -  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); -  } -  } -  }); -  } - #endif -  -  array(string) args=backtrace()[0][3]; -  array(string) testsuites=({}); -  args=args[..sizeof(args)-1-argc]; -  add_constant("RUNPIKE",Array.map(args,Process.sh_quote)*" "); -  -  foreach(Getopt.find_all_options(argv,aggregate( -  ({"no-watchdog",Getopt.NO_ARG,({"--no-watchdog"})}), -  ({"watchdog",Getopt.HAS_ARG,({"--watchdog"})}), -  ({"help",Getopt.NO_ARG,({"-h","--help"})}), -  ({"verbose",Getopt.MAY_HAVE_ARG,({"-v","--verbose"})}), -  ({"prompt",Getopt.NO_ARG,({"-p","--prompt"})}), -  ({"quiet",Getopt.NO_ARG,({"-q","--quiet"})}), -  ({"start",Getopt.HAS_ARG,({"-s","--start-test"})}), -  ({"end",Getopt.HAS_ARG,({"-e","--end-after"})}), -  ({"fail",Getopt.MAY_HAVE_ARG,({"-f","--fail"})}), -  ({"loop",Getopt.MAY_HAVE_ARG,({"-l","--loop"})}), -  ({"trace",Getopt.MAY_HAVE_ARG,({"-t","--trace"})}), -  ({"check",Getopt.MAY_HAVE_ARG,({"-c","--check"})}), -  ({"mem",Getopt.MAY_HAVE_ARG,({"-m","--mem","--memory"})}), -  ({"auto",Getopt.MAY_HAVE_ARG,({"-a","--auto"})}), -  ({"notty",Getopt.NO_ARG,({"-T","--notty"})}), - #ifdef HAVE_DEBUG -  ({"debug",Getopt.MAY_HAVE_ARG,({"-d","--debug"})}), - #endif -  )),array opt) -  { -  switch(opt[0]) -  { -  case "no-watchdog": -  use_watchdog=0; -  break; -  -  case "watchdog": + void run_watchdog(int pid) {   #ifdef WATCHDOG    int cnt=0; -  int pid=(int)opt[1]; +     int last_time=time();    int exit_quietly;   #ifdef WATCHDOG_PIPE
204: Inside #if defined(WATCHDOG) and #if defined(WATCHDOG_PIPE)
   object o=Stdio.File("stdin");    while(strlen(o->read(1) || ""))    { - // werror("[WATCHDOG] Pong!\n"); +     last_time=time();    } - // werror("[WATCHDOG] exiting.\n"); +     exit_quietly=1;    });   #endif
217: Inside #if defined(WATCHDOG) and #if defined(WATCHDOG_SIGNAL)
   if(signum("SIGQUIT")>=0)    {    werror("Setting signal (2)\n"); -  signal(signum("SIGQUIT"),lambda() { - // werror("[WATCHDOG] Pong!\n"); +  signal( signum("SIGQUIT"), +  lambda() {    last_time=time();    }); -  }else{ +  } +  else {    exit(1);    }   #endif - // werror("[WATCHDOG] started, watching %d.\n",pid); +        while(1)    {
234: Inside #if defined(WATCHDOG) and #if undefined(__NT__)
  #ifndef __NT__    if(!kill(pid, 0)) _exit(0);   #endif - // werror("[WATCHDOG] t=%d\n",time()-last_time); +        /* I hope 30 minutes per test is enough for everybody */    if(time() - last_time > WATCHDOG_TIMEOUT)
263:   #else    _exit(1);   #endif + } +  +  + int main(int argc, array(string) argv) + { +  int e, verbose, prompt, successes, errors, t, check; +  int skipped, quiet; +  array(string) tests; +  program testprogram; +  int start, fail, mem; +  int loop=1; +  int end=0x7fffffff; +  string extra_info=""; +  int shift; +  + #if constant(signal) && constant(signum) +  if(signum("SIGQUIT")>=0) +  { +  signal(signum("SIGQUIT"),lambda() +  { +  master()->handle_error( ({"\nSIGQUIT recived, printing backtrace and continuing.\n",backtrace() }) ); +  +  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); +  } +  } +  }); +  } + #endif +  +  array(string) args=backtrace()[0][3]; +  array(string) testsuites=({}); +  args=args[..sizeof(args)-1-argc]; +  add_constant("RUNPIKE",Array.map(args,Process.sh_quote)*" "); +  +  foreach(Getopt.find_all_options(argv,aggregate( +  ({"no-watchdog",Getopt.NO_ARG,({"--no-watchdog"})}), +  ({"watchdog",Getopt.HAS_ARG,({"--watchdog"})}), +  ({"help",Getopt.NO_ARG,({"-h","--help"})}), +  ({"verbose",Getopt.MAY_HAVE_ARG,({"-v","--verbose"})}), +  ({"prompt",Getopt.NO_ARG,({"-p","--prompt"})}), +  ({"quiet",Getopt.NO_ARG,({"-q","--quiet"})}), +  ({"start",Getopt.HAS_ARG,({"-s","--start-test"})}), +  ({"end",Getopt.HAS_ARG,({"-e","--end-after"})}), +  ({"fail",Getopt.NO_ARG,({"-f","--fail"})}), +  ({"loop",Getopt.HAS_ARG,({"-l","--loop"})}), +  ({"trace",Getopt.HAS_ARG,({"-t","--trace"})}), +  ({"check",Getopt.MAY_HAVE_ARG,({"-c","--check"})}), +  ({"mem",Getopt.NO_ARG,({"-m","--mem","--memory"})}), +  ({"auto",Getopt.NO_ARG,({"-a","--auto"})}), +  ({"notty",Getopt.NO_ARG,({"-T","--notty"})}), + #ifdef HAVE_DEBUG +  ({"debug",Getopt.MAY_HAVE_ARG,({"-d","--debug"})}), + #endif +  )),array opt) +  { +  switch(opt[0]) +  { +  case "no-watchdog": +  use_watchdog=0;    break;    -  +  case "watchdog": +  run_watchdog( (int)opt[1] ); +  break; +     case "notty":    istty_cache=-1;    break;       case "help": -  werror("Usage: "+argv[e]+" [-v | --verbose] [-p | --prompt] [-h | --help] [-t <testno>] <testfile>\n"); +  write(doc);    return 0;       case "verbose": verbose+=foo(opt[1]); break;
278:    case "quiet": quiet=1; istty_cache=-1; break;    case "start": start=foo(opt[1]); start--; break;    case "end": end=foo(opt[1]); break; -  case "fail": fail+=foo(opt[1]); break; -  case "loop": loop+=foo(opt[1]); break; +  case "fail": fail=1; break; +  case "loop": loop=foo(opt[1]); break;    case "trace": t+=foo(opt[1]); break;    case "check": check+=foo(opt[1]); break; -  case "mem": mem+=foo(opt[1]); break; +  case "mem": mem=1; break;       case "auto":    testsuites=find_testsuites(".");
337:    add_constant("__signal_watchdog",lambda(){});   #endif    -  argv=Getopt.get_args(argv,1)+testsuites; -  if(sizeof(argv)<1) +  testsuites += Getopt.get_args(argv, 1)[1..]; +  if(!sizeof(testsuites))    { -  if(!tmp) -  { -  werror("No tests?\n"); +  werror("No tests found. Use --help for more information.\n");    exit(1);    } -  } +        while(loop--)    {    successes=errors=0; -  for(int f=1;f<sizeof(argv);f++) +  testloop: +  foreach(testsuites, string testsuite)    { -  tmp=read_bytes(argv[f]); -  if(!tmp) -  { -  werror("Failed to read test file %O, errno=%d.\n", -  argv[f], errno()); -  exit(1); -  } +  tests = read_tests( testsuite );    -  tests=tmp/"\n....\n"; -  tmp=0; -  tests=tests[0..sizeof(tests)-2]; -  -  werror("Doing tests in %s (%d tests)\n",argv[f],sizeof(tests)); +  werror("Doing tests in %s (%d tests)\n", testsuite, sizeof(tests));    int qmade, qskipped, qmadep, qskipp;       for(e=start;e<sizeof(tests);e++)
379:       if(check)    { -  if(check < 0) -  { -  if(!(e % -check)) +  if(check>0 || (e % -check)==0 )    _verify_internals(); -  }else{ -  _verify_internals(); +     } -  } +     if(check>3) {    gc();    _verify_internals();    }       test=tests[e]; -  if(sscanf(test,"COND %s\n%s",condition,test)==2) +  if( sscanf(test, "COND %s\n%s", condition, test)==2 )    {    int tmp;    if(!(tmp=cond_cache[condition]))    { -  mixed err; -  if (err = catch { +  mixed err = catch {    tmp=!!(compile_string("mixed c() { return "+condition+"; }",    "Cond "+(e+1))()->c()); -  }) { -  werror(sprintf("\nConditional %d failed:\n" -  "%s\n", -  e+1, describe_backtrace(err))); +  }; +  +  if(err) { +  werror( "\nConditional %d failed:\n" +  "%s\n", e+1, describe_backtrace(err) );    errors++;    tmp = -1;    } -  +     if(!tmp) tmp=-1;    cond_cache[condition]=tmp;    }
423:    }    }    -  +     if(istty())    {    if(!verbose)    werror("%6d\r",e+1); -  }else if(quiet){ +  } +  else if(quiet){    if(skip) {    if(qmade) werror(" Made %d test%s.\n", qmade, qmade==1?"":"s");    qmade=0;
441:    qmadep=1;    qmade++;    } -  }else{ +  } +  else {    /* Use + instead of . so that sendmail and    * cron will not cut us off... :(    */
468:    }    if(skip) continue;    +  sscanf(test, "%s\n%s", type, test); +  sscanf(type, "%*s expected result: %s", type);    -  sscanf(test,"%s\n%s",type,test); -  sscanf(type,"%*s expected result: %s",type); -  -  if(verbose) -  { +     if (prompt) {    if (Stdio.Readline()->    read(sprintf("About to run test: %d. [<RETURN>/'quit']: ",    e + 1)) == "quit") { -  f = 999999; -  break; +  break testloop;    }    } -  +  +  if(verbose) +  {    werror("Doing test %d (%d total)%s\n",e+1,successes+errors+1,extra_info);    if(verbose>1) bzot(test);    }
489:    if(check > 1) _verify_internals();       shift++; -  string fname = argv[f] + ": Test " + (e + 1) + +  string fname = testsuite + ": Test " + (e + 1) +    " (shift " + (shift%3) + ")";       string widener = ([ 0:"",
532:    to_compile=replace(to_compile,"\n","\r\n");    }    -  +     // _optimizer_debug(5);       if(verbose>9) bzot(to_compile);
548:    werror("\n" + fname + " failed.\n");    bzot(test);    errors++; -  }else{ +  } +  else {    _dmalloc_set_name();    successes++;    }
561:    {    _dmalloc_set_name();    successes++; -  }else{ +  } +  else {    _dmalloc_set_name();    werror("\n" + fname + " failed (expected compile error).\n");    bzot(test);
585:    successes++;    if(verbose>2)    werror("Time in a(): %f\n",at); -  }else{ +  } +  else {    _dmalloc_set_name();    werror("\n" + fname + " failed (expected eval error).\n");    bzot(test);
660:    bzot(test);    werror(sprintf("o->a(): %O\n",a));    errors++; -  }else{ +  } +  else {    successes++;    }    break;
672:    bzot(test);    werror(sprintf("o->a(): %O\n",a));    errors++; -  }else{ +  } +  else {    successes++;    }    break;
681:    successes++;    break;    +  case "RUNCT": +  if(!a || !arrayp(a) || sizeof(a)!=2 || !intp(a[0]) || !intp(a[1])) { +  werror("\n" + fname + " failed to return proper results.\n"); +  bzot(test); +  werror(sprintf("o->a(): %O\n",a)); +  errors++; +  } +  else { +  successes += a[0]; +  errors += a[1]; +  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); +  } +  break; +     case "EQ":    if(a!=b)    {
689:    werror(sprintf("o->a(): %O\n",a));    werror(sprintf("o->b(): %O\n",b));    errors++; -  }else{ +  } +  else {    successes++;    }    break;
702:    werror(sprintf("o->a(): %O\n",a));    werror(sprintf("o->b(): %O\n",b));    errors++; -  }else{ +  } +  else {    successes++;    }    break;
720:       if(successes+errors > end)    { -  f=sizeof(argv); -  break; +  break testloop;    }       a=b=0;
730:    if(istty())    {    werror(" \r"); -  }else if(quiet){ +  } +  else if(quiet) {    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{ +  } +  else {    werror("\n");    }    } -  +     if(mem)    {    int total;
758:    total+=tmp[foo+"_bytes"];    }    } -  write(sprintf("%-10s: %6s %10d\n", -  "Total", -  "", -  total)); +  write( "%-10s: %6s %10d\n", +  "Total", "", total );    }    }    if(errors || verbose)
792:       return errors;   } +  + constant doc = #" + Usage: test_pike [args] [testfiles] +  + --no-watchdog Watchdog will not be used. + --watchdog=pid Run only the watchdog and monitor the process with the given pid. + -h, --help Prints this message. + -v[level], + --verbose[=level] Select the level of verbosity. Every verbose level includes the +  printouts from the levels below. +  0 No extra printouts. +  1 Some extra information about test that will or won't be run. +  2 Every test is printed out. +  3 Time spent in individual tests are printed out. +  10 The actual pike code compiled, including wrappers, is printed. + -p, --prompt The user will be asked before every test is run. + -q, --quiet Less outputs than normal. + -sX, --start=X Where in the testsuite testing should start, e.g. ignores X tests +  in every testsuite. + -eX, --end=X How many tests should be run. + -f, --fail If set, the testsuite always fails. + -lX, --loop=X The number of times the testsuite should be run. Default is 1. + -tX, --trace=X Run tests with trace level X. + -c[X], --check[=X] The level of extra pike consistency checks performed. +  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. +  X<0 For values below zero, _verify_internals will be run before +  every n:th test, where n=abs(X). + -m, --mem, --memory Print out memory allocations after the tests. + -a, --auto Let the test program find the testsuits self. + -T, --notty Format output for non-tty. + -d, --debug Opens a debug port. + ";