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 15'''Module that contains the test TestCallApiFuns.''' 16 17from __future__ import absolute_import 18 19import re 20import string 21 22from harness.test_base_remote import TestBaseRemote 23from harness import RS_funs 24from harness.decorators import ( 25 wimpy, 26 ordered_test, 27 cpp_only_test, 28) 29 30 31class _APIFunsExprTestsMeta(type): 32 """ 33 Generate unique, standalone test methods from a list of lldb expressions. 34 The lldb expression evaluation engine for calling RenderScript 35 builtins need to be tested thoroughly; rather than manually 36 write the 1000s of individual test cases, we automatically generate them 37 and their variants to add to the test class. This is done from a list 38 of expressions that are all tested in the same way. 39 """ 40 def __new__(self, name, bases, class_dict): 41 func_name_sub = re.compile(r'[%s\s]+' % string.punctuation) 42 43 for count, line in enumerate(RS_funs.FUNC_LIST): 44 def make_test(line): 45 """ 46 We use an extra level of indirection here to properly 47 close over the *value* of the loop variable, `line` 48 """ 49 @ordered_test(count) 50 def test(self): 51 # build the expression 52 ret, expr = RS_funs.build_expr(line) 53 try: 54 # evaluate the expression with expected return value 55 self.try_command(expr, [], [RS_funs.TYPE_MAP[ret]]) 56 except KeyError: 57 # or just check the return type if no return value 58 # specified 59 self.try_command(expr, '(%s)' % ret) 60 return test 61 62 # Make a pretty python method that adheres to the testcase standard 63 # Use the `count` parameter to ensure the name is unique in the class 64 test_name = 'test_%s_%s' % (re.sub(func_name_sub, '_', line), count) 65 test = make_test(line) 66 test.func_name = test_name 67 # We mark every 10th test case as runnable in wimpy mode 68 class_dict[test_name] = wimpy(test) if count % 10 == 0 else test 69 70 return type(name, bases, class_dict) 71 72 73class TestCallApiFuns(TestBaseRemote): 74 '''Tests calling of some RS API functions. This tests that JITing works.''' 75 76 __metaclass__ = _APIFunsExprTestsMeta 77 78 bundle_target = { 79 'java': "KernelVariables", 80 'jni': "JNIKernelVariables", 81 'cpp': "CppKernelVariables" 82 } 83 84 @wimpy 85 @ordered_test(-2) 86 def test_setup(self): 87 self.try_command('language renderscript status', 88 ['Runtime Library discovered', 89 'Runtime Driver discovered']) 90 91 self.try_command('b -f simple.rs -l 145', []) 92 93 self.try_command('process continue', 94 ['resuming', 95 'stopped', 96 'stop reason = breakpoint']) 97 98 @wimpy 99 @ordered_test(-1) 100 def test_call_api_funs_atomic(self): 101 # Test the atomics separately because we want to check the output 102 # AtomicAdd(1234, 2) 103 self.try_command('expr rsAtomicAdd(&int_global, 2)', 104 ['1234'], 105 [r'\(int(32_t)?\)']) 106 107 self.try_command('expr int_global', 108 ['(int)', 109 '1236']) 110 111 # AtomicAnd(2345, 333) 112 self.try_command('expr rsAtomicAnd(&uint_global, 333)', 113 ['2345'], 114 [r'\(int(32_t)?\)']) 115 116 self.try_command('expr uint_global', 117 ['(uint)', 118 '265']) 119 120 # AtomicCas(1236, 1236, 2345) 121 self.try_command('expr rsAtomicCas(&int_global, 1236, 2345)', 122 ['1236'], 123 [r'\(int(32_t)?\)']) 124 125 self.try_command('expr int_global', 126 ['(int)', 127 '2345']) 128 129 # AtomicDec(265) 130 self.try_command('expr rsAtomicDec(&uint_global)', 131 ['265'], 132 [r'\(int(32_t)?\)']) 133 134 self.try_command('expr uint_global', 135 ['(uint)', 136 '264']) 137 138 # AtomicInc(2345) 139 self.try_command('expr rsAtomicInc(&int_global)', 140 ['2345'], 141 [r'\(int(32_t)?\)']) 142 143 self.try_command('expr int_global', 144 ['(int)', 145 '2346']) 146 147 # AtomicMax(264, 3456) 148 self.try_command('expr rsAtomicMax(&uint_global, 3456)', 149 ['264'], 150 [r'\(uint(32_t)?\)']) 151 152 self.try_command('expr uint_global', 153 ['(uint)', 154 '3456']) 155 156 # AtomicMin(2346, 3) 157 self.try_command('expr rsAtomicMin(&int_global, 3)', 158 ['2346'], 159 [r'\(int(32_t)?\)']) 160 161 self.try_command('expr int_global', 162 ['(int)', 163 '3']) 164 165 # AtomicOr(3, 456) 166 self.try_command('expr rsAtomicOr(&int_global, 456)', 167 ['3'], 168 [r'\(int(32_t)?\)']) 169 170 self.try_command('expr int_global', 171 ['(int)', 172 '459']) 173 174 # AtomicSub(3456, 7) 175 self.try_command('expr rsAtomicSub(&uint_global, 7)', 176 ['3456'], 177 [r'\(int(32_t)?\)']) 178 179 self.try_command('expr uint_global', 180 ['(uint)', 181 '3449']) 182 183 # AtomicXor(459, 89) 184 self.try_command('expr rsAtomicXor(&int_global, 89)', 185 ['459'], 186 [r'\(int(32_t)?\)']) 187 188 self.try_command('expr int_global', 189 ['(int)', 190 '402']) 191 192 @ordered_test('last') 193 @cpp_only_test() 194 def test_cpp_cleanup(self): 195 self.try_command('breakpoint delete 1', ['1 breakpoints deleted']) 196 197 self.try_command('process continue', ['exited with status = 0']) 198