1*9e94795aSAndroid Build Coastguard Worker# 2*9e94795aSAndroid Build Coastguard Worker# Copyright (C) 2017 The Android Open Source Project 3*9e94795aSAndroid Build Coastguard Worker# 4*9e94795aSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 5*9e94795aSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 6*9e94795aSAndroid Build Coastguard Worker# You may obtain a copy of the License at 7*9e94795aSAndroid Build Coastguard Worker# 8*9e94795aSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 9*9e94795aSAndroid Build Coastguard Worker# 10*9e94795aSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 11*9e94795aSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 12*9e94795aSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*9e94795aSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 14*9e94795aSAndroid Build Coastguard Worker# limitations under the License. 15*9e94795aSAndroid Build Coastguard Worker# 16*9e94795aSAndroid Build Coastguard Worker 17*9e94795aSAndroid Build Coastguard Workerimport filecmp 18*9e94795aSAndroid Build Coastguard Workerimport os.path 19*9e94795aSAndroid Build Coastguard Worker 20*9e94795aSAndroid Build Coastguard Workerimport common 21*9e94795aSAndroid Build Coastguard Workerimport test_utils 22*9e94795aSAndroid Build Coastguard Workerfrom build_image import ( 23*9e94795aSAndroid Build Coastguard Worker BuildImageError, CheckHeadroom, GetFilesystemCharacteristics, 24*9e94795aSAndroid Build Coastguard Worker SetUpInDirAndFsConfig) 25*9e94795aSAndroid Build Coastguard Worker 26*9e94795aSAndroid Build Coastguard Worker 27*9e94795aSAndroid Build Coastguard Workerclass BuildImageTest(test_utils.ReleaseToolsTestCase): 28*9e94795aSAndroid Build Coastguard Worker 29*9e94795aSAndroid Build Coastguard Worker # Available: 1000 blocks. 30*9e94795aSAndroid Build Coastguard Worker EXT4FS_OUTPUT = ( 31*9e94795aSAndroid Build Coastguard Worker "Created filesystem with 2777/129024 inodes and 515099/516099 blocks") 32*9e94795aSAndroid Build Coastguard Worker 33*9e94795aSAndroid Build Coastguard Worker def test_CheckHeadroom_SizeUnderLimit(self): 34*9e94795aSAndroid Build Coastguard Worker # Required headroom: 1000 blocks. 35*9e94795aSAndroid Build Coastguard Worker prop_dict = { 36*9e94795aSAndroid Build Coastguard Worker 'fs_type' : 'ext4', 37*9e94795aSAndroid Build Coastguard Worker 'partition_headroom' : '4096000', 38*9e94795aSAndroid Build Coastguard Worker 'mount_point' : 'system', 39*9e94795aSAndroid Build Coastguard Worker } 40*9e94795aSAndroid Build Coastguard Worker CheckHeadroom(self.EXT4FS_OUTPUT, prop_dict) 41*9e94795aSAndroid Build Coastguard Worker 42*9e94795aSAndroid Build Coastguard Worker def test_CheckHeadroom_InsufficientHeadroom(self): 43*9e94795aSAndroid Build Coastguard Worker # Required headroom: 1001 blocks. 44*9e94795aSAndroid Build Coastguard Worker prop_dict = { 45*9e94795aSAndroid Build Coastguard Worker 'fs_type' : 'ext4', 46*9e94795aSAndroid Build Coastguard Worker 'partition_headroom' : '4100096', 47*9e94795aSAndroid Build Coastguard Worker 'mount_point' : 'system', 48*9e94795aSAndroid Build Coastguard Worker } 49*9e94795aSAndroid Build Coastguard Worker self.assertRaises( 50*9e94795aSAndroid Build Coastguard Worker BuildImageError, CheckHeadroom, self.EXT4FS_OUTPUT, prop_dict) 51*9e94795aSAndroid Build Coastguard Worker 52*9e94795aSAndroid Build Coastguard Worker @test_utils.SkipIfExternalToolsUnavailable() 53*9e94795aSAndroid Build Coastguard Worker def test_CheckHeadroom_WrongFsType(self): 54*9e94795aSAndroid Build Coastguard Worker prop_dict = { 55*9e94795aSAndroid Build Coastguard Worker 'fs_type' : 'f2fs', 56*9e94795aSAndroid Build Coastguard Worker 'partition_headroom' : '4100096', 57*9e94795aSAndroid Build Coastguard Worker 'mount_point' : 'system', 58*9e94795aSAndroid Build Coastguard Worker } 59*9e94795aSAndroid Build Coastguard Worker self.assertRaises( 60*9e94795aSAndroid Build Coastguard Worker AssertionError, CheckHeadroom, self.EXT4FS_OUTPUT, prop_dict) 61*9e94795aSAndroid Build Coastguard Worker 62*9e94795aSAndroid Build Coastguard Worker def test_CheckHeadroom_MissingProperties(self): 63*9e94795aSAndroid Build Coastguard Worker prop_dict = { 64*9e94795aSAndroid Build Coastguard Worker 'fs_type' : 'ext4', 65*9e94795aSAndroid Build Coastguard Worker 'partition_headroom' : '4100096', 66*9e94795aSAndroid Build Coastguard Worker } 67*9e94795aSAndroid Build Coastguard Worker self.assertRaises( 68*9e94795aSAndroid Build Coastguard Worker AssertionError, CheckHeadroom, self.EXT4FS_OUTPUT, prop_dict) 69*9e94795aSAndroid Build Coastguard Worker 70*9e94795aSAndroid Build Coastguard Worker prop_dict = { 71*9e94795aSAndroid Build Coastguard Worker 'fs_type' : 'ext4', 72*9e94795aSAndroid Build Coastguard Worker 'mount_point' : 'system', 73*9e94795aSAndroid Build Coastguard Worker } 74*9e94795aSAndroid Build Coastguard Worker self.assertRaises( 75*9e94795aSAndroid Build Coastguard Worker AssertionError, CheckHeadroom, self.EXT4FS_OUTPUT, prop_dict) 76*9e94795aSAndroid Build Coastguard Worker 77*9e94795aSAndroid Build Coastguard Worker @test_utils.SkipIfExternalToolsUnavailable() 78*9e94795aSAndroid Build Coastguard Worker def test_CheckHeadroom_WithMke2fsOutput(self): 79*9e94795aSAndroid Build Coastguard Worker """Tests the result parsing from actual call to mke2fs.""" 80*9e94795aSAndroid Build Coastguard Worker input_dir = common.MakeTempDir() 81*9e94795aSAndroid Build Coastguard Worker output_image = common.MakeTempFile(suffix='.img') 82*9e94795aSAndroid Build Coastguard Worker command = ['mkuserimg_mke2fs', input_dir, output_image, 'ext4', 83*9e94795aSAndroid Build Coastguard Worker '/system', '409600', '-j', '0'] 84*9e94795aSAndroid Build Coastguard Worker proc = common.Run(command) 85*9e94795aSAndroid Build Coastguard Worker ext4fs_output, _ = proc.communicate() 86*9e94795aSAndroid Build Coastguard Worker self.assertEqual(0, proc.returncode) 87*9e94795aSAndroid Build Coastguard Worker 88*9e94795aSAndroid Build Coastguard Worker prop_dict = { 89*9e94795aSAndroid Build Coastguard Worker 'fs_type' : 'ext4', 90*9e94795aSAndroid Build Coastguard Worker 'partition_headroom' : '40960', 91*9e94795aSAndroid Build Coastguard Worker 'mount_point' : 'system', 92*9e94795aSAndroid Build Coastguard Worker } 93*9e94795aSAndroid Build Coastguard Worker CheckHeadroom(ext4fs_output, prop_dict) 94*9e94795aSAndroid Build Coastguard Worker 95*9e94795aSAndroid Build Coastguard Worker prop_dict = { 96*9e94795aSAndroid Build Coastguard Worker 'fs_type' : 'ext4', 97*9e94795aSAndroid Build Coastguard Worker 'partition_headroom' : '413696', 98*9e94795aSAndroid Build Coastguard Worker 'mount_point' : 'system', 99*9e94795aSAndroid Build Coastguard Worker } 100*9e94795aSAndroid Build Coastguard Worker self.assertRaises(BuildImageError, CheckHeadroom, ext4fs_output, prop_dict) 101*9e94795aSAndroid Build Coastguard Worker 102*9e94795aSAndroid Build Coastguard Worker def test_SetUpInDirAndFsConfig_NonSystem(self): 103*9e94795aSAndroid Build Coastguard Worker prop_dict = { 104*9e94795aSAndroid Build Coastguard Worker 'fs_config': 'fs-config', 105*9e94795aSAndroid Build Coastguard Worker 'mount_point': 'vendor', 106*9e94795aSAndroid Build Coastguard Worker } 107*9e94795aSAndroid Build Coastguard Worker in_dir, fs_config = SetUpInDirAndFsConfig('/path/to/in_dir', prop_dict) 108*9e94795aSAndroid Build Coastguard Worker self.assertEqual('/path/to/in_dir', in_dir) 109*9e94795aSAndroid Build Coastguard Worker self.assertEqual('fs-config', fs_config) 110*9e94795aSAndroid Build Coastguard Worker self.assertEqual('vendor', prop_dict['mount_point']) 111*9e94795aSAndroid Build Coastguard Worker 112*9e94795aSAndroid Build Coastguard Worker @staticmethod 113*9e94795aSAndroid Build Coastguard Worker def _gen_fs_config(partition): 114*9e94795aSAndroid Build Coastguard Worker fs_config = common.MakeTempFile(suffix='.txt') 115*9e94795aSAndroid Build Coastguard Worker with open(fs_config, 'w') as fs_config_fp: 116*9e94795aSAndroid Build Coastguard Worker fs_config_fp.write('fs-config-{}\n'.format(partition)) 117*9e94795aSAndroid Build Coastguard Worker return fs_config 118*9e94795aSAndroid Build Coastguard Worker 119*9e94795aSAndroid Build Coastguard Worker def test_SetUpInDirAndFsConfig(self): 120*9e94795aSAndroid Build Coastguard Worker root_dir = common.MakeTempDir() 121*9e94795aSAndroid Build Coastguard Worker with open(os.path.join(root_dir, 'init'), 'w') as init_fp: 122*9e94795aSAndroid Build Coastguard Worker init_fp.write('init') 123*9e94795aSAndroid Build Coastguard Worker 124*9e94795aSAndroid Build Coastguard Worker origin_in = common.MakeTempDir() 125*9e94795aSAndroid Build Coastguard Worker with open(os.path.join(origin_in, 'file'), 'w') as in_fp: 126*9e94795aSAndroid Build Coastguard Worker in_fp.write('system-file') 127*9e94795aSAndroid Build Coastguard Worker os.symlink('../etc', os.path.join(origin_in, 'symlink')) 128*9e94795aSAndroid Build Coastguard Worker 129*9e94795aSAndroid Build Coastguard Worker fs_config_system = self._gen_fs_config('system') 130*9e94795aSAndroid Build Coastguard Worker 131*9e94795aSAndroid Build Coastguard Worker prop_dict = { 132*9e94795aSAndroid Build Coastguard Worker 'fs_config': fs_config_system, 133*9e94795aSAndroid Build Coastguard Worker 'mount_point': 'system', 134*9e94795aSAndroid Build Coastguard Worker 'root_dir': root_dir, 135*9e94795aSAndroid Build Coastguard Worker } 136*9e94795aSAndroid Build Coastguard Worker in_dir, fs_config = SetUpInDirAndFsConfig(origin_in, prop_dict) 137*9e94795aSAndroid Build Coastguard Worker 138*9e94795aSAndroid Build Coastguard Worker self.assertTrue(filecmp.cmp( 139*9e94795aSAndroid Build Coastguard Worker os.path.join(in_dir, 'init'), os.path.join(root_dir, 'init'))) 140*9e94795aSAndroid Build Coastguard Worker self.assertTrue(filecmp.cmp( 141*9e94795aSAndroid Build Coastguard Worker os.path.join(in_dir, 'system', 'file'), 142*9e94795aSAndroid Build Coastguard Worker os.path.join(origin_in, 'file'))) 143*9e94795aSAndroid Build Coastguard Worker self.assertTrue(os.path.islink(os.path.join(in_dir, 'system', 'symlink'))) 144*9e94795aSAndroid Build Coastguard Worker 145*9e94795aSAndroid Build Coastguard Worker self.assertTrue(filecmp.cmp(fs_config_system, fs_config)) 146*9e94795aSAndroid Build Coastguard Worker self.assertEqual('/', prop_dict['mount_point']) 147*9e94795aSAndroid Build Coastguard Worker 148*9e94795aSAndroid Build Coastguard Worker def test_SetUpInDirAndFsConfig_WithRootFsConfig(self): 149*9e94795aSAndroid Build Coastguard Worker root_dir = common.MakeTempDir() 150*9e94795aSAndroid Build Coastguard Worker with open(os.path.join(root_dir, 'init'), 'w') as init_fp: 151*9e94795aSAndroid Build Coastguard Worker init_fp.write('init') 152*9e94795aSAndroid Build Coastguard Worker 153*9e94795aSAndroid Build Coastguard Worker origin_in = common.MakeTempDir() 154*9e94795aSAndroid Build Coastguard Worker with open(os.path.join(origin_in, 'file'), 'w') as in_fp: 155*9e94795aSAndroid Build Coastguard Worker in_fp.write('system-file') 156*9e94795aSAndroid Build Coastguard Worker os.symlink('../etc', os.path.join(origin_in, 'symlink')) 157*9e94795aSAndroid Build Coastguard Worker 158*9e94795aSAndroid Build Coastguard Worker fs_config_system = self._gen_fs_config('system') 159*9e94795aSAndroid Build Coastguard Worker fs_config_root = self._gen_fs_config('root') 160*9e94795aSAndroid Build Coastguard Worker 161*9e94795aSAndroid Build Coastguard Worker prop_dict = { 162*9e94795aSAndroid Build Coastguard Worker 'fs_config': fs_config_system, 163*9e94795aSAndroid Build Coastguard Worker 'mount_point': 'system', 164*9e94795aSAndroid Build Coastguard Worker 'root_dir': root_dir, 165*9e94795aSAndroid Build Coastguard Worker 'root_fs_config': fs_config_root, 166*9e94795aSAndroid Build Coastguard Worker } 167*9e94795aSAndroid Build Coastguard Worker in_dir, fs_config = SetUpInDirAndFsConfig(origin_in, prop_dict) 168*9e94795aSAndroid Build Coastguard Worker 169*9e94795aSAndroid Build Coastguard Worker self.assertTrue(filecmp.cmp( 170*9e94795aSAndroid Build Coastguard Worker os.path.join(in_dir, 'init'), os.path.join(root_dir, 'init'))) 171*9e94795aSAndroid Build Coastguard Worker self.assertTrue(filecmp.cmp( 172*9e94795aSAndroid Build Coastguard Worker os.path.join(in_dir, 'system', 'file'), 173*9e94795aSAndroid Build Coastguard Worker os.path.join(origin_in, 'file'))) 174*9e94795aSAndroid Build Coastguard Worker self.assertTrue(os.path.islink(os.path.join(in_dir, 'system', 'symlink'))) 175*9e94795aSAndroid Build Coastguard Worker 176*9e94795aSAndroid Build Coastguard Worker with open(fs_config) as fs_config_fp: 177*9e94795aSAndroid Build Coastguard Worker fs_config_data = fs_config_fp.readlines() 178*9e94795aSAndroid Build Coastguard Worker self.assertIn('fs-config-system\n', fs_config_data) 179*9e94795aSAndroid Build Coastguard Worker self.assertIn('fs-config-root\n', fs_config_data) 180*9e94795aSAndroid Build Coastguard Worker self.assertEqual('/', prop_dict['mount_point']) 181*9e94795aSAndroid Build Coastguard Worker 182*9e94795aSAndroid Build Coastguard Worker @test_utils.SkipIfExternalToolsUnavailable() 183*9e94795aSAndroid Build Coastguard Worker def test_GetFilesystemCharacteristics(self): 184*9e94795aSAndroid Build Coastguard Worker input_dir = common.MakeTempDir() 185*9e94795aSAndroid Build Coastguard Worker output_image = common.MakeTempFile(suffix='.img') 186*9e94795aSAndroid Build Coastguard Worker command = ['mkuserimg_mke2fs', input_dir, output_image, 'ext4', 187*9e94795aSAndroid Build Coastguard Worker '/system', '409600', '-j', '0'] 188*9e94795aSAndroid Build Coastguard Worker proc = common.Run(command) 189*9e94795aSAndroid Build Coastguard Worker proc.communicate() 190*9e94795aSAndroid Build Coastguard Worker self.assertEqual(0, proc.returncode) 191*9e94795aSAndroid Build Coastguard Worker 192*9e94795aSAndroid Build Coastguard Worker output_file = common.MakeTempFile(suffix='.img') 193*9e94795aSAndroid Build Coastguard Worker cmd = ["img2simg", output_image, output_file] 194*9e94795aSAndroid Build Coastguard Worker p = common.Run(cmd) 195*9e94795aSAndroid Build Coastguard Worker p.communicate() 196*9e94795aSAndroid Build Coastguard Worker self.assertEqual(0, p.returncode) 197*9e94795aSAndroid Build Coastguard Worker 198*9e94795aSAndroid Build Coastguard Worker fs_dict = GetFilesystemCharacteristics('ext4', output_file) 199*9e94795aSAndroid Build Coastguard Worker self.assertEqual(int(fs_dict['Block size']), 4096) 200*9e94795aSAndroid Build Coastguard Worker self.assertGreaterEqual(int(fs_dict['Free blocks']), 0) # expect ~88 201*9e94795aSAndroid Build Coastguard Worker self.assertGreater(int(fs_dict['Inode count']), 0) # expect ~64 202*9e94795aSAndroid Build Coastguard Worker self.assertGreaterEqual(int(fs_dict['Free inodes']), 0) # expect ~53 203*9e94795aSAndroid Build Coastguard Worker self.assertGreater(int(fs_dict['Inode count']), int(fs_dict['Free inodes'])) 204