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, targets): 18 """Creates the analyzer conflig 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, 'targets': targets } 22 json.dump(to_write, f) 23 f.close() 24 25 26def _CreateBogusConfigFile(): 27 f = open('test_file','w') 28 f.write('bogus') 29 f.close() 30 31 32def _ReadOutputFileContents(): 33 f = open('analyzer_output', 'r') 34 result = json.load(f) 35 f.close() 36 return result 37 38 39# NOTE: this would be clearer if it subclassed TestGypCustom, but that trips 40# over a bug in pylint (E1002). 41test = TestGyp.TestGypCustom(format='analyzer') 42 43def CommonArgs(): 44 return ('-Gconfig_path=test_file', 45 '-Ganalyzer_output_path=analyzer_output') 46 47 48def run_analyzer(*args, **kw): 49 """Runs the test specifying a particular config and output path.""" 50 args += CommonArgs() 51 test.run_gyp('test.gyp', *args, **kw) 52 53 54def run_analyzer2(*args, **kw): 55 """Same as run_analyzer(), but passes in test2.gyp instead of test.gyp.""" 56 args += CommonArgs() 57 test.run_gyp('test2.gyp', *args, **kw) 58 59 60def run_analyzer3(*args, **kw): 61 """Same as run_analyzer(), but passes in test3.gyp instead of test.gyp.""" 62 args += CommonArgs() 63 test.run_gyp('test3.gyp', *args, **kw) 64 65 66def run_analyzer4(*args, **kw): 67 """Same as run_analyzer(), but passes in test3.gyp instead of test.gyp.""" 68 args += CommonArgs() 69 test.run_gyp('test4.gyp', *args, **kw) 70 71 72def EnsureContains(targets=set(), matched=False, build_targets=set()): 73 """Verifies output contains |targets|.""" 74 result = _ReadOutputFileContents() 75 if result.get('error', None): 76 print 'unexpected error', result.get('error') 77 test.fail_test() 78 79 if result.get('warning', None): 80 print 'unexpected warning', result.get('warning') 81 test.fail_test() 82 83 actual_targets = set(result['targets']) 84 if actual_targets != targets: 85 print 'actual targets:', actual_targets, '\nexpected targets:', targets 86 test.fail_test() 87 88 actual_build_targets = set(result['build_targets']) 89 if actual_build_targets != build_targets: 90 print 'actual build_targets:', actual_build_targets, \ 91 '\nexpected build_targets:', build_targets 92 test.fail_test() 93 94 if matched and result['status'] != found: 95 print 'expected', found, 'got', result['status'] 96 test.fail_test() 97 elif not matched and result['status'] != not_found: 98 print 'expected', not_found, 'got', result['status'] 99 test.fail_test() 100 101 102def EnsureMatchedAll(targets): 103 result = _ReadOutputFileContents() 104 if result.get('error', None): 105 print 'unexpected error', result.get('error') 106 test.fail_test() 107 108 if result.get('warning', None): 109 print 'unexpected warning', result.get('warning') 110 test.fail_test() 111 112 if result['status'] != found_all: 113 print 'expected', found_all, 'got', result['status'] 114 test.fail_test() 115 116 actual_targets = set(result['targets']) 117 if actual_targets != targets: 118 print 'actual targets:', actual_targets, '\nexpected targets:', targets 119 test.fail_test() 120 121 122def EnsureError(expected_error_string): 123 """Verifies output contains the error string.""" 124 result = _ReadOutputFileContents() 125 if result.get('error', '').find(expected_error_string) == -1: 126 print 'actual error:', result.get('error', ''), '\nexpected error:', \ 127 expected_error_string 128 test.fail_test() 129 130 131def EnsureStdoutContains(expected_error_string): 132 if test.stdout().find(expected_error_string) == -1: 133 print 'actual stdout:', test.stdout(), '\nexpected stdout:', \ 134 expected_error_string 135 test.fail_test() 136 137 138def EnsureWarning(expected_warning_string): 139 """Verifies output contains the warning string.""" 140 result = _ReadOutputFileContents() 141 if result.get('warning', '').find(expected_warning_string) == -1: 142 print 'actual warning:', result.get('warning', ''), \ 143 '\nexpected warning:', expected_warning_string 144 test.fail_test() 145 146# Verifies config_path must be specified. 147test.run_gyp('test.gyp') 148EnsureStdoutContains('Must specify files to analyze via config_path') 149 150# Verifies config_path must point to a valid file. 151test.run_gyp('test.gyp', '-Gconfig_path=bogus_file', 152 '-Ganalyzer_output_path=analyzer_output') 153EnsureError('Unable to open file bogus_file') 154 155# Verify get warning when bad target is specified. 156_CreateConfigFile(['exe2.c'], ['bad_target']) 157run_analyzer() 158EnsureWarning('Unable to find all targets') 159 160# Verifies config_path must point to a valid json file. 161_CreateBogusConfigFile() 162run_analyzer() 163EnsureError('Unable to parse config file test_file') 164 165# Trivial test of a source. 166_CreateConfigFile(['foo.c'], []) 167run_analyzer() 168EnsureContains(matched=True, build_targets={'exe'}) 169 170# Conditional source that is excluded. 171_CreateConfigFile(['conditional_source.c'], []) 172run_analyzer() 173EnsureContains(matched=False) 174 175# Conditional source that is included by way of argument. 176_CreateConfigFile(['conditional_source.c'], []) 177run_analyzer('-Dtest_variable=1') 178EnsureContains(matched=True, build_targets={'exe'}) 179 180# Two unknown files. 181_CreateConfigFile(['unknown1.c', 'unoknow2.cc'], []) 182run_analyzer() 183EnsureContains() 184 185# Two unknown files. 186_CreateConfigFile(['unknown1.c', 'subdir/subdir_sourcex.c'], []) 187run_analyzer() 188EnsureContains() 189 190# Included dependency 191_CreateConfigFile(['unknown1.c', 'subdir/subdir_source.c'], []) 192run_analyzer() 193EnsureContains(matched=True, build_targets={'exe', 'exe3'}) 194 195# Included inputs to actions. 196_CreateConfigFile(['action_input.c'], []) 197run_analyzer() 198EnsureContains(matched=True, build_targets={'exe'}) 199 200# Don't consider outputs. 201_CreateConfigFile(['action_output.c'], []) 202run_analyzer() 203EnsureContains(matched=False) 204 205# Rule inputs. 206_CreateConfigFile(['rule_input.c'], []) 207run_analyzer() 208EnsureContains(matched=True, build_targets={'exe'}) 209 210# Ignore path specified with PRODUCT_DIR. 211_CreateConfigFile(['product_dir_input.c'], []) 212run_analyzer() 213EnsureContains(matched=False) 214 215# Path specified via a variable. 216_CreateConfigFile(['subdir/subdir_source2.c'], []) 217run_analyzer() 218EnsureContains(matched=True, build_targets={'exe'}) 219 220# Verifies paths with // are fixed up correctly. 221_CreateConfigFile(['parent_source.c'], []) 222run_analyzer() 223EnsureContains(matched=True, build_targets={'exe', 'exe3'}) 224 225# Verifies relative paths are resolved correctly. 226_CreateConfigFile(['subdir/subdir_source.h'], []) 227run_analyzer() 228EnsureContains(matched=True, build_targets={'exe'}) 229 230# Various permutations when passing in targets. 231_CreateConfigFile(['exe2.c', 'subdir/subdir2b_source.c'], ['exe', 'exe3']) 232run_analyzer() 233EnsureContains(matched=True, targets={'exe3'}, build_targets={'exe2', 'exe3'}) 234 235_CreateConfigFile(['exe2.c', 'subdir/subdir2b_source.c'], ['exe']) 236run_analyzer() 237EnsureContains(matched=True, build_targets={'exe2', 'exe3'}) 238 239# Verifies duplicates are ignored. 240_CreateConfigFile(['exe2.c', 'subdir/subdir2b_source.c'], ['exe', 'exe']) 241run_analyzer() 242EnsureContains(matched=True, build_targets={'exe2', 'exe3'}) 243 244_CreateConfigFile(['exe2.c'], ['exe']) 245run_analyzer() 246EnsureContains(matched=True, build_targets={'exe2'}) 247 248_CreateConfigFile(['exe2.c'], []) 249run_analyzer() 250EnsureContains(matched=True, build_targets={'exe2'}) 251 252_CreateConfigFile(['subdir/subdir2b_source.c', 'exe2.c'], []) 253run_analyzer() 254EnsureContains(matched=True, build_targets={'exe2', 'exe3'}) 255 256_CreateConfigFile(['subdir/subdir2b_source.c'], ['exe3']) 257run_analyzer() 258EnsureContains(matched=True, targets={'exe3'}, build_targets={'exe3'}) 259 260_CreateConfigFile(['exe2.c'], []) 261run_analyzer() 262EnsureContains(matched=True, build_targets={'exe2'}) 263 264_CreateConfigFile(['foo.c'], []) 265run_analyzer() 266EnsureContains(matched=True, build_targets={'exe'}) 267 268# Assertions when modifying build (gyp/gypi) files, especially when said files 269# are included. 270_CreateConfigFile(['subdir2/d.cc'], ['exe', 'exe2', 'foo', 'exe3']) 271run_analyzer2() 272EnsureContains(matched=True, targets={'exe', 'foo'}, build_targets={'exe'}) 273 274_CreateConfigFile(['subdir2/subdir.includes.gypi'], 275 ['exe', 'exe2', 'foo', 'exe3']) 276run_analyzer2() 277EnsureContains(matched=True, targets={'exe', 'foo'}, build_targets={'exe'}) 278 279_CreateConfigFile(['subdir2/subdir.gyp'], ['exe', 'exe2', 'foo', 'exe3']) 280run_analyzer2() 281EnsureContains(matched=True, targets={'exe', 'foo'}, build_targets={'exe'}) 282 283_CreateConfigFile(['test2.includes.gypi'], ['exe', 'exe2', 'foo', 'exe3']) 284run_analyzer2() 285EnsureContains(matched=True, targets={'exe', 'exe2', 'exe3'}, 286 build_targets={'exe', 'exe2', 'exe3'}) 287 288# Verify modifying a file included makes all targets dirty. 289_CreateConfigFile(['common.gypi'], ['exe', 'exe2', 'foo', 'exe3']) 290run_analyzer2('-Icommon.gypi') 291EnsureMatchedAll({'exe', 'exe2', 'foo', 'exe3'}) 292 293# Assertions from test3.gyp. 294_CreateConfigFile(['d.c', 'f.c'], ['a']) 295run_analyzer3() 296EnsureContains(matched=True, targets={'a'}, build_targets={'a', 'b'}) 297 298_CreateConfigFile(['f.c'], ['a']) 299run_analyzer3() 300EnsureContains(matched=True, targets={'a'}, build_targets={'a', 'b'}) 301 302_CreateConfigFile(['f.c'], []) 303run_analyzer3() 304EnsureContains(matched=True, build_targets={'a', 'b'}) 305 306_CreateConfigFile(['c.c', 'e.c'], []) 307run_analyzer3() 308EnsureContains(matched=True, build_targets={'a', 'b', 'c', 'e'}) 309 310_CreateConfigFile(['d.c'], ['a']) 311run_analyzer3() 312EnsureContains(matched=True, targets={'a'}, build_targets={'a', 'b'}) 313 314_CreateConfigFile(['a.c'], ['a', 'b']) 315run_analyzer3() 316EnsureContains(matched=True, targets={'a'}, build_targets={'a'}) 317 318_CreateConfigFile(['a.c'], ['a', 'b']) 319run_analyzer3() 320EnsureContains(matched=True, targets={'a'}, build_targets={'a'}) 321 322_CreateConfigFile(['d.c'], ['a', 'b']) 323run_analyzer3() 324EnsureContains(matched=True, targets={'a', 'b'}, build_targets={'a', 'b'}) 325 326_CreateConfigFile(['f.c'], ['a']) 327run_analyzer3() 328EnsureContains(matched=True, targets={'a'}, build_targets={'a', 'b'}) 329 330_CreateConfigFile(['a.c'], ['a']) 331run_analyzer3() 332EnsureContains(matched=True, targets={'a'}, build_targets={'a'}) 333 334_CreateConfigFile(['a.c'], []) 335run_analyzer3() 336EnsureContains(matched=True, build_targets={'a'}) 337 338_CreateConfigFile(['d.c'], []) 339run_analyzer3() 340EnsureContains(matched=True, build_targets={'a', 'b'}) 341 342# Assertions around test4.gyp. 343_CreateConfigFile(['f.c'], []) 344run_analyzer4() 345EnsureContains(matched=True, build_targets={'e', 'f'}) 346 347_CreateConfigFile(['d.c'], []) 348run_analyzer4() 349EnsureContains(matched=True, build_targets={'a', 'b', 'c', 'd'}) 350 351_CreateConfigFile(['i.c'], []) 352run_analyzer4() 353EnsureContains(matched=True, build_targets={'h'}) 354 355test.pass_test() 356