Home | History | Annotate | Download | only in binder_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 BinderPerformanceTest(base_test.BaseTestClass):
     30     """A testcase for the Binder 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": 150000,
     40             "8": 150000,
     41             "16": 150000,
     42             "32": 150000,
     43             "64": 150000,
     44             "128": 150000,
     45             "256": 150000,
     46             "512": 150000,
     47             "1024": 150000,
     48             "2k": 200000,
     49             "4k": 300000,
     50             "8k": 400000,
     51             "16k": 600000,
     52             "32k": 800000,
     53             "64k": 1000000,
     54         },
     55         64: {
     56             "4": 150000,
     57             "8": 150000,
     58             "16": 150000,
     59             "32": 150000,
     60             "64": 150000,
     61             "128": 150000,
     62             "256": 150000,
     63             "512": 150000,
     64             "1024": 150000,
     65             "2k": 200000,
     66             "4k": 300000,
     67             "8k": 400000,
     68             "16k": 600000,
     69             "32k": 800000,
     70             "64k": 1000000,
     71         }
     72     }
     73 
     74     def setUpClass(self):
     75         self.dut = self.registerController(android_device)[0]
     76         self.dut.shell.InvokeTerminal("one")
     77         self.dut.shell.one.Execute("stop")
     78         self.dut.shell.one.Execute("setprop sys.boot_completed 0")
     79         self._cpu_freq = cpu_frequency_scaling.CpuFrequencyScalingController(self.dut)
     80         self._cpu_freq.DisableCpuScaling()
     81 
     82     def setUp(self):
     83         self._cpu_freq.SkipIfThermalThrottling(retry_delay_secs=30)
     84 
     85     def tearDown(self):
     86         self._cpu_freq.SkipIfThermalThrottling()
     87 
     88     def tearDownClass(self):
     89         self._cpu_freq.EnableCpuScaling()
     90         self.dut.shell.one.Execute("start")
     91         self.dut.waitForBootCompletion()
     92 
     93     def testRunBenchmark32Bit(self):
     94         """A testcase which runs the 32-bit benchmark."""
     95         self.RunBenchmark(32)
     96 
     97     def testRunBenchmark64Bit(self):
     98         """A testcase which runs the 64-bit benchmark."""
     99         self.RunBenchmark(64)
    100 
    101     def RunBenchmark(self, bits):
    102         """Runs the native binary and parses its result.
    103 
    104         Args:
    105             bits: integer (32 or 64), the number of bits in a word chosen
    106                   at the compile time (e.g., 32- vs. 64-bit library).
    107         """
    108         # Runs the benchmark.
    109         logging.info("Start to run the benchmark (%s bit mode)", bits)
    110         binary = "/data/local/tmp/%s/libbinder_benchmark%s" % (bits, bits)
    111 
    112         results = self.dut.shell.one.Execute([
    113             "chmod 755 %s" % binary, "LD_LIBRARY_PATH=/data/local/tmp/%s/hw:"
    114             "/data/local/tmp/%s:$LD_LIBRARY_PATH "
    115             "%s --benchmark_format=json" % (bits, bits, binary)
    116         ])
    117 
    118         # Parses the result.
    119         asserts.assertEqual(len(results[const.STDOUT]), 2)
    120         logging.info("stderr: %s", results[const.STDERR][1])
    121         logging.info("stdout: %s", results[const.STDOUT][1])
    122         asserts.assertFalse(
    123             any(results[const.EXIT_CODE]),
    124             "BinderPerformanceTest failed.")
    125         parser = benchmark_parser.GoogleBenchmarkJsonParser(
    126             results[const.STDOUT][1])
    127         label_result = parser.GetArguments()
    128         value_result = parser.GetRealTime()
    129         table_name = "binder_vector_roundtrip_latency_benchmark_%sbits" % bits
    130         self.addTableToResult(table_name, parser.ToTable())
    131 
    132         # To upload to the web DB.
    133         self.web.AddProfilingDataLabeledVector(
    134             table_name,
    135             label_result,
    136             value_result,
    137             x_axis_label="Message Size (Bytes)",
    138             y_axis_label="Roundtrip Binder RPC Latency (nanoseconds)")
    139 
    140         # Assertions to check the performance requirements
    141         for label, value in zip(label_result, value_result):
    142             if label in self.THRESHOLD[bits]:
    143                 asserts.assertLess(
    144                     value, self.THRESHOLD[bits][label],
    145                     "%s ns for %s is longer than the threshold %s ns" % (
    146                         value, label, self.THRESHOLD[bits][label]))
    147 
    148 
    149 if __name__ == "__main__":
    150     test_runner.main()
    151