• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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