10aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang/* 20bebaf393a6e531e5c0b20306c4e8ebc9e4d64f2Xia Wang * Copyright (C) 2013 The Android Open Source Project 30aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * 40aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * Licensed under the Apache License, Version 2.0 (the "License"); 50aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * you may not use this file except in compliance with the License. 60aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * You may obtain a copy of the License at 70aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * 80aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * http://www.apache.org/licenses/LICENSE-2.0 90aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * 100aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * Unless required by applicable law or agreed to in writing, software 110aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * distributed under the License is distributed on an "AS IS" BASIS, 120aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * See the License for the specific language governing permissions and 140aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * limitations under the License. 150aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang */ 160aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang 170bebaf393a6e531e5c0b20306c4e8ebc9e4d64f2Xia Wangpackage com.android.uiautomator.platform; 180aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang 190aac99898b24c3633876b1cc6ab0612b2e893910Xia Wangimport android.os.Bundle; 200aac99898b24c3633876b1cc6ab0612b2e893910Xia Wangimport android.os.Environment; 210aac99898b24c3633876b1cc6ab0612b2e893910Xia Wangimport android.util.Log; 220aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang 230aac99898b24c3633876b1cc6ab0612b2e893910Xia Wangimport com.android.uiautomator.core.UiDevice; 240aac99898b24c3633876b1cc6ab0612b2e893910Xia Wangimport com.android.uiautomator.testrunner.UiAutomatorTestCase; 250aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang 265967bd5f7085577474e1ea7905db714f046de862Xia Wangimport java.io.BufferedOutputStream; 275967bd5f7085577474e1ea7905db714f046de862Xia Wangimport java.io.BufferedReader; 280aac99898b24c3633876b1cc6ab0612b2e893910Xia Wangimport java.io.BufferedWriter; 290aac99898b24c3633876b1cc6ab0612b2e893910Xia Wangimport java.io.File; 300aac99898b24c3633876b1cc6ab0612b2e893910Xia Wangimport java.io.FileInputStream; 310aac99898b24c3633876b1cc6ab0612b2e893910Xia Wangimport java.io.FileNotFoundException; 325967bd5f7085577474e1ea7905db714f046de862Xia Wangimport java.io.FileOutputStream; 330aac99898b24c3633876b1cc6ab0612b2e893910Xia Wangimport java.io.FileWriter; 340aac99898b24c3633876b1cc6ab0612b2e893910Xia Wangimport java.io.IOException; 355967bd5f7085577474e1ea7905db714f046de862Xia Wangimport java.io.InputStream; 365967bd5f7085577474e1ea7905db714f046de862Xia Wangimport java.io.InputStreamReader; 375967bd5f7085577474e1ea7905db714f046de862Xia Wangimport java.util.ArrayList; 385967bd5f7085577474e1ea7905db714f046de862Xia Wangimport java.util.List; 390aac99898b24c3633876b1cc6ab0612b2e893910Xia Wangimport java.util.Properties; 400aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang 410aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang/** 425967bd5f7085577474e1ea7905db714f046de862Xia Wang * Base class for jank test. 435967bd5f7085577474e1ea7905db714f046de862Xia Wang * All jank test needs to extend JankTestBase 440aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang */ 450aac99898b24c3633876b1cc6ab0612b2e893910Xia Wangpublic class JankTestBase extends UiAutomatorTestCase { 4644ef31d58e8b998ac487ad6973fff3ac156f77e2Xia Wang private static final String TAG = JankTestBase.class.getSimpleName(); 475967bd5f7085577474e1ea7905db714f046de862Xia Wang 480aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang protected UiDevice mDevice; 495967bd5f7085577474e1ea7905db714f046de862Xia Wang protected TestWatchers mTestWatchers = null; 500aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang protected BufferedWriter mWriter = null; 510aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang protected BufferedWriter mStatusWriter = null; 5276c7edc9e8b5e9108c9006a73a9abb80775edc4fXia Wang protected int mIteration = 20; // default iteration is set 20 535967bd5f7085577474e1ea7905db714f046de862Xia Wang /* can be used to enable/disable systrace in the test */ 545967bd5f7085577474e1ea7905db714f046de862Xia Wang protected int mTraceTime = 0; 550aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang protected Bundle mParams; 560aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang protected String mTestCaseName; 570aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang protected int mSuccessTestRuns = 0; 585967bd5f7085577474e1ea7905db714f046de862Xia Wang protected Thread mThread = null; 590aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang 600aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang // holds all params for the derived tests 6144ef31d58e8b998ac487ad6973fff3ac156f77e2Xia Wang private static final String PROPERTY_FILE_NAME = "UiJankinessTests.conf"; 6244ef31d58e8b998ac487ad6973fff3ac156f77e2Xia Wang private static final String PARAM_CONFIG = "conf"; 6344ef31d58e8b998ac487ad6973fff3ac156f77e2Xia Wang private static final String LOCAL_TMP_DIR = "/data/local/tmp/"; 640aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang // File that hold the test results 650aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang private static String OUTPUT_FILE_NAME = LOCAL_TMP_DIR + "UiJankinessTestsOutput.txt"; 660aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang // File that hold test status, e.g successful test iterations 670aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang private static String STATUS_FILE_NAME = LOCAL_TMP_DIR + "UiJankinessTestsStatus.txt"; 6844ef31d58e8b998ac487ad6973fff3ac156f77e2Xia Wang private static final String RAW_DATA_DIR = LOCAL_TMP_DIR + "UiJankinessRawData"; 695967bd5f7085577474e1ea7905db714f046de862Xia Wang 700aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang private static int SUCCESS_THRESHOLD = 80; 710aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang private static boolean DEBUG = false; 720aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang 735967bd5f7085577474e1ea7905db714f046de862Xia Wang /* default animation time is set to 2 seconds */ 7444ef31d58e8b998ac487ad6973fff3ac156f77e2Xia Wang protected static final long DEFAULT_ANIMATION_TIME = 2 * 1000; 755967bd5f7085577474e1ea7905db714f046de862Xia Wang /* default swipe steps for fling animation */ 7644ef31d58e8b998ac487ad6973fff3ac156f77e2Xia Wang protected static final int DEFAULT_FLING_STEPS = 8; 775967bd5f7085577474e1ea7905db714f046de862Xia Wang 780aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang /* Array to record jankiness data in each test iteration */ 790aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang private int[] jankinessArray; 800aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang /* Array to record frame rate in each test iteration */ 810aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang private double[] frameRateArray; 820aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang /* Array to save max accumulated frame number in each test iteration */ 830aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang private int[] maxDeltaVsyncArray; 845967bd5f7085577474e1ea7905db714f046de862Xia Wang /* Default file to store the systrace */ 8544ef31d58e8b998ac487ad6973fff3ac156f77e2Xia Wang private static final File SYSTRACE_DIR = new File(LOCAL_TMP_DIR, "systrace"); 865967bd5f7085577474e1ea7905db714f046de862Xia Wang /* Default trace file name */ 8744ef31d58e8b998ac487ad6973fff3ac156f77e2Xia Wang private static final String TRACE_FILE_NAME = "trace.txt"; 885967bd5f7085577474e1ea7905db714f046de862Xia Wang /* Default tracing time is 5 seconds */ 8944ef31d58e8b998ac487ad6973fff3ac156f77e2Xia Wang private static final int DEFAULT_TRACE_TIME = 5; // 5 seconds 905967bd5f7085577474e1ea7905db714f046de862Xia Wang // Command to dump compressed trace data 9144ef31d58e8b998ac487ad6973fff3ac156f77e2Xia Wang private static final String ATRACE_COMMAND = "atrace -z -t %d gfx input view sched freq"; 925967bd5f7085577474e1ea7905db714f046de862Xia Wang 935967bd5f7085577474e1ea7905db714f046de862Xia Wang /** 945967bd5f7085577474e1ea7905db714f046de862Xia Wang * Thread to capture systrace log from the test 955967bd5f7085577474e1ea7905db714f046de862Xia Wang */ 965967bd5f7085577474e1ea7905db714f046de862Xia Wang public class SystraceTracker implements Runnable { 975967bd5f7085577474e1ea7905db714f046de862Xia Wang File mFile = new File(SYSTRACE_DIR, TRACE_FILE_NAME); 985967bd5f7085577474e1ea7905db714f046de862Xia Wang int mTime = DEFAULT_TRACE_TIME; 995967bd5f7085577474e1ea7905db714f046de862Xia Wang 1005967bd5f7085577474e1ea7905db714f046de862Xia Wang public SystraceTracker(int traceTime, String fileName) { 1015967bd5f7085577474e1ea7905db714f046de862Xia Wang try { 1025967bd5f7085577474e1ea7905db714f046de862Xia Wang if (!SYSTRACE_DIR.exists()) { 1035967bd5f7085577474e1ea7905db714f046de862Xia Wang if (!SYSTRACE_DIR.mkdir()) { 1045967bd5f7085577474e1ea7905db714f046de862Xia Wang log(String.format("create directory %s failed, you can manually create " 1055967bd5f7085577474e1ea7905db714f046de862Xia Wang + "it and start the test again", SYSTRACE_DIR.getAbsolutePath())); 1065967bd5f7085577474e1ea7905db714f046de862Xia Wang return; 1075967bd5f7085577474e1ea7905db714f046de862Xia Wang } 1085967bd5f7085577474e1ea7905db714f046de862Xia Wang } 1095967bd5f7085577474e1ea7905db714f046de862Xia Wang } catch (SecurityException e) { 1105967bd5f7085577474e1ea7905db714f046de862Xia Wang Log.e(TAG, "creating directory failed?", e); 1115967bd5f7085577474e1ea7905db714f046de862Xia Wang } 1125967bd5f7085577474e1ea7905db714f046de862Xia Wang 1135967bd5f7085577474e1ea7905db714f046de862Xia Wang if (traceTime > 0) { 1145967bd5f7085577474e1ea7905db714f046de862Xia Wang mTime = traceTime; 1155967bd5f7085577474e1ea7905db714f046de862Xia Wang } 1165967bd5f7085577474e1ea7905db714f046de862Xia Wang if (fileName != null) { 1175967bd5f7085577474e1ea7905db714f046de862Xia Wang mFile = new File(SYSTRACE_DIR, fileName); 1185967bd5f7085577474e1ea7905db714f046de862Xia Wang } 1195967bd5f7085577474e1ea7905db714f046de862Xia Wang } 1205967bd5f7085577474e1ea7905db714f046de862Xia Wang 1215967bd5f7085577474e1ea7905db714f046de862Xia Wang @Override 1225967bd5f7085577474e1ea7905db714f046de862Xia Wang public void run() { 1235967bd5f7085577474e1ea7905db714f046de862Xia Wang String command = String.format(ATRACE_COMMAND, mTime); 1245967bd5f7085577474e1ea7905db714f046de862Xia Wang Log.v(TAG, "command: " + command); 1255967bd5f7085577474e1ea7905db714f046de862Xia Wang Process p = null; 1265967bd5f7085577474e1ea7905db714f046de862Xia Wang InputStream in = null; 1275967bd5f7085577474e1ea7905db714f046de862Xia Wang BufferedOutputStream out = null; 1285967bd5f7085577474e1ea7905db714f046de862Xia Wang try { 1295967bd5f7085577474e1ea7905db714f046de862Xia Wang p = Runtime.getRuntime().exec(command); 1305967bd5f7085577474e1ea7905db714f046de862Xia Wang Log.v(TAG, "write systrace into file: " + mFile.getAbsolutePath()); 1315967bd5f7085577474e1ea7905db714f046de862Xia Wang // read bytes from the process output stream as the output is compressed 1325967bd5f7085577474e1ea7905db714f046de862Xia Wang byte[] buffer = new byte[1024]; 1335967bd5f7085577474e1ea7905db714f046de862Xia Wang in = p.getInputStream(); 1345967bd5f7085577474e1ea7905db714f046de862Xia Wang out = new BufferedOutputStream(new FileOutputStream(mFile)); 1355967bd5f7085577474e1ea7905db714f046de862Xia Wang int n; 1365967bd5f7085577474e1ea7905db714f046de862Xia Wang while ((n = in.read(buffer)) != -1) { 1375967bd5f7085577474e1ea7905db714f046de862Xia Wang out.write(buffer, 0, n); 1385967bd5f7085577474e1ea7905db714f046de862Xia Wang out.flush(); 1395967bd5f7085577474e1ea7905db714f046de862Xia Wang } 1405967bd5f7085577474e1ea7905db714f046de862Xia Wang in.close(); 1415967bd5f7085577474e1ea7905db714f046de862Xia Wang out.close(); 1425967bd5f7085577474e1ea7905db714f046de862Xia Wang // read error message 1435967bd5f7085577474e1ea7905db714f046de862Xia Wang BufferedReader br = new BufferedReader(new InputStreamReader(p.getErrorStream())); 1445967bd5f7085577474e1ea7905db714f046de862Xia Wang String line; 1455967bd5f7085577474e1ea7905db714f046de862Xia Wang while ((line = br.readLine()) != null) { 1465967bd5f7085577474e1ea7905db714f046de862Xia Wang Log.e(TAG, "Command return errors: " + line); 1475967bd5f7085577474e1ea7905db714f046de862Xia Wang } 1485967bd5f7085577474e1ea7905db714f046de862Xia Wang br.close(); 1495967bd5f7085577474e1ea7905db714f046de862Xia Wang 1505967bd5f7085577474e1ea7905db714f046de862Xia Wang // Due to limited buffer size for standard input and output stream, 1515967bd5f7085577474e1ea7905db714f046de862Xia Wang // promptly reading from the input stream or output stream to avoid block 1525967bd5f7085577474e1ea7905db714f046de862Xia Wang int status = p.waitFor(); 1535967bd5f7085577474e1ea7905db714f046de862Xia Wang if (status != 0) { 1545967bd5f7085577474e1ea7905db714f046de862Xia Wang Log.e(TAG, String.format("Run shell command: %s, status: %s", 1555967bd5f7085577474e1ea7905db714f046de862Xia Wang command, status)); 1565967bd5f7085577474e1ea7905db714f046de862Xia Wang } 1575967bd5f7085577474e1ea7905db714f046de862Xia Wang } catch (InterruptedException e) { 1585967bd5f7085577474e1ea7905db714f046de862Xia Wang Log.e(TAG, "Exception from command " + command + ":"); 1595967bd5f7085577474e1ea7905db714f046de862Xia Wang Log.e(TAG, "Thread interrupted? ", e); 1605967bd5f7085577474e1ea7905db714f046de862Xia Wang } catch (IOException e) { 1615967bd5f7085577474e1ea7905db714f046de862Xia Wang Log.e(TAG, "Open file error: ", e); 1625967bd5f7085577474e1ea7905db714f046de862Xia Wang } catch (IllegalThreadStateException e) { 1635967bd5f7085577474e1ea7905db714f046de862Xia Wang Log.e(TAG, "the process has not exit yet ", e); 1645967bd5f7085577474e1ea7905db714f046de862Xia Wang } 1655967bd5f7085577474e1ea7905db714f046de862Xia Wang } 1665967bd5f7085577474e1ea7905db714f046de862Xia Wang } 1670aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang 1680aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang @Override 1690aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang protected void setUp() throws Exception { 1700aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang super.setUp(); 1710aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang mDevice = UiDevice.getInstance(); 1725967bd5f7085577474e1ea7905db714f046de862Xia Wang mTestWatchers = new TestWatchers(); // extends the common class UiWatchers 1735967bd5f7085577474e1ea7905db714f046de862Xia Wang mTestWatchers.registerAnrAndCrashWatchers(); 1740aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang 1750aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang mWriter = new BufferedWriter(new FileWriter(new File(OUTPUT_FILE_NAME), true)); 1760aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang mStatusWriter = new BufferedWriter(new FileWriter(new File(STATUS_FILE_NAME), true)); 1770aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang 1780aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang mParams = getParams(); 1790aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang if (mParams != null && !mParams.isEmpty()) { 1800aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang log("mParams is not empty, get properties."); 1815967bd5f7085577474e1ea7905db714f046de862Xia Wang String mIterationStr = getPropertyString(mParams, "iteration"); 1825967bd5f7085577474e1ea7905db714f046de862Xia Wang if (mIterationStr != null) { 1830aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang mIteration = Integer.valueOf(mIterationStr); 1840aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang } 1855967bd5f7085577474e1ea7905db714f046de862Xia Wang String mTraceTimeStr = getPropertyString(mParams, "tracetime"); 1865967bd5f7085577474e1ea7905db714f046de862Xia Wang if (mTraceTimeStr != null) { 1875967bd5f7085577474e1ea7905db714f046de862Xia Wang mTraceTime = Integer.valueOf(mTraceTimeStr); 1885967bd5f7085577474e1ea7905db714f046de862Xia Wang } 1890aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang } 1900aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang jankinessArray = new int[mIteration]; 1910aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang frameRateArray = new double[mIteration]; 1920aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang maxDeltaVsyncArray = new int[mIteration]; 1930aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang mTestCaseName = this.getName(); 1940aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang 1950aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang mSuccessTestRuns = 0; 1960aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang mDevice.pressHome(); 1970aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang } 1980aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang 1990aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang /** 2005967bd5f7085577474e1ea7905db714f046de862Xia Wang * Create a new thread for systrace and start the thread 2015967bd5f7085577474e1ea7905db714f046de862Xia Wang * 2025967bd5f7085577474e1ea7905db714f046de862Xia Wang * @param testCaseName 2035967bd5f7085577474e1ea7905db714f046de862Xia Wang * @param iteration 2045967bd5f7085577474e1ea7905db714f046de862Xia Wang */ 2055967bd5f7085577474e1ea7905db714f046de862Xia Wang protected void startTrace(String testCaseName, int iteration) { 2065967bd5f7085577474e1ea7905db714f046de862Xia Wang if (mTraceTime > 0) { 2075967bd5f7085577474e1ea7905db714f046de862Xia Wang String outputFile = String.format("%s_%d_trace", mTestCaseName, iteration); 2085967bd5f7085577474e1ea7905db714f046de862Xia Wang mThread = new Thread(new SystraceTracker(mTraceTime, outputFile)); 2095967bd5f7085577474e1ea7905db714f046de862Xia Wang mThread.start(); 2105967bd5f7085577474e1ea7905db714f046de862Xia Wang } 2115967bd5f7085577474e1ea7905db714f046de862Xia Wang } 2125967bd5f7085577474e1ea7905db714f046de862Xia Wang 2135967bd5f7085577474e1ea7905db714f046de862Xia Wang /** 2145967bd5f7085577474e1ea7905db714f046de862Xia Wang * Wait for the tracing thread to exit 2155967bd5f7085577474e1ea7905db714f046de862Xia Wang */ 2165967bd5f7085577474e1ea7905db714f046de862Xia Wang protected void endTrace() { 2175967bd5f7085577474e1ea7905db714f046de862Xia Wang if (mThread != null) { 2185967bd5f7085577474e1ea7905db714f046de862Xia Wang try { 2195967bd5f7085577474e1ea7905db714f046de862Xia Wang mThread.join(); 2205967bd5f7085577474e1ea7905db714f046de862Xia Wang } catch (InterruptedException e) { 2215967bd5f7085577474e1ea7905db714f046de862Xia Wang Log.e(TAG, "wait for the trace thread to exit exception:", e); 2225967bd5f7085577474e1ea7905db714f046de862Xia Wang } 2235967bd5f7085577474e1ea7905db714f046de862Xia Wang } 2245967bd5f7085577474e1ea7905db714f046de862Xia Wang } 2255967bd5f7085577474e1ea7905db714f046de862Xia Wang 2265967bd5f7085577474e1ea7905db714f046de862Xia Wang /** 2270aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * Expects a file from the command line via conf param or default following format each on its 2280aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * own line. <code> 2290aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * key=Value 2300aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * Browser_URL1=cnn.com 2310aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * Browser_URL2=google.com 2320aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * Camera_ShutterDelay=1000 2330aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * etc... 2340aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * </code> 2350aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * @param Bundle params 2360aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * @param key 2370aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * @return the value of the property else defaultValue 2380aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * @throws FileNotFoundException 2390aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * @throws IOException 2400aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang */ 2410aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang protected String getPropertyString(Bundle params, String key) 2420aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang throws FileNotFoundException, IOException { 2430aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang Properties prop = new Properties(); 2440aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang prop.load(new FileInputStream(new File(LOCAL_TMP_DIR, 2450aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang params.getString(PARAM_CONFIG, PROPERTY_FILE_NAME)))); 2460aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang String value = prop.getProperty(key); 2470aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang if (value != null && !value.isEmpty()) 2480aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang return value; 2490aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang return null; 2500aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang } 2510aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang 2520aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang /** 2530aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * Expects a file from the command line via conf param or default following format each on its 2540aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * own line. <code> 2550aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * key=Value 2560aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * Browser_URL1=cnn.com 2570aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * Browser_URL2=google.com 2580aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * Camera_ShutterDelay=1000 2590aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * etc... 2600aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * </code> 2610aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * @param Bundle params 2620aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * @param key 2630aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * @return the value of the property else defaultValue 2640aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * @throws FileNotFoundException 2650aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * @throws IOException 2660aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang */ 2670aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang protected long getPropertyLong(Bundle params, String key) 2680aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang throws FileNotFoundException, IOException { 2690aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang Properties prop = new Properties(); 2700aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang prop.load(new FileInputStream(new File(LOCAL_TMP_DIR, 2710aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang params.getString(PARAM_CONFIG, PROPERTY_FILE_NAME)))); 2720aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang String value = prop.getProperty(key); 2730aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang if (value != null && !value.trim().isEmpty()) 2740aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang return Long.valueOf(value.trim()); 2750aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang return 0; 2760aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang } 2770aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang 2780aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang /** 27944ef31d58e8b998ac487ad6973fff3ac156f77e2Xia Wang * Verify the test result by comparing data sample size with expected value 28044ef31d58e8b998ac487ad6973fff3ac156f77e2Xia Wang * @param expectedDataSize the expected data size 28144ef31d58e8b998ac487ad6973fff3ac156f77e2Xia Wang */ 28244ef31d58e8b998ac487ad6973fff3ac156f77e2Xia Wang protected boolean validateResults(int expectedDataSize) { 28344ef31d58e8b998ac487ad6973fff3ac156f77e2Xia Wang int receivedDataSize = SurfaceFlingerHelper.getDataSampleSize(); 28444ef31d58e8b998ac487ad6973fff3ac156f77e2Xia Wang return ((expectedDataSize > 0) && (receivedDataSize >= expectedDataSize)); 28544ef31d58e8b998ac487ad6973fff3ac156f77e2Xia Wang } 28644ef31d58e8b998ac487ad6973fff3ac156f77e2Xia Wang 28744ef31d58e8b998ac487ad6973fff3ac156f77e2Xia Wang /** 2880aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * Process the raw data, calculate jankiness, frame rate and max accumulated frames number 2890aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * @param testCaseName 2900aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * @param iteration 2910aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang */ 2920aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang protected void recordResults(String testCaseName, int iteration) { 2930aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang long refreshPeriod = SurfaceFlingerHelper.getRefreshPeriod(); 2945967bd5f7085577474e1ea7905db714f046de862Xia Wang // if the raw directory doesn't exit, create the directory 2955967bd5f7085577474e1ea7905db714f046de862Xia Wang File rawDataDir = new File(RAW_DATA_DIR); 2965967bd5f7085577474e1ea7905db714f046de862Xia Wang try { 2975967bd5f7085577474e1ea7905db714f046de862Xia Wang if (!rawDataDir.exists()) { 2985967bd5f7085577474e1ea7905db714f046de862Xia Wang if (!rawDataDir.mkdir()) { 2995967bd5f7085577474e1ea7905db714f046de862Xia Wang log(String.format("create directory %s failed, you can manually create " + 3005967bd5f7085577474e1ea7905db714f046de862Xia Wang "it and start the test again", rawDataDir)); 3015967bd5f7085577474e1ea7905db714f046de862Xia Wang } 3025967bd5f7085577474e1ea7905db714f046de862Xia Wang } 3035967bd5f7085577474e1ea7905db714f046de862Xia Wang } catch (SecurityException e) { 3045967bd5f7085577474e1ea7905db714f046de862Xia Wang Log.e(TAG, "create directory failed: ", e); 3055967bd5f7085577474e1ea7905db714f046de862Xia Wang } 3065967bd5f7085577474e1ea7905db714f046de862Xia Wang String rawFileName = String.format("%s/%s_%d.txt", RAW_DATA_DIR, testCaseName, iteration); 3075967bd5f7085577474e1ea7905db714f046de862Xia Wang // write results into a file 3085967bd5f7085577474e1ea7905db714f046de862Xia Wang BufferedWriter fw = null; 3095967bd5f7085577474e1ea7905db714f046de862Xia Wang try { 3105967bd5f7085577474e1ea7905db714f046de862Xia Wang fw = new BufferedWriter(new FileWriter(new File(rawFileName), false)); 3115967bd5f7085577474e1ea7905db714f046de862Xia Wang fw.write(SurfaceFlingerHelper.getFrameBufferData()); 3125967bd5f7085577474e1ea7905db714f046de862Xia Wang } catch (IOException e) { 3135967bd5f7085577474e1ea7905db714f046de862Xia Wang Log.e(TAG, "failed to write to file", e); 3145967bd5f7085577474e1ea7905db714f046de862Xia Wang return; 3155967bd5f7085577474e1ea7905db714f046de862Xia Wang } finally { 3165967bd5f7085577474e1ea7905db714f046de862Xia Wang try { 3175967bd5f7085577474e1ea7905db714f046de862Xia Wang if (fw != null) { 3185967bd5f7085577474e1ea7905db714f046de862Xia Wang fw.close(); 3195967bd5f7085577474e1ea7905db714f046de862Xia Wang } 3205967bd5f7085577474e1ea7905db714f046de862Xia Wang } 3215967bd5f7085577474e1ea7905db714f046de862Xia Wang catch (IOException e) { 3225967bd5f7085577474e1ea7905db714f046de862Xia Wang Log.e(TAG, "close file failed.", e); 3235967bd5f7085577474e1ea7905db714f046de862Xia Wang } 3245967bd5f7085577474e1ea7905db714f046de862Xia Wang } 3255967bd5f7085577474e1ea7905db714f046de862Xia Wang 3260aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang // get jankiness count 3270aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang int jankinessCount = SurfaceFlingerHelper.getVsyncJankiness(); 3280aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang // get frame rate 3290aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang double frameRate = SurfaceFlingerHelper.getFrameRate(); 3300aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang // get max accumulated frames 3310aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang int maxDeltaVsync = SurfaceFlingerHelper.getMaxDeltaVsync(); 3320aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang 3330aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang // only record data when they are valid 3340aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang if (jankinessCount >=0 && frameRate > 0) { 3350aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang jankinessArray[iteration] = jankinessCount; 3360aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang frameRateArray[iteration] = frameRate; 3370aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang maxDeltaVsyncArray[iteration] = maxDeltaVsync; 3380aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang mSuccessTestRuns++; 3390aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang } 3400aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang String msg = String.format("%s, iteration %d\n" + 3410aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang "refresh period: %d\n" + 3420aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang "jankiness count: %d\n" + 3430aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang "frame rate: %f\n" + 3440aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang "max accumulated frames: %d\n", 3450aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang testCaseName, iteration, refreshPeriod, 3460aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang jankinessCount, frameRate, maxDeltaVsync); 3470aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang log(msg); 3480aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang if (DEBUG) { 3490aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang SurfaceFlingerHelper.printData(testCaseName, iteration); 3500aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang } 3510aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang } 3520aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang 3530aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang /** 3540aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * Process data from all test iterations, and save to disk 3550aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * @param testCaseName 3560aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang */ 3570aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang protected void saveResults(String testCaseName) { 3580aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang // write test status into status file 3590aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang try { 3600aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang mStatusWriter.write(String.format("%s: %d success runs out of %d iterations\n", 3610aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang testCaseName, mSuccessTestRuns, mIteration)); 3620aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang } catch (IOException e) { 3630aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang log("failed to write output for test case " + testCaseName); 3640aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang } 3650aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang 3660aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang // if successful test runs is less than the threshold, no results will be saved. 3670aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang if (mSuccessTestRuns * 100 / mIteration < SUCCESS_THRESHOLD) { 3680aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang log(String.format("In %s, # of successful test runs out of %s iterations: %d ", 3690aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang testCaseName, mIteration, mSuccessTestRuns)); 3700aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang log(String.format("threshold is %d%%", SUCCESS_THRESHOLD)); 3710aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang return; 3720aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang } 3730aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang 3740aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang if (DEBUG) { 3750aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang print(jankinessArray, "jankiness array"); 3760aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang print(frameRateArray, "frame rate array"); 3770aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang print(maxDeltaVsyncArray, "max delta vsync array"); 3780aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang } 3790aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang double avgJankinessCount = getAverage(jankinessArray); 3800aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang int maxJankinessCount = getMaxValue(jankinessArray); 3810aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang double avgFrameRate = getAverage(frameRateArray); 3820aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang double avgMaxDeltaVsync = getAverage(maxDeltaVsyncArray); 3830aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang 3840aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang String avgMsg = String.format("%s\n" + 3850aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang "average number of jankiness: %f\n" + 3860aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang "max number of jankiness: %d\n" + 3870aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang "average frame rate: %f\n" + 3880aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang "average of max accumulated frames: %f\n", 3890aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang testCaseName, avgJankinessCount, maxJankinessCount, avgFrameRate, avgMaxDeltaVsync); 3900aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang log(avgMsg); 3910aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang 3920aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang try { 3930aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang mWriter.write(avgMsg); 3940aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang } catch (IOException e) { 3950aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang log("failed to write output for test case " + testCaseName); 3960aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang } 3970aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang } 3980aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang 3990aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang // return the max value in an integer array 4000aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang private int getMaxValue(int[] intArray) { 4010aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang int index = 0; 4020aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang int max = intArray[index]; 4030aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang for (int i = 1; i < intArray.length; i++) { 4040aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang if (max < intArray[i]) { 4050aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang max = intArray[i]; 4060aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang } 4070aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang } 4080aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang return max; 4090aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang } 4100aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang 4110aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang private double getAverage(int[] intArray) { 4120aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang int mean = 0; 4130aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang int numberTests = 0; 4140aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang for (int i = 0; i < intArray.length; i++) { 4150aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang // in case in some iteration, test fails, no data points is collected 4160aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang if (intArray[i] >= 0) { 4170aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang mean += intArray[i]; 4180aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang ++numberTests; 4190aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang } 4200aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang } 4210aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang return (double)mean/numberTests; 4220aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang } 4230aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang 4240aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang private double getAverage(double[] doubleArray) { 4250aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang double mean = 0; 4260aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang int numberTests = 0; 4270aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang for (int i = 0; i < doubleArray.length; i++) { 4280aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang // in case in some iteration, test fails, no data points is collected 4290aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang if (doubleArray[i] >= 0) { 4300aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang mean += doubleArray[i]; 4310aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang ++numberTests; 4320aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang } 4330aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang } 4340aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang return mean/numberTests; 4350aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang } 4360aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang 4370aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang private void print(int[] intArray, String arrayName) { 4380aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang log("start to print array for " + arrayName); 4390aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang for (int i = 0; i < intArray.length; i++) { 4400aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang log(String.format("%d: %d", i, intArray[i])); 4410aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang } 4420aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang } 4430aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang 4440aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang private void print(double[] doubleArray, String arrayName) { 4450aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang log("start to print array for " + arrayName); 4460aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang for (int i = 0; i < doubleArray.length; i++) { 4470aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang log(String.format("%d: %f", i, doubleArray[i])); 4480aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang } 4490aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang } 4500aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang 4510aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang @Override 4520aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang protected void tearDown() throws Exception { 4530aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang super.tearDown(); 4540aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang if (mWriter != null) { 4550aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang mWriter.close(); 4560aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang } 4570aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang if (mStatusWriter != null) { 4580aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang mStatusWriter.close(); 4590aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang } 4600aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang } 4610aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang 4620aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang private void log(String message) { 4630aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang Log.v(TAG, message); 4640aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang } 4650aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang 4660aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang /** 4670aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * Set the total number of test iteration 4680aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * @param iteration 4690aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang */ 4700aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang protected void setIteration(int iteration){ 4710aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang mIteration = iteration; 4720aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang } 4730aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang 4740aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang /** 4750aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * Get the total number of test iteration 4760aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang * @return iteration 4770aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang */ 4780aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang protected int getIteration(){ 4790aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang return mIteration; 4800aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang } 4810aac99898b24c3633876b1cc6ab0612b2e893910Xia Wang} 482