1#!/usr/bin/env python3 2# 3# Copyright (C) 2022 The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17import json 18import unittest 19from unittest.mock import patch, mock_open 20 21from find_api_packages import read, BazelLabel, ApiPackageFinder, \ 22 ApiPackageDecodeException, ContributionData 23from finder import FileFinder 24 25 26class TestBazelLabel(unittest.TestCase): 27 28 def test_label_to_string(self): 29 label = BazelLabel(package="//build/bazel", target="mytarget") 30 self.assertEqual("//build/bazel:mytarget", label.to_string()) 31 label = BazelLabel(package="build/bazel", 32 target="target/in/another/dir/mytarget") 33 self.assertEqual("build/bazel:target/in/another/dir/mytarget", 34 label.to_string()) 35 36 def test_colon_handling(self): 37 label = BazelLabel(package="//build/bazel:", target=":mytarget.txt") 38 self.assertEqual("//build/bazel:mytarget.txt", label.to_string()) 39 40 41class TestApiPackageReadUtils(unittest.TestCase): 42 43 def test_read_empty_file(self): 44 test_data = "" 45 with patch("builtins.open", mock_open(read_data=test_data)): 46 self.assertRaises(ApiPackageDecodeException, read, 47 "some_file.json") 48 49 def test_read_malformed_file(self): 50 test_data = "not a json file" 51 with patch("builtins.open", mock_open(read_data=test_data)): 52 self.assertRaises(ApiPackageDecodeException, read, 53 "some_file.json") 54 55 def test_read_file_missing_api_domain(self): 56 data = {"api_package": "//frameworks/base"} 57 with patch("builtins.open", mock_open(read_data=json.dumps(data))): 58 self.assertRaises(ApiPackageDecodeException, read, 59 "some_file.json") 60 61 def test_read_file_missing_api_package(self): 62 data = {"api_domain": "system"} 63 with patch("builtins.open", mock_open(read_data=json.dumps(data))): 64 self.assertRaises(ApiPackageDecodeException, read, 65 "some_file.json") 66 67 def test_read_well_formed_json(self): 68 data = {"api_domain": "system", "api_package": "//frameworks/base"} 69 with patch("builtins.open", mock_open(read_data=json.dumps(data))): 70 results = read("some_file.json") 71 self.assertEqual("system", results.api_domain) 72 self.assertEqual("//frameworks/base", 73 results.api_contribution_bazel_label.package) 74 self.assertEqual("contributions", 75 results.api_contribution_bazel_label.target) 76 77 def test_read_target_provided_by_user(self): 78 data = { 79 "api_domain": "system", 80 "api_package": "//frameworks/base", 81 "api_target": "mytarget" 82 } 83 with patch("builtins.open", mock_open(read_data=json.dumps(data))): 84 results = read("some_file.json") 85 self.assertEqual("system", results.api_domain) 86 self.assertEqual("//frameworks/base", 87 results.api_contribution_bazel_label.package) 88 self.assertEqual("mytarget", 89 results.api_contribution_bazel_label.target) 90 91 92class TestApiPackageFinder(unittest.TestCase): 93 94 def _mock_fs(self, mock_data): 95 # Create a mock fs for finder.find 96 # The mock fs contains files in packages/modules. 97 return lambda path, search_depth: list(mock_data.keys( 98 )) if "packages/modules" in path else [] 99 100 @patch.object(FileFinder, "find") 101 def test_exception_if_api_package_file_is_missing(self, find_mock): 102 find_mock.return_value = [] # no files found 103 api_package_finder = ApiPackageFinder("mock_inner_tree") 104 self.assertEqual(None, 105 api_package_finder.find_api_label_string("system")) 106 107 @patch("find_api_packages.read") 108 @patch.object(FileFinder, "find") 109 def test_no_exception_if_api_domain_not_found(self, find_mock, read_mock): 110 # api_packages.json files exist in the tree, but none of them contain 111 # the api_domain we are interested in. 112 113 # Return a mock file from packages/modules. 114 def _mock_fs(path, search_depth): 115 return ["some_file.json"] if "packages/modules" in path else [] 116 117 find_mock.side_effect = _mock_fs 118 read_mock.return_value = [ContributionData( 119 "com.android.foo", 120 BazelLabel("//packages/modules/foo", "contributions"))] 121 api_package_finder = ApiPackageFinder("mock_inner_tree") 122 self.assertEqual(None, 123 api_package_finder.find_api_label_string("system")) 124 self.assertEqual( 125 "//packages/modules/foo:contributions", 126 api_package_finder.find_api_label_string("com.android.foo")) 127 128 @patch("find_api_packages.read") 129 @patch.object(FileFinder, "find") 130 def test_exception_duplicate_entries(self, find_mock, read_mock): 131 first_contribution_data = ContributionData( 132 "com.android.foo", 133 BazelLabel("//packages/modules/foo", "contributions")) 134 second_contribution_data = ContributionData( 135 "com.android.foo", 136 BazelLabel("//packages/modules/foo_other", "contributions")) 137 mock_data = { 138 "first.json": [first_contribution_data], 139 "second.json": [second_contribution_data], 140 } 141 142 find_mock.side_effect = self._mock_fs(mock_data) 143 read_mock.side_effect = lambda x: mock_data.get(x) 144 api_package_finder = ApiPackageFinder("mock_inner_tree") 145 with self.assertRaises(AssertionError): 146 api_package_finder.find_api_label_string("com.android.foo") 147 148 @patch("find_api_packages.read") 149 @patch.object(FileFinder, "find") 150 def test_user_provided_filter(self, find_mock, read_mock): 151 foo_contribution_data = ContributionData( 152 "com.android.foo", 153 BazelLabel("//packages/modules/foo", "contributions")) 154 bar_contribution_data = ContributionData( 155 "com.android.bar", 156 BazelLabel("//packages/modules/bar", "contributions")) 157 mock_data = { 158 "foo.json": [foo_contribution_data], 159 "bar.json": [bar_contribution_data], 160 } 161 162 find_mock.side_effect = self._mock_fs(mock_data) 163 read_mock.side_effect = lambda x: mock_data.get(x) 164 api_package_finder = ApiPackageFinder("mock_inner_tree") 165 166 all_contributions = api_package_finder.find_api_label_string_using_filter( 167 lambda x: True) 168 self.assertEqual(2, len(all_contributions)) 169 self.assertEqual("//packages/modules/foo:contributions", 170 all_contributions[0]) 171 self.assertEqual("//packages/modules/bar:contributions", 172 all_contributions[1]) 173 174 175if __name__ == "__main__": 176 unittest.main() 177