1# Copyright (C) 2016 The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#      http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15import re
16
17REDUCE_ITERATIONS = 128  # This is in MainActivity.java
18REDUCE_STARTVAL = 10 # This is in MainActivity.java
19REDUCE_AUTO_COMB_SCRIPT = "reduce_common.rsh"
20REDUCE_SCRIPT = "reduce_common.rsh"
21X_TESTS = 100
22Y_TESTS = 2
23Z_TESTS = 2
24
25
26class ReductionMixin(object):
27    def _test_func_role_combinations(self, func_role_combinations):
28        """
29        Assert that when a reduction breakpoint is conditional on a function
30        role, that breakpoints are only set on the the given functions.
31        We do this by setting breakpoints on all possible pairs of functions
32        and check that the resolved breakpoints are on functions that are part
33        of the given pair
34        """
35        for combination in func_role_combinations:
36            self._delete_breakpoints()
37            self.try_command(
38                'language renderscript reduction breakpoint set '
39                'find_min_user_type --function-role %s' % (
40                    ','.join(combination)
41                ),
42                [r'Breakpoint(s) created']
43            )
44            func_suffixes = [combination[0][:4], combination[1][:4]]
45            # just match the first 4 chars of the roles prefix
46            funcs_match = 'find_min_user_type_((%s|%s))' % tuple(func_suffixes)
47            # now check we stop on both functions for each coordinate in the
48            # allocation
49            for x in range(REDUCE_ITERATIONS):
50                output = self.try_command(
51                    'process continue',
52                    expected_regex=[
53                        r'resuming',
54                        r'Process \d+ stopped',
55                        r'frame #0: (0x[0-9a-fA-F]+ )?librs.reduce.so`%s' % funcs_match
56                    ]
57                )
58                for line in output.splitlines():
59                    match = re.search(funcs_match, line)
60                    if match:
61                        try:
62                            func_suffixes.remove(match.group(1))
63                        except ValueError:
64                            # The outconverter may only be called in the final
65                            # step but the accumulator will be called for every
66                            # input index
67                            continue
68                        break
69                if len(func_suffixes) == 0:
70                    # We've popped the functions we're interested in off the list
71                    break
72            else:
73                raise self.TestFail(
74                    "unable to match function roles for " + repr(combination))
75
76    def _reduction_breakpoint_set_single_type(
77            self, script_soname, script_basename, reduce_name, funcname_types):
78        """
79        Assert - for each function role - that the correct symbol is resolved
80        and trapped by the debugger.
81        """
82        for func, typename in funcname_types:
83            self._delete_breakpoints()
84            breakpoint_match = r'Breakpoint \d+: where = librs.%s.so`%s'
85            # Autogenerated combiners don't have a filename in the debugger
86            if not func.endswith(".combiner"):
87                breakpoint_match = r'%s (\+ \d+ )?at %s' % (
88                        breakpoint_match, script_basename)
89            self.try_command(
90                'language renderscript reduction breakpoint set %s'
91                ' --function-role %s' % (reduce_name, typename),
92                expected_regex=[breakpoint_match % (script_soname, func)]
93            )
94            self.try_command(
95                'process continue',
96                expected_regex=[
97                    r'resuming',
98                    r'Process \d+ stopped',
99                    r'frame #0: (0x[0-9a-fA-F]+ )?librs.%s.so`%s' % (
100                        script_soname, func)
101                ]
102            )
103