diff --git a/tools/releasetools/TEST_MAPPING b/tools/releasetools/TEST_MAPPING new file mode 100644 index 0000000000..77cef07d84 --- /dev/null +++ b/tools/releasetools/TEST_MAPPING @@ -0,0 +1,8 @@ +{ + "presubmit": [ + { + "name": "releasetools_test", + "host": true + } + ] +} diff --git a/tools/releasetools/test_add_img_to_target_files.py b/tools/releasetools/test_add_img_to_target_files.py index 482f86c7cd..013ade65b6 100644 --- a/tools/releasetools/test_add_img_to_target_files.py +++ b/tools/releasetools/test_add_img_to_target_files.py @@ -34,18 +34,6 @@ class AddImagesToTargetFilesTest(test_utils.ReleaseToolsTestCase): def setUp(self): OPTIONS.input_tmp = common.MakeTempDir() - def _verifyCareMap(self, expected, file_name): - """Parses the care_map.pb; and checks the content in plain text.""" - text_file = common.MakeTempFile(prefix="caremap-", suffix=".txt") - - # Calls an external binary to convert the proto message. - cmd = ["care_map_generator", "--parse_proto", file_name, text_file] - common.RunAndCheckOutput(cmd) - - with open(text_file, 'r') as verify_fp: - plain_text = verify_fp.read() - self.assertEqual('\n'.join(expected), plain_text) - @staticmethod def _create_images(images, prefix): """Creates images under OPTIONS.input_tmp/prefix.""" @@ -164,6 +152,19 @@ class AddImagesToTargetFilesTest(test_utils.ReleaseToolsTestCase): } return image_paths + def _verifyCareMap(self, expected, file_name): + """Parses the care_map.pb; and checks the content in plain text.""" + text_file = common.MakeTempFile(prefix="caremap-", suffix=".txt") + + # Calls an external binary to convert the proto message. + cmd = ["care_map_generator", "--parse_proto", file_name, text_file] + common.RunAndCheckOutput(cmd) + + with open(text_file) as verify_fp: + plain_text = verify_fp.read() + self.assertEqual('\n'.join(expected), plain_text) + + @test_utils.SkipIfExternalToolsUnavailable() def test_AddCareMapForAbOta(self): image_paths = self._test_AddCareMapForAbOta() @@ -179,6 +180,7 @@ class AddImagesToTargetFilesTest(test_utils.ReleaseToolsTestCase): self._verifyCareMap(expected, care_map_file) + @test_utils.SkipIfExternalToolsUnavailable() def test_AddCareMapForAbOta_withNonCareMapPartitions(self): """Partitions without care_map should be ignored.""" image_paths = self._test_AddCareMapForAbOta() @@ -196,6 +198,7 @@ class AddImagesToTargetFilesTest(test_utils.ReleaseToolsTestCase): self._verifyCareMap(expected, care_map_file) + @test_utils.SkipIfExternalToolsUnavailable() def test_AddCareMapForAbOta_withAvb(self): """Tests the case for device using AVB.""" image_paths = self._test_AddCareMapForAbOta() @@ -223,6 +226,7 @@ class AddImagesToTargetFilesTest(test_utils.ReleaseToolsTestCase): self._verifyCareMap(expected, care_map_file) + @test_utils.SkipIfExternalToolsUnavailable() def test_AddCareMapForAbOta_noFingerprint(self): """Tests the case for partitions without fingerprint.""" image_paths = self._test_AddCareMapForAbOta() @@ -240,6 +244,7 @@ class AddImagesToTargetFilesTest(test_utils.ReleaseToolsTestCase): self._verifyCareMap(expected, care_map_file) + @test_utils.SkipIfExternalToolsUnavailable() def test_AddCareMapForAbOta_withThumbprint(self): """Tests the case for partitions with thumbprint.""" image_paths = self._test_AddCareMapForAbOta() @@ -282,6 +287,7 @@ class AddImagesToTargetFilesTest(test_utils.ReleaseToolsTestCase): self.assertRaises(AssertionError, AddCareMapForAbOta, None, ['system', 'vendor'], image_paths) + @test_utils.SkipIfExternalToolsUnavailable() def test_AddCareMapForAbOta_zipOutput(self): """Tests the case with ZIP output.""" image_paths = self._test_AddCareMapForAbOta() @@ -304,6 +310,7 @@ class AddImagesToTargetFilesTest(test_utils.ReleaseToolsTestCase): "google/sailfish/678:user/dev-keys"] self._verifyCareMap(expected, os.path.join(temp_dir, care_map_name)) + @test_utils.SkipIfExternalToolsUnavailable() def test_AddCareMapForAbOta_zipOutput_careMapEntryExists(self): """Tests the case with ZIP output which already has care_map entry.""" image_paths = self._test_AddCareMapForAbOta() @@ -338,6 +345,7 @@ class AddImagesToTargetFilesTest(test_utils.ReleaseToolsTestCase): self.assertEqual( ['--include_descriptors_from_image', '/path/to/system.img'], cmd) + @test_utils.SkipIfExternalToolsUnavailable() def test_AppendVBMetaArgsForPartition_vendorAsChainedPartition(self): testdata_dir = test_utils.get_testdata_dir() pubkey = os.path.join(testdata_dir, 'testkey.pubkey.pem') diff --git a/tools/releasetools/test_apex_utils.py b/tools/releasetools/test_apex_utils.py index 76d4d58df2..c7d5807302 100644 --- a/tools/releasetools/test_apex_utils.py +++ b/tools/releasetools/test_apex_utils.py @@ -39,6 +39,7 @@ class ApexUtilsTest(test_utils.ReleaseToolsTestCase): payload_fp.write(os.urandom(8192)) return payload_file + @test_utils.SkipIfExternalToolsUnavailable() def test_ParseApexPayloadInfo(self): payload_file = self._GetTestPayload() apex_utils.SignApexPayload( @@ -48,12 +49,14 @@ class ApexUtilsTest(test_utils.ReleaseToolsTestCase): self.assertEqual(self.SALT, payload_info['Salt']) self.assertEqual('testkey', payload_info['apex.key']) + @test_utils.SkipIfExternalToolsUnavailable() def test_SignApexPayload(self): payload_file = self._GetTestPayload() apex_utils.SignApexPayload( payload_file, self.payload_key, 'testkey', 'SHA256_RSA2048', self.SALT) apex_utils.VerifyApexPayload(payload_file, self.payload_key) + @test_utils.SkipIfExternalToolsUnavailable() def test_SignApexPayload_withSignerHelper(self): payload_file = self._GetTestPayload() signing_helper = os.path.join(self.testdata_dir, 'signing_helper.sh') @@ -67,6 +70,7 @@ class ApexUtilsTest(test_utils.ReleaseToolsTestCase): payload_signer_args) apex_utils.VerifyApexPayload(payload_file, self.payload_key) + @test_utils.SkipIfExternalToolsUnavailable() def test_SignApexPayload_invalidKey(self): self.assertRaises( apex_utils.ApexSigningError, @@ -77,6 +81,7 @@ class ApexUtilsTest(test_utils.ReleaseToolsTestCase): 'SHA256_RSA2048', self.SALT) + @test_utils.SkipIfExternalToolsUnavailable() def test_VerifyApexPayload_wrongKey(self): payload_file = self._GetTestPayload() apex_utils.SignApexPayload( diff --git a/tools/releasetools/test_build_image.py b/tools/releasetools/test_build_image.py index 1cebd0c095..b24805f319 100644 --- a/tools/releasetools/test_build_image.py +++ b/tools/releasetools/test_build_image.py @@ -18,12 +18,13 @@ import filecmp import os.path import common +import test_utils from build_image import ( - BuildImageError, CheckHeadroom, GetFilesystemCharacteristics, SetUpInDirAndFsConfig) -from test_utils import ReleaseToolsTestCase + BuildImageError, CheckHeadroom, GetFilesystemCharacteristics, + SetUpInDirAndFsConfig) -class BuildImageTest(ReleaseToolsTestCase): +class BuildImageTest(test_utils.ReleaseToolsTestCase): # Available: 1000 blocks. EXT4FS_OUTPUT = ( @@ -48,6 +49,7 @@ class BuildImageTest(ReleaseToolsTestCase): self.assertRaises( BuildImageError, CheckHeadroom, self.EXT4FS_OUTPUT, prop_dict) + @test_utils.SkipIfExternalToolsUnavailable() def test_CheckHeadroom_WrongFsType(self): prop_dict = { 'fs_type' : 'f2fs', @@ -72,6 +74,7 @@ class BuildImageTest(ReleaseToolsTestCase): self.assertRaises( AssertionError, CheckHeadroom, self.EXT4FS_OUTPUT, prop_dict) + @test_utils.SkipIfExternalToolsUnavailable() def test_CheckHeadroom_WithMke2fsOutput(self): """Tests the result parsing from actual call to mke2fs.""" input_dir = common.MakeTempDir() @@ -177,13 +180,14 @@ class BuildImageTest(ReleaseToolsTestCase): self.assertIn('fs-config-root\n', fs_config_data) self.assertEqual('/', prop_dict['mount_point']) + @test_utils.SkipIfExternalToolsUnavailable() def test_GetFilesystemCharacteristics(self): input_dir = common.MakeTempDir() output_image = common.MakeTempFile(suffix='.img') command = ['mkuserimg_mke2fs', input_dir, output_image, 'ext4', '/system', '409600', '-j', '0'] proc = common.Run(command) - ext4fs_output, _ = proc.communicate() + proc.communicate() self.assertEqual(0, proc.returncode) output_file = common.MakeTempFile(suffix='.img') diff --git a/tools/releasetools/test_common.py b/tools/releasetools/test_common.py index 89add4093c..9b76734fab 100644 --- a/tools/releasetools/test_common.py +++ b/tools/releasetools/test_common.py @@ -315,6 +315,7 @@ class CommonZipTest(test_utils.ReleaseToolsTestCase): finally: os.remove(zip_file_name) + @test_utils.SkipIfExternalToolsUnavailable() def test_ZipDelete(self): zip_file = tempfile.NamedTemporaryFile(delete=False, suffix='.zip') output_zip = zipfile.ZipFile(zip_file.name, 'w', @@ -376,6 +377,7 @@ class CommonZipTest(test_utils.ReleaseToolsTestCase): common.ZipClose(output_zip) return zip_file + @test_utils.SkipIfExternalToolsUnavailable() def test_UnzipTemp(self): zip_file = self._test_UnzipTemp_createZipFile() unzipped_dir = common.UnzipTemp(zip_file) @@ -385,6 +387,7 @@ class CommonZipTest(test_utils.ReleaseToolsTestCase): self.assertTrue(os.path.exists(os.path.join(unzipped_dir, 'Bar4'))) self.assertTrue(os.path.exists(os.path.join(unzipped_dir, 'Dir5/Baz5'))) + @test_utils.SkipIfExternalToolsUnavailable() def test_UnzipTemp_withPatterns(self): zip_file = self._test_UnzipTemp_createZipFile() @@ -425,6 +428,7 @@ class CommonZipTest(test_utils.ReleaseToolsTestCase): self.assertFalse(os.path.exists(os.path.join(unzipped_dir, 'Bar4'))) self.assertFalse(os.path.exists(os.path.join(unzipped_dir, 'Dir5/Baz5'))) + @test_utils.SkipIfExternalToolsUnavailable() def test_UnzipTemp_withPartiallyMatchingPatterns(self): zip_file = self._test_UnzipTemp_createZipFile() unzipped_dir = common.UnzipTemp(zip_file, ['Test*', 'Nonexistent*']) @@ -575,6 +579,7 @@ class CommonApkUtilsTest(test_utils.ReleaseToolsTestCase): wrong_input = os.path.join(self.testdata_dir, 'testkey.pk8') self.assertRaises(AssertionError, common.ExtractPublicKey, wrong_input) + @test_utils.SkipIfExternalToolsUnavailable() def test_ExtractAvbPublicKey(self): privkey = os.path.join(self.testdata_dir, 'testkey.key') pubkey = os.path.join(self.testdata_dir, 'testkey.pubkey.pem') @@ -594,18 +599,22 @@ class CommonApkUtilsTest(test_utils.ReleaseToolsTestCase): actual = common.ParseCertificate(cert_fp.read()) self.assertEqual(expected, actual) + @test_utils.SkipIfExternalToolsUnavailable() def test_GetMinSdkVersion(self): test_app = os.path.join(self.testdata_dir, 'TestApp.apk') self.assertEqual('24', common.GetMinSdkVersion(test_app)) + @test_utils.SkipIfExternalToolsUnavailable() def test_GetMinSdkVersion_invalidInput(self): self.assertRaises( common.ExternalError, common.GetMinSdkVersion, 'does-not-exist.apk') + @test_utils.SkipIfExternalToolsUnavailable() def test_GetMinSdkVersionInt(self): test_app = os.path.join(self.testdata_dir, 'TestApp.apk') self.assertEqual(24, common.GetMinSdkVersionInt(test_app, {})) + @test_utils.SkipIfExternalToolsUnavailable() def test_GetMinSdkVersionInt_invalidInput(self): self.assertRaises( common.ExternalError, common.GetMinSdkVersionInt, 'does-not-exist.apk', @@ -617,6 +626,7 @@ class CommonUtilsTest(test_utils.ReleaseToolsTestCase): def setUp(self): self.testdata_dir = test_utils.get_testdata_dir() + @test_utils.SkipIfExternalToolsUnavailable() def test_GetSparseImage_emptyBlockMapFile(self): target_files = common.MakeTempFile(prefix='target_files-', suffix='.zip') with zipfile.ZipFile(target_files, 'w') as target_files_zip: @@ -649,6 +659,7 @@ class CommonUtilsTest(test_utils.ReleaseToolsTestCase): AssertionError, common.GetSparseImage, 'unknown', self.testdata_dir, None, False) + @test_utils.SkipIfExternalToolsUnavailable() def test_GetSparseImage_missingBlockMapFile(self): target_files = common.MakeTempFile(prefix='target_files-', suffix='.zip') with zipfile.ZipFile(target_files, 'w') as target_files_zip: @@ -667,6 +678,7 @@ class CommonUtilsTest(test_utils.ReleaseToolsTestCase): AssertionError, common.GetSparseImage, 'system', tempdir, input_zip, False) + @test_utils.SkipIfExternalToolsUnavailable() def test_GetSparseImage_sharedBlocks_notAllowed(self): """Tests the case of having overlapping blocks but disallowed.""" target_files = common.MakeTempFile(prefix='target_files-', suffix='.zip') @@ -689,6 +701,7 @@ class CommonUtilsTest(test_utils.ReleaseToolsTestCase): AssertionError, common.GetSparseImage, 'system', tempdir, input_zip, False) + @test_utils.SkipIfExternalToolsUnavailable() def test_GetSparseImage_sharedBlocks_allowed(self): """Tests the case for target using BOARD_EXT4_SHARE_DUP_BLOCKS := true.""" target_files = common.MakeTempFile(prefix='target_files-', suffix='.zip') @@ -731,6 +744,7 @@ class CommonUtilsTest(test_utils.ReleaseToolsTestCase): self.assertFalse(sparse_image.file_map['__NONZERO-0'].extra) self.assertFalse(sparse_image.file_map['/system/file1'].extra) + @test_utils.SkipIfExternalToolsUnavailable() def test_GetSparseImage_incompleteRanges(self): """Tests the case of ext4 images with holes.""" target_files = common.MakeTempFile(prefix='target_files-', suffix='.zip') @@ -754,6 +768,7 @@ class CommonUtilsTest(test_utils.ReleaseToolsTestCase): self.assertFalse(sparse_image.file_map['/system/file1'].extra) self.assertTrue(sparse_image.file_map['/system/file2'].extra['incomplete']) + @test_utils.SkipIfExternalToolsUnavailable() def test_GetSparseImage_systemRootImage_filenameWithExtraLeadingSlash(self): target_files = common.MakeTempFile(prefix='target_files-', suffix='.zip') with zipfile.ZipFile(target_files, 'w') as target_files_zip: @@ -781,6 +796,7 @@ class CommonUtilsTest(test_utils.ReleaseToolsTestCase): self.assertTrue( sparse_image.file_map['/system/app/file3'].extra['incomplete']) + @test_utils.SkipIfExternalToolsUnavailable() def test_GetSparseImage_systemRootImage_nonSystemFiles(self): target_files = common.MakeTempFile(prefix='target_files-', suffix='.zip') with zipfile.ZipFile(target_files, 'w') as target_files_zip: @@ -803,6 +819,7 @@ class CommonUtilsTest(test_utils.ReleaseToolsTestCase): self.assertFalse(sparse_image.file_map['//system/file1'].extra) self.assertTrue(sparse_image.file_map['//init.rc'].extra['incomplete']) + @test_utils.SkipIfExternalToolsUnavailable() def test_GetSparseImage_fileNotFound(self): target_files = common.MakeTempFile(prefix='target_files-', suffix='.zip') with zipfile.ZipFile(target_files, 'w') as target_files_zip: @@ -822,6 +839,7 @@ class CommonUtilsTest(test_utils.ReleaseToolsTestCase): AssertionError, common.GetSparseImage, 'system', tempdir, input_zip, False) + @test_utils.SkipIfExternalToolsUnavailable() def test_GetAvbChainedPartitionArg(self): pubkey = os.path.join(self.testdata_dir, 'testkey.pubkey.pem') info_dict = { @@ -835,6 +853,7 @@ class CommonUtilsTest(test_utils.ReleaseToolsTestCase): self.assertEqual('2', args[1]) self.assertTrue(os.path.exists(args[2])) + @test_utils.SkipIfExternalToolsUnavailable() def test_GetAvbChainedPartitionArg_withPrivateKey(self): key = os.path.join(self.testdata_dir, 'testkey.key') info_dict = { @@ -848,6 +867,7 @@ class CommonUtilsTest(test_utils.ReleaseToolsTestCase): self.assertEqual('2', args[1]) self.assertTrue(os.path.exists(args[2])) + @test_utils.SkipIfExternalToolsUnavailable() def test_GetAvbChainedPartitionArg_withSpecifiedKey(self): info_dict = { 'avb_avbtool': 'avbtool', @@ -862,6 +882,7 @@ class CommonUtilsTest(test_utils.ReleaseToolsTestCase): self.assertEqual('2', args[1]) self.assertTrue(os.path.exists(args[2])) + @test_utils.SkipIfExternalToolsUnavailable() def test_GetAvbChainedPartitionArg_invalidKey(self): pubkey = os.path.join(self.testdata_dir, 'testkey_with_passwd.x509.pem') info_dict = { @@ -922,6 +943,7 @@ class CommonUtilsTest(test_utils.ReleaseToolsTestCase): self.assertIn('/', loaded_dict['fstab']) self.assertIn('/system', loaded_dict['fstab']) + @test_utils.SkipIfExternalToolsUnavailable() def test_LoadInfoDict_dirInput(self): target_files = self._test_LoadInfoDict_createTargetFiles( self.INFO_DICT_DEFAULT, @@ -933,6 +955,7 @@ class CommonUtilsTest(test_utils.ReleaseToolsTestCase): self.assertIn('/', loaded_dict['fstab']) self.assertIn('/system', loaded_dict['fstab']) + @test_utils.SkipIfExternalToolsUnavailable() def test_LoadInfoDict_dirInput_legacyRecoveryFstabPath(self): target_files = self._test_LoadInfoDict_createTargetFiles( self.INFO_DICT_DEFAULT, @@ -990,6 +1013,7 @@ class CommonUtilsTest(test_utils.ReleaseToolsTestCase): self.assertEqual(2, loaded_dict['fstab_version']) self.assertIsNone(loaded_dict['fstab']) + @test_utils.SkipIfExternalToolsUnavailable() def test_LoadInfoDict_missingMetaMiscInfoTxt(self): target_files = self._test_LoadInfoDict_createTargetFiles( self.INFO_DICT_DEFAULT, @@ -998,6 +1022,7 @@ class CommonUtilsTest(test_utils.ReleaseToolsTestCase): with zipfile.ZipFile(target_files, 'r') as target_files_zip: self.assertRaises(ValueError, common.LoadInfoDict, target_files_zip) + @test_utils.SkipIfExternalToolsUnavailable() def test_LoadInfoDict_repacking(self): target_files = self._test_LoadInfoDict_createTargetFiles( self.INFO_DICT_DEFAULT, @@ -1066,6 +1091,7 @@ class InstallRecoveryScriptFormatTest(test_utils.ReleaseToolsTestCase): validate_target_files.ValidateInstallRecoveryScript(self._tempdir, self._info) + @test_utils.SkipIfExternalToolsUnavailable() def test_recovery_from_boot(self): recovery_image = common.File("recovery.img", self.recovery_data) self._out_tmp_sink("recovery.img", recovery_image.data, "IMAGES") diff --git a/tools/releasetools/test_merge_target_files.py b/tools/releasetools/test_merge_target_files.py index bb9ce8e276..ec452a8cc6 100644 --- a/tools/releasetools/test_merge_target_files.py +++ b/tools/releasetools/test_merge_target_files.py @@ -16,7 +16,6 @@ import os.path -import common import test_utils from merge_target_files import ( read_config_list, validate_config_lists, default_system_item_list, diff --git a/tools/releasetools/test_ota_from_target_files.py b/tools/releasetools/test_ota_from_target_files.py index bb0236b8dc..bf94cc2e35 100644 --- a/tools/releasetools/test_ota_from_target_files.py +++ b/tools/releasetools/test_ota_from_target_files.py @@ -427,6 +427,7 @@ class OtaFromTargetFilesTest(test_utils.ReleaseToolsTestCase): common.OPTIONS.search_path = test_utils.get_search_path() self.assertIsNotNone(common.OPTIONS.search_path) + @test_utils.SkipIfExternalToolsUnavailable() def test_GetPackageMetadata_abOta_full(self): target_info_dict = copy.deepcopy(self.TEST_TARGET_INFO_DICT) target_info_dict['ab_update'] = 'true' @@ -445,6 +446,7 @@ class OtaFromTargetFilesTest(test_utils.ReleaseToolsTestCase): }, metadata) + @test_utils.SkipIfExternalToolsUnavailable() def test_GetPackageMetadata_abOta_incremental(self): target_info_dict = copy.deepcopy(self.TEST_TARGET_INFO_DICT) target_info_dict['ab_update'] = 'true' @@ -467,6 +469,7 @@ class OtaFromTargetFilesTest(test_utils.ReleaseToolsTestCase): }, metadata) + @test_utils.SkipIfExternalToolsUnavailable() def test_GetPackageMetadata_nonAbOta_full(self): target_info = BuildInfo(self.TEST_TARGET_INFO_DICT, None) metadata = GetPackageMetadata(target_info) @@ -482,6 +485,7 @@ class OtaFromTargetFilesTest(test_utils.ReleaseToolsTestCase): }, metadata) + @test_utils.SkipIfExternalToolsUnavailable() def test_GetPackageMetadata_nonAbOta_incremental(self): target_info = BuildInfo(self.TEST_TARGET_INFO_DICT, None) source_info = BuildInfo(self.TEST_SOURCE_INFO_DICT, None) @@ -501,6 +505,7 @@ class OtaFromTargetFilesTest(test_utils.ReleaseToolsTestCase): }, metadata) + @test_utils.SkipIfExternalToolsUnavailable() def test_GetPackageMetadata_wipe(self): target_info = BuildInfo(self.TEST_TARGET_INFO_DICT, None) common.OPTIONS.wipe_user_data = True @@ -518,6 +523,7 @@ class OtaFromTargetFilesTest(test_utils.ReleaseToolsTestCase): }, metadata) + @test_utils.SkipIfExternalToolsUnavailable() def test_GetPackageMetadata_retrofitDynamicPartitions(self): target_info = BuildInfo(self.TEST_TARGET_INFO_DICT, None) common.OPTIONS.retrofit_dynamic_partitions = True @@ -542,6 +548,7 @@ class OtaFromTargetFilesTest(test_utils.ReleaseToolsTestCase): source_info['build.prop']['ro.build.date.utc'], target_info['build.prop']['ro.build.date.utc']) + @test_utils.SkipIfExternalToolsUnavailable() def test_GetPackageMetadata_unintentionalDowngradeDetected(self): target_info_dict = copy.deepcopy(self.TEST_TARGET_INFO_DICT) source_info_dict = copy.deepcopy(self.TEST_SOURCE_INFO_DICT) @@ -554,6 +561,7 @@ class OtaFromTargetFilesTest(test_utils.ReleaseToolsTestCase): self.assertRaises(RuntimeError, GetPackageMetadata, target_info, source_info) + @test_utils.SkipIfExternalToolsUnavailable() def test_GetPackageMetadata_downgrade(self): target_info_dict = copy.deepcopy(self.TEST_TARGET_INFO_DICT) source_info_dict = copy.deepcopy(self.TEST_SOURCE_INFO_DICT) @@ -582,6 +590,7 @@ class OtaFromTargetFilesTest(test_utils.ReleaseToolsTestCase): }, metadata) + @test_utils.SkipIfExternalToolsUnavailable() def test_GetTargetFilesZipForSecondaryImages(self): input_file = construct_target_files(secondary=True) target_file = GetTargetFilesZipForSecondaryImages(input_file) @@ -600,6 +609,7 @@ class OtaFromTargetFilesTest(test_utils.ReleaseToolsTestCase): self.assertNotIn('IMAGES/system_other.img', namelist) self.assertNotIn('IMAGES/system.map', namelist) + @test_utils.SkipIfExternalToolsUnavailable() def test_GetTargetFilesZipForSecondaryImages_skipPostinstall(self): input_file = construct_target_files(secondary=True) target_file = GetTargetFilesZipForSecondaryImages( @@ -619,6 +629,7 @@ class OtaFromTargetFilesTest(test_utils.ReleaseToolsTestCase): self.assertNotIn('IMAGES/system.map', namelist) self.assertNotIn(POSTINSTALL_CONFIG, namelist) + @test_utils.SkipIfExternalToolsUnavailable() def test_GetTargetFilesZipForSecondaryImages_withoutRadioImages(self): input_file = construct_target_files(secondary=True) common.ZipDelete(input_file, 'RADIO/bootloader.img') @@ -639,12 +650,14 @@ class OtaFromTargetFilesTest(test_utils.ReleaseToolsTestCase): self.assertNotIn('RADIO/bootloader.img', namelist) self.assertNotIn('RADIO/modem.img', namelist) + @test_utils.SkipIfExternalToolsUnavailable() def test_GetTargetFilesZipWithoutPostinstallConfig(self): input_file = construct_target_files() target_file = GetTargetFilesZipWithoutPostinstallConfig(input_file) with zipfile.ZipFile(target_file) as verify_zip: self.assertNotIn(POSTINSTALL_CONFIG, verify_zip.namelist()) + @test_utils.SkipIfExternalToolsUnavailable() def test_GetTargetFilesZipWithoutPostinstallConfig_missingEntry(self): input_file = construct_target_files() common.ZipDelete(input_file, POSTINSTALL_CONFIG) @@ -675,20 +688,25 @@ class OtaFromTargetFilesTest(test_utils.ReleaseToolsTestCase): FinalizeMetadata(metadata, zip_file, output_file, needed_property_files) self.assertIn('ota-test-property-files', metadata) + @test_utils.SkipIfExternalToolsUnavailable() def test_FinalizeMetadata(self): self._test_FinalizeMetadata() + @test_utils.SkipIfExternalToolsUnavailable() def test_FinalizeMetadata_withNoSigning(self): common.OPTIONS.no_signing = True self._test_FinalizeMetadata() + @test_utils.SkipIfExternalToolsUnavailable() def test_FinalizeMetadata_largeEntry(self): self._test_FinalizeMetadata(large_entry=True) + @test_utils.SkipIfExternalToolsUnavailable() def test_FinalizeMetadata_largeEntry_withNoSigning(self): common.OPTIONS.no_signing = True self._test_FinalizeMetadata(large_entry=True) + @test_utils.SkipIfExternalToolsUnavailable() def test_FinalizeMetadata_insufficientSpace(self): entries = [ 'required-entry1', @@ -766,6 +784,7 @@ class PropertyFilesTest(test_utils.ReleaseToolsTestCase): expected = entry.replace('.', '-').upper().encode() self.assertEqual(expected, input_fp.read(size)) + @test_utils.SkipIfExternalToolsUnavailable() def test_Compute(self): entries = ( 'required-entry1', @@ -805,6 +824,7 @@ class PropertyFilesTest(test_utils.ReleaseToolsTestCase): with zipfile.ZipFile(zip_file, 'r') as zip_fp: self.assertRaises(KeyError, property_files.Compute, zip_fp) + @test_utils.SkipIfExternalToolsUnavailable() def test_Finalize(self): entries = [ 'required-entry1', @@ -825,6 +845,7 @@ class PropertyFilesTest(test_utils.ReleaseToolsTestCase): entries[2] = 'metadata' self._verify_entries(zip_file, tokens, entries) + @test_utils.SkipIfExternalToolsUnavailable() def test_Finalize_assertReservedLength(self): entries = ( 'required-entry1', @@ -998,6 +1019,7 @@ class AbOtaPropertyFilesTest(PropertyFilesTest): ), property_files.optional) + @test_utils.SkipIfExternalToolsUnavailable() def test_GetPayloadMetadataOffsetAndSize(self): target_file = construct_target_files() payload = Payload() @@ -1071,6 +1093,7 @@ class AbOtaPropertyFilesTest(PropertyFilesTest): return zip_file + @test_utils.SkipIfExternalToolsUnavailable() def test_Compute(self): zip_file = self.construct_zip_package_withValidPayload() property_files = AbOtaPropertyFiles() @@ -1084,6 +1107,7 @@ class AbOtaPropertyFilesTest(PropertyFilesTest): self._verify_entries( zip_file, tokens, ('care_map.txt', 'compatibility.zip')) + @test_utils.SkipIfExternalToolsUnavailable() def test_Finalize(self): zip_file = self.construct_zip_package_withValidPayload(with_metadata=True) property_files = AbOtaPropertyFiles() @@ -1099,6 +1123,7 @@ class AbOtaPropertyFilesTest(PropertyFilesTest): self._verify_entries( zip_file, tokens, ('care_map.txt', 'compatibility.zip')) + @test_utils.SkipIfExternalToolsUnavailable() def test_Verify(self): zip_file = self.construct_zip_package_withValidPayload(with_metadata=True) property_files = AbOtaPropertyFiles() @@ -1204,6 +1229,7 @@ class PayloadSignerTest(test_utils.ReleaseToolsTestCase): def test_GetKeySizeInBytes_512Bytes(self): signing_key = os.path.join(self.testdata_dir, 'testkey_RSA4096.key') + # pylint: disable=protected-access key_size = PayloadSigner._GetKeySizeInBytes(signing_key) self.assertEqual(512, key_size) @@ -1273,14 +1299,17 @@ class PayloadTest(test_utils.ReleaseToolsTestCase): payload.Generate(target_file, source_file) return payload + @test_utils.SkipIfExternalToolsUnavailable() def test_Generate_full(self): payload = self._create_payload_full() self.assertTrue(os.path.exists(payload.payload_file)) + @test_utils.SkipIfExternalToolsUnavailable() def test_Generate_incremental(self): payload = self._create_payload_incremental() self.assertTrue(os.path.exists(payload.payload_file)) + @test_utils.SkipIfExternalToolsUnavailable() def test_Generate_additionalArgs(self): target_file = construct_target_files() source_file = construct_target_files() @@ -1291,12 +1320,14 @@ class PayloadTest(test_utils.ReleaseToolsTestCase): target_file, additional_args=["--source_image", source_file]) self.assertTrue(os.path.exists(payload.payload_file)) + @test_utils.SkipIfExternalToolsUnavailable() def test_Generate_invalidInput(self): target_file = construct_target_files() common.ZipDelete(target_file, 'IMAGES/vendor.img') payload = Payload() self.assertRaises(common.ExternalError, payload.Generate, target_file) + @test_utils.SkipIfExternalToolsUnavailable() def test_Sign_full(self): payload = self._create_payload_full() payload.Sign(PayloadSigner()) @@ -1310,6 +1341,7 @@ class PayloadTest(test_utils.ReleaseToolsTestCase): os.path.join(self.testdata_dir, 'testkey.x509.pem'), output_file) + @test_utils.SkipIfExternalToolsUnavailable() def test_Sign_incremental(self): payload = self._create_payload_incremental() payload.Sign(PayloadSigner()) @@ -1323,6 +1355,7 @@ class PayloadTest(test_utils.ReleaseToolsTestCase): os.path.join(self.testdata_dir, 'testkey.x509.pem'), output_file) + @test_utils.SkipIfExternalToolsUnavailable() def test_Sign_withDataWipe(self): common.OPTIONS.wipe_user_data = True payload = self._create_payload_full() @@ -1331,6 +1364,7 @@ class PayloadTest(test_utils.ReleaseToolsTestCase): with open(payload.payload_properties) as properties_fp: self.assertIn("POWERWASH=1", properties_fp.read()) + @test_utils.SkipIfExternalToolsUnavailable() def test_Sign_secondary(self): payload = self._create_payload_full(secondary=True) payload.Sign(PayloadSigner()) @@ -1338,6 +1372,7 @@ class PayloadTest(test_utils.ReleaseToolsTestCase): with open(payload.payload_properties) as properties_fp: self.assertIn("SWITCH_SLOT_ON_REBOOT=0", properties_fp.read()) + @test_utils.SkipIfExternalToolsUnavailable() def test_Sign_badSigner(self): """Tests that signing failure can be captured.""" payload = self._create_payload_full() @@ -1345,6 +1380,7 @@ class PayloadTest(test_utils.ReleaseToolsTestCase): payload_signer.signer_args.append('bad-option') self.assertRaises(common.ExternalError, payload.Sign, payload_signer) + @test_utils.SkipIfExternalToolsUnavailable() def test_WriteToZip(self): payload = self._create_payload_full() payload.Sign(PayloadSigner()) @@ -1366,6 +1402,7 @@ class PayloadTest(test_utils.ReleaseToolsTestCase): continue self.assertEqual(zipfile.ZIP_STORED, entry_info.compress_type) + @test_utils.SkipIfExternalToolsUnavailable() def test_WriteToZip_unsignedPayload(self): """Unsigned payloads should not be allowed to be written to zip.""" payload = self._create_payload_full() @@ -1381,6 +1418,7 @@ class PayloadTest(test_utils.ReleaseToolsTestCase): with zipfile.ZipFile(output_file, 'w') as output_zip: self.assertRaises(AssertionError, payload.WriteToZip, output_zip) + @test_utils.SkipIfExternalToolsUnavailable() def test_WriteToZip_secondary(self): payload = self._create_payload_full(secondary=True) payload.Sign(PayloadSigner()) diff --git a/tools/releasetools/test_utils.py b/tools/releasetools/test_utils.py index ca127b1366..1e919f7bb5 100755 --- a/tools/releasetools/test_utils.py +++ b/tools/releasetools/test_utils.py @@ -31,6 +31,18 @@ import common # Some test runner doesn't like outputs from stderr. logging.basicConfig(stream=sys.stdout) +# Use ANDROID_BUILD_TOP as an indicator to tell if the needed tools (e.g. +# avbtool, mke2fs) are available while running the tests. Not having the var or +# having empty string means we can't run the tests that require external tools. +EXTERNAL_TOOLS_UNAVAILABLE = not os.environ.get("ANDROID_BUILD_TOP") + + +def SkipIfExternalToolsUnavailable(): + """Decorator function that allows skipping tests per tools availability.""" + if EXTERNAL_TOOLS_UNAVAILABLE: + return unittest.skip('External tools unavailable') + return lambda func: func + def get_testdata_dir(): """Returns the testdata dir, in relative to the script dir.""" diff --git a/tools/releasetools/test_validate_target_files.py b/tools/releasetools/test_validate_target_files.py index 5f619ec79a..70e3b497af 100644 --- a/tools/releasetools/test_validate_target_files.py +++ b/tools/releasetools/test_validate_target_files.py @@ -55,6 +55,7 @@ class ValidateTargetFilesTest(test_utils.ReleaseToolsTestCase): 0, proc.returncode, "Failed to sign boot image with boot_signer: {}".format(stdoutdata)) + @test_utils.SkipIfExternalToolsUnavailable() def test_ValidateVerifiedBootImages_bootImage(self): input_tmp = common.MakeTempDir() os.mkdir(os.path.join(input_tmp, 'IMAGES')) @@ -69,6 +70,7 @@ class ValidateTargetFilesTest(test_utils.ReleaseToolsTestCase): } ValidateVerifiedBootImages(input_tmp, info_dict, options) + @test_utils.SkipIfExternalToolsUnavailable() def test_ValidateVerifiedBootImages_bootImage_wrongKey(self): input_tmp = common.MakeTempDir() os.mkdir(os.path.join(input_tmp, 'IMAGES')) @@ -85,6 +87,7 @@ class ValidateTargetFilesTest(test_utils.ReleaseToolsTestCase): AssertionError, ValidateVerifiedBootImages, input_tmp, info_dict, options) + @test_utils.SkipIfExternalToolsUnavailable() def test_ValidateVerifiedBootImages_bootImage_corrupted(self): input_tmp = common.MakeTempDir() os.mkdir(os.path.join(input_tmp, 'IMAGES')) @@ -139,6 +142,7 @@ class ValidateTargetFilesTest(test_utils.ReleaseToolsTestCase): # Append the verity metadata. verity_image_builder.Build(output_file) + @test_utils.SkipIfExternalToolsUnavailable() def test_ValidateVerifiedBootImages_systemImage(self): input_tmp = common.MakeTempDir() os.mkdir(os.path.join(input_tmp, 'IMAGES')) @@ -162,6 +166,7 @@ class ValidateTargetFilesTest(test_utils.ReleaseToolsTestCase): } ValidateVerifiedBootImages(input_tmp, info_dict, options) + @test_utils.SkipIfExternalToolsUnavailable() def test_ValidateFileConsistency_incompleteRange(self): input_tmp = common.MakeTempDir() os.mkdir(os.path.join(input_tmp, 'IMAGES')) diff --git a/tools/releasetools/test_verity_utils.py b/tools/releasetools/test_verity_utils.py index e0607c8831..1cc539f201 100644 --- a/tools/releasetools/test_verity_utils.py +++ b/tools/releasetools/test_verity_utils.py @@ -24,7 +24,8 @@ import random import common import sparse_img from rangelib import RangeSet -from test_utils import get_testdata_dir, ReleaseToolsTestCase +from test_utils import ( + get_testdata_dir, ReleaseToolsTestCase, SkipIfExternalToolsUnavailable) from verity_utils import ( CreateHashtreeInfoGenerator, CreateVerityImageBuilder, HashtreeInfo, VerifiedBootVersion1HashtreeInfoGenerator) @@ -89,6 +90,7 @@ class VerifiedBootVersion1HashtreeInfoGeneratorTest(ReleaseToolsTestCase): return output_file + @SkipIfExternalToolsUnavailable() def test_CreateHashtreeInfoGenerator(self): image_file = sparse_img.SparseImage(self._generate_image()) @@ -99,6 +101,7 @@ class VerifiedBootVersion1HashtreeInfoGeneratorTest(ReleaseToolsTestCase): self.assertEqual(self.partition_size, generator.partition_size) self.assertTrue(generator.fec_supported) + @SkipIfExternalToolsUnavailable() def test_DecomposeSparseImage(self): image_file = sparse_img.SparseImage(self._generate_image()) @@ -109,6 +112,7 @@ class VerifiedBootVersion1HashtreeInfoGeneratorTest(ReleaseToolsTestCase): self.assertEqual(12288, generator.hashtree_size) self.assertEqual(32768, generator.metadata_size) + @SkipIfExternalToolsUnavailable() def test_ParseHashtreeMetadata(self): image_file = sparse_img.SparseImage(self._generate_image()) generator = VerifiedBootVersion1HashtreeInfoGenerator( @@ -123,6 +127,7 @@ class VerifiedBootVersion1HashtreeInfoGeneratorTest(ReleaseToolsTestCase): self.assertEqual(self.fixed_salt, generator.hashtree_info.salt) self.assertEqual(self.expected_root_hash, generator.hashtree_info.root_hash) + @SkipIfExternalToolsUnavailable() def test_ValidateHashtree_smoke(self): generator = VerifiedBootVersion1HashtreeInfoGenerator( self.partition_size, 4096, True) @@ -138,6 +143,7 @@ class VerifiedBootVersion1HashtreeInfoGeneratorTest(ReleaseToolsTestCase): self.assertTrue(generator.ValidateHashtree()) + @SkipIfExternalToolsUnavailable() def test_ValidateHashtree_failure(self): generator = VerifiedBootVersion1HashtreeInfoGenerator( self.partition_size, 4096, True) @@ -153,6 +159,7 @@ class VerifiedBootVersion1HashtreeInfoGeneratorTest(ReleaseToolsTestCase): self.assertFalse(generator.ValidateHashtree()) + @SkipIfExternalToolsUnavailable() def test_Generate(self): image_file = sparse_img.SparseImage(self._generate_image()) generator = CreateHashtreeInfoGenerator('system', 4096, self.prop_dict) @@ -193,6 +200,7 @@ class VerifiedBootVersion1VerityImageBuilderTest(ReleaseToolsTestCase): del prop_dict['verity_block_device'] self.assertIsNone(CreateVerityImageBuilder(prop_dict)) + @SkipIfExternalToolsUnavailable() def test_CalculateMaxImageSize(self): verity_image_builder = CreateVerityImageBuilder(self.DEFAULT_PROP_DICT) size = verity_image_builder.CalculateMaxImageSize() @@ -221,11 +229,13 @@ class VerifiedBootVersion1VerityImageBuilderTest(ReleaseToolsTestCase): cmd = ['verity_verifier', image, '-mincrypt', verify_key] common.RunAndCheckOutput(cmd) + @SkipIfExternalToolsUnavailable() def test_Build(self): self._BuildAndVerify( self.DEFAULT_PROP_DICT, os.path.join(get_testdata_dir(), 'testkey_mincrypt')) + @SkipIfExternalToolsUnavailable() def test_Build_SanityCheck(self): # A sanity check for the test itself: the image shouldn't be verifiable # with wrong key. @@ -235,6 +245,7 @@ class VerifiedBootVersion1VerityImageBuilderTest(ReleaseToolsTestCase): self.DEFAULT_PROP_DICT, os.path.join(get_testdata_dir(), 'verity_mincrypt')) + @SkipIfExternalToolsUnavailable() def test_Build_FecDisabled(self): prop_dict = copy.deepcopy(self.DEFAULT_PROP_DICT) del prop_dict['verity_fec'] @@ -242,6 +253,7 @@ class VerifiedBootVersion1VerityImageBuilderTest(ReleaseToolsTestCase): prop_dict, os.path.join(get_testdata_dir(), 'testkey_mincrypt')) + @SkipIfExternalToolsUnavailable() def test_Build_SquashFs(self): verity_image_builder = CreateVerityImageBuilder(self.DEFAULT_PROP_DICT) verity_image_builder.CalculateMaxImageSize() @@ -282,6 +294,7 @@ class VerifiedBootVersion2VerityImageBuilderTest(ReleaseToolsTestCase): verity_image_builder = CreateVerityImageBuilder(prop_dict) self.assertIsNone(verity_image_builder) + @SkipIfExternalToolsUnavailable() def test_Build(self): prop_dict = copy.deepcopy(self.DEFAULT_PROP_DICT) verity_image_builder = CreateVerityImageBuilder(prop_dict)