1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.tradefed.testtype.suite.module;
17 
18 import com.android.tradefed.config.Option;
19 import com.android.tradefed.device.DeviceNotAvailableException;
20 import com.android.tradefed.device.ITestDevice;
21 import com.android.tradefed.device.StubDevice;
22 import com.android.tradefed.invoker.IInvocationContext;
23 import com.android.tradefed.log.LogUtil.CLog;
24 import com.android.tradefed.util.AbiUtils;
25 
26 /** Base class for a module controller to not run tests when it doesn't match the architecture . */
27 public class KernelTestModuleController extends BaseModuleController {
28     private final String lowMemProp = "ro.config.low_ram";
29     private final String productNameProp = "ro.product.name";
30 
31     @Option(name = "arch",
32             description = "The architecture name that should run for this module."
33                     + "This should be like arm64, arm, x86_64, x86, mips64, or mips.",
34             mandatory = true)
35     private String mArch = null;
36 
37     @Option(name = "is-low-mem",
38             description = "If this option set to true, run this module if device prop"
39                     + "of 'ro.config.low_ram' is true else skip it.")
40     private boolean mIsLowMem = false;
41 
42     @Option(name = "is-hwasan",
43             description = "If this option set to true, run this module if device prop "
44                     + "of 'ro.product.name' ended with _hwasan else skip it.")
45     private boolean mIsHwasan = false;
46 
47     @Override
shouldRun(IInvocationContext context)48     public RunStrategy shouldRun(IInvocationContext context) {
49         // This should return arm64-v8a or armeabi-v7a
50         String moduleAbiName = getModuleAbi().getName();
51         // Use AbiUtils to get the actual architecture name.
52         // If moduleAbiName is arm64-v8a then the moduleArchName will be arm64
53         // If moduleAbiName is armeabi-v7a then the moduleArchName will be arm
54         String moduleArchName = AbiUtils.getArchForAbi(moduleAbiName);
55 
56         if (mIsLowMem) {
57             if (!deviceLowMem(context)) {
58                 CLog.d("Skipping module %s because %s is False.", getModuleName(), lowMemProp);
59                 return RunStrategy.FULL_MODULE_BYPASS;
60             }
61         } else {
62             if (deviceLowMem(context)) {
63                 CLog.d("Skipping module %s because the test is not for low memory device.",
64                         getModuleName());
65                 return RunStrategy.FULL_MODULE_BYPASS;
66             }
67         }
68 
69         if (mIsHwasan) {
70             if (!deviceWithHwasan(context)) {
71                 CLog.d("Skipping module %s because %s is not ended with _hwasan.", getModuleName(),
72                         productNameProp);
73                 return RunStrategy.FULL_MODULE_BYPASS;
74             }
75         } else {
76             if (deviceWithHwasan(context)) {
77                 CLog.d("Skipping module %s because the test is for device of hwasan.",
78                         getModuleName());
79                 return RunStrategy.FULL_MODULE_BYPASS;
80             }
81         }
82 
83         if (mArch.equals(moduleArchName)) {
84             return RunStrategy.RUN;
85         }
86         CLog.d("Skipping module %s running on abi %s, which doesn't match any required setting "
87                         + "of %s.",
88                 getModuleName(), moduleAbiName, mArch);
89         return RunStrategy.FULL_MODULE_BYPASS;
90     }
91 
deviceLowMem(IInvocationContext context)92     private boolean deviceLowMem(IInvocationContext context) {
93         for (ITestDevice device : context.getDevices()) {
94             if (device.getIDevice() instanceof StubDevice) {
95                 continue;
96             }
97             try {
98                 String lowMemString = device.getProperty(lowMemProp);
99                 boolean isLowMem = false;
100                 if (lowMemString != null) {
101                     isLowMem = Boolean.parseBoolean(lowMemString);
102                 } else {
103                     CLog.d("Cannot get the prop of %s.", lowMemProp);
104                 }
105                 if (isLowMem) {
106                     continue;
107                 }
108                 return false;
109             } catch (DeviceNotAvailableException e) {
110                 CLog.e("Couldn't check prop of %s on %s", lowMemProp, device.getSerialNumber());
111                 CLog.e(e);
112                 throw new RuntimeException(e);
113             }
114         }
115         return true;
116     }
117 
deviceWithHwasan(IInvocationContext context)118     private boolean deviceWithHwasan(IInvocationContext context) {
119         for (ITestDevice device : context.getDevices()) {
120             if (device.getIDevice() instanceof StubDevice) {
121                 continue;
122             }
123             try {
124                 String productName = device.getProperty(productNameProp);
125                 boolean isHwasan = false;
126                 if (productName != null) {
127                     isHwasan = productName.contains("_hwasan");
128                 } else {
129                     CLog.d("Cannot get the prop of %s.", productNameProp);
130                 }
131                 if (isHwasan) {
132                     continue;
133                 }
134                 return false;
135             } catch (DeviceNotAvailableException e) {
136                 CLog.e("Couldn't check prop of %s on %s", productNameProp,
137                         device.getSerialNumber());
138                 CLog.e(e);
139                 throw new RuntimeException(e);
140             }
141         }
142         return true;
143     }
144 }
145