/* * 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.IDevice; 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.ITestInvocationListener; import com.android.tradefed.result.InputStreamSource; import com.android.tradefed.result.LogDataType; import com.android.tradefed.result.SnapshotInputStreamSource; import com.android.tradefed.testtype.IDeviceTest; import com.android.tradefed.testtype.IRemoteTest; import com.android.tradefed.util.FileUtil; import com.android.tradefed.util.StreamUtil; import junit.framework.Assert; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileReader; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Run the Sms stress test. This test stresses sms message sending and receiving */ public class SmsStressTest implements IRemoteTest, IDeviceTest { private ITestDevice mTestDevice = null; // Define instrumentation test package and runner. private static final String TEST_PACKAGE_NAME = "com.android.mms.tests"; private static final String TEST_RUNNER_NAME = "com.android.mms.SmsTestRunner"; private static final String TEST_CLASS_NAME = "com.android.mms.ui.SmsStressTest"; private static final String ITEM_KEY = "single_thread"; private static final String METRICS_NAME = "sms_stress"; private static final Pattern MESSAGE_PATTERN = Pattern.compile("^send message (\\d+) out of (\\d+)"); private static final String INSERT_COMMAND = "sqlite3 /data/data/com.android.providers.settings/databases/settings.db " + "\"INSERT INTO global (name, value) values (\'%s\',\'%s\');\""; private String mOutputFile = "result.txt"; @Option(name="recipient", description="The recipient of sms messages") private String mRecipient = null; @Option(name="messages", description="The total number of messages to send") private int mNumMessages = 100; @Option(name="messagefile", description="The file to load sending message") private String mMessageFile = null; @Option(name="recipientfile", description="The file to load recipients") private String mRecipientFile = null; @Option(name="receivetimer", description="The timer before verifying messages receiption when sending sms" + "to the test device itself (s)") private int mReceiveTimer = 300; @Option(name="sendinterval", description="The time interval between two consecutive sms.") private int mSendInterval = 10; @Override public void setDevice(ITestDevice testDevice) { mTestDevice = testDevice; } @Override public ITestDevice getDevice() { return mTestDevice; } /** * Configure device with special settings */ private void setupDevice() throws DeviceNotAvailableException { String command = String.format( INSERT_COMMAND, "sms_outgoing_check_max_count", "20000"); CLog.d("Command to set sms_outgoing_check_max_count: %s", command); mTestDevice.executeShellCommand(command); // reboot to allow the setting to take effect // post setup will be taken care by the reboot mTestDevice.reboot(); } /** * Run sms stress test and parse test results */ @Override public void run(ITestInvocationListener standardListener) throws DeviceNotAvailableException { Assert.assertNotNull(mTestDevice); setupDevice(); RadioHelper mRadioHelper = new RadioHelper(mTestDevice); // Capture a bugreport if activation or data setup failed if (!mRadioHelper.radioActivation() || !mRadioHelper.waitForDataSetup()) { mRadioHelper.getBugreport(standardListener); return; } IRemoteAndroidTestRunner runner = new RemoteAndroidTestRunner( TEST_PACKAGE_NAME, TEST_RUNNER_NAME, mTestDevice.getIDevice()); runner.setClassName(TEST_CLASS_NAME); if (mRecipient != null) { runner.addInstrumentationArg("recipient", mRecipient); } if (mMessageFile != null) { runner.addInstrumentationArg("messagefile", mMessageFile); } if (mRecipientFile != null) { runner.addInstrumentationArg("messagefile", mMessageFile); } runner.addInstrumentationArg("messages", Integer.toString(mNumMessages)); runner.addInstrumentationArg( "receivetimer", Integer.toString(mReceiveTimer)); runner.addInstrumentationArg( "sendinterval", Integer.toString(mSendInterval)); mTestDevice.runInstrumentationTests(runner, standardListener); logOutputFile(standardListener); cleanOutputFiles(); } /** * Collect test results and report test results. * * @param listener */ private void logOutputFile(ITestInvocationListener listener) throws DeviceNotAvailableException { // Capture a bugreport right after the test InputStreamSource bugreport = mTestDevice.getBugreport(); listener.testLog("bugreport", LogDataType.TEXT, bugreport); bugreport.cancel(); InputStreamSource outputSource = null; Map<String, String> runMetrics = new HashMap<String, String>(); File resFile = null; BufferedReader br = null; try { resFile = mTestDevice.pullFileFromExternal(mOutputFile); if (resFile == null) { return; } // Save a copy of the output file CLog.d("Sending %d byte file %s into the logosphere!", resFile.length(), resFile); outputSource = new SnapshotInputStreamSource(new FileInputStream(resFile)); listener.testLog(mOutputFile, LogDataType.TEXT, outputSource); // Parse the results file and post results to test listener br = new BufferedReader(new FileReader(resFile)); String line = null; while ((line = br.readLine()) != null) { Matcher match = MESSAGE_PATTERN.matcher(line); if (match.matches()) { String value = match.group(1); CLog.d("iteration: %s", value); runMetrics.put(ITEM_KEY, value); } } } catch (IOException e) { CLog.e("IOException while reading from data stream: %s", e); } finally { FileUtil.deleteFile(resFile); StreamUtil.cancel(outputSource); StreamUtil.close(br); } reportMetrics(METRICS_NAME, listener, runMetrics); } /** * Report run metrics by creating an empty test run to stick them in */ private void reportMetrics(String metricsName, ITestInvocationListener listener, Map<String, String> metrics) { // 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); } /** * Clean up output files from the last test run */ private void cleanOutputFiles() throws DeviceNotAvailableException { CLog.d("Remove output file: %s", mOutputFile); String extStore = mTestDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE); mTestDevice.executeShellCommand(String.format("rm %s/%s", extStore, mOutputFile)); } }