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