1"""Utilities for writing tests of license rules.""" 2 3import codecs 4import json 5 6# This is extracted out to make it easier to keep test equivalence between 7# the OSS version and Google. 8LICENSE_PACKAGE_BASE = "/" 9 10 11def load_licenses_info(info_path): 12 """Loads the licenses_info() JSON format.""" 13 with codecs.open(info_path, encoding="utf-8") as licenses_file: 14 return json.loads(licenses_file.read()) 15 16 17def filter_dependencies(licenses_info, target_filter=None, 18 licenses_filter=None): 19 """Filters licenses_info to only include dependencies of interest. 20 21 Args: 22 licenses_info: (dict) licenses info. 23 target_filter: (function): function which returns true if we should include 24 the target. 25 licenses_filter: (function): function which returns true if we should 26 include the license. 27 Returns: 28 (dict) a valid licenses_info dict. 29 """ 30 top_target = licenses_info[0] 31 new_top_target = dict(top_target) 32 new_deps = [] 33 for dep in top_target["dependencies"]: 34 target_name = dep["target_under_license"] 35 if target_filter and not target_filter(target_name): 36 continue 37 licenses = dep["licenses"] 38 if licenses_filter: 39 licenses = [lic for lic in licenses if licenses_filter(lic)] 40 new_deps.append({ 41 "target_under_license": target_name, 42 "licenses": licenses}) 43 new_top_target["dependencies"] = new_deps 44 return [new_top_target] 45 46 47def check_licenses_of_dependencies(test_case, licenses_info, expected, 48 path_prefix=LICENSE_PACKAGE_BASE): 49 """Checks that licenses_info contains an expected set of licenses. 50 51 Args: 52 test_case: (TestCase) the test. 53 licenses_info: (dict) licenses info. 54 expected: (dict) map of target name suffixes to the licenses they are under. 55 path_prefix: (str) prefix to prepend to targets and licenses in expected. 56 This turns the relative target names to absolute ones. 57 """ 58 59 # Turn the list of deps into a dict by target for easier comparison. 60 deps_to_licenses = { 61 x["target_under_license"].lstrip("@"): set(l.strip("@") for l in x["licenses"]) 62 for x in licenses_info[0]["dependencies"]} 63 64 target_names = ",".join(deps_to_licenses.keys()) 65 # This is n**2, but N is typically < 3 or we are doing this wrong. 66 for want_target, want_licenses in expected.items(): 67 found_target = False 68 for got_target, got_licenses in deps_to_licenses.items(): 69 if got_target.endswith(want_target): 70 found_target = True 71 test_case.assertEqual(len(want_licenses), len(got_licenses)) 72 found_license = False 73 for want_l in want_licenses: 74 for got_l in got_licenses: 75 if got_l.endswith(want_l): 76 found_license = True 77 break 78 test_case.assertTrue( 79 found_license, 80 msg="license (%s) not a suffix in %s" % (want_l, got_licenses)) 81 break 82 test_case.assertTrue( 83 found_target, 84 msg="target (%s) not a suffix in [%s]" % (want_target, target_names)) 85