1#!/usr/bin/env python3
2# Copyright 2018 The Android Open Source Project
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#      http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16"""Unittests for android_test_mapping_format."""
17
18import os
19import shutil
20import tempfile
21import unittest
22
23import android_test_mapping_format
24
25
26_VALID_TEST_MAPPING = r"""
27{
28  "presubmit": [
29    {
30      "name": "CtsWindowManagerDeviceTestCases",
31      "options": [
32        {
33          "include-annotation": "android.platform.test.annotations.Presubmit"
34        }
35      ]
36    }
37  ],
38  "postsubmit": [
39    {
40      "name": "CtsWindowManagerDeviceTestCases",
41      "host": true,
42      "preferred_targets": ["a", "b"],
43      "file_patterns": [".*\\.java"]
44    }
45  ],
46  "imports": [
47    {
48      "path": "frameworks/base/services/core/java/com/android/server/am"
49    },
50    {
51      "path": "frameworks/base/services/core/java/com/android/server/wm"
52    }
53  ]
54}
55"""
56
57_BAD_JSON = """
58{wrong format}
59"""
60
61_BAD_TEST_WRONG_KEY = """
62{
63  "presubmit": [
64    {
65      "bad_name": "CtsWindowManagerDeviceTestCases"
66    }
67  ]
68}
69"""
70
71_BAD_TEST_WRONG_HOST_VALUE = """
72{
73  "presubmit": [
74    {
75      "name": "CtsWindowManagerDeviceTestCases",
76      "host": "bad_value"
77    }
78  ]
79}
80"""
81
82
83_BAD_TEST_WRONG_PREFERRED_TARGETS_VALUE_NONE_LIST = """
84{
85  "presubmit": [
86    {
87      "name": "CtsWindowManagerDeviceTestCases",
88      "preferred_targets": "bad_value"
89    }
90  ]
91}
92"""
93
94_BAD_TEST_WRONG_PREFERRED_TARGETS_VALUE_WRONG_TYPE = """
95{
96  "presubmit": [
97    {
98      "name": "CtsWindowManagerDeviceTestCases",
99      "preferred_targets": ["bad_value", 123]
100    }
101  ]
102}
103"""
104
105_BAD_TEST_WRONG_OPTION = """
106{
107  "presubmit": [
108    {
109      "name": "CtsWindowManagerDeviceTestCases",
110      "options": [
111        {
112          "include-annotation": "android.platform.test.annotations.Presubmit",
113          "bad_option": "some_name"
114        }
115      ]
116    }
117  ]
118}
119"""
120
121_BAD_IMPORT_WRONG_KEY = """
122{
123  "imports": [
124    {
125      "name": "frameworks/base/services/core/java/com/android/server/am"
126    }
127  ]
128}
129"""
130
131_BAD_IMPORT_WRONG_IMPORT_VALUE = """
132{
133  "imports": [
134    {
135      "path": "frameworks/base/services/core/java/com/android/server/am",
136      "option": "something"
137    }
138  ]
139}
140"""
141
142_BAD_FILE_PATTERNS = """
143{
144  "presubmit": [
145    {
146      "name": "CtsWindowManagerDeviceTestCases",
147      "file_patterns": ["pattern", 123]
148    }
149  ]
150}
151"""
152
153_TEST_MAPPING_WITH_SUPPORTED_COMMENTS = r"""
154// supported comment
155{
156  // supported comment!@#$%^&*()_
157  "presubmit": [
158    {
159      "name": "CtsWindowManagerDeviceTestCases\"foo//baz",
160      "options": [
161        // supported comment!@#$%^&*()_
162        {
163          "include-annotation": "android.platform.test.annotations.Presubmit"
164        }
165      ]
166    }
167  ],
168  "imports": [
169    {
170      "path": "path1//path2//path3"
171    }
172  ]
173}
174"""
175
176_TEST_MAPPING_WITH_NON_SUPPORTED_COMMENTS = """
177{ #non-supported comments
178  // supported comments
179  "presubmit": [#non-supported comments
180    {  // non-supported comments
181      "name": "CtsWindowManagerDeviceTestCases",
182    }
183  ]
184}
185"""
186
187
188class AndroidTestMappingFormatTests(unittest.TestCase):
189    """Unittest for android_test_mapping_format module."""
190
191    def setUp(self):
192        self.tempdir = tempfile.mkdtemp()
193        self.test_mapping_file = os.path.join(self.tempdir, 'TEST_MAPPING')
194
195    def tearDown(self):
196        shutil.rmtree(self.tempdir)
197
198    def test_valid_test_mapping(self):
199        """Verify that the check doesn't raise any error for valid test mapping.
200        """
201        with open(self.test_mapping_file, 'w') as file:
202            file.write(_VALID_TEST_MAPPING)
203        with open(self.test_mapping_file, 'r') as file:
204            android_test_mapping_format.process_file(file.read())
205
206    def test_invalid_test_mapping_bad_json(self):
207        """Verify that TEST_MAPPING file with bad json can be detected."""
208        with open(self.test_mapping_file, 'w') as file:
209            file.write(_BAD_JSON)
210        with open(self.test_mapping_file, 'r') as file:
211            self.assertRaises(
212                ValueError, android_test_mapping_format.process_file,
213                file.read())
214
215    def test_invalid_test_mapping_wrong_test_key(self):
216        """Verify that test config using wrong key can be detected."""
217        with open(self.test_mapping_file, 'w') as file:
218            file.write(_BAD_TEST_WRONG_KEY)
219        with open(self.test_mapping_file, 'r') as file:
220            self.assertRaises(
221                android_test_mapping_format.InvalidTestMappingError,
222                android_test_mapping_format.process_file,
223                file.read())
224
225    def test_invalid_test_mapping_wrong_test_value(self):
226        """Verify that test config using wrong host value can be detected."""
227        with open(self.test_mapping_file, 'w') as file:
228            file.write(_BAD_TEST_WRONG_HOST_VALUE)
229        with open(self.test_mapping_file, 'r') as file:
230            self.assertRaises(
231                android_test_mapping_format.InvalidTestMappingError,
232                android_test_mapping_format.process_file,
233                file.read())
234
235    def test_invalid_test_mapping_wrong_preferred_targets_value(self):
236        """Verify invalid preferred_targets are rejected."""
237        with open(self.test_mapping_file, 'w') as file:
238            file.write(_BAD_TEST_WRONG_PREFERRED_TARGETS_VALUE_NONE_LIST)
239        with open(self.test_mapping_file, 'r') as file:
240            self.assertRaises(
241                android_test_mapping_format.InvalidTestMappingError,
242                android_test_mapping_format.process_file,
243                file.read())
244        with open(self.test_mapping_file, 'w') as file:
245            file.write(_BAD_TEST_WRONG_PREFERRED_TARGETS_VALUE_WRONG_TYPE)
246        with open(self.test_mapping_file, 'r') as file:
247            self.assertRaises(
248                android_test_mapping_format.InvalidTestMappingError,
249                android_test_mapping_format.process_file,
250                file.read())
251
252    def test_invalid_test_mapping_wrong_test_option(self):
253        """Verify that test config using wrong option can be detected."""
254        with open(self.test_mapping_file, 'w') as file:
255            file.write(_BAD_TEST_WRONG_OPTION)
256        with open(self.test_mapping_file, 'r') as file:
257            self.assertRaises(
258                android_test_mapping_format.InvalidTestMappingError,
259                android_test_mapping_format.process_file,
260                file.read())
261
262    def test_invalid_test_mapping_wrong_import_key(self):
263        """Verify that import setting using wrong key can be detected."""
264        with open(self.test_mapping_file, 'w') as file:
265            file.write(_BAD_IMPORT_WRONG_KEY)
266        with open(self.test_mapping_file, 'r') as file:
267            self.assertRaises(
268                android_test_mapping_format.InvalidTestMappingError,
269                android_test_mapping_format.process_file,
270                file.read())
271
272    def test_invalid_test_mapping_wrong_import_value(self):
273        """Verify that import setting using wrong value can be detected."""
274        with open(self.test_mapping_file, 'w') as file:
275            file.write(_BAD_IMPORT_WRONG_IMPORT_VALUE)
276        with open(self.test_mapping_file, 'r') as file:
277            self.assertRaises(
278                android_test_mapping_format.InvalidTestMappingError,
279                android_test_mapping_format.process_file,
280                file.read())
281
282    def test_invalid_test_mapping_file_patterns_value(self):
283        """Verify that file_patterns using wrong value can be detected."""
284        with open(self.test_mapping_file, 'w') as file:
285            file.write(_BAD_FILE_PATTERNS)
286        with open(self.test_mapping_file, 'r') as file:
287            self.assertRaises(
288                android_test_mapping_format.InvalidTestMappingError,
289                android_test_mapping_format.process_file,
290                file.read())
291
292    def test_valid_test_mapping_file_with_supported_comments(self):
293        """Verify that '//'-format comment can be filtered."""
294        with open(self.test_mapping_file, 'w') as file:
295            file.write(_TEST_MAPPING_WITH_SUPPORTED_COMMENTS)
296        with open(self.test_mapping_file, 'r') as file:
297            android_test_mapping_format.process_file(file.read())
298
299    def test_valid_test_mapping_file_with_non_supported_comments(self):
300        """Verify that non-supported comment can be detected."""
301        with open(self.test_mapping_file, 'w') as file:
302            file.write(_TEST_MAPPING_WITH_NON_SUPPORTED_COMMENTS)
303        with open(self.test_mapping_file, 'r') as file:
304            self.assertRaises(
305                ValueError, android_test_mapping_format.process_file,
306                file.read())
307
308
309if __name__ == '__main__':
310    unittest.main()
311