blob: 313a9232723dbdc941c4e937d0b6db9c7e3df002 [file] [log] [blame]
/*
* Copyright (C) 2018 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.suite.checker;
import com.android.tradefed.config.Option;
import com.android.tradefed.config.OptionClass;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.log.LogUtil.CLog;
import com.android.tradefed.suite.checker.StatusCheckerResult.CheckStatus;
/**
* Check if the shell status is as expected before and after a module run. Any changes may
* unexpectedly affect test cases.
*
* <p>There is a command-line option to disable the checker entirely:
*
* <pre>--skip-system-status-check=com.android.tradefed.suite.checker.ShellStatusChecker
* </pre>
*/
@OptionClass(alias = "shell-status-checker")
public class ShellStatusChecker implements ISystemStatusChecker {
private static final String FAIL_STRING = " Reset failed.";
/* Option for the expected root state at pre- and post-check. */
@Option(
name = "expect-root",
description =
"Controls whether the shell root status is expected to be "
+ "root ('true') or non-root ('false'). "
+ "The checker will warn and try to revert the state "
+ "if not as expected at pre- or post-check."
)
private boolean mExpectedRoot = false;
/** {@inheritDoc} */
@Override
public StatusCheckerResult preExecutionCheck(ITestDevice device)
throws DeviceNotAvailableException {
StatusCheckerResult result = new StatusCheckerResult(CheckStatus.SUCCESS);
if (mExpectedRoot != device.isAdbRoot()) {
String message =
"This module unexpectedly started in a "
+ (mExpectedRoot ? "non-root" : "root")
+ " shell. Leaked from earlier module?";
result.setStatus(CheckStatus.FAILED);
boolean reset;
if (mExpectedRoot) {
reset = device.enableAdbRoot();
} else {
reset = device.disableAdbRoot();
}
if (!reset) {
message += FAIL_STRING;
}
CLog.w(message);
result.setErrorMessage(message);
}
return result;
}
/** {@inheritDoc} */
@Override
public StatusCheckerResult postExecutionCheck(ITestDevice device)
throws DeviceNotAvailableException {
StatusCheckerResult result = new StatusCheckerResult(CheckStatus.SUCCESS);
if (mExpectedRoot != device.isAdbRoot()) {
String message =
"This module changed shell root status to "
+ (mExpectedRoot ? "non-root" : "root")
+ ". Leaked from a test case or setup?";
result.setStatus(CheckStatus.FAILED);
boolean reset;
if (mExpectedRoot) {
reset = device.enableAdbRoot();
} else {
reset = device.disableAdbRoot();
}
if (!reset) {
message += FAIL_STRING;
}
CLog.w(message);
result.setErrorMessage(message);
}
return result;
}
}