Advertisement
Guest User

Untitled

a guest
Oct 28th, 2016
285
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.70 KB | None | 0 0
  1. #!/usr/bin/python
  2. #
  3. # Utility to run outfoxed exercise
  4. #
  5. # Written for CS3214 Spring 2016 by G. Back (godmar@gmail.com)
  6. #
  7.  
  8. import re, os, sys, subprocess, operator, signal, resource, getopt
  9.  
  10. exe = "./outfoxed"
  11. debug_exe = "./outfoxed.debug"
  12. helgrind = ["valgrind", "--tool=helgrind", "--fair-sched=yes"]
  13.  
  14. ex_dir = os.path.dirname(os.path.realpath(__file__))
  15. driver_cfile = "%s/outfoxed-driver.c" % (ex_dir)
  16. sol_cfile = "outfoxed.c"
  17.  
  18. # number of tests
  19. NTEST = 100
  20. # number of CPUs on which to run tests, used round-robin
  21. cpus = [4, 8, 10, 20, 2]
  22.  
  23. try:
  24.     opts, args = getopt.getopt(sys.argv[1:], "fn:s:", ["force", "ntests"])
  25. except getopt.GetoptError, err:
  26.     print str(err)
  27.     sys.exit(2)
  28.  
  29. force = False
  30. for opt, arg in opts:
  31.     if opt == "-f":
  32.         force = True
  33.     if opt == "-n":
  34.         NTEST = int(arg)
  35.     if opt == "-s":
  36.         sol_cfile = arg
  37.  
  38. if len(args) < 1:
  39.     print "Usage: %s [-f] [-n <ntests>] [-s <solutionfile.c>] <gamecode>" % (sys.argv[0])
  40.     sys.exit()
  41.  
  42. code = int(args[0])
  43.  
  44. # from http://stackoverflow.com/questions/2281850/timeout-function-if-it-takes-too-long-to-finish
  45. from functools import wraps
  46. import errno, signal
  47.  
  48. class TimeoutError(Exception):
  49.     pass
  50.  
  51. def timeout(seconds=10, error_message=os.strerror(errno.ETIME)):
  52.     def decorator(func):
  53.         def _handle_timeout(signum, frame):
  54.             raise TimeoutError(error_message)
  55.  
  56.         def wrapper(*args, **kwargs):
  57.             signal.signal(signal.SIGALRM, _handle_timeout)
  58.             signal.alarm(seconds)
  59.             try:
  60.                 result = func(*args, **kwargs)
  61.             finally:
  62.                 signal.alarm(0)
  63.             return result
  64.  
  65.         return wraps(func)(wrapper)
  66.  
  67.     return decorator
  68.  
  69. if not os.access(sol_cfile, os.R_OK):
  70.     raise Exception(sol_cfile + " not found in the current directory. ")
  71.  
  72. print "Compiling..."
  73. compile_cmd = "gcc -I%s -pthread -std=gnu11 -O2 -Wall -Werror %s %s -o %s" % (ex_dir, sol_cfile, driver_cfile, exe)
  74.  
  75. if os.system(compile_cmd):
  76.     raise Exception("Compile failed, run\n\n%s\n\nto see why" % compile_cmd)
  77.  
  78. if not os.access(exe, os.X_OK):
  79.     raise Exception(exe + " did not build")
  80.  
  81. print "Ok."
  82.  
  83. # test scenarios (#threads, #tasks)
  84.  
  85. def check_one_run(sp, output):
  86.  
  87.     if sp.returncode < 0:
  88.         signames = dict((k, v) for v, k in signal.__dict__.iteritems() if v.startswith('SIG'))
  89.         signum = -sp.returncode
  90.         print "Program terminated with signal %d (%s)\n" % (signum, signames[signum])
  91.         lines = output.split("\n")
  92.         if len(lines) > 1:
  93.             print "Last line output was:"
  94.             print lines[-2]
  95.  
  96.         return False
  97.  
  98.     expected = r'^A chicken detective has caught the thief!  It was: \S+$'
  99.     lines = output.split("\n")
  100.  
  101.     if len(lines) != 53:
  102.         print "Program did not output the expected number of lines (53)"
  103.         print "Check that you do not have additional output to stdout."
  104.         print "Keep output to stderr to a minimum."
  105.         return False
  106.  
  107.     if not all(re.match(expected, line) for line in output.split("\n")[2:-1]):
  108.         print "Output did not match expected format."
  109.         return False
  110.  
  111.     return True
  112.  
  113. @timeout(seconds=3)
  114. def run_one(n):
  115.     """
  116.    Run once using CPU 0...n-1
  117.    """
  118.     cmd = ["taskset", "-c", ",".join(map(str, range(n))), exe, str(code)]
  119.     #print " ".join(cmd)
  120.     sp = subprocess.Popen(cmd, stdout=subprocess.PIPE)
  121.     output = sp.communicate()[0]
  122.  
  123.     return check_one_run(sp, output)
  124.  
  125. @timeout(seconds=20)
  126. def run_on_one_cpu():
  127.     """
  128.    Run on one CPU to check for busy-waiting.
  129.    """
  130.     print "I will now run your code on one CPU"
  131.     before = resource.getrusage(resource.RUSAGE_CHILDREN);
  132.     sp = subprocess.Popen(["taskset", "-c", "1", exe, str(code)], stdout=subprocess.PIPE)
  133.     output = sp.communicate()[0]
  134.     after = resource.getrusage(resource.RUSAGE_CHILDREN);
  135.  
  136.     if not check_one_run(sp, output):
  137.         return False
  138.  
  139.     cputimeused = after.ru_utime - before.ru_utime
  140.     print "Your program used %f seconds of CPU time when run on one CPU." % (cputimeused)
  141.     if cputimeused > 0.1:
  142.         print "It should not need more than a small fraction of a second."
  143.         print "Check that your program is not busy-waiting."
  144.         return False
  145.     else:
  146.         print "Good."
  147.         return True
  148.  
  149. if not run_on_one_cpu():
  150.     print "This will result in substantial deductions."
  151.     print "Run with -f to continue anyway."
  152.     if not force:
  153.         sys.exit(0)
  154.  
  155. successes = 0
  156. cpus = [4, 8, 10, 20, 2]
  157. for i in range(NTEST):
  158.     print ".",
  159.     sys.stdout.flush()
  160.     try:
  161.         if run_one(cpus[i%len(cpus)]):
  162.             successes += 1
  163.     except TimeoutError:
  164.         print >> sys.stderr, "Time-out"
  165.  
  166. print "done"
  167.  
  168. if successes == NTEST:
  169.     print "Congrats, your code ran successfully %d out of %d times." % (successes, NTEST)
  170.     sys.exit()
  171.  
  172. print "Your code ran successfully only %d out of %d times." % (successes, NTEST)
  173. print "Compiling debug version..."
  174. compile_cmd = "gcc -I%s -pthread -std=gnu11 -g -Wall -Werror %s %s -o %s" % (ex_dir, sol_cfile, driver_cfile, debug_exe)
  175.  
  176. if os.system(compile_cmd):
  177.     raise Exception("Compile failed, run\n\n%s\n\nto see why" % compile_cmd)
  178.  
  179. if not os.access(debug_exe, os.X_OK):
  180.     raise Exception(debug_exe + " did not build")
  181.  
  182. print "Ok."
  183. print "Checking for race conditions using helgrind"
  184.  
  185. cmd = helgrind + [debug_exe, str(code)]
  186. print "Running", " ".join(cmd), "...",
  187. sp = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  188. stderr = sp.communicate()[1]
  189. if not re.search("ERROR SUMMARY: 0 errors from 0 contexts", stderr):
  190.     raise Exception("Your program contains race conditions:\n" + stderr)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement