| #!/usr/bin/env python3 |
| # |
| # Copyright (C) 2022 The Android Open Source Project |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| |
| import json |
| import unittest |
| from unittest.mock import patch, mock_open |
| |
| from find_api_packages import read, BazelLabel, ApiPackageFinder, \ |
| ApiPackageDecodeException, ContributionData |
| from finder import FileFinder |
| |
| |
| class TestBazelLabel(unittest.TestCase): |
| |
| def test_label_to_string(self): |
| label = BazelLabel(package="//build/bazel", target="mytarget") |
| self.assertEqual("//build/bazel:mytarget", label.to_string()) |
| label = BazelLabel(package="build/bazel", |
| target="target/in/another/dir/mytarget") |
| self.assertEqual("build/bazel:target/in/another/dir/mytarget", |
| label.to_string()) |
| |
| def test_colon_handling(self): |
| label = BazelLabel(package="//build/bazel:", target=":mytarget.txt") |
| self.assertEqual("//build/bazel:mytarget.txt", label.to_string()) |
| |
| |
| class TestApiPackageReadUtils(unittest.TestCase): |
| |
| def test_read_empty_file(self): |
| test_data = "" |
| with patch("builtins.open", mock_open(read_data=test_data)): |
| self.assertRaises(ApiPackageDecodeException, read, |
| "some_file.json") |
| |
| def test_read_malformed_file(self): |
| test_data = "not a json file" |
| with patch("builtins.open", mock_open(read_data=test_data)): |
| self.assertRaises(ApiPackageDecodeException, read, |
| "some_file.json") |
| |
| def test_read_file_missing_api_domain(self): |
| data = {"api_package": "//frameworks/base"} |
| with patch("builtins.open", mock_open(read_data=json.dumps(data))): |
| self.assertRaises(ApiPackageDecodeException, read, |
| "some_file.json") |
| |
| def test_read_file_missing_api_package(self): |
| data = {"api_domain": "system"} |
| with patch("builtins.open", mock_open(read_data=json.dumps(data))): |
| self.assertRaises(ApiPackageDecodeException, read, |
| "some_file.json") |
| |
| def test_read_well_formed_json(self): |
| data = {"api_domain": "system", "api_package": "//frameworks/base"} |
| with patch("builtins.open", mock_open(read_data=json.dumps(data))): |
| results = read("some_file.json") |
| self.assertEqual("system", results.api_domain) |
| self.assertEqual("//frameworks/base", |
| results.api_contribution_bazel_label.package) |
| self.assertEqual("contributions", |
| results.api_contribution_bazel_label.target) |
| |
| def test_read_target_provided_by_user(self): |
| data = { |
| "api_domain": "system", |
| "api_package": "//frameworks/base", |
| "api_target": "mytarget" |
| } |
| with patch("builtins.open", mock_open(read_data=json.dumps(data))): |
| results = read("some_file.json") |
| self.assertEqual("system", results.api_domain) |
| self.assertEqual("//frameworks/base", |
| results.api_contribution_bazel_label.package) |
| self.assertEqual("mytarget", |
| results.api_contribution_bazel_label.target) |
| |
| |
| class TestApiPackageFinder(unittest.TestCase): |
| |
| def _mock_fs(self, mock_data): |
| # Create a mock fs for finder.find |
| # The mock fs contains files in packages/modules. |
| return lambda path, search_depth: list(mock_data.keys( |
| )) if "packages/modules" in path else [] |
| |
| @patch.object(FileFinder, "find") |
| def test_exception_if_api_package_file_is_missing(self, find_mock): |
| find_mock.return_value = [] # no files found |
| api_package_finder = ApiPackageFinder("mock_inner_tree") |
| self.assertEqual(None, |
| api_package_finder.find_api_label_string("system")) |
| |
| @patch("find_api_packages.read") |
| @patch.object(FileFinder, "find") |
| def test_no_exception_if_api_domain_not_found(self, find_mock, read_mock): |
| # api_packages.json files exist in the tree, but none of them contain |
| # the api_domain we are interested in. |
| |
| # Return a mock file from packages/modules. |
| def _mock_fs(path, search_depth): |
| return ["some_file.json"] if "packages/modules" in path else [] |
| |
| find_mock.side_effect = _mock_fs |
| read_mock.return_value = ContributionData( |
| "com.android.foo", |
| BazelLabel("//packages/modules/foo", "contributions")) |
| api_package_finder = ApiPackageFinder("mock_inner_tree") |
| self.assertEqual(None, |
| api_package_finder.find_api_label_string("system")) |
| self.assertEqual( |
| "//packages/modules/foo:contributions", |
| api_package_finder.find_api_label_string("com.android.foo")) |
| |
| @patch("find_api_packages.read") |
| @patch.object(FileFinder, "find") |
| def test_exception_duplicate_entries(self, find_mock, read_mock): |
| first_contribution_data = ContributionData( |
| "com.android.foo", |
| BazelLabel("//packages/modules/foo", "contributions")) |
| second_contribution_data = ContributionData( |
| "com.android.foo", |
| BazelLabel("//packages/modules/foo_other", "contributions")) |
| mock_data = { |
| "first.json": first_contribution_data, |
| "second.json": second_contribution_data, |
| } |
| |
| find_mock.side_effect = self._mock_fs(mock_data) |
| read_mock.side_effect = lambda x: mock_data.get(x) |
| api_package_finder = ApiPackageFinder("mock_inner_tree") |
| with self.assertRaises(AssertionError): |
| api_package_finder.find_api_label_string("com.android.foo") |
| |
| @patch("find_api_packages.read") |
| @patch.object(FileFinder, "find") |
| def test_user_provided_filter(self, find_mock, read_mock): |
| foo_contribution_data = ContributionData( |
| "com.android.foo", |
| BazelLabel("//packages/modules/foo", "contributions")) |
| bar_contribution_data = ContributionData( |
| "com.android.bar", |
| BazelLabel("//packages/modules/bar", "contributions")) |
| mock_data = { |
| "foo.json": foo_contribution_data, |
| "bar.json": bar_contribution_data, |
| } |
| |
| find_mock.side_effect = self._mock_fs(mock_data) |
| read_mock.side_effect = lambda x: mock_data.get(x) |
| api_package_finder = ApiPackageFinder("mock_inner_tree") |
| |
| all_contributions = api_package_finder.find_api_label_string_using_filter( |
| lambda x: True) |
| self.assertEqual(2, len(all_contributions)) |
| self.assertEqual("//packages/modules/foo:contributions", |
| all_contributions[0]) |
| self.assertEqual("//packages/modules/bar:contributions", |
| all_contributions[1]) |
| |
| |
| if __name__ == "__main__": |
| unittest.main() |