1# Lint as: python3 2# 3# Copyright (C) 2020 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"""Tests for the generate_module package.""" 17 18import io 19import os 20from xml.etree import cElementTree as ET 21import csuite_test 22import generate_module 23from pyfakefs import fake_filesystem_unittest 24 25_AUTO_GENERATE_NOTE = 'THIS FILE WAS AUTO-GENERATED. DO NOT EDIT MANUALLY!' 26 27 28class WriteTestModuleTest(csuite_test.TestCase): 29 30 def test_output_contains_license(self): 31 out = io.StringIO() 32 33 generate_module.write_module(generate_module.DEFAULT_BUILD_MODULE_TEMPLATE, 34 'a.package.name', out) 35 36 self.assertIn('Copyright', out.getvalue()) 37 self.assertIn('Android Open Source Project', out.getvalue()) 38 39 def test_output_is_valid_xml(self): 40 out = io.StringIO() 41 42 generate_module.write_module(generate_module.DEFAULT_TEST_MODULE_TEMPLATE, 43 'a.package.name', out) 44 45 self.assert_valid_xml(out.getvalue()) 46 47 def test_output_contains_package_name(self): 48 package_name = 'a.package.name' 49 out = io.StringIO() 50 51 generate_module.write_module(generate_module.DEFAULT_TEST_MODULE_TEMPLATE, 52 'a.package.name', out) 53 54 self.assertIn(package_name, out.getvalue()) 55 56 def assert_valid_xml(self, xml_str: bytes) -> None: 57 try: 58 ET.parse(io.BytesIO(xml_str.encode('utf8'))) 59 except ET.ParseError as e: 60 self.fail('Input \'%s\' is not a valid XML document: %s' % (xml_str, e)) 61 62 63class WriteBuildModuleTest(csuite_test.TestCase): 64 65 def test_output_contains_license(self): 66 out = io.StringIO() 67 68 generate_module.write_module(generate_module.DEFAULT_BUILD_MODULE_TEMPLATE, 69 'a.package.name', out) 70 71 self.assertIn('Copyright', out.getvalue()) 72 self.assertIn('Android Open Source Project', out.getvalue()) 73 74 def test_output_is_valid_build_file(self): 75 package_name = 'a.package.name' 76 out = io.StringIO() 77 78 generate_module.write_module(generate_module.DEFAULT_BUILD_MODULE_TEMPLATE, 79 'a.package.name', out) 80 81 out_str = out.getvalue() 82 self.assert_braces_balanced(out_str) 83 self.assertIn('csuite_config', out_str) 84 self.assertIn(package_name, out_str) 85 86 def assert_braces_balanced(self, generated_str: bytes) -> None: 87 """Checks whether all braces in the provided string are balanced.""" 88 count = 0 89 90 for c in generated_str: 91 if c == '{': 92 count += 1 93 elif c == '}': 94 count -= 1 95 96 if count < 0: 97 break 98 99 self.assertEqual(count, 0, 100 'Braces in \'%s\' are not balanced' % generated_str) 101 102 103class ParsePackageListTest(csuite_test.TestCase): 104 105 def test_accepts_empty_lines(self): 106 lines = io.StringIO('\n\n\npackage_name\n\n') 107 108 package_list = generate_module.parse_package_list(lines) 109 110 self.assertListEqual(['package_name'], list(package_list)) 111 112 def test_strips_trailing_whitespace(self): 113 lines = io.StringIO(' package_name ') 114 115 package_list = generate_module.parse_package_list(lines) 116 117 self.assertListEqual(['package_name'], list(package_list)) 118 119 def test_duplicate_package_name(self): 120 lines = io.StringIO('\n\npackage_name\n\npackage_name\n') 121 122 package_list = generate_module.parse_package_list(lines) 123 124 self.assertListEqual(['package_name'], list(package_list)) 125 126 def test_ignore_comment_lines(self): 127 lines = io.StringIO('\n# Comments.\npackage_name\n') 128 129 package_list = generate_module.parse_package_list(lines) 130 131 self.assertListEqual(['package_name'], list(package_list)) 132 133 134class ParseArgsTest(fake_filesystem_unittest.TestCase): 135 136 def setUp(self): 137 super(ParseArgsTest, self).setUp() 138 self.setUpPyfakefs() 139 140 def test_configuration_file_not_exist(self): 141 package_list_file_path = '/test/package_list.txt' 142 root_dir = '/test/modules' 143 os.makedirs(root_dir) 144 145 with self.assertRaises(SystemExit): 146 generate_module.parse_args( 147 ['--package-list', package_list_file_path, '--root-dir', root_dir], 148 out=io.StringIO(), 149 err=io.StringIO()) 150 151 def test_module_dir_not_exist(self): 152 package_list_file_path = '/test/package_list.txt' 153 package_name1 = 'package_name_1' 154 package_name2 = 'package_name_2' 155 self.fs.create_file( 156 package_list_file_path, contents=(package_name1 + '\n' + package_name2)) 157 root_dir = '/test/modules' 158 159 with self.assertRaises(SystemExit): 160 generate_module.parse_args( 161 ['--package-list', package_list_file_path, '--root-dir', root_dir], 162 out=io.StringIO(), 163 err=io.StringIO()) 164 165 def test_test_module_template_file_not_exist(self): 166 package_list_file_path = '/test/package_list.txt' 167 package_name1 = 'package_name_1' 168 package_name2 = 'package_name_2' 169 self.fs.create_file( 170 package_list_file_path, contents=(package_name1 + '\n' + package_name2)) 171 root_dir = '/test/modules' 172 os.makedirs(root_dir) 173 template_file_path = '/test/template.txt' 174 175 with self.assertRaises(SystemExit): 176 generate_module.parse_args([ 177 '--package-list', package_list_file_path, '--root-dir', root_dir, 178 '--test', template_file_path 179 ], 180 out=io.StringIO(), 181 err=io.StringIO()) 182 183 def test_build_module_template_file_not_exist(self): 184 package_list_file_path = '/test/package_list.txt' 185 package_name1 = 'package_name_1' 186 package_name2 = 'package_name_2' 187 self.fs.create_file( 188 package_list_file_path, contents=(package_name1 + '\n' + package_name2)) 189 root_dir = '/test/modules' 190 os.makedirs(root_dir) 191 template_file_path = '/test/template.txt' 192 193 with self.assertRaises(SystemExit): 194 generate_module.parse_args([ 195 '--package-list', package_list_file_path, '--root-dir', root_dir, 196 '--template', template_file_path 197 ], 198 out=io.StringIO(), 199 err=io.StringIO()) 200 201 202class GenerateAllModulesFromConfigTest(fake_filesystem_unittest.TestCase): 203 204 def setUp(self): 205 super(GenerateAllModulesFromConfigTest, self).setUp() 206 self.setUpPyfakefs() 207 208 def test_creates_package_files(self): 209 package_list_file_path = '/test/package_list.txt' 210 package_name1 = 'package_name_1' 211 package_name2 = 'package_name_2' 212 self.fs.create_file( 213 package_list_file_path, contents=(package_name1 + '\n' + package_name2)) 214 root_dir = '/test/modules' 215 self.fs.create_dir(root_dir) 216 217 generate_module.generate_all_modules_from_config(package_list_file_path, 218 root_dir) 219 220 self.assertTrue( 221 os.path.exists(os.path.join(root_dir, package_name1, 'Android.bp'))) 222 self.assertTrue( 223 os.path.exists( 224 os.path.join(root_dir, package_name1, 'AndroidTest.xml'))) 225 self.assertTrue( 226 os.path.exists(os.path.join(root_dir, package_name2, 'Android.bp'))) 227 self.assertTrue( 228 os.path.exists( 229 os.path.join(root_dir, package_name2, 'AndroidTest.xml'))) 230 231 def test_removes_all_existing_package_files(self): 232 root_dir = '/test/' 233 package_dir = '/test/existing_package/' 234 self.fs.create_file( 235 'test/existing_package/AndroidTest.xml', contents=_AUTO_GENERATE_NOTE) 236 self.fs.create_file( 237 'test/existing_package/Android.bp', contents=_AUTO_GENERATE_NOTE) 238 239 generate_module.remove_existing_package_files(root_dir) 240 241 self.assertFalse(os.path.exists(package_dir)) 242 243 244if __name__ == '__main__': 245 csuite_test.main() 246