| /* |
| * Copyright (C) 2020 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package com.android.tradefed.testtype.suite.module; |
| |
| import com.android.tradefed.config.Option; |
| import com.android.tradefed.device.DeviceNotAvailableException; |
| import com.android.tradefed.device.ITestDevice; |
| import com.android.tradefed.device.StubDevice; |
| import com.android.tradefed.invoker.IInvocationContext; |
| import com.android.tradefed.log.LogUtil.CLog; |
| import com.android.tradefed.util.AbiUtils; |
| |
| /** Base class for a module controller to not run tests when it doesn't match the architecture . */ |
| public class KernelTestModuleController extends BaseModuleController { |
| private final String lowMemProp = "ro.config.low_ram"; |
| private final String productNameProp = "ro.product.name"; |
| |
| @Option(name = "arch", |
| description = "The architecture name that should run for this module." |
| + "This should be like arm64, arm, riscv64, x86_64, or x86.", |
| mandatory = true) |
| private String mArch = null; |
| |
| @Option(name = "is-low-mem", |
| description = "If this option set to true, run this module if device prop" |
| + "of 'ro.config.low_ram' is true else skip it.") |
| private boolean mIsLowMem = false; |
| |
| @Option(name = "is-hwasan", |
| description = "If this option set to true, run this module if device prop " |
| + "of 'ro.product.name' ended with _hwasan else skip it.") |
| private boolean mIsHwasan = false; |
| |
| @Override |
| public RunStrategy shouldRun(IInvocationContext context) { |
| // This should return arm64-v8a or armeabi-v7a |
| String moduleAbiName = getModuleAbi().getName(); |
| // Use AbiUtils to get the actual architecture name. |
| // If moduleAbiName is arm64-v8a then the moduleArchName will be arm64 |
| // If moduleAbiName is armeabi-v7a then the moduleArchName will be arm |
| String moduleArchName = AbiUtils.getArchForAbi(moduleAbiName); |
| |
| if (mIsLowMem) { |
| if (!deviceLowMem(context)) { |
| CLog.d("Skipping module %s because %s is False.", getModuleName(), lowMemProp); |
| return RunStrategy.FULL_MODULE_BYPASS; |
| } |
| } else { |
| if (deviceLowMem(context)) { |
| CLog.d("Skipping module %s because the test is not for low memory device.", |
| getModuleName()); |
| return RunStrategy.FULL_MODULE_BYPASS; |
| } |
| } |
| |
| if (mIsHwasan) { |
| if (!deviceWithHwasan(context)) { |
| CLog.d("Skipping module %s because %s is not ended with _hwasan.", getModuleName(), |
| productNameProp); |
| return RunStrategy.FULL_MODULE_BYPASS; |
| } |
| } else { |
| if (deviceWithHwasan(context)) { |
| CLog.d("Skipping module %s because the test is for device of hwasan.", |
| getModuleName()); |
| return RunStrategy.FULL_MODULE_BYPASS; |
| } |
| } |
| |
| if (mArch.equals(moduleArchName)) { |
| return RunStrategy.RUN; |
| } |
| CLog.d("Skipping module %s running on abi %s, which doesn't match any required setting " |
| + "of %s.", |
| getModuleName(), moduleAbiName, mArch); |
| return RunStrategy.FULL_MODULE_BYPASS; |
| } |
| |
| private boolean deviceLowMem(IInvocationContext context) { |
| for (ITestDevice device : context.getDevices()) { |
| if (device.getIDevice() instanceof StubDevice) { |
| continue; |
| } |
| try { |
| String lowMemString = device.getProperty(lowMemProp); |
| boolean isLowMem = false; |
| if (lowMemString != null) { |
| isLowMem = Boolean.parseBoolean(lowMemString); |
| } else { |
| CLog.d("Cannot get the prop of %s.", lowMemProp); |
| } |
| if (isLowMem) { |
| continue; |
| } |
| return false; |
| } catch (DeviceNotAvailableException e) { |
| CLog.e("Couldn't check prop of %s on %s", lowMemProp, device.getSerialNumber()); |
| CLog.e(e); |
| throw new RuntimeException(e); |
| } |
| } |
| return true; |
| } |
| |
| private boolean deviceWithHwasan(IInvocationContext context) { |
| for (ITestDevice device : context.getDevices()) { |
| if (device.getIDevice() instanceof StubDevice) { |
| continue; |
| } |
| try { |
| String productName = device.getProperty(productNameProp); |
| boolean isHwasan = false; |
| if (productName != null) { |
| isHwasan = productName.contains("_hwasan"); |
| } else { |
| CLog.d("Cannot get the prop of %s.", productNameProp); |
| } |
| if (isHwasan) { |
| continue; |
| } |
| return false; |
| } catch (DeviceNotAvailableException e) { |
| CLog.e("Couldn't check prop of %s on %s", productNameProp, |
| device.getSerialNumber()); |
| CLog.e(e); |
| throw new RuntimeException(e); |
| } |
| } |
| return true; |
| } |
| } |