From 21c3f19f66c4609d5fd7ac557152539edbb9a84f Mon Sep 17 00:00:00 2001 From: ccremers Date: Fri, 4 Mar 2005 15:34:41 +0000 Subject: [PATCH] - Split cache again out of test program. --- test/scyther.py | 132 +--------------------------------------- test/scythercache.py | 140 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 143 insertions(+), 129 deletions(-) create mode 100755 test/scythercache.py diff --git a/test/scyther.py b/test/scyther.py index 8c3050c..8e3d6de 100755 --- a/test/scyther.py +++ b/test/scyther.py @@ -1,138 +1,12 @@ #!/usr/bin/python # -# Scyther caching mechanism +# Scyther wrapper # -# Uses md5 hashes to store previously calculated results. +# Standard tests # -# (c)2005 Cas Cremers -# -# -# TODO: -# -# - Maybe it is an idea to time the output. If Scyther takes less -# than a second, we don't need to cache the output. That would -# reduce the required cache size significantly. -# If so, we only need to create directories for the cached files -# we actually create. -# - -import md5 -import commands -import os import sys -import time -from tempfile import NamedTemporaryFile, gettempdir from optparse import OptionParser - -#---------------------------------------------------------------------------- -# Global definitions -#---------------------------------------------------------------------------- - -# Minimum duration for something to get into the cache -CacheTimer = 0.1 - -#---------------------------------------------------------------------------- -# How to call Scyther -#---------------------------------------------------------------------------- - -# scyther should reside in $PATH -def scythercall (argumentstring, inputfile): - clstring = "scyther " + argumentstring + " " + inputfile - (status,scout) = commands.getstatusoutput(clstring) - return (status,scout) - -#---------------------------------------------------------------------------- -# Cached evaluation -#---------------------------------------------------------------------------- - -# cached results -# input: a large string (consisting of read input files) -# argstring: a smaller string -def evaluate (argumentstring, inputstring): - - def cacheid(): - m = md5.new() - - # # Determine scyther version - # (status, scout) = scythercall ("--version", "") - # if status == 1 or status < 0: - # # some problem - # print "Problem with determining scyther version!" - # os.exit() - # # Add version to hash - # m.update (scout) - - # Add inputfile to hash - m.update (inputstring) - - # Add arguments to hash - m.update (argumentstring) - - # Return a readable ID (good for a filename) - return m.hexdigest() - - # slashcutter - # Takes 'str': cuts of the first 'depth' strings of length - # 'width' and puts 'substr' in between - def slashcutter(str,substr,width,depth): - res = "" - while len(str)>width and depth>0: - res = res + str[0:width] + substr - str = str[width:] - depth = depth-1 - return res + str - - # Determine name - def cachefilename(id): - fn = gettempdir() + "/scyther/" - fn = fn + slashcutter(id,"/",3,2) - fn = fn + ".txt" - return fn - - # Ensure directory - def ensureDirectory (path): - if not os.path.exists(path): - os.mkdir(path) - - # Ensure directories for a file - def ensureDirectories (filename): - for i in range(1,len(filename)): - if filename[i] == '/': - np = i+1 - ensureDirectory(filename[:np]) - - # Determine the unique filename for this test - cachefile = cachefilename(cacheid()) - - # Does it already exist? - if os.path.exists(cachefile): - # Great: return the cached results - f = open(cachefile,'r') - res = f.read() - f.close() - # TODO technically, we should store the status in the - # cache file as well. For now, we just return 0 status. - return (0,res) - else: - # Hmm, we need to compute this result - # Compute duration (in seconds) - h = NamedTemporaryFile() - h.write(inputstring) - h.flush() - starttime = time.time() - (status, scout) = scythercall (argumentstring, h.name) - duration = time.time() - starttime - h.close() - - # Only cache if it took some time - if duration >= CacheTimer: - # Write cache file even if it's wrong - ensureDirectories(cachefile) - f = open(cachefile,'w') - f.write(scout) - f.close() - - return (status,scout) +from scythercache import evaluate #---------------------------------------------------------------------------- # Parsing Output diff --git a/test/scythercache.py b/test/scythercache.py new file mode 100755 index 0000000..0abd713 --- /dev/null +++ b/test/scythercache.py @@ -0,0 +1,140 @@ +#!/usr/bin/python +# +# Scyther caching mechanism +# +# Uses md5 hashes to store previously calculated results. +# +# (c)2005 Cas Cremers +# +# + +import md5 +import commands +import os +import sys +import time +from tempfile import NamedTemporaryFile, gettempdir + +#---------------------------------------------------------------------------- +# Global definitions +#---------------------------------------------------------------------------- + +# Minimum duration for a test to get into the cache (in seconds) +CacheTimer = 0.1 + +#---------------------------------------------------------------------------- +# How to call Scyther +#---------------------------------------------------------------------------- + +# scyther should reside in $PATH +def scythercall (argumentstring, inputfile): + clstring = "scyther " + argumentstring + " " + inputfile + (status,scout) = commands.getstatusoutput(clstring) + return (status,scout) + +#---------------------------------------------------------------------------- +# Cached evaluation +#---------------------------------------------------------------------------- + +# cached results +# input: a large string (consisting of read input files) +# argstring: a smaller string +def evaluate (argumentstring, inputstring): + + def cacheid(): + m = md5.new() + + # # Determine scyther version + # (status, scout) = scythercall ("--version", "") + # if status == 1 or status < 0: + # # some problem + # print "Problem with determining scyther version!" + # os.exit() + # # Add version to hash + # m.update (scout) + + # Add inputfile to hash + m.update (inputstring) + + # Add arguments to hash + m.update (argumentstring) + + # Return a readable ID (good for a filename) + return m.hexdigest() + + # slashcutter + # Takes 'str': cuts of the first 'depth' strings of length + # 'width' and puts 'substr' in between + def slashcutter(str,substr,width,depth): + res = "" + while len(str)>width and depth>0: + res = res + str[0:width] + substr + str = str[width:] + depth = depth-1 + return res + str + + # Determine name + def cachefilename(id): + fn = gettempdir() + "/scyther/" + fn = fn + slashcutter(id,"/",3,2) + fn = fn + ".txt" + return fn + + # Ensure directory + def ensureDirectory (path): + if not os.path.exists(path): + os.mkdir(path) + + # Ensure directories for a file + def ensureDirectories (filename): + for i in range(1,len(filename)): + if filename[i] == '/': + np = i+1 + ensureDirectory(filename[:np]) + + def compute_and_cache(cachefile): + # Hmm, we need to compute this result + # Compute duration (in seconds) + h = NamedTemporaryFile() + h.write(inputstring) + h.flush() + starttime = time.time() + (status, scout) = scythercall (argumentstring, h.name) + duration = time.time() - starttime + h.close() + + # Only cache if it took some time + if duration >= CacheTimer: + # Write cache file even if it's wrong + ensureDirectories(cachefile) + f = open(cachefile,'w') + f.write(scout) + f.close() + + return (status,scout) + + def retrieve_from_cache(file): + f = open(file,'r') + res = f.read() + f.close() + # TODO technically, we should store the status in the + # cache file as well. For now, we just return 0 status. + return (0,res) + + # Determine the unique filename for this test + cachefile = cachefilename(cacheid()) + if os.path.exists(cachefile): + return retrieve_from_cache(cachefile) + else: + return compute_and_cache(cachefile) + +#---------------------------------------------------------------------------- +# Standalone usage +#---------------------------------------------------------------------------- + +def main(): + print "This module has currently no standalone functionality." + +# Only if main stuff +if __name__ == '__main__': + main()