/* * Copyright (C) 2011 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.wireless.tests; import com.android.ddmlib.testrunner.IRemoteAndroidTestRunner; import com.android.ddmlib.testrunner.RemoteAndroidTestRunner; 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.result.BugreportCollector; import com.android.tradefed.result.CollectingTestListener; import com.android.tradefed.result.ITestInvocationListener; import com.android.tradefed.result.InputStreamSource; import com.android.tradefed.result.LogDataType; import com.android.tradefed.testtype.IDeviceTest; import com.android.tradefed.testtype.IRemoteTest; import junit.framework.Assert; import java.util.HashMap; import java.util.Map; /** * Run radio startup stress test. The test stresses the radio by run-time reboot a device * for multiple times. In each iteration, voice and/or data connection is verified. */ public class RadioStressTest implements IRemoteTest, IDeviceTest { private ITestDevice mTestDevice = null; private static String TEST_NAME = "RadioStartupStress"; // Define metrics for result report private static final String METRICS_NAME = "RadioStartupStress"; private static final int VOICE_TEST_TIMER = 5 * 60 * 1000; // 5 minutes for voice test // Define instrumentation test package and runner. private static final String TEST_PACKAGE_NAME = "com.android.phonetests"; private static final String TEST_RUNNER_NAME = ".PhoneInstrumentationStressTestRunner"; private static final String TEST_CLASS_NAME = "com.android.phonetests.stress.telephony.TelephonyStress"; public static final String TEST_METHOD = "testSingleCallPowerUsage"; private RadioHelper mRadioHelper; @Option(name="iteration", description="The number of times to run the tests") private int mIteration = 100; @Option(name="call-duration", description="The time of a call to be held in the test (in seconds)") private String mCallDuration = "5"; @Option(name="phone-number", description="The phone number used for outgoing call test") private String mPhoneNumber = null; @Option(name="voice", description="To verify the voice call") private boolean mVoiceVerificationFlag = true; // From the past test, if there are too many failures, they are similar // set the threshold so that the test won't drag too long @Option(name="threshold", description="Threshold to stop the test") private int mThreshold = 100; /** * Run radio startup stress test, capture bugreport if the test failed. * Report results to dashboard after the test */ @Override public void run(ITestInvocationListener listener) throws DeviceNotAvailableException { CLog.d("input options: mIteration(%s), mCallDuration(%s), mPhoneNumber(%s), " + "mVoiceVerificationFlag(%s)", mIteration, mCallDuration, mPhoneNumber, mVoiceVerificationFlag); Assert.assertNotNull(mTestDevice); Assert.assertNotNull(mPhoneNumber); mRadioHelper = new RadioHelper(mTestDevice); // capture a bugreport if activation or data setup failed if (!mRadioHelper.radioActivation() || !mRadioHelper.waitForDataSetup()) { mRadioHelper.getBugreport(listener); return; } int mSuccessRun = 0; for (int i = 0; i < mIteration; i++) { // reset device before rebooting CLog.d("Radio startup test iteration : %d, success runs: %d", i, mSuccessRun); if ((i + 1) - mSuccessRun > mThreshold) { CLog.d("Too many failures, stop the test"); break; } mRadioHelper.resetBootComplete(); // run-time reboot device mTestDevice.executeShellCommand("stop"); mTestDevice.executeShellCommand("start"); mTestDevice.waitForDeviceAvailable(); // Setup up device mTestDevice.enableAdbRoot(); mTestDevice.postBootSetup(); mTestDevice.clearErrorDialogs(); // verify data connection first boolean dataFlag = false; if (verifyDataConnection()) { dataFlag = true; } else { getBugReport(listener, i); } // verify voice connection if (mVoiceVerificationFlag) { boolean voiceFlag = verifyVoiceConnection(listener); dataFlag = verifyDataConnection(); if (voiceFlag && dataFlag) { mSuccessRun++; } } else { if (dataFlag) { mSuccessRun++; } } } CLog.d("success runs out of total %d runs: %d", mIteration, mSuccessRun); Map<String, String> runMetrics = new HashMap<String, String>(1); runMetrics.put("iteration", String.valueOf(mSuccessRun)); reportMetrics(METRICS_NAME, runMetrics, listener); } /** * Capture a bugreport * @param listener is the TestInvocationListener * @param iteration is the index of the test run * @throws DeviceNotAvailableException */ private void getBugReport(ITestInvocationListener listener, int iteration) throws DeviceNotAvailableException { // take a bug report, it is possible the system crashed InputStreamSource bugreport = mTestDevice.getBugreport(); listener.testLog(String.format("bugreport_%d.txt", iteration), LogDataType.TEXT, bugreport); bugreport.cancel(); } private boolean verifyVoiceConnection(ITestInvocationListener listener) throws DeviceNotAvailableException { CLog.d("Verify voice connection started"); IRemoteAndroidTestRunner runner = new RemoteAndroidTestRunner(TEST_PACKAGE_NAME, TEST_RUNNER_NAME, mTestDevice.getIDevice()); runner.setClassName(TEST_CLASS_NAME); runner.setMethodName(TEST_CLASS_NAME, TEST_METHOD); runner.addInstrumentationArg("callduration", mCallDuration); runner.addInstrumentationArg("phonenumber", mPhoneNumber); runner.addInstrumentationArg("repeatcount", "1"); runner.setMaxtimeToOutputResponse(VOICE_TEST_TIMER); // Add bugreport listener for failed test BugreportCollector bugListener = new BugreportCollector(listener, mTestDevice); bugListener.addPredicate(BugreportCollector.AFTER_FAILED_TESTCASES); bugListener.setDescriptiveName(TEST_NAME); // Device may reboot during the test, to capture a bugreport after that, // wait for 30 seconds for device to be online, otherwise, bugreport will be empty bugListener.setDeviceWaitTime(30); CollectingTestListener collectListener = new CollectingTestListener(); mTestDevice.runInstrumentationTests(runner, bugListener, collectListener); if (collectListener.hasFailedTests()) { CLog.d("Voice call failed."); return false; } return true; } private boolean verifyDataConnection() throws DeviceNotAvailableException { return mRadioHelper.waitForDataSetup(); } /** * Report run metrics by creating an empty test run to stick them in * <p /> * Exposed for unit testing */ private void reportMetrics(String metricsName, Map<String, String> metrics, ITestInvocationListener listener) { // Create an empty testRun to report the parsed runMetrics CLog.d("About to report metrics to %s: %s", metricsName, metrics); listener.testRunStarted(metricsName, 0); listener.testRunEnded(0, metrics); } @Override public void setDevice(ITestDevice testDevice) { mTestDevice = testDevice; } @Override public ITestDevice getDevice() { return mTestDevice; } }