1*f4ee7fbaSAndroid Build Coastguard Workerfrom __future__ import print_function 2*f4ee7fbaSAndroid Build Coastguard Workerimport filecmp 3*f4ee7fbaSAndroid Build Coastguard Workerimport glob 4*f4ee7fbaSAndroid Build Coastguard Workerimport itertools 5*f4ee7fbaSAndroid Build Coastguard Workerimport os 6*f4ee7fbaSAndroid Build Coastguard Workerimport sys 7*f4ee7fbaSAndroid Build Coastguard Workerimport sysconfig 8*f4ee7fbaSAndroid Build Coastguard Workerimport tempfile 9*f4ee7fbaSAndroid Build Coastguard Workerimport unittest 10*f4ee7fbaSAndroid Build Coastguard Worker 11*f4ee7fbaSAndroid Build Coastguard Worker 12*f4ee7fbaSAndroid Build Coastguard Workerproject_dir = os.path.abspath(os.path.join(__file__, '..', '..', '..')) 13*f4ee7fbaSAndroid Build Coastguard Workersrc_dir = os.path.join(project_dir, 'python') 14*f4ee7fbaSAndroid Build Coastguard Workertest_dir = os.path.join(project_dir, 'tests') 15*f4ee7fbaSAndroid Build Coastguard Worker 16*f4ee7fbaSAndroid Build Coastguard Workerpython_exe = sys.executable or 'python' 17*f4ee7fbaSAndroid Build Coastguard Workerbro_path = os.path.join(src_dir, 'bro.py') 18*f4ee7fbaSAndroid Build Coastguard WorkerBRO_ARGS = [python_exe, bro_path] 19*f4ee7fbaSAndroid Build Coastguard Worker 20*f4ee7fbaSAndroid Build Coastguard Worker# Get the platform/version-specific build folder. 21*f4ee7fbaSAndroid Build Coastguard Worker# By default, the distutils build base is in the same location as setup.py. 22*f4ee7fbaSAndroid Build Coastguard Workerplatform_lib_name = 'lib.{platform}-{version[0]}.{version[1]}'.format( 23*f4ee7fbaSAndroid Build Coastguard Worker platform=sysconfig.get_platform(), version=sys.version_info) 24*f4ee7fbaSAndroid Build Coastguard Workerbuild_dir = os.path.join(project_dir, 'bin', platform_lib_name) 25*f4ee7fbaSAndroid Build Coastguard Worker 26*f4ee7fbaSAndroid Build Coastguard Worker# Prepend the build folder to sys.path and the PYTHONPATH environment variable. 27*f4ee7fbaSAndroid Build Coastguard Workerif build_dir not in sys.path: 28*f4ee7fbaSAndroid Build Coastguard Worker sys.path.insert(0, build_dir) 29*f4ee7fbaSAndroid Build Coastguard WorkerTEST_ENV = os.environ.copy() 30*f4ee7fbaSAndroid Build Coastguard Workerif 'PYTHONPATH' not in TEST_ENV: 31*f4ee7fbaSAndroid Build Coastguard Worker TEST_ENV['PYTHONPATH'] = build_dir 32*f4ee7fbaSAndroid Build Coastguard Workerelse: 33*f4ee7fbaSAndroid Build Coastguard Worker TEST_ENV['PYTHONPATH'] = build_dir + os.pathsep + TEST_ENV['PYTHONPATH'] 34*f4ee7fbaSAndroid Build Coastguard Worker 35*f4ee7fbaSAndroid Build Coastguard WorkerTESTDATA_DIR = os.path.join(test_dir, 'testdata') 36*f4ee7fbaSAndroid Build Coastguard Worker 37*f4ee7fbaSAndroid Build Coastguard WorkerTESTDATA_FILES = [ 38*f4ee7fbaSAndroid Build Coastguard Worker 'empty', # Empty file 39*f4ee7fbaSAndroid Build Coastguard Worker '10x10y', # Small text 40*f4ee7fbaSAndroid Build Coastguard Worker 'alice29.txt', # Large text 41*f4ee7fbaSAndroid Build Coastguard Worker 'random_org_10k.bin', # Small data 42*f4ee7fbaSAndroid Build Coastguard Worker 'mapsdatazrh', # Large data 43*f4ee7fbaSAndroid Build Coastguard Worker] 44*f4ee7fbaSAndroid Build Coastguard Worker 45*f4ee7fbaSAndroid Build Coastguard WorkerTESTDATA_PATHS = [os.path.join(TESTDATA_DIR, f) for f in TESTDATA_FILES] 46*f4ee7fbaSAndroid Build Coastguard Worker 47*f4ee7fbaSAndroid Build Coastguard WorkerTESTDATA_PATHS_FOR_DECOMPRESSION = glob.glob( 48*f4ee7fbaSAndroid Build Coastguard Worker os.path.join(TESTDATA_DIR, '*.compressed')) 49*f4ee7fbaSAndroid Build Coastguard Worker 50*f4ee7fbaSAndroid Build Coastguard WorkerTEMP_DIR = tempfile.mkdtemp() 51*f4ee7fbaSAndroid Build Coastguard Worker 52*f4ee7fbaSAndroid Build Coastguard Worker 53*f4ee7fbaSAndroid Build Coastguard Workerdef get_temp_compressed_name(filename): 54*f4ee7fbaSAndroid Build Coastguard Worker return os.path.join(TEMP_DIR, os.path.basename(filename + '.bro')) 55*f4ee7fbaSAndroid Build Coastguard Worker 56*f4ee7fbaSAndroid Build Coastguard Worker 57*f4ee7fbaSAndroid Build Coastguard Workerdef get_temp_uncompressed_name(filename): 58*f4ee7fbaSAndroid Build Coastguard Worker return os.path.join(TEMP_DIR, os.path.basename(filename + '.unbro')) 59*f4ee7fbaSAndroid Build Coastguard Worker 60*f4ee7fbaSAndroid Build Coastguard Worker 61*f4ee7fbaSAndroid Build Coastguard Workerdef bind_method_args(method, *args, **kwargs): 62*f4ee7fbaSAndroid Build Coastguard Worker return lambda self: method(self, *args, **kwargs) 63*f4ee7fbaSAndroid Build Coastguard Worker 64*f4ee7fbaSAndroid Build Coastguard Worker 65*f4ee7fbaSAndroid Build Coastguard Workerdef generate_test_methods(test_case_class, 66*f4ee7fbaSAndroid Build Coastguard Worker for_decompression=False, 67*f4ee7fbaSAndroid Build Coastguard Worker variants=None): 68*f4ee7fbaSAndroid Build Coastguard Worker # Add test methods for each test data file. This makes identifying problems 69*f4ee7fbaSAndroid Build Coastguard Worker # with specific compression scenarios easier. 70*f4ee7fbaSAndroid Build Coastguard Worker if for_decompression: 71*f4ee7fbaSAndroid Build Coastguard Worker paths = TESTDATA_PATHS_FOR_DECOMPRESSION 72*f4ee7fbaSAndroid Build Coastguard Worker else: 73*f4ee7fbaSAndroid Build Coastguard Worker paths = TESTDATA_PATHS 74*f4ee7fbaSAndroid Build Coastguard Worker opts = [] 75*f4ee7fbaSAndroid Build Coastguard Worker if variants: 76*f4ee7fbaSAndroid Build Coastguard Worker opts_list = [] 77*f4ee7fbaSAndroid Build Coastguard Worker for k, v in variants.items(): 78*f4ee7fbaSAndroid Build Coastguard Worker opts_list.append([r for r in itertools.product([k], v)]) 79*f4ee7fbaSAndroid Build Coastguard Worker for o in itertools.product(*opts_list): 80*f4ee7fbaSAndroid Build Coastguard Worker opts_name = '_'.join([str(i) for i in itertools.chain(*o)]) 81*f4ee7fbaSAndroid Build Coastguard Worker opts_dict = dict(o) 82*f4ee7fbaSAndroid Build Coastguard Worker opts.append([opts_name, opts_dict]) 83*f4ee7fbaSAndroid Build Coastguard Worker else: 84*f4ee7fbaSAndroid Build Coastguard Worker opts.append(['', {}]) 85*f4ee7fbaSAndroid Build Coastguard Worker for method in [m for m in dir(test_case_class) if m.startswith('_test')]: 86*f4ee7fbaSAndroid Build Coastguard Worker for testdata in paths: 87*f4ee7fbaSAndroid Build Coastguard Worker for (opts_name, opts_dict) in opts: 88*f4ee7fbaSAndroid Build Coastguard Worker f = os.path.splitext(os.path.basename(testdata))[0] 89*f4ee7fbaSAndroid Build Coastguard Worker name = 'test_{method}_{options}_{file}'.format( 90*f4ee7fbaSAndroid Build Coastguard Worker method=method, options=opts_name, file=f) 91*f4ee7fbaSAndroid Build Coastguard Worker func = bind_method_args( 92*f4ee7fbaSAndroid Build Coastguard Worker getattr(test_case_class, method), testdata, **opts_dict) 93*f4ee7fbaSAndroid Build Coastguard Worker setattr(test_case_class, name, func) 94*f4ee7fbaSAndroid Build Coastguard Worker 95*f4ee7fbaSAndroid Build Coastguard Worker 96*f4ee7fbaSAndroid Build Coastguard Workerclass TestCase(unittest.TestCase): 97*f4ee7fbaSAndroid Build Coastguard Worker 98*f4ee7fbaSAndroid Build Coastguard Worker def tearDown(self): 99*f4ee7fbaSAndroid Build Coastguard Worker for f in TESTDATA_PATHS: 100*f4ee7fbaSAndroid Build Coastguard Worker try: 101*f4ee7fbaSAndroid Build Coastguard Worker os.unlink(get_temp_compressed_name(f)) 102*f4ee7fbaSAndroid Build Coastguard Worker except OSError: 103*f4ee7fbaSAndroid Build Coastguard Worker pass 104*f4ee7fbaSAndroid Build Coastguard Worker try: 105*f4ee7fbaSAndroid Build Coastguard Worker os.unlink(get_temp_uncompressed_name(f)) 106*f4ee7fbaSAndroid Build Coastguard Worker except OSError: 107*f4ee7fbaSAndroid Build Coastguard Worker pass 108*f4ee7fbaSAndroid Build Coastguard Worker 109*f4ee7fbaSAndroid Build Coastguard Worker def assertFilesMatch(self, first, second): 110*f4ee7fbaSAndroid Build Coastguard Worker self.assertTrue( 111*f4ee7fbaSAndroid Build Coastguard Worker filecmp.cmp(first, second, shallow=False), 112*f4ee7fbaSAndroid Build Coastguard Worker 'File {} differs from {}'.format(first, second)) 113