Admin/mira.py
changeset 41542 a5478b1c8b8a
child 41554 6a515ace714b
equal deleted inserted replaced
41541:1fa4725c4656 41542:a5478b1c8b8a
       
     1 """
       
     2     Test configuration descriptions for mira.
       
     3 """
       
     4 
       
     5 import os
       
     6 from os import path
       
     7 from glob import glob
       
     8 import subprocess
       
     9 import re
       
    10 
       
    11 import util
       
    12 
       
    13 from mira.environment import configuration
       
    14 
       
    15 from repositories import *
       
    16 
       
    17 
       
    18 # build and evaluation tools
       
    19 
       
    20 def prepare_isabelle_repository(loc_isabelle, loc_contrib, loc_dependency_heaps, parallelism = True):
       
    21 
       
    22     loc_contrib = path.expanduser(loc_contrib)
       
    23     if not path.exists(loc_contrib):
       
    24         raise IOError('Bad file: %s' % loc_contrib)
       
    25     subprocess.check_call(['ln', '-s', loc_contrib, '%s/contrib' % loc_isabelle])
       
    26 
       
    27     contributed_components = path.join(loc_isabelle, 'Admin', 'contributed_components')
       
    28     if path.exists(contributed_components):
       
    29         components = []
       
    30         for component in util.readfile_lines(contributed_components):
       
    31             loc_component = path.join(loc_isabelle, component)
       
    32             if path.exists(loc_component):
       
    33                 components.append(loc_component)
       
    34         writer = open(path.join(loc_isabelle, 'etc', 'components'), 'a')
       
    35         for component in components:
       
    36             writer.write(component + '\n')
       
    37         writer.close()
       
    38 
       
    39     if loc_dependency_heaps:
       
    40         isabelle_path = loc_dependency_heaps + '/$ISABELLE_IDENTIFIER:$ISABELLE_OUTPUT'
       
    41     else:
       
    42         isabelle_path = '$ISABELLE_OUTPUT'
       
    43 
       
    44     if parallelism:
       
    45         parallelism_options = '-M max'
       
    46     else:
       
    47         parallelism_options = '-M 1 -q 0'
       
    48 
       
    49     extra_settings = '''
       
    50 ISABELLE_HOME_USER="$ISABELLE_HOME/home_user"
       
    51 ISABELLE_OUTPUT="$ISABELLE_HOME/heaps"
       
    52 ISABELLE_BROWSER_INFO="$ISABELLE_HOME/browser_info"
       
    53 ISABELLE_PATH="%s"
       
    54 
       
    55 ISABELLE_USEDIR_OPTIONS="$ISABELLE_USEDIR_OPTIONS %s -t true -v true -d pdf -g true -i true"
       
    56 ''' % (isabelle_path, parallelism_options)
       
    57 
       
    58     writer = open(path.join(loc_isabelle, 'etc', 'settings'), 'a')
       
    59     writer.write(extra_settings)
       
    60     writer.close()
       
    61 
       
    62 
       
    63 def extract_isabelle_run_timing(logdata):
       
    64 
       
    65     def to_secs(h, m, s):
       
    66         return (int(h) * 60 + int(m)) * 60 + int(s)
       
    67     pat = r'Finished (\S+) \((\d+):(\d+):(\d+) elapsed time, (\d+):(\d+):(\d+) cpu time'
       
    68     pat2 = r'Timing (\S+) \((\d+) threads, (\d+\.\d+)s elapsed time, (\d+\.\d+)s cpu time, (\d+\.\d+)s GC time\)'
       
    69     t = dict((name, {'elapsed': to_secs(eh,em,es), 'cpu': to_secs(ch,cm,cs)})
       
    70              for name, eh, em, es, ch, cm, cs in re.findall(pat, logdata))
       
    71     for name, threads, elapsed, cpu, gc in re.findall(pat2, logdata):
       
    72 
       
    73         if name not in t:
       
    74             t[name] = {}
       
    75 
       
    76         t[name]['threads'] = int(threads)
       
    77         t[name]['elapsed_inner'] = elapsed
       
    78         t[name]['cpu_inner'] = cpu
       
    79         t[name]['gc'] = gc
       
    80 
       
    81     return t
       
    82 
       
    83 
       
    84 def extract_isabelle_run_summary(logdata):
       
    85 
       
    86     re_error = re.compile(r'^\*\*\* (.*)$', re.MULTILINE)
       
    87     summary = '\n'.join(re_error.findall(logdata))
       
    88     if summary == '':
       
    89         summary = 'ok'
       
    90 
       
    91     return summary
       
    92 
       
    93 
       
    94 def isabelle_usedir(env, isa_path, isabelle_usedir_opts, base_image, dir_name):
       
    95 
       
    96     return env.run_process('%s/bin/isabelle' % isa_path, 'usedir',
       
    97         isabelle_usedir_opts, base_image, dir_name)
       
    98 
       
    99 
       
   100 def isabelle_dependency_only(env, case, paths, dep_paths, playground):
       
   101 
       
   102     p = paths[0]
       
   103     result = path.join(p, 'heaps')
       
   104     os.makedirs(result)
       
   105     for dep_path in dep_paths:
       
   106         subprocess.check_call(['cp', '-R'] + glob(dep_path + '/*') + [result])
       
   107 
       
   108     return (True, 'ok', {}, {}, result)
       
   109 
       
   110 
       
   111 def build_isabelle_image(subdir, base, img, env, case, paths, dep_paths, playground):
       
   112 
       
   113     p = paths[0]
       
   114     dep_path = dep_paths[0]
       
   115     prepare_isabelle_repository(p, env.settings.contrib, dep_path)
       
   116     os.chdir(path.join(p, 'src', subdir))
       
   117 
       
   118     (return_code, log) = isabelle_usedir(env, p, '-b', base, img)
       
   119 
       
   120     result = path.join(p, 'heaps')
       
   121     return (return_code == 0, extract_isabelle_run_summary(log),
       
   122       {'timing': extract_isabelle_run_timing(log)}, {'log': log}, result)
       
   123 
       
   124 
       
   125 def isabelle_makeall(env, case, paths, dep_paths, playground):
       
   126 
       
   127     p = paths[0]
       
   128     dep_path = dep_paths[0]
       
   129     prepare_isabelle_repository(p, env.settings.contrib, dep_path)
       
   130     os.chdir(p)
       
   131 
       
   132     (return_code, log) = env.run_process('%s/bin/isabelle' % p, 'makeall', '-k', 'all')
       
   133 
       
   134     return (return_code == 0, extract_isabelle_run_summary(log),
       
   135       {'timing': extract_isabelle_run_timing(log)}, {'log': log}, None)
       
   136 
       
   137 
       
   138 # Isabelle configurations
       
   139 
       
   140 @configuration(repos = [Isabelle], deps = [])
       
   141 def Pure(env, case, paths, dep_paths, playground):
       
   142     """Pure image"""
       
   143 
       
   144     p = paths[0]
       
   145     prepare_isabelle_repository(p, env.settings.contrib, '')
       
   146     os.chdir(path.join(p, 'src', 'Pure'))
       
   147 
       
   148     (return_code, log) = env.run_process('%s/bin/isabelle' % p, 'make', 'Pure')
       
   149 
       
   150     result = path.join(p, 'heaps')
       
   151     return (return_code == 0, extract_isabelle_run_summary(log),
       
   152       {'timing': extract_isabelle_run_timing(log)}, {'log': log}, result)
       
   153 
       
   154 @configuration(repos = [Isabelle], deps = [(Pure, [0])])
       
   155 def FOL(*args):
       
   156     """FOL image"""
       
   157     return build_isabelle_image('FOL', 'Pure', 'FOL', *args)
       
   158 
       
   159 @configuration(repos = [Isabelle], deps = [(Pure, [0])])
       
   160 def HOL(*args):
       
   161     """HOL image"""
       
   162     return build_isabelle_image('HOL', 'Pure', 'HOL', *args)
       
   163 
       
   164 @configuration(repos = [Isabelle], deps = [(HOL, [0])])
       
   165 def HOL_HOLCF(*args):
       
   166     """HOL-HOLCF image"""
       
   167     return build_isabelle_image('HOL/HOLCF', 'HOL', 'HOLCF', *args)
       
   168 
       
   169 @configuration(repos = [Isabelle], deps = [(HOL, [0])])
       
   170 def HOL_Nominal(*args):
       
   171     """HOL-Nominal image"""
       
   172     return build_isabelle_image('HOL/Nominal', 'HOL', 'HOL-Nominal', *args)
       
   173 
       
   174 @configuration(repos = [Isabelle], deps = [(HOL, [0])])
       
   175 def HOL_Word(*args):
       
   176     """HOL-Word image"""
       
   177     return build_isabelle_image('HOL/Word', 'HOL', 'HOL-Word', *args)
       
   178 
       
   179 @configuration(repos = [Isabelle], deps = [
       
   180     (HOL, [0]),
       
   181     (HOL_HOLCF, [0]),
       
   182     (HOL_Nominal, [0]),
       
   183     (HOL_Word, [0])
       
   184   ])
       
   185 def AFP_images(*args):
       
   186     """Isabelle images needed for the AFP"""
       
   187     return isabelle_dependency_only(*args)
       
   188 
       
   189 @configuration(repos = [Isabelle], deps = [
       
   190     (AFP_images, [0])
       
   191   ])
       
   192 def Isabelle_makeall(*args):
       
   193     """Isabelle makeall"""
       
   194     return isabelle_makeall(*args)
       
   195 
       
   196 
       
   197 # Mutabelle configurations
       
   198 
       
   199 def invoke_mutabelle(theory, env, case, paths, dep_paths, playground):
       
   200 
       
   201     """Mutant testing for counterexample generators in Isabelle"""
       
   202 
       
   203     (loc_isabelle,) = paths
       
   204     (dep_isabelle,) = dep_paths
       
   205     prepare_isabelle_repository(loc_isabelle, env.settings.contrib, dep_isabelle)
       
   206     os.chdir(loc_isabelle)
       
   207     
       
   208     (return_code, log) = env.run_process('bin/isabelle',
       
   209       'mutabelle', '-O', playground, theory)
       
   210     
       
   211     try:
       
   212         mutabelle_log = util.readfile(path.join(playground, 'log'))
       
   213     except IOError:
       
   214         mutabelle_log = ''
       
   215 
       
   216     attachments = { 'log': log, 'mutabelle_log': mutabelle_log}
       
   217 
       
   218     return (return_code == 0 and mutabelle_log != '', extract_isabelle_run_summary(log),
       
   219       {'timing': extract_isabelle_run_timing(log)}, {'log': log}, None)
       
   220 
       
   221 @configuration(repos = [Isabelle], deps = [(HOL, [0])])
       
   222 def Mutabelle_Relation(*args):
       
   223     """Mutabelle regression suite on Relation theory"""
       
   224     return invoke_mutabelle('Relation', *args)
       
   225 
       
   226 @configuration(repos = [Isabelle], deps = [(HOL, [0])])
       
   227 def Mutabelle_List(*args):
       
   228     """Mutabelle regression suite on List theory"""
       
   229     return invoke_mutabelle('List', *args)
       
   230 
       
   231 @configuration(repos = [Isabelle], deps = [(HOL, [0])])
       
   232 def Mutabelle_Set(*args):
       
   233     """Mutabelle regression suite on Set theory"""
       
   234     return invoke_mutabelle('Set', *args)
       
   235 
       
   236 @configuration(repos = [Isabelle], deps = [(HOL, [0])])
       
   237 def Mutabelle_Map(*args):
       
   238     """Mutabelle regression suite on Map theory"""
       
   239     return invoke_mutabelle('Map', *args)
       
   240 
       
   241 @configuration(repos = [Isabelle], deps = [(HOL, [0])])
       
   242 def Mutabelle_Divides(*args):
       
   243     """Mutabelle regression suite on Divides theory"""
       
   244     return invoke_mutabelle('Divides', *args)
       
   245 
       
   246 @configuration(repos = [Isabelle], deps = [(HOL, [0])])
       
   247 def Mutabelle_MacLaurin(*args):
       
   248     """Mutabelle regression suite on MacLaurin theory"""
       
   249     return invoke_mutabelle('MacLaurin', *args)
       
   250 
       
   251 @configuration(repos = [Isabelle], deps = [(HOL, [0])])
       
   252 def Mutabelle_Fun(*args):
       
   253     """Mutabelle regression suite on Fun theory"""
       
   254     return invoke_mutabelle('Fun', *args)