1# 2# Copyright (C) 2017 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 17import filecmp 18import os.path 19 20import common 21from build_image import ( 22 BuildImageError, CheckHeadroom, GetFilesystemCharacteristics, SetUpInDirAndFsConfig) 23from test_utils import ReleaseToolsTestCase 24 25 26class BuildImageTest(ReleaseToolsTestCase): 27 28 # Available: 1000 blocks. 29 EXT4FS_OUTPUT = ( 30 "Created filesystem with 2777/129024 inodes and 515099/516099 blocks") 31 32 def test_CheckHeadroom_SizeUnderLimit(self): 33 # Required headroom: 1000 blocks. 34 prop_dict = { 35 'fs_type' : 'ext4', 36 'partition_headroom' : '4096000', 37 'mount_point' : 'system', 38 } 39 CheckHeadroom(self.EXT4FS_OUTPUT, prop_dict) 40 41 def test_CheckHeadroom_InsufficientHeadroom(self): 42 # Required headroom: 1001 blocks. 43 prop_dict = { 44 'fs_type' : 'ext4', 45 'partition_headroom' : '4100096', 46 'mount_point' : 'system', 47 } 48 self.assertRaises( 49 BuildImageError, CheckHeadroom, self.EXT4FS_OUTPUT, prop_dict) 50 51 def test_CheckHeadroom_WrongFsType(self): 52 prop_dict = { 53 'fs_type' : 'f2fs', 54 'partition_headroom' : '4100096', 55 'mount_point' : 'system', 56 } 57 self.assertRaises( 58 AssertionError, CheckHeadroom, self.EXT4FS_OUTPUT, prop_dict) 59 60 def test_CheckHeadroom_MissingProperties(self): 61 prop_dict = { 62 'fs_type' : 'ext4', 63 'partition_headroom' : '4100096', 64 } 65 self.assertRaises( 66 AssertionError, CheckHeadroom, self.EXT4FS_OUTPUT, prop_dict) 67 68 prop_dict = { 69 'fs_type' : 'ext4', 70 'mount_point' : 'system', 71 } 72 self.assertRaises( 73 AssertionError, CheckHeadroom, self.EXT4FS_OUTPUT, prop_dict) 74 75 def test_CheckHeadroom_WithMke2fsOutput(self): 76 """Tests the result parsing from actual call to mke2fs.""" 77 input_dir = common.MakeTempDir() 78 output_image = common.MakeTempFile(suffix='.img') 79 command = ['mkuserimg_mke2fs', input_dir, output_image, 'ext4', 80 '/system', '409600', '-j', '0'] 81 proc = common.Run(command) 82 ext4fs_output, _ = proc.communicate() 83 self.assertEqual(0, proc.returncode) 84 85 prop_dict = { 86 'fs_type' : 'ext4', 87 'partition_headroom' : '40960', 88 'mount_point' : 'system', 89 } 90 CheckHeadroom(ext4fs_output, prop_dict) 91 92 prop_dict = { 93 'fs_type' : 'ext4', 94 'partition_headroom' : '413696', 95 'mount_point' : 'system', 96 } 97 self.assertRaises(BuildImageError, CheckHeadroom, ext4fs_output, prop_dict) 98 99 def test_SetUpInDirAndFsConfig_SystemRootImageTrue_NonSystem(self): 100 prop_dict = { 101 'fs_config': 'fs-config', 102 'mount_point': 'vendor', 103 'system_root_image': 'true', 104 } 105 in_dir, fs_config = SetUpInDirAndFsConfig('/path/to/in_dir', prop_dict) 106 self.assertEqual('/path/to/in_dir', in_dir) 107 self.assertEqual('fs-config', fs_config) 108 self.assertEqual('vendor', prop_dict['mount_point']) 109 110 @staticmethod 111 def _gen_fs_config(partition): 112 fs_config = common.MakeTempFile(suffix='.txt') 113 with open(fs_config, 'w') as fs_config_fp: 114 fs_config_fp.write('fs-config-{}\n'.format(partition)) 115 return fs_config 116 117 def test_SetUpInDirAndFsConfig(self): 118 root_dir = common.MakeTempDir() 119 with open(os.path.join(root_dir, 'init'), 'w') as init_fp: 120 init_fp.write('init') 121 122 origin_in = common.MakeTempDir() 123 with open(os.path.join(origin_in, 'file'), 'w') as in_fp: 124 in_fp.write('system-file') 125 os.symlink('../etc', os.path.join(origin_in, 'symlink')) 126 127 fs_config_system = self._gen_fs_config('system') 128 129 prop_dict = { 130 'fs_config': fs_config_system, 131 'mount_point': 'system', 132 'root_dir': root_dir, 133 } 134 in_dir, fs_config = SetUpInDirAndFsConfig(origin_in, prop_dict) 135 136 self.assertTrue(filecmp.cmp( 137 os.path.join(in_dir, 'init'), os.path.join(root_dir, 'init'))) 138 self.assertTrue(filecmp.cmp( 139 os.path.join(in_dir, 'system', 'file'), 140 os.path.join(origin_in, 'file'))) 141 self.assertTrue(os.path.islink(os.path.join(in_dir, 'system', 'symlink'))) 142 143 self.assertTrue(filecmp.cmp(fs_config_system, fs_config)) 144 self.assertEqual('/', prop_dict['mount_point']) 145 146 def test_SetUpInDirAndFsConfig_WithRootFsConfig(self): 147 root_dir = common.MakeTempDir() 148 with open(os.path.join(root_dir, 'init'), 'w') as init_fp: 149 init_fp.write('init') 150 151 origin_in = common.MakeTempDir() 152 with open(os.path.join(origin_in, 'file'), 'w') as in_fp: 153 in_fp.write('system-file') 154 os.symlink('../etc', os.path.join(origin_in, 'symlink')) 155 156 fs_config_system = self._gen_fs_config('system') 157 fs_config_root = self._gen_fs_config('root') 158 159 prop_dict = { 160 'fs_config': fs_config_system, 161 'mount_point': 'system', 162 'root_dir': root_dir, 163 'root_fs_config': fs_config_root, 164 } 165 in_dir, fs_config = SetUpInDirAndFsConfig(origin_in, prop_dict) 166 167 self.assertTrue(filecmp.cmp( 168 os.path.join(in_dir, 'init'), os.path.join(root_dir, 'init'))) 169 self.assertTrue(filecmp.cmp( 170 os.path.join(in_dir, 'system', 'file'), 171 os.path.join(origin_in, 'file'))) 172 self.assertTrue(os.path.islink(os.path.join(in_dir, 'system', 'symlink'))) 173 174 with open(fs_config) as fs_config_fp: 175 fs_config_data = fs_config_fp.readlines() 176 self.assertIn('fs-config-system\n', fs_config_data) 177 self.assertIn('fs-config-root\n', fs_config_data) 178 self.assertEqual('/', prop_dict['mount_point']) 179 180 def test_GetFilesystemCharacteristics(self): 181 input_dir = common.MakeTempDir() 182 output_image = common.MakeTempFile(suffix='.img') 183 command = ['mkuserimg_mke2fs', input_dir, output_image, 'ext4', 184 '/system', '409600', '-j', '0'] 185 proc = common.Run(command) 186 ext4fs_output, _ = proc.communicate() 187 self.assertEqual(0, proc.returncode) 188 189 output_file = common.MakeTempFile(suffix='.img') 190 cmd = ["img2simg", output_image, output_file] 191 p = common.Run(cmd) 192 p.communicate() 193 self.assertEqual(0, p.returncode) 194 195 fs_dict = GetFilesystemCharacteristics(output_file) 196 self.assertEqual(int(fs_dict['Block size']), 4096) 197 self.assertGreaterEqual(int(fs_dict['Free blocks']), 0) # expect ~88 198 self.assertGreater(int(fs_dict['Inode count']), 0) # expect ~64 199 self.assertGreaterEqual(int(fs_dict['Free inodes']), 0) # expect ~53 200 self.assertGreater(int(fs_dict['Inode count']), int(fs_dict['Free inodes'])) 201