1#!/usr/bin/env python
2#
3# Copyright 2017, 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
17"""Unittests for auto_gen_test_config."""
18
19import os
20import shutil
21import tempfile
22import unittest
23
24import auto_gen_test_config
25
26TEST_MODULE = 'TestModule'
27
28MANIFEST_INVALID = """<?xml version="1.0" encoding="utf-8"?>
29<manifest xmlns:android="http://schemas.android.com/apk/res/android">
30</manifest>
31"""
32
33XMLTREE_JUNIT_TEST = """N: android=http://schemas.android.com/apk/res/android (line=2)
34  E: manifest (line=2)
35    A: package="com.android.my.tests.x" (Raw: "com.android.my.tests.x")
36      E: instrumentation (line=9)
37        A: http://schemas.android.com/apk/res/android:label(0x01010001)="TestModule" (Raw: "TestModule")
38        A: http://schemas.android.com/apk/res/android:name(0x01010003)="androidx.test.runner.AndroidJUnitRunner" (Raw: "androidx.test.runner.AndroidJUnitRunner")
39        A: http://schemas.android.com/apk/res/android:targetPackage(0x01010021)="com.android.my.tests" (Raw: "com.android.my.tests")
40"""
41
42XMLTREE_INSTRUMENTATION_TEST = """N: android=http://schemas.android.com/apk/res/android (line=2)
43  E: manifest (line=2)
44    A: package="com.android.my.tests.x" (Raw: "com.android.my.tests.x")
45      E: instrumentation (line=9)
46        A: http://schemas.android.com/apk/res/android:label(0x01010001)="TestModule" (Raw: "TestModule")
47        A: http://schemas.android.com/apk/res/android:name(0x01010003)="android.test.InstrumentationTestRunner" (Raw: "android.test.InstrumentationTestRunner")
48        A: http://schemas.android.com/apk/res/android:targetPackage(0x01010021)="com.android.my.tests" (Raw: "com.android.my.tests")
49"""
50
51MANIFEST_JUNIT_TEST = """<?xml version="1.0" encoding="utf-8"?>
52<manifest xmlns:android="http://schemas.android.com/apk/res/android"
53  package="com.android.my.tests.x">
54    <instrumentation
55        android:name="androidx.test.runner.AndroidJUnitRunner"
56        android:targetPackage="com.android.my.tests" />
57</manifest>
58"""
59
60MANIFEST_INSTRUMENTATION_TEST = """<?xml version="1.0" encoding="utf-8"?>
61<manifest xmlns:android="http://schemas.android.com/apk/res/android"
62  package="com.android.my.tests.x">
63    <instrumentation
64        android:name="android.test.InstrumentationTestRunner"
65        android:targetPackage="com.android.my.tests"
66        android:label="TestModule" />
67</manifest>
68"""
69
70EXPECTED_JUNIT_TEST_CONFIG = """<?xml version="1.0" encoding="utf-8"?>
71<!-- Copyright (C) 2023 The Android Open Source Project
72
73     Licensed under the Apache License, Version 2.0 (the "License");
74     you may not use this file except in compliance with the License.
75     You may obtain a copy of the License at
76
77          http://www.apache.org/licenses/LICENSE-2.0
78
79     Unless required by applicable law or agreed to in writing, software
80     distributed under the License is distributed on an "AS IS" BASIS,
81     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
82     See the License for the specific language governing permissions and
83     limitations under the License.
84-->
85<!-- This test config file is auto-generated. -->
86<configuration description="Runs TestModule.">
87    <option name="test-suite-tag" value="apct" />
88    <option name="test-suite-tag" value="apct-instrumentation" />
89
90    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
91        <option name="cleanup-apks" value="true" />
92        <option name="test-file-name" value="TestModule.apk" />
93    </target_preparer>
94
95    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
96        <option name="package" value="com.android.my.tests.x" />
97        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
98    </test>
99</configuration>
100"""
101
102EXPECTED_INSTRUMENTATION_TEST_CONFIG = """<?xml version="1.0" encoding="utf-8"?>
103<!-- Copyright (C) 2023 The Android Open Source Project
104
105     Licensed under the Apache License, Version 2.0 (the "License");
106     you may not use this file except in compliance with the License.
107     You may obtain a copy of the License at
108
109          http://www.apache.org/licenses/LICENSE-2.0
110
111     Unless required by applicable law or agreed to in writing, software
112     distributed under the License is distributed on an "AS IS" BASIS,
113     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
114     See the License for the specific language governing permissions and
115     limitations under the License.
116-->
117<!-- This test config file is auto-generated. -->
118<configuration description="Runs TestModule.">
119    <option name="test-suite-tag" value="apct" />
120    <option name="test-suite-tag" value="apct-instrumentation" />
121
122    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
123        <option name="cleanup-apks" value="true" />
124        <option name="test-file-name" value="TestModule.apk" />
125    </target_preparer>
126
127    <test class="com.android.tradefed.testtype.InstrumentationTest" >
128        <option name="package" value="com.android.my.tests.x" />
129        <option name="runner" value="android.test.InstrumentationTestRunner" />
130    </test>
131</configuration>
132"""
133
134EMPTY_TEST_CONFIG_CONTENT = """<?xml version="1.0" encoding="utf-8"?>
135<!-- Copyright (C) 2017 The Android Open Source Project
136
137     Licensed under the Apache License, Version 2.0 (the "License");
138     you may not use this file except in compliance with the License.
139     You may obtain a copy of the License at
140
141          http://www.apache.org/licenses/LICENSE-2.0
142
143     Unless required by applicable law or agreed to in writing, software
144     distributed under the License is distributed on an "AS IS" BASIS,
145     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
146     See the License for the specific language governing permissions and
147     limitations under the License.
148-->
149<!-- No AndroidTest.xml was provided and the manifest does not include
150     instrumentation, hence this apk is not instrumentable.
151-->
152<configuration description="Empty Configuration" />
153"""
154
155INSTRUMENTATION_TEST_CONFIG_TEMPLATE_CONTENT = """<?xml version="1.0" encoding="utf-8"?>
156<!-- Copyright (C) 2023 The Android Open Source Project
157
158     Licensed under the Apache License, Version 2.0 (the "License");
159     you may not use this file except in compliance with the License.
160     You may obtain a copy of the License at
161
162          http://www.apache.org/licenses/LICENSE-2.0
163
164     Unless required by applicable law or agreed to in writing, software
165     distributed under the License is distributed on an "AS IS" BASIS,
166     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
167     See the License for the specific language governing permissions and
168     limitations under the License.
169-->
170<!-- This test config file is auto-generated. -->
171<configuration description="Runs {LABEL}.">
172    <option name="test-suite-tag" value="apct" />
173    <option name="test-suite-tag" value="apct-instrumentation" />
174{EXTRA_CONFIGS}
175    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
176        <option name="cleanup-apks" value="true" />
177        <option name="test-file-name" value="{MODULE}.apk" />
178    </target_preparer>
179
180    <test class="com.android.tradefed.testtype.{TEST_TYPE}" >
181        <option name="package" value="{PACKAGE}" />
182        <option name="runner" value="{RUNNER}" />
183    </test>
184</configuration>
185"""
186
187
188class AutoGenTestConfigUnittests(unittest.TestCase):
189  """Unittests for auto_gen_test_config."""
190
191  def setUp(self):
192    """Setup directory for test."""
193    self.test_dir = tempfile.mkdtemp()
194    self.config_file = os.path.join(self.test_dir, TEST_MODULE + '.config')
195    self.manifest_file = os.path.join(self.test_dir, 'AndroidManifest.xml')
196    self.xmltree_file = os.path.join(self.test_dir, TEST_MODULE + '.xmltree')
197    self.empty_test_config_file = os.path.join(self.test_dir, 'empty.config')
198    self.instrumentation_test_config_template_file = os.path.join(
199        self.test_dir, 'instrumentation.config')
200
201    with open(self.empty_test_config_file, 'w') as f:
202      f.write(EMPTY_TEST_CONFIG_CONTENT)
203
204    with open(self.instrumentation_test_config_template_file, 'w') as f:
205      f.write(INSTRUMENTATION_TEST_CONFIG_TEMPLATE_CONTENT)
206
207  def tearDown(self):
208    """Cleanup the test directory."""
209    shutil.rmtree(self.test_dir, ignore_errors=True)
210
211  def testInvalidManifest(self):
212    """An empty test config should be generated if AndroidManifest is invalid.
213    """
214    with open(self.manifest_file, 'w') as f:
215      f.write(MANIFEST_INVALID)
216
217    argv = [self.config_file,
218            self.manifest_file,
219            self.empty_test_config_file,
220            self.instrumentation_test_config_template_file]
221    auto_gen_test_config.main(argv)
222    with open(self.config_file) as config_file:
223      with open(self.empty_test_config_file) as empty_config:
224        self.assertEqual(config_file.read(), empty_config.read())
225
226  def testCreateJUnitTestConfig(self):
227    """Test creating test config for AndroidJUnitTest.
228    """
229    with open(self.manifest_file, 'w') as f:
230      f.write(MANIFEST_JUNIT_TEST)
231
232    argv = [self.config_file,
233            self.manifest_file,
234            self.empty_test_config_file,
235            self.instrumentation_test_config_template_file]
236    auto_gen_test_config.main(argv)
237    with open(self.config_file) as config_file:
238      self.assertEqual(config_file.read(), EXPECTED_JUNIT_TEST_CONFIG)
239
240  def testCreateInstrumentationTestConfig(self):
241    """Test creating test config for InstrumentationTest.
242    """
243    with open(self.manifest_file, 'w') as f:
244      f.write(MANIFEST_INSTRUMENTATION_TEST)
245
246    argv = [self.config_file,
247            self.manifest_file,
248            self.empty_test_config_file,
249            self.instrumentation_test_config_template_file]
250    auto_gen_test_config.main(argv)
251    with open(self.config_file) as config_file:
252      self.assertEqual(
253          config_file.read(), EXPECTED_INSTRUMENTATION_TEST_CONFIG)
254
255  def testCreateJUnitTestConfigWithXMLTree(self):
256    """Test creating test config for AndroidJUnitTest.
257    """
258    with open(self.xmltree_file, 'w') as f:
259      f.write(XMLTREE_JUNIT_TEST)
260
261    argv = [self.config_file,
262            self.xmltree_file,
263            self.empty_test_config_file,
264            self.instrumentation_test_config_template_file]
265    auto_gen_test_config.main(argv)
266    with open(self.config_file) as config_file:
267      self.assertEqual(config_file.read(), EXPECTED_JUNIT_TEST_CONFIG)
268
269  def testCreateInstrumentationTestConfigWithXMLTree(self):
270    """Test creating test config for InstrumentationTest.
271    """
272    with open(self.xmltree_file, 'w') as f:
273      f.write(XMLTREE_INSTRUMENTATION_TEST)
274
275    argv = [self.config_file,
276            self.xmltree_file,
277            self.empty_test_config_file,
278            self.instrumentation_test_config_template_file]
279    auto_gen_test_config.main(argv)
280    with open(self.config_file) as config_file:
281      self.assertEqual(
282          config_file.read(), EXPECTED_INSTRUMENTATION_TEST_CONFIG)
283
284if __name__ == '__main__':
285  unittest.main()
286