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