Home | History | Annotate | Download | only in site_scons
      1 import subprocess
      2 import sys
      3 import re
      4 
      5 try:
      6     # Make terminal colors work on windows
      7     import colorama
      8     colorama.init()
      9 except ImportError:
     10     pass
     11 
     12 def add_nanopb_builders(env):
     13     '''Add the necessary builder commands for nanopb tests.'''
     14 
     15     # Build command that runs a test program and saves the output
     16     def run_test(target, source, env):
     17         if len(source) > 1:
     18             infile = open(str(source[1]))
     19         else:
     20             infile = None
     21         
     22         if env.has_key("COMMAND"):
     23             args = [env["COMMAND"]]
     24         else:
     25             args = [str(source[0])]
     26         
     27         if env.has_key('ARGS'):
     28             args.extend(env['ARGS'])
     29         
     30         print 'Command line: ' + str(args)
     31         pipe = subprocess.Popen(args,
     32                                 stdin = infile,
     33                                 stdout = open(str(target[0]), 'w'),
     34                                 stderr = sys.stderr)
     35         result = pipe.wait()
     36         if result == 0:
     37             print '\033[32m[ OK ]\033[0m   Ran ' + args[0]
     38         else:
     39             print '\033[31m[FAIL]\033[0m   Program ' + args[0] + ' returned ' + str(result)
     40         return result
     41         
     42     run_test_builder = Builder(action = run_test,
     43                                suffix = '.output')
     44     env.Append(BUILDERS = {'RunTest': run_test_builder})
     45 
     46     # Build command that decodes a message using protoc
     47     def decode_actions(source, target, env, for_signature):
     48         esc = env['ESCAPE']
     49         dirs = ' '.join(['-I' + esc(env.GetBuildPath(d)) for d in env['PROTOCPATH']])
     50         return '$PROTOC $PROTOCFLAGS %s --decode=%s %s <%s >%s' % (
     51             dirs, env['MESSAGE'], esc(str(source[1])), esc(str(source[0])), esc(str(target[0])))
     52 
     53     decode_builder = Builder(generator = decode_actions,
     54                              suffix = '.decoded')
     55     env.Append(BUILDERS = {'Decode': decode_builder})    
     56 
     57     # Build command that encodes a message using protoc
     58     def encode_actions(source, target, env, for_signature):
     59         esc = env['ESCAPE']
     60         dirs = ' '.join(['-I' + esc(env.GetBuildPath(d)) for d in env['PROTOCPATH']])
     61         return '$PROTOC $PROTOCFLAGS %s --encode=%s %s <%s >%s' % (
     62             dirs, env['MESSAGE'], esc(str(source[1])), esc(str(source[0])), esc(str(target[0])))
     63 
     64     encode_builder = Builder(generator = encode_actions,
     65                              suffix = '.encoded')
     66     env.Append(BUILDERS = {'Encode': encode_builder})    
     67 
     68     # Build command that asserts that two files be equal
     69     def compare_files(target, source, env):
     70         data1 = open(str(source[0]), 'rb').read()
     71         data2 = open(str(source[1]), 'rb').read()
     72         if data1 == data2:
     73             print '\033[32m[ OK ]\033[0m   Files equal: ' + str(source[0]) + ' and ' + str(source[1])
     74             return 0
     75         else:
     76             print '\033[31m[FAIL]\033[0m   Files differ: ' + str(source[0]) + ' and ' + str(source[1])
     77             return 1
     78 
     79     compare_builder = Builder(action = compare_files,
     80                               suffix = '.equal')
     81     env.Append(BUILDERS = {'Compare': compare_builder})
     82 
     83     # Build command that checks that each pattern in source2 is found in source1.
     84     def match_files(target, source, env):
     85         data = open(str(source[0]), 'rU').read()
     86         patterns = open(str(source[1]))
     87         for pattern in patterns:
     88             if pattern.strip() and not re.search(pattern.strip(), data, re.MULTILINE):
     89                 print '\033[31m[FAIL]\033[0m   Pattern not found in ' + str(source[0]) + ': ' + pattern
     90                 return 1
     91         else:
     92             print '\033[32m[ OK ]\033[0m   All patterns found in ' + str(source[0])
     93             return 0
     94 
     95     match_builder = Builder(action = match_files, suffix = '.matched')
     96     env.Append(BUILDERS = {'Match': match_builder})
     97     
     98 
     99