1#!/usr/bin/env python 2# Copyright (c) 2014 Google Inc. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6"""Tests for analyzer 7""" 8 9import json 10import TestGyp 11 12found = 'Found dependency' 13found_all = 'Found dependency (all)' 14not_found = 'No dependencies' 15 16 17def _CreateConfigFile(files, additional_compile_targets, test_targets=[]): 18 """Creates the analyzer config file, which is used as the input to analyzer. 19 See description of analyzer.py for description of the arguments.""" 20 f = open('test_file', 'w') 21 to_write = {'files': files, 22 'test_targets': test_targets, 23 'additional_compile_targets': additional_compile_targets } 24 json.dump(to_write, f) 25 f.close() 26 27 28def _CreateBogusConfigFile(): 29 f = open('test_file','w') 30 f.write('bogus') 31 f.close() 32 33 34def _ReadOutputFileContents(): 35 f = open('analyzer_output', 'r') 36 result = json.load(f) 37 f.close() 38 return result 39 40 41# NOTE: this would be clearer if it subclassed TestGypCustom, but that trips 42# over a bug in pylint (E1002). 43test = TestGyp.TestGypCustom(format='analyzer') 44 45def CommonArgs(): 46 return ('-Gconfig_path=test_file', 47 '-Ganalyzer_output_path=analyzer_output') 48 49 50def run_analyzer(*args, **kw): 51 """Runs the test specifying a particular config and output path.""" 52 args += CommonArgs() 53 test.run_gyp('test.gyp', *args, **kw) 54 55 56def run_analyzer2(*args, **kw): 57 """Same as run_analyzer(), but passes in test2.gyp instead of test.gyp.""" 58 args += CommonArgs() 59 test.run_gyp('test2.gyp', *args, **kw) 60 61 62def run_analyzer3(*args, **kw): 63 """Same as run_analyzer(), but passes in test3.gyp instead of test.gyp.""" 64 args += CommonArgs() 65 test.run_gyp('test3.gyp', *args, **kw) 66 67 68def run_analyzer4(*args, **kw): 69 """Same as run_analyzer(), but passes in test3.gyp instead of test.gyp.""" 70 args += CommonArgs() 71 test.run_gyp('test4.gyp', *args, **kw) 72 73 74def EnsureContains(matched=False, compile_targets=set(), test_targets=set()): 75 """Verifies output contains |compile_targets|.""" 76 result = _ReadOutputFileContents() 77 if 'error' in result: 78 print 'unexpected error', result.get('error') 79 test.fail_test() 80 81 if 'invalid_targets' in result: 82 print 'unexpected invalid_targets', result.get('invalid_targets') 83 test.fail_test() 84 85 actual_compile_targets = set(result['compile_targets']) 86 if actual_compile_targets != compile_targets: 87 print 'actual compile_targets:', actual_compile_targets, \ 88 '\nexpected compile_targets:', compile_targets 89 test.fail_test() 90 91 actual_test_targets = set(result['test_targets']) 92 if actual_test_targets != test_targets: 93 print 'actual test_targets:', actual_test_targets, \ 94 '\nexpected test_targets:', test_targets 95 test.fail_test() 96 97 if matched and result['status'] != found: 98 print 'expected', found, 'got', result['status'] 99 test.fail_test() 100 elif not matched and result['status'] != not_found: 101 print 'expected', not_found, 'got', result['status'] 102 test.fail_test() 103 104 105def EnsureMatchedAll(compile_targets, test_targets=set()): 106 result = _ReadOutputFileContents() 107 if 'error' in result: 108 print 'unexpected error', result.get('error') 109 test.fail_test() 110 111 if 'invalid_targets' in result: 112 print 'unexpected invalid_targets', result.get('invalid_targets') 113 test.fail_test() 114 115 if result['status'] != found_all: 116 print 'expected', found_all, 'got', result['status'] 117 test.fail_test() 118 119 actual_compile_targets = set(result['compile_targets']) 120 if actual_compile_targets != compile_targets: 121 print ('actual compile_targets:', actual_compile_targets, 122 '\nexpected compile_targets:', compile_targets) 123 test.fail_test() 124 125 actual_test_targets = set(result['test_targets']) 126 if actual_test_targets != test_targets: 127 print ('actual test_targets:', actual_test_targets, 128 '\nexpected test_targets:', test_targets) 129 test.fail_test() 130 131 132def EnsureError(expected_error_string): 133 """Verifies output contains the error string.""" 134 result = _ReadOutputFileContents() 135 if result.get('error', '').find(expected_error_string) == -1: 136 print 'actual error:', result.get('error', ''), '\nexpected error:', \ 137 expected_error_string 138 test.fail_test() 139 140 141def EnsureStdoutContains(expected_error_string): 142 if test.stdout().find(expected_error_string) == -1: 143 print 'actual stdout:', test.stdout(), '\nexpected stdout:', \ 144 expected_error_string 145 test.fail_test() 146 147 148def EnsureInvalidTargets(expected_invalid_targets): 149 """Verifies output contains invalid_targets.""" 150 result = _ReadOutputFileContents() 151 actual_invalid_targets = set(result['invalid_targets']) 152 if actual_invalid_targets != expected_invalid_targets: 153 print 'actual invalid_targets:', actual_invalid_targets, \ 154 '\nexpected :', expected_invalid_targets 155 test.fail_test() 156 157 158# Two targets, A and B (both static_libraries) and A depends upon B. If a file 159# in B changes, then both A and B are output. It is not strictly necessary that 160# A is compiled in this case, only B. 161_CreateConfigFile(['b.c'], ['all']) 162test.run_gyp('static_library_test.gyp', *CommonArgs()) 163EnsureContains(matched=True, compile_targets={'a' ,'b'}) 164 165# Verifies config_path must be specified. 166test.run_gyp('test.gyp') 167EnsureStdoutContains('Must specify files to analyze via config_path') 168 169# Verifies config_path must point to a valid file. 170test.run_gyp('test.gyp', '-Gconfig_path=bogus_file', 171 '-Ganalyzer_output_path=analyzer_output') 172EnsureError('Unable to open file bogus_file') 173 174# Verify 'invalid_targets' is present when bad target is specified. 175_CreateConfigFile(['exe2.c'], ['bad_target']) 176run_analyzer() 177EnsureInvalidTargets({'bad_target'}) 178 179# Verifies config_path must point to a valid json file. 180_CreateBogusConfigFile() 181run_analyzer() 182EnsureError('Unable to parse config file test_file') 183 184# Trivial test of a source. 185_CreateConfigFile(['foo.c'], ['all']) 186run_analyzer() 187EnsureContains(matched=True, compile_targets={'exe'}) 188 189# Conditional source that is excluded. 190_CreateConfigFile(['conditional_source.c'], ['all']) 191run_analyzer() 192EnsureContains(matched=False) 193 194# Conditional source that is included by way of argument. 195_CreateConfigFile(['conditional_source.c'], ['all']) 196run_analyzer('-Dtest_variable=1') 197EnsureContains(matched=True, compile_targets={'exe'}) 198 199# Two unknown files. 200_CreateConfigFile(['unknown1.c', 'unoknow2.cc'], ['all']) 201run_analyzer() 202EnsureContains() 203 204# Two unknown files. 205_CreateConfigFile(['unknown1.c', 'subdir/subdir_sourcex.c'], ['all']) 206run_analyzer() 207EnsureContains() 208 209# Included dependency 210_CreateConfigFile(['unknown1.c', 'subdir/subdir_source.c'], ['all']) 211run_analyzer() 212EnsureContains(matched=True, compile_targets={'exe', 'exe3'}) 213 214# Included inputs to actions. 215_CreateConfigFile(['action_input.c'], ['all']) 216run_analyzer() 217EnsureContains(matched=True, compile_targets={'exe'}) 218 219# Don't consider outputs. 220_CreateConfigFile(['action_output.c'], ['all']) 221run_analyzer() 222EnsureContains(matched=False) 223 224# Rule inputs. 225_CreateConfigFile(['rule_input.c'], ['all']) 226run_analyzer() 227EnsureContains(matched=True, compile_targets={'exe'}) 228 229# Ignore path specified with PRODUCT_DIR. 230_CreateConfigFile(['product_dir_input.c'], ['all']) 231run_analyzer() 232EnsureContains(matched=False) 233 234# Path specified via a variable. 235_CreateConfigFile(['subdir/subdir_source2.c'], ['all']) 236run_analyzer() 237EnsureContains(matched=True, compile_targets={'exe'}) 238 239# Verifies paths with // are fixed up correctly. 240_CreateConfigFile(['parent_source.c'], ['all']) 241run_analyzer() 242EnsureContains(matched=True, compile_targets={'exe', 'exe3'}) 243 244# Verifies relative paths are resolved correctly. 245_CreateConfigFile(['subdir/subdir_source.h'], ['all']) 246run_analyzer() 247EnsureContains(matched=True, compile_targets={'exe'}) 248 249# Verifies relative paths in inputs are resolved correctly. 250_CreateConfigFile(['rel_path1.h'], ['all']) 251run_analyzer() 252EnsureContains(matched=True, compile_targets={'exe'}) 253 254# Various permutations when passing in targets. 255_CreateConfigFile(['exe2.c', 'subdir/subdir2b_source.c'], 256 ['all'], ['exe', 'exe3']) 257run_analyzer() 258EnsureContains(matched=True, test_targets={'exe3'}, 259 compile_targets={'exe2', 'exe3'}) 260 261_CreateConfigFile(['exe2.c', 'subdir/subdir2b_source.c'], ['all'], ['exe']) 262run_analyzer() 263EnsureContains(matched=True, compile_targets={'exe2', 'exe3'}) 264 265# Verifies duplicates are ignored. 266_CreateConfigFile(['exe2.c', 'subdir/subdir2b_source.c'], ['all'], 267 ['exe', 'exe']) 268run_analyzer() 269EnsureContains(matched=True, compile_targets={'exe2', 'exe3'}) 270 271_CreateConfigFile(['exe2.c'], ['all'], ['exe']) 272run_analyzer() 273EnsureContains(matched=True, compile_targets={'exe2'}) 274 275_CreateConfigFile(['exe2.c'], ['all']) 276run_analyzer() 277EnsureContains(matched=True, compile_targets={'exe2'}) 278 279_CreateConfigFile(['subdir/subdir2b_source.c', 'exe2.c'], ['all']) 280run_analyzer() 281EnsureContains(matched=True, compile_targets={'exe2', 'exe3'}) 282 283_CreateConfigFile(['subdir/subdir2b_source.c'], ['all'], ['exe3']) 284run_analyzer() 285EnsureContains(matched=True, test_targets={'exe3'}, compile_targets={'exe3'}) 286 287_CreateConfigFile(['exe2.c'], ['all']) 288run_analyzer() 289EnsureContains(matched=True, compile_targets={'exe2'}) 290 291_CreateConfigFile(['foo.c'], ['all']) 292run_analyzer() 293EnsureContains(matched=True, compile_targets={'exe'}) 294 295# Assertions when modifying build (gyp/gypi) files, especially when said files 296# are included. 297_CreateConfigFile(['subdir2/d.cc'], ['all'], ['exe', 'exe2', 'foo', 'exe3']) 298run_analyzer2() 299EnsureContains(matched=True, test_targets={'exe', 'foo'}, 300 compile_targets={'exe', 'foo'}) 301 302_CreateConfigFile(['subdir2/subdir.includes.gypi'], ['all'], 303 ['exe', 'exe2', 'foo', 'exe3']) 304run_analyzer2() 305EnsureContains(matched=True, test_targets={'exe', 'foo'}, 306 compile_targets={'exe', 'foo'}) 307 308_CreateConfigFile(['subdir2/subdir.gyp'], ['all'], 309 ['exe', 'exe2', 'foo', 'exe3']) 310run_analyzer2() 311EnsureContains(matched=True, test_targets={'exe', 'foo'}, 312 compile_targets={'exe', 'foo'}) 313 314_CreateConfigFile(['test2.includes.gypi'], ['all'], 315 ['exe', 'exe2', 'foo', 'exe3']) 316run_analyzer2() 317EnsureContains(matched=True, test_targets={'exe', 'exe2', 'exe3'}, 318 compile_targets={'exe', 'exe2', 'exe3'}) 319 320# Verify modifying a file included makes all targets dirty. 321_CreateConfigFile(['common.gypi'], ['all'], ['exe', 'exe2', 'foo', 'exe3']) 322run_analyzer2('-Icommon.gypi') 323EnsureMatchedAll({'all', 'exe', 'exe2', 'foo', 'exe3'}, 324 {'exe', 'exe2', 'foo', 'exe3'}) 325 326# Assertions from test3.gyp. 327_CreateConfigFile(['d.c', 'f.c'], ['all'], ['a']) 328run_analyzer3() 329EnsureContains(matched=True, test_targets={'a'}, compile_targets={'a', 'b'}) 330 331_CreateConfigFile(['f.c'], ['all'], ['a']) 332run_analyzer3() 333EnsureContains(matched=True, test_targets={'a'}, compile_targets={'a', 'b'}) 334 335_CreateConfigFile(['f.c'], ['all']) 336run_analyzer3() 337EnsureContains(matched=True, compile_targets={'a', 'b'}) 338 339_CreateConfigFile(['c.c', 'e.c'], ['all']) 340run_analyzer3() 341EnsureContains(matched=True, compile_targets={'a', 'b', 'c', 'e'}) 342 343_CreateConfigFile(['d.c'], ['all'], ['a']) 344run_analyzer3() 345EnsureContains(matched=True, test_targets={'a'}, compile_targets={'a', 'b'}) 346 347_CreateConfigFile(['a.c'], ['all'], ['a', 'b']) 348run_analyzer3() 349EnsureContains(matched=True, test_targets={'a'}, compile_targets={'a'}) 350 351_CreateConfigFile(['a.c'], ['all'], ['a', 'b']) 352run_analyzer3() 353EnsureContains(matched=True, test_targets={'a'}, compile_targets={'a'}) 354 355_CreateConfigFile(['d.c'], ['all'], ['a', 'b']) 356run_analyzer3() 357EnsureContains(matched=True, test_targets={'a', 'b'}, 358 compile_targets={'a', 'b'}) 359 360_CreateConfigFile(['f.c'], ['all'], ['a']) 361run_analyzer3() 362EnsureContains(matched=True, test_targets={'a'}, compile_targets={'a', 'b'}) 363 364_CreateConfigFile(['a.c'], ['all'], ['a']) 365run_analyzer3() 366EnsureContains(matched=True, test_targets={'a'}, compile_targets={'a'}) 367 368_CreateConfigFile(['a.c'], ['all']) 369run_analyzer3() 370EnsureContains(matched=True, compile_targets={'a'}) 371 372_CreateConfigFile(['d.c'], ['all']) 373run_analyzer3() 374EnsureContains(matched=True, compile_targets={'a', 'b'}) 375 376# Assertions around test4.gyp. 377_CreateConfigFile(['f.c'], ['all']) 378run_analyzer4() 379EnsureContains(matched=True, compile_targets={'e', 'f'}) 380 381_CreateConfigFile(['d.c'], ['all']) 382run_analyzer4() 383EnsureContains(matched=True, compile_targets={'a', 'b', 'c', 'd'}) 384 385_CreateConfigFile(['i.c'], ['all']) 386run_analyzer4() 387EnsureContains(matched=True, compile_targets={'h', 'i'}) 388 389# Assertions where 'all' is not supplied in compile_targets. 390 391_CreateConfigFile(['exe2.c'], [], ['exe2']) 392run_analyzer() 393EnsureContains(matched=True, test_targets={'exe2'}, compile_targets={'exe2'}) 394 395_CreateConfigFile(['exe20.c'], [], ['exe2']) 396run_analyzer() 397EnsureContains(matched=False) 398 399 400_CreateConfigFile(['exe2.c', 'exe3.c'], [], ['exe2', 'exe3']) 401run_analyzer() 402EnsureContains(matched=True, test_targets={'exe2', 'exe3'}, 403 compile_targets={'exe2', 'exe3'}) 404 405_CreateConfigFile(['exe2.c', 'exe3.c'], ['exe3'], ['exe2']) 406run_analyzer() 407EnsureContains(matched=True, test_targets={'exe2'}, 408 compile_targets={'exe2', 'exe3'}) 409 410_CreateConfigFile(['exe3.c'], ['exe2'], ['exe2']) 411run_analyzer() 412EnsureContains(matched=False) 413 414# Assertions with 'all' listed as a test_target. 415_CreateConfigFile(['exe3.c'], [], ['all']) 416run_analyzer() 417EnsureContains(matched=True, compile_targets={'exe3', 'all'}, 418 test_targets={'all'}) 419 420_CreateConfigFile(['exe2.c'], [], ['all', 'exe2']) 421run_analyzer() 422EnsureContains(matched=True, compile_targets={'exe2', 'all'}, 423 test_targets={'all', 'exe2'}) 424 425test.pass_test() 426