Home | History | Annotate | Download | only in hwbinder_benchmark
      1 #!/usr/bin/env python
      2 #
      3 # Copyright (C) 2016 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 
     18 import logging
     19 
     20 from vts.runners.host import asserts
     21 from vts.runners.host import base_test
     22 from vts.runners.host import const
     23 from vts.runners.host import test_runner
     24 from vts.utils.python.controllers import android_device
     25 from vts.utils.python.cpu import cpu_frequency_scaling
     26 from vts.utils.python.performance import benchmark_parser
     27 
     28 
     29 class HwBinderPerformanceTest(base_test.BaseTestClass):
     30     """A test case for the HWBinder performance benchmarking.
     31 
     32     Attributes:
     33         dut: the target DUT (device under test) instance.
     34         _cpu_freq: CpuFrequencyScalingController instance of self.dut.
     35     """
     36 
     37     THRESHOLD = {
     38         32: {
     39             "4": 100000,
     40             "8": 100000,
     41             "16": 100000,
     42             "32": 100000,
     43             "64": 100000,
     44             "128": 100000,
     45             "256": 100000,
     46             "512": 100000,
     47             "1024": 100000,
     48             "2k": 100000,
     49             "4k": 100000,
     50             "8k": 110000,
     51             "16k": 120000,
     52             "32k": 140000,
     53             "64k": 170000,
     54         },
     55         64: {
     56             "4": 100000,
     57             "8": 100000,
     58             "16": 100000,
     59             "32": 100000,
     60             "64": 100000,
     61             "128": 100000,
     62             "256": 100000,
     63             "512": 100000,
     64             "1024": 100000,
     65             "2k": 100000,
     66             "4k": 100000,
     67             "8k": 110000,
     68             "16k": 120000,
     69             "32k": 150000,
     70             "64k": 200000,
     71         }
     72     }
     73 
     74     def setUpClass(self):
     75         required_params = ["hidl_hal_mode"]
     76         self.getUserParams(required_params)
     77         self.dut = self.registerController(android_device)[0]
     78         self.dut.shell.InvokeTerminal("one")
     79         self.dut.shell.one.Execute("stop")
     80         self.dut.shell.one.Execute("setprop sys.boot_completed 0")
     81         self._cpu_freq = cpu_frequency_scaling.CpuFrequencyScalingController(self.dut)
     82         self._cpu_freq.DisableCpuScaling()
     83 
     84     def setUp(self):
     85         self._cpu_freq.SkipIfThermalThrottling(retry_delay_secs=30)
     86 
     87     def tearDown(self):
     88         self._cpu_freq.SkipIfThermalThrottling()
     89 
     90     def tearDownClass(self):
     91         self._cpu_freq.EnableCpuScaling()
     92         self.dut.shell.one.Execute("start")
     93         self.dut.waitForBootCompletion()
     94 
     95     def testRunBenchmark32Bit(self):
     96         """A testcase which runs the 32-bit benchmark."""
     97         self.RunBenchmark(32)
     98 
     99     def testRunBenchmark64Bit(self):
    100         """A testcase which runs the 64-bit benchmark."""
    101         self.RunBenchmark(64)
    102 
    103     def RunBenchmark(self, bits):
    104         """Runs the native binary and parses its result.
    105 
    106         Args:
    107             bits: integer (32 or 64), the number of bits in a word chosen
    108                   at the compile time (e.g., 32- vs. 64-bit library).
    109         """
    110         # Runs the benchmark.
    111         logging.info(
    112             "Start to run the benchmark with HIDL mode %s (%s bit mode)",
    113             self.hidl_hal_mode, bits)
    114         binary = "/data/local/tmp/%s/libhwbinder_benchmark%s" % (bits, bits)
    115 
    116         results = self.dut.shell.one.Execute([
    117             "chmod 755 %s" % binary,
    118             "VTS_ROOT_PATH=/data/local/tmp " \
    119             "LD_LIBRARY_PATH=/system/lib%s:/data/local/tmp/%s/hw:"
    120             "/data/local/tmp/%s:$LD_LIBRARY_PATH "
    121             "%s -m %s --benchmark_format=json" %
    122             (bits, bits, bits, binary, self.hidl_hal_mode.encode("utf-8"))
    123         ])
    124 
    125         # Parses the result.
    126         asserts.assertEqual(len(results[const.STDOUT]), 2)
    127         logging.info("stderr: %s", results[const.STDERR][1])
    128         logging.info("stdout: %s", results[const.STDOUT][1])
    129         asserts.assertFalse(
    130             any(results[const.EXIT_CODE]),
    131             "HwBinderPerformanceTest failed.")
    132         parser = benchmark_parser.GoogleBenchmarkJsonParser(
    133             results[const.STDOUT][1])
    134         label_result = parser.GetArguments()
    135         value_result = parser.GetRealTime()
    136         table_name = "hwbinder_vector_roundtrip_latency_benchmark_%sbits" % bits
    137         self.addTableToResult(table_name, parser.ToTable())
    138 
    139         # To upload to the web DB.
    140         self.web.AddProfilingDataLabeledVector(
    141             table_name,
    142             label_result,
    143             value_result,
    144             x_axis_label="Message Size (Bytes)",
    145             y_axis_label="Roundtrip HwBinder RPC Latency (naonseconds)")
    146 
    147         # Assertions to check the performance requirements
    148         for label, value in zip(label_result, value_result):
    149             if label in self.THRESHOLD[bits]:
    150                 asserts.assertLess(
    151                     value, self.THRESHOLD[bits][label],
    152                     "%s ns for %s is longer than the threshold %s ns" % (
    153                         value, label, self.THRESHOLD[bits][label]))
    154 
    155 
    156 if __name__ == "__main__":
    157     test_runner.main()
    158