1#!/usr/bin/env python 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 17import io 18import os 19import unittest 20 21from lxml import etree 22from pyfakefs import fake_filesystem_unittest 23 24import generate_module 25 26 27class WriteTestModuleTest(unittest.TestCase): 28 29 def test_xml_is_valid(self): 30 package_name = 'package_name' 31 out = io.StringIO() 32 33 generate_module.write_test_module(package_name, out) 34 35 test_module_generated = out.getvalue() 36 self.assertTrue(self._contains_license(test_module_generated)) 37 self.assertTrue(self._is_validate_xml(test_module_generated)) 38 39 def _contains_license(self, generated_str: bytes) -> bool: 40 return 'Copyright' in generated_str and \ 41 'Android Open Source Project' in generated_str 42 43 def _is_validate_xml(self, xml_str: bytes) -> bool: 44 xmlschema_doc = etree.parse( 45 io.BytesIO('''<?xml version="1.0" encoding="UTF-8" ?> 46 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 47 <xs:element name="configuration"> 48 <xs:complexType> 49 <xs:sequence> 50 <xs:element name="option" minOccurs="0" maxOccurs="unbounded"/> 51 <xs:element name="target_preparer" minOccurs="0" maxOccurs="unbounded"/> 52 <xs:element name="test" minOccurs="0" maxOccurs="unbounded"/> 53 </xs:sequence> 54 <xs:attribute name="description"/> 55 </xs:complexType> 56 </xs:element> 57 </xs:schema> 58 '''.encode('utf8'))) 59 xmlschema = etree.XMLSchema(xmlschema_doc) 60 61 xml_doc = etree.parse(io.BytesIO(xml_str.encode('utf8'))) 62 result = xmlschema.validate(xml_doc) 63 64 return result 65 66 67class WriteBuildModuleTest(unittest.TestCase): 68 69 def test_build_file_is_valid(self): 70 package_name = 'package_name' 71 out = io.StringIO() 72 73 generate_module.write_build_module(package_name, out) 74 75 build_module_generated = out.getvalue() 76 self.assertTrue(self._contains_license(build_module_generated)) 77 self.assertTrue(self._are_parentheses_balanced(build_module_generated)) 78 self.assertIn('csuite_config', build_module_generated) 79 self.assertIn(package_name, build_module_generated) 80 81 def _contains_license(self, generated_str: bytes) -> bool: 82 return 'Copyright' in generated_str and \ 83 'Android Open Source Project' in generated_str 84 85 def _are_parentheses_balanced(self, generated_str: bytes) -> bool: 86 parenthese_count = 0 87 88 for elem in generated_str: 89 if elem == '{': 90 parenthese_count += 1 91 elif elem == '}': 92 parenthese_count -= 1 93 94 if parenthese_count < 0: 95 return False 96 97 return parenthese_count == 0 98 99 100class ParsePackageListTest(unittest.TestCase): 101 102 def test_accepts_empty_lines(self): 103 input = io.StringIO('\n\n\npackage_name\n\n') 104 105 package_list = generate_module.parse_package_list(input) 106 107 self.assertEqual(len(package_list), 1) 108 self.assertIn('package_name', package_list) 109 self.assertTrue(all(package_list)) 110 111 def test_strips_trailing_whitespace(self): 112 input = io.StringIO(' package_name ') 113 114 package_list = generate_module.parse_package_list(input) 115 116 self.assertEqual(len(package_list), 1) 117 self.assertIn('package_name', package_list) 118 self.assertTrue(all(package_list)) 119 120 def test_duplicate_package_name(self): 121 input = io.StringIO('\n\npackage_name\n\npackage_name\n') 122 123 package_list = generate_module.parse_package_list(input) 124 125 self.assertEqual(len(package_list), 1) 126 self.assertIn('package_name', package_list) 127 self.assertTrue(all(package_list)) 128 129 130class ParseArgsTest(fake_filesystem_unittest.TestCase): 131 132 def setUp(self): 133 super(ParseArgsTest, self).setUp() 134 self.setUpPyfakefs() 135 136 def test_configuration_file_not_exist(self): 137 package_list_file_path = '/test/package_list.txt' 138 root_dir = '/test/modules' 139 os.makedirs(root_dir) 140 141 with self.assertRaises(SystemExit): 142 generate_module.parse_args( 143 ['--package_list', package_list_file_path, 144 '--root_dir', root_dir]) 145 146 def test_module_dir_not_exist(self): 147 package_list_file_path = '/test/package_list.txt' 148 package_name1 = 'package_name_1' 149 package_name2 = 'package_name_2' 150 self.fs.create_file(package_list_file_path, 151 contents=(package_name1+'\n'+package_name2)) 152 root_dir = '/test/modules' 153 154 with self.assertRaises(SystemExit): 155 generate_module.parse_args( 156 ['--package_list', package_list_file_path, 157 '--root_dir', root_dir]) 158 159 160class GenerateAllModulesFromConfigTest(fake_filesystem_unittest.TestCase): 161 162 def setUp(self): 163 super(GenerateAllModulesFromConfigTest, self).setUp() 164 self.setUpPyfakefs() 165 166 def test_creates_package_files(self): 167 package_list_file_path = '/test/package_list.txt' 168 package_name1 = 'package_name_1' 169 package_name2 = 'package_name_2' 170 self.fs.create_file(package_list_file_path, 171 contents=(package_name1+'\n'+package_name2)) 172 root_dir = '/test/modules' 173 self.fs.create_dir(root_dir) 174 175 generate_module.generate_all_modules_from_config( 176 package_list_file_path, root_dir) 177 178 self.assertTrue(os.path.exists( 179 os.path.join(root_dir, package_name1, 'Android.bp'))) 180 self.assertTrue(os.path.exists( 181 os.path.join(root_dir, package_name1, 'AndroidTest.xml'))) 182 self.assertTrue(os.path.exists( 183 os.path.join(root_dir, package_name2, 'Android.bp'))) 184 self.assertTrue(os.path.exists( 185 os.path.join(root_dir, package_name2, 'AndroidTest.xml'))) 186 187 def test_removes_all_existing_package_files(self): 188 root_dir = '/test/' 189 package_dir = '/test/existing_package/' 190 existing_package_file1 = 'test/existing_package/AndroidTest.xml' 191 existing_package_file2 = 'test/existing_package/Android.bp' 192 self.fs.create_file(existing_package_file1, contents='auto-generated') 193 self.fs.create_file(existing_package_file2, contents='auto-generated') 194 195 generate_module.remove_existing_package_files(root_dir) 196 197 self.assertFalse(os.path.exists(existing_package_file1)) 198 self.assertFalse(os.path.exists(existing_package_file2)) 199 self.assertFalse(os.path.exists(package_dir)) 200 201 202if __name__ == '__main__': 203 unittest.main() 204