1#!/usr/bin/env python 2# 3# Copyright (C) 2018 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# 17"""VTS tests to verify ACPIO partition overlay application.""" 18 19import logging 20import os 21import shutil 22import struct 23import subprocess 24import tempfile 25import zlib 26 27from vts.runners.host import asserts 28from vts.runners.host import base_test 29from vts.runners.host import const 30from vts.runners.host import test_runner 31from vts.utils.python.android import api 32from vts.utils.python.file import target_file_utils 33from vts.utils.python.os import path_utils 34from hashlib import sha1 35 36BLOCK_DEV_PATH = "/dev/block" # path to block devices 37PROPERTY_SLOT_SUFFIX = "ro.boot.slot_suffix" # indicates current slot suffix for A/B devices 38SSDT_PATH = "/sys/firmware/acpi/tables" 39acpio_idx_string = "" 40 41class VtsFirmwareAcpioVerification(base_test.BaseTestClass): 42 """Validates ACPI overlay application. 43 44 Attributes: 45 temp_dir: The temporary directory on host. 46 device_path: The temporary directory on device. 47 """ 48 49 def setUpClass(self): 50 """Initializes the DUT and creates temporary directories.""" 51 self.dut = self.android_devices[0] 52 self.shell = self.dut.shell 53 self.adb = self.dut.adb 54 self.temp_dir = tempfile.mkdtemp() 55 logging.debug("Create %s", self.temp_dir) 56 57 def setUp(self): 58 """Checks if the the preconditions to run the test are met.""" 59 global acpio_idx_string 60 asserts.skipIf("x86" not in self.dut.cpu_abi, "Skipping test for NON-x86 ABI") 61 acpio_idx_string = self.adb.shell( 62 "cat /proc/cmdline | " 63 "grep -o \"androidboot.acpio_idx=[^ ]*\" |" 64 "cut -d \"=\" -f 2 ") 65 acpio_idx_string = acpio_idx_string.replace('\n','') 66 asserts.assertTrue(acpio_idx_string, "Skipping test for x86 NON-ACPI ABI") 67 68 def getSha1(self, filename): 69 """Check the file hash.""" 70 sha1Obj = sha1() 71 with open(filename, 'rb') as f: 72 sha1Obj.update(f.read()) 73 return sha1Obj.hexdigest() 74 75 def testAcpioPartition(self): 76 """Validates ACPIO partition using mkdtboimg.py.""" 77 temp_SSDT_dump = "SSDT.dump" 78 temp_SSDT_dump_hashes = [] 79 current_SSDT = "SSDT" 80 current_SSDT_hashes = [] 81 82 slot_suffix = str(self.dut.getProp(PROPERTY_SLOT_SUFFIX)) 83 current_acpio_partition = "acpio" + slot_suffix 84 acpio_path = target_file_utils.FindFiles( 85 self.shell, BLOCK_DEV_PATH, current_acpio_partition, "-type l") 86 if not acpio_path: 87 asserts.fail("Unable to find path to acpio image on device.") 88 logging.debug("ACPIO path %s", acpio_path) 89 host_acpio_image = os.path.join(self.temp_dir, "acpio") 90 self.adb.pull("%s %s" % (acpio_path[0], host_acpio_image)) 91 mkdtimg_bin_path = os.path.join("host", "bin", "mkdtboimg.py") 92 unpacked_acpio_file = os.path.join(self.temp_dir, temp_SSDT_dump) 93 acpio_dump_cmd = [ 94 "%s" % mkdtimg_bin_path, "dump", 95 "%s" % host_acpio_image, "-b", 96 "%s" % unpacked_acpio_file 97 ] 98 try: 99 subprocess.check_call(acpio_dump_cmd) 100 except Exception as e: 101 logging.exception(e) 102 asserts.fail("Invalid ACPIO Image") 103 asserts.assertTrue(acpio_idx_string, "Kernel command line missing androidboot.acpio_idx") 104 acpio_idx_list = acpio_idx_string.split(",") 105 for idx in acpio_idx_list: 106 temp_SSDT_dump_file = "SSDT.dump." + idx.rstrip() 107 temp_SSDT_dump_file_hash=self.getSha1(os.path.join(self.temp_dir, temp_SSDT_dump_file)) 108 temp_SSDT_dump_hashes.append(temp_SSDT_dump_file_hash) 109 110 SSDT_path = target_file_utils.FindFiles(self.shell, SSDT_PATH, "SSDT*") 111 for current_SSDT_file in SSDT_path: 112 host_SSDT_file = os.path.join(self.temp_dir, current_SSDT) 113 self.adb.pull("%s %s" % (current_SSDT_file, host_SSDT_file)) 114 SSDT_file_hash=self.getSha1(host_SSDT_file) 115 current_SSDT_hashes.append(SSDT_file_hash) 116 asserts.assertTrue(current_SSDT_hashes, "No get current SSDT hash.") 117 asserts.assertTrue(set(temp_SSDT_dump_hashes) & set(current_SSDT_hashes), "Hash is not the same.") 118 119if __name__ == "__main__": 120 test_runner.main() 121