blob: d296fabb150454913741d7b33a117551bbf7e3b7 [file] [log] [blame]
/*
* Copyright (C) 2017 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.annotations.VisibleForTesting;
import com.android.tradefed.config.Option;
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;
import com.android.tradefed.util.ProcessInfo;
import com.android.tradefed.util.StreamUtil;
/**
* Check if the pid of system_server has changed from before and after a module run. A new pid would
* mean a runtime restart occurred during the module run.
*/
public class SystemServerStatusChecker implements ISystemStatusChecker {
@Option(
name = "disable-recovery-reboot",
description =
"If status checker is detected down (no process), attempt to reboot the device."
)
private boolean mShouldRecover = true;
private ProcessInfo mSystemServerProcess;
private boolean mShouldSkip = false;
/** {@inheritDoc} */
@Override
public StatusCheckerResult preExecutionCheck(ITestDevice device)
throws DeviceNotAvailableException {
if (mShouldSkip) {
return new StatusCheckerResult(CheckStatus.SUCCESS);
}
// process info relies on a time function fixed after P
if (device.getApiLevel() < 29) {
mShouldSkip = true;
CLog.d("Api level is under 29 skipping SystemServerStatusChecker");
return new StatusCheckerResult(CheckStatus.SUCCESS);
}
mSystemServerProcess = device.getProcessByName("system_server");
StatusCheckerResult result = new StatusCheckerResult(CheckStatus.SUCCESS);
if (mSystemServerProcess == null) {
if (mShouldRecover) {
device.reboot();
}
String message = "No valid system_server process is found.";
CLog.w(message);
result.setStatus(CheckStatus.FAILED);
result.setBugreportNeeded(true);
result.setErrorMessage(message);
return result;
}
return result;
}
/** {@inheritDoc} */
@Override
public StatusCheckerResult postExecutionCheck(ITestDevice device)
throws DeviceNotAvailableException {
if (mShouldSkip) {
return new StatusCheckerResult(CheckStatus.SUCCESS);
}
if (mSystemServerProcess == null) {
CLog.d(
"No valid system_server process was found in preExecutionCheck, "
+ "skipping system_server postExecutionCheck.");
return new StatusCheckerResult(CheckStatus.SUCCESS);
}
try {
if (!device.deviceSoftRestarted(mSystemServerProcess)) {
return new StatusCheckerResult(CheckStatus.SUCCESS);
}
} catch (RuntimeException e) {
CLog.w(StreamUtil.getStackTrace(e));
StatusCheckerResult result = new StatusCheckerResult(CheckStatus.FAILED);
result.setBugreportNeeded(true);
result.setErrorMessage(StreamUtil.getStackTrace(e));
return result;
}
StatusCheckerResult result = new StatusCheckerResult(CheckStatus.FAILED);
result.setErrorMessage("The system-server crashed during test execution");
return result;
}
/** Returns the current time. */
@VisibleForTesting
protected long getCurrentTime() {
return System.currentTimeMillis();
}
}