• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
18import logging
19
20from vts.runners.host import asserts
21from vts.runners.host import base_test
22from vts.runners.host import const
23from vts.runners.host import test_runner
24from vts.utils.python.controllers import adb
25from vts.utils.python.controllers import android_device
26
27
28class HwBinderPerformanceAdbTest(base_test.BaseTestClass):
29    """A test case for the HWBinder performance benchmarking.
30
31    Attributes:
32        dut: the target DUT (device under test) instance.
33        _cpu_freq: CpuFrequencyScalingController instance of self.dut.
34    """
35
36    THRESHOLD = {
37        32: {
38            "4": 100000,
39            "8": 100000,
40            "16": 100000,
41            "32": 100000,
42            "64": 100000,
43            "128": 100000,
44            "256": 100000,
45            "512": 100000,
46            "1024": 100000,
47            "2k": 100000,
48            "4k": 100000,
49            "8k": 110000,
50            "16k": 120000,
51            "32k": 140000,
52            "64k": 170000,
53        },
54        64: {
55            "4": 100000,
56            "8": 100000,
57            "16": 100000,
58            "32": 100000,
59            "64": 100000,
60            "128": 100000,
61            "256": 100000,
62            "512": 100000,
63            "1024": 100000,
64            "2k": 100000,
65            "4k": 100000,
66            "8k": 110000,
67            "16k": 120000,
68            "32k": 150000,
69            "64k": 200000,
70        }
71    }
72    LABEL_PREFIX_BINDERIZE = "BM_sendVec_binderize/"
73    LABEL_PREFIX_PASSTHROUGH = "BM_sendVec_passthrough/"
74
75    def setUpClass(self):
76        required_params = ["hidl_hal_mode"]
77        self.getUserParams(required_params)
78        self.dut = self.registerController(android_device, False)[0]
79        # Reboot target without restarting VTS services.
80        self.dut.reboot(False)
81        self.dut.stop()
82
83    def tearDownClass(self):
84        self.dut.start()
85
86    def testRunBenchmark32Bit(self):
87        """A testcase which runs the 32-bit benchmark."""
88        self.RunBenchmark(32)
89
90    def testRunBenchmark64Bit(self):
91        """A testcase which runs the 64-bit benchmark."""
92        self.RunBenchmark(64)
93
94    def RunBenchmark(self, bits):
95        """Runs the native binary and parses its result.
96
97        Args:
98            bits: integer (32 or 64), the number of bits in a word chosen
99                  at the compile time (e.g., 32- vs. 64-bit library).
100        """
101        # Runs the benchmark.
102        logging.info(
103            "Start to run the benchmark with HIDL mode %s (%s bit mode)",
104            self.hidl_hal_mode, bits)
105        binary = "/data/local/tmp/%s/libhwbinder_benchmark%s" % (bits, bits)
106
107        self.dut.adb.shell("chmod 755 %s" % binary)
108
109        try:
110            result = self.dut.adb.shell(
111                "LD_LIBRARY_PATH=/system/lib%s:/data/local/tmp/%s/hw:"
112                "/data/local/tmp/%s:"
113                "$LD_LIBRARY_PATH %s -m %s" %
114                (bits, bits, bits, binary, self.hidl_hal_mode.encode("utf-8")))
115        except adb.AdbError as e:
116            asserts.fail("HwBinderPerformanceTest failed.")
117
118        # Parses the result.
119        stdout_lines = result.split("\n")
120        logging.info("stdout: %s", stdout_lines)
121        label_result = []
122        value_result = []
123        prefix = (self.LABEL_PREFIX_BINDERIZE
124                  if self.hidl_hal_mode == "BINDERIZE" else
125                  self.LABEL_PREFIX_PASSTHROUGH)
126        for line in stdout_lines:
127            if line.startswith(prefix):
128                tokens = line.split()
129                benchmark_name = tokens[0]
130                time_in_ns = tokens[1].split()[0]
131                logging.info(benchmark_name)
132                logging.info(time_in_ns)
133                label_result.append(benchmark_name.replace(prefix, ""))
134                value_result.append(int(time_in_ns))
135
136        logging.info("result label for %sbits: %s", bits, label_result)
137        logging.info("result value for %sbits: %s", bits, value_result)
138        # To upload to the web DB.
139        self.web.AddProfilingDataLabeledVector(
140            "hwbinder_vector_roundtrip_latency_benchmark_%sbits" % bits,
141            label_result,
142            value_result,
143            x_axis_label="Message Size (Bytes)",
144            y_axis_label="Roundtrip HwBinder RPC Latency (naonseconds)")
145
146        # Assertions to check the performance requirements
147        for label, value in zip(label_result, value_result):
148            if label in self.THRESHOLD[bits]:
149                asserts.assertLess(
150                    value, self.THRESHOLD[bits][label],
151                    "%s ns for %s is longer than the threshold %s ns" % (
152                        value, label, self.THRESHOLD[bits][label]))
153
154
155if __name__ == "__main__":
156    test_runner.main()
157