github.com/westcoastroms/westcoastroms-build@v0.0.0-20190928114312-2350e5a73030/build/make/tools/releasetools/test_add_img_to_target_files.py (about)

     1  #
     2  # Copyright (C) 2018 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  
    17  import os
    18  import os.path
    19  import unittest
    20  import zipfile
    21  
    22  import common
    23  import test_utils
    24  from add_img_to_target_files import (
    25      AddCareMapTxtForAbOta, AddPackRadioImages, AddRadioImagesForAbOta,
    26      GetCareMap)
    27  from rangelib import RangeSet
    28  
    29  
    30  OPTIONS = common.OPTIONS
    31  
    32  
    33  class AddImagesToTargetFilesTest(unittest.TestCase):
    34  
    35    def setUp(self):
    36      OPTIONS.input_tmp = common.MakeTempDir()
    37  
    38    def tearDown(self):
    39      common.Cleanup()
    40  
    41    @staticmethod
    42    def _create_images(images, prefix):
    43      """Creates images under OPTIONS.input_tmp/prefix."""
    44      path = os.path.join(OPTIONS.input_tmp, prefix)
    45      if not os.path.exists(path):
    46        os.mkdir(path)
    47  
    48      for image in images:
    49        image_path = os.path.join(path, image + '.img')
    50        with open(image_path, 'wb') as image_fp:
    51          image_fp.write(image.encode())
    52  
    53      images_path = os.path.join(OPTIONS.input_tmp, 'IMAGES')
    54      if not os.path.exists(images_path):
    55        os.mkdir(images_path)
    56      return images, images_path
    57  
    58    def test_AddRadioImagesForAbOta_imageExists(self):
    59      """Tests the case with existing images under IMAGES/."""
    60      images, images_path = self._create_images(['aboot', 'xbl'], 'IMAGES')
    61      AddRadioImagesForAbOta(None, images)
    62  
    63      for image in images:
    64        self.assertTrue(
    65            os.path.exists(os.path.join(images_path, image + '.img')))
    66  
    67    def test_AddRadioImagesForAbOta_copyFromRadio(self):
    68      """Tests the case that copies images from RADIO/."""
    69      images, images_path = self._create_images(['aboot', 'xbl'], 'RADIO')
    70      AddRadioImagesForAbOta(None, images)
    71  
    72      for image in images:
    73        self.assertTrue(
    74            os.path.exists(os.path.join(images_path, image + '.img')))
    75  
    76    def test_AddRadioImagesForAbOta_copyFromRadio_zipOutput(self):
    77      images, _ = self._create_images(['aboot', 'xbl'], 'RADIO')
    78  
    79      # Set up the output zip.
    80      output_file = common.MakeTempFile(suffix='.zip')
    81      with zipfile.ZipFile(output_file, 'w') as output_zip:
    82        AddRadioImagesForAbOta(output_zip, images)
    83  
    84      with zipfile.ZipFile(output_file, 'r') as verify_zip:
    85        for image in images:
    86          self.assertIn('IMAGES/' + image + '.img', verify_zip.namelist())
    87  
    88    def test_AddRadioImagesForAbOta_copyFromVendorImages(self):
    89      """Tests the case that copies images from VENDOR_IMAGES/."""
    90      vendor_images_path = os.path.join(OPTIONS.input_tmp, 'VENDOR_IMAGES')
    91      os.mkdir(vendor_images_path)
    92  
    93      partitions = ['aboot', 'xbl']
    94      for index, partition in enumerate(partitions):
    95        subdir = os.path.join(vendor_images_path, 'subdir-{}'.format(index))
    96        os.mkdir(subdir)
    97  
    98        partition_image_path = os.path.join(subdir, partition + '.img')
    99        with open(partition_image_path, 'wb') as partition_fp:
   100          partition_fp.write(partition.encode())
   101  
   102      # Set up the output dir.
   103      images_path = os.path.join(OPTIONS.input_tmp, 'IMAGES')
   104      os.mkdir(images_path)
   105  
   106      AddRadioImagesForAbOta(None, partitions)
   107  
   108      for partition in partitions:
   109        self.assertTrue(
   110            os.path.exists(os.path.join(images_path, partition + '.img')))
   111  
   112    def test_AddRadioImagesForAbOta_missingImages(self):
   113      images, _ = self._create_images(['aboot', 'xbl'], 'RADIO')
   114      self.assertRaises(AssertionError, AddRadioImagesForAbOta, None,
   115                        images + ['baz'])
   116  
   117    def test_AddRadioImagesForAbOta_missingImages_zipOutput(self):
   118      images, _ = self._create_images(['aboot', 'xbl'], 'RADIO')
   119  
   120      # Set up the output zip.
   121      output_file = common.MakeTempFile(suffix='.zip')
   122      with zipfile.ZipFile(output_file, 'w') as output_zip:
   123        self.assertRaises(AssertionError, AddRadioImagesForAbOta, output_zip,
   124                          images + ['baz'])
   125  
   126    def test_AddPackRadioImages(self):
   127      images, images_path = self._create_images(['foo', 'bar'], 'RADIO')
   128      AddPackRadioImages(None, images)
   129  
   130      for image in images:
   131        self.assertTrue(
   132            os.path.exists(os.path.join(images_path, image + '.img')))
   133  
   134    def test_AddPackRadioImages_with_suffix(self):
   135      images, images_path = self._create_images(['foo', 'bar'], 'RADIO')
   136      images_with_suffix = [image + '.img' for image in images]
   137      AddPackRadioImages(None, images_with_suffix)
   138  
   139      for image in images:
   140        self.assertTrue(
   141            os.path.exists(os.path.join(images_path, image + '.img')))
   142  
   143    def test_AddPackRadioImages_zipOutput(self):
   144      images, _ = self._create_images(['foo', 'bar'], 'RADIO')
   145  
   146      # Set up the output zip.
   147      output_file = common.MakeTempFile(suffix='.zip')
   148      with zipfile.ZipFile(output_file, 'w') as output_zip:
   149        AddPackRadioImages(output_zip, images)
   150  
   151      with zipfile.ZipFile(output_file, 'r') as verify_zip:
   152        for image in images:
   153          self.assertIn('IMAGES/' + image + '.img', verify_zip.namelist())
   154  
   155    def test_AddPackRadioImages_imageExists(self):
   156      images, images_path = self._create_images(['foo', 'bar'], 'RADIO')
   157  
   158      # Additionally create images under IMAGES/ so that they should be skipped.
   159      images, images_path = self._create_images(['foo', 'bar'], 'IMAGES')
   160  
   161      AddPackRadioImages(None, images)
   162  
   163      for image in images:
   164        self.assertTrue(
   165            os.path.exists(os.path.join(images_path, image + '.img')))
   166  
   167    def test_AddPackRadioImages_missingImages(self):
   168      images, _ = self._create_images(['foo', 'bar'], 'RADIO')
   169      AddPackRadioImages(None, images)
   170  
   171      self.assertRaises(AssertionError, AddPackRadioImages, None,
   172                        images + ['baz'])
   173  
   174    @staticmethod
   175    def _test_AddCareMapTxtForAbOta():
   176      """Helper function to set up the test for test_AddCareMapTxtForAbOta()."""
   177      OPTIONS.info_dict = {
   178          'system_verity_block_device' : '/dev/block/system',
   179          'vendor_verity_block_device' : '/dev/block/vendor',
   180      }
   181  
   182      # Prepare the META/ folder.
   183      meta_path = os.path.join(OPTIONS.input_tmp, 'META')
   184      if not os.path.exists(meta_path):
   185        os.mkdir(meta_path)
   186  
   187      system_image = test_utils.construct_sparse_image([
   188          (0xCAC1, 6),
   189          (0xCAC3, 4),
   190          (0xCAC1, 6)])
   191      vendor_image = test_utils.construct_sparse_image([
   192          (0xCAC2, 10)])
   193  
   194      image_paths = {
   195          'system' : system_image,
   196          'vendor' : vendor_image,
   197      }
   198      return image_paths
   199  
   200    def test_AddCareMapTxtForAbOta(self):
   201      image_paths = self._test_AddCareMapTxtForAbOta()
   202  
   203      AddCareMapTxtForAbOta(None, ['system', 'vendor'], image_paths)
   204  
   205      care_map_file = os.path.join(OPTIONS.input_tmp, 'META', 'care_map.txt')
   206      with open(care_map_file, 'r') as verify_fp:
   207        care_map = verify_fp.read()
   208  
   209      lines = care_map.split('\n')
   210      self.assertEqual(4, len(lines))
   211      self.assertEqual('system', lines[0])
   212      self.assertEqual(RangeSet("0-5 10-15").to_string_raw(), lines[1])
   213      self.assertEqual('vendor', lines[2])
   214      self.assertEqual(RangeSet("0-9").to_string_raw(), lines[3])
   215  
   216    def test_AddCareMapTxtForAbOta_withNonCareMapPartitions(self):
   217      """Partitions without care_map should be ignored."""
   218      image_paths = self._test_AddCareMapTxtForAbOta()
   219  
   220      AddCareMapTxtForAbOta(
   221          None, ['boot', 'system', 'vendor', 'vbmeta'], image_paths)
   222  
   223      care_map_file = os.path.join(OPTIONS.input_tmp, 'META', 'care_map.txt')
   224      with open(care_map_file, 'r') as verify_fp:
   225        care_map = verify_fp.read()
   226  
   227      lines = care_map.split('\n')
   228      self.assertEqual(4, len(lines))
   229      self.assertEqual('system', lines[0])
   230      self.assertEqual(RangeSet("0-5 10-15").to_string_raw(), lines[1])
   231      self.assertEqual('vendor', lines[2])
   232      self.assertEqual(RangeSet("0-9").to_string_raw(), lines[3])
   233  
   234    def test_AddCareMapTxtForAbOta_withAvb(self):
   235      """Tests the case for device using AVB."""
   236      image_paths = self._test_AddCareMapTxtForAbOta()
   237      OPTIONS.info_dict = {
   238          'avb_system_hashtree_enable' : 'true',
   239          'avb_vendor_hashtree_enable' : 'true',
   240      }
   241  
   242      AddCareMapTxtForAbOta(None, ['system', 'vendor'], image_paths)
   243  
   244      care_map_file = os.path.join(OPTIONS.input_tmp, 'META', 'care_map.txt')
   245      with open(care_map_file, 'r') as verify_fp:
   246        care_map = verify_fp.read()
   247  
   248      lines = care_map.split('\n')
   249      self.assertEqual(4, len(lines))
   250      self.assertEqual('system', lines[0])
   251      self.assertEqual(RangeSet("0-5 10-15").to_string_raw(), lines[1])
   252      self.assertEqual('vendor', lines[2])
   253      self.assertEqual(RangeSet("0-9").to_string_raw(), lines[3])
   254  
   255    def test_AddCareMapTxtForAbOta_verityNotEnabled(self):
   256      """No care_map.txt should be generated if verity not enabled."""
   257      image_paths = self._test_AddCareMapTxtForAbOta()
   258      OPTIONS.info_dict = {}
   259      AddCareMapTxtForAbOta(None, ['system', 'vendor'], image_paths)
   260  
   261      care_map_file = os.path.join(OPTIONS.input_tmp, 'META', 'care_map.txt')
   262      self.assertFalse(os.path.exists(care_map_file))
   263  
   264    def test_AddCareMapTxtForAbOta_missingImageFile(self):
   265      """Missing image file should be considered fatal."""
   266      image_paths = self._test_AddCareMapTxtForAbOta()
   267      image_paths['vendor'] = ''
   268      self.assertRaises(AssertionError, AddCareMapTxtForAbOta, None,
   269                        ['system', 'vendor'], image_paths)
   270  
   271    def test_AddCareMapTxtForAbOta_zipOutput(self):
   272      """Tests the case with ZIP output."""
   273      image_paths = self._test_AddCareMapTxtForAbOta()
   274  
   275      output_file = common.MakeTempFile(suffix='.zip')
   276      with zipfile.ZipFile(output_file, 'w') as output_zip:
   277        AddCareMapTxtForAbOta(output_zip, ['system', 'vendor'], image_paths)
   278  
   279      with zipfile.ZipFile(output_file, 'r') as verify_zip:
   280        care_map = verify_zip.read('META/care_map.txt').decode('ascii')
   281  
   282      lines = care_map.split('\n')
   283      self.assertEqual(4, len(lines))
   284      self.assertEqual('system', lines[0])
   285      self.assertEqual(RangeSet("0-5 10-15").to_string_raw(), lines[1])
   286      self.assertEqual('vendor', lines[2])
   287      self.assertEqual(RangeSet("0-9").to_string_raw(), lines[3])
   288  
   289    def test_AddCareMapTxtForAbOta_zipOutput_careMapEntryExists(self):
   290      """Tests the case with ZIP output which already has care_map entry."""
   291      image_paths = self._test_AddCareMapTxtForAbOta()
   292  
   293      output_file = common.MakeTempFile(suffix='.zip')
   294      with zipfile.ZipFile(output_file, 'w') as output_zip:
   295        # Create an existing META/care_map.txt entry.
   296        common.ZipWriteStr(output_zip, 'META/care_map.txt', 'dummy care_map.txt')
   297  
   298        # Request to add META/care_map.txt again.
   299        AddCareMapTxtForAbOta(output_zip, ['system', 'vendor'], image_paths)
   300  
   301      # The one under OPTIONS.input_tmp must have been replaced.
   302      care_map_file = os.path.join(OPTIONS.input_tmp, 'META', 'care_map.txt')
   303      with open(care_map_file, 'r') as verify_fp:
   304        care_map = verify_fp.read()
   305  
   306      lines = care_map.split('\n')
   307      self.assertEqual(4, len(lines))
   308      self.assertEqual('system', lines[0])
   309      self.assertEqual(RangeSet("0-5 10-15").to_string_raw(), lines[1])
   310      self.assertEqual('vendor', lines[2])
   311      self.assertEqual(RangeSet("0-9").to_string_raw(), lines[3])
   312  
   313      # The existing entry should be scheduled to be replaced.
   314      self.assertIn('META/care_map.txt', OPTIONS.replace_updated_files_list)
   315  
   316    def test_GetCareMap(self):
   317      sparse_image = test_utils.construct_sparse_image([
   318          (0xCAC1, 6),
   319          (0xCAC3, 4),
   320          (0xCAC1, 6)])
   321      OPTIONS.info_dict = {
   322          'system_adjusted_partition_size' : 12,
   323      }
   324      name, care_map = GetCareMap('system', sparse_image)
   325      self.assertEqual('system', name)
   326      self.assertEqual(RangeSet("0-5 10-12").to_string_raw(), care_map)
   327  
   328    def test_GetCareMap_invalidPartition(self):
   329      self.assertRaises(AssertionError, GetCareMap, 'oem', None)
   330  
   331    def test_GetCareMap_invalidAdjustedPartitionSize(self):
   332      sparse_image = test_utils.construct_sparse_image([
   333          (0xCAC1, 6),
   334          (0xCAC3, 4),
   335          (0xCAC1, 6)])
   336      OPTIONS.info_dict = {
   337          'system_adjusted_partition_size' : -12,
   338      }
   339      self.assertRaises(AssertionError, GetCareMap, 'system', sparse_image)