1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.tradefed.testtype; 17 18 import com.android.ddmlib.testrunner.ITestRunListener; 19 import com.android.ddmlib.testrunner.TestIdentifier; 20 21 import junit.framework.TestCase; 22 import org.easymock.EasyMock; 23 24 import java.io.BufferedReader; 25 import java.io.File; 26 import java.io.FileReader; 27 import java.io.IOException; 28 import java.text.ParseException; 29 import java.text.SimpleDateFormat; 30 import java.util.Collections; 31 import java.util.Date; 32 33 /** 34 * Unit tests for {@link VtsMultiDeviceTestResultParser}. 35 */ 36 public class VtsMultiDeviceTestResultParserTest extends TestCase { 37 38 // for file path 39 private static final String TEST_DIR = "tests"; 40 private static final String OUTPUT_FILE_1 = "vts_multi_device_test_parser_output.txt"; 41 private static final String OUTPUT_FILE_2 = "vts_multi_device_test_parser_output_timeout.txt"; 42 private static final String OUTPUT_FILE_3 = "vts_multi_device_test_parser_output_error.txt"; 43 private static final String USER_DIR = "user.dir"; 44 private static final String RES = "res"; 45 private static final String TEST_TYPE = "testtype"; 46 47 //test results 48 static final String PASS = "PASS"; 49 static final String FAIL = "FAIL"; 50 static final String TIME_OUT = "TIMEOUT"; 51 52 // test name 53 private static final String RUN_NAME = "SampleLightFuzzTest"; 54 private static final String TEST_NAME_1 = "testTurnOnLightBlackBoxFuzzing"; 55 private static final String TEST_NAME_2 = "testTurnOnLightWhiteBoxFuzzing"; 56 57 // enumeration to indicate the input file used for each run. 58 private TestCase mTestCase = TestCase.NORMAL; 59 private enum TestCase { 60 NORMAL, ERROR, TIMEOUT; 61 } 62 63 /** 64 * Test the run method with a normal input. 65 * @throws IOException 66 */ 67 public void testRunTimeoutInput() throws IOException{ 68 mTestCase = TestCase.TIMEOUT; 69 String[] contents = getOutput(); 70 long totalTime = getTotalTime(contents); 71 72 // prepare the mock object 73 ITestRunListener mockRunListener = EasyMock.createMock(ITestRunListener.class); 74 mockRunListener.testRunStarted(TEST_NAME_1, 2); 75 mockRunListener.testRunStarted(TEST_NAME_2, 2); 76 mockRunListener.testStarted(new TestIdentifier(RUN_NAME, TEST_NAME_1)); 77 mockRunListener.testStarted(new TestIdentifier(RUN_NAME, TEST_NAME_2)); 78 mockRunListener.testEnded(new TestIdentifier(RUN_NAME, TEST_NAME_1), 79 Collections.<String, String>emptyMap()); 80 mockRunListener.testFailed(new TestIdentifier(RUN_NAME, TEST_NAME_2), TIME_OUT); 81 mockRunListener.testRunEnded(totalTime, Collections.<String, String>emptyMap()); 82 83 EasyMock.replay(mockRunListener); 84 VtsMultiDeviceTestResultParser resultParser = new VtsMultiDeviceTestResultParser( 85 mockRunListener, RUN_NAME); 86 resultParser.processNewLines(contents); 87 resultParser.done(); 88 } 89 90 /** 91 * Test the run method with a normal input. 92 * @throws IOException 93 */ 94 public void testRunNormalInput() throws IOException{ 95 mTestCase = TestCase.NORMAL; 96 String[] contents = getOutput(); 97 long totalTime = getTotalTime(contents); 98 99 // prepare the mock object 100 ITestRunListener mockRunListener = EasyMock.createMock(ITestRunListener.class); 101 mockRunListener.testRunStarted(TEST_NAME_1, 2); 102 mockRunListener.testRunStarted(TEST_NAME_2, 2); 103 mockRunListener.testStarted(new TestIdentifier(RUN_NAME, TEST_NAME_1)); 104 mockRunListener.testStarted(new TestIdentifier(RUN_NAME, TEST_NAME_2)); 105 mockRunListener.testEnded(new TestIdentifier(RUN_NAME, TEST_NAME_1), 106 Collections.<String, String>emptyMap()); 107 mockRunListener.testEnded(new TestIdentifier(RUN_NAME, TEST_NAME_2), 108 Collections.<String, String>emptyMap()); 109 mockRunListener.testRunEnded(totalTime, Collections.<String, String>emptyMap()); 110 111 EasyMock.replay(mockRunListener); 112 VtsMultiDeviceTestResultParser resultParser = new VtsMultiDeviceTestResultParser( 113 mockRunListener, RUN_NAME); 114 resultParser.processNewLines(contents); 115 resultParser.done(); 116 } 117 118 /** 119 * Test the run method with a erroneous input. 120 * @throws IOException 121 */ 122 public void testRunErrorInput() throws IOException{ 123 mTestCase = TestCase.ERROR; 124 String[] contents = getOutput(); 125 long totalTime = getTotalTime(contents); 126 127 // prepare the mock object 128 ITestRunListener mockRunListener = EasyMock.createMock(ITestRunListener.class); 129 mockRunListener.testRunStarted(null, 0); 130 mockRunListener.testRunEnded(totalTime, Collections.<String, String>emptyMap()); 131 132 EasyMock.replay(mockRunListener); 133 VtsMultiDeviceTestResultParser resultParser = new VtsMultiDeviceTestResultParser( 134 mockRunListener, RUN_NAME); 135 resultParser.processNewLines(contents); 136 resultParser.done(); 137 } 138 /** 139 * @param contents The logs that are used for a test case. 140 * @return {long} total running time of the test. 141 */ 142 private long getTotalTime(String[] contents) { 143 Date startDate = getDate(contents, true); 144 Date endDate = getDate(contents, false); 145 146 if (startDate == null || endDate == null) { 147 return 0; 148 } 149 return endDate.getTime() - startDate.getTime(); 150 } 151 152 /** 153 * Returns the sample shell output for a test command. 154 * @return {String} shell output 155 * @throws IOException 156 */ 157 private String[] getOutput() throws IOException{ 158 BufferedReader br = null; 159 String output = null; 160 try { 161 br = new BufferedReader(new FileReader(getFileName())); 162 StringBuilder sb = new StringBuilder(); 163 String line = br.readLine(); 164 165 while (line != null) { 166 sb.append(line); 167 sb.append(System.lineSeparator()); 168 line = br.readLine(); 169 } 170 output = sb.toString(); 171 } finally { 172 br.close(); 173 } 174 return output.split("\n"); 175 } 176 177 /** Return the file path that contains sample shell output logs. 178 * 179 * @return {String} The file path. 180 */ 181 private String getFileName(){ 182 String fileName = null; 183 switch (mTestCase) { 184 case NORMAL: 185 fileName = OUTPUT_FILE_1; 186 break; 187 case TIMEOUT: 188 fileName = OUTPUT_FILE_2; 189 break; 190 case ERROR: 191 fileName = OUTPUT_FILE_3; 192 break; 193 default: 194 break; 195 } 196 StringBuilder path = new StringBuilder(); 197 path.append(System.getProperty(USER_DIR)).append(File.separator).append(TEST_DIR). 198 append(File.separator).append(RES).append(File.separator). 199 append(TEST_TYPE).append(File.separator).append(fileName); 200 return path.toString(); 201 } 202 203 /** 204 * Return the time in milliseconds to calculate the time elapsed in a particular test. 205 * 206 * @param lines The logs that need to be parsed. 207 * @param calculateStartDate flag which is true if we need to calculate start date. 208 * @return {Date} the start and end time corresponding to a test. 209 */ 210 private Date getDate(String[] lines, boolean calculateStartDate) { 211 Date date = null; 212 int begin = calculateStartDate ? 0 : lines.length - 1; 213 int diff = calculateStartDate ? 1 : -1; 214 215 for (int index = begin; index >= 0 && index < lines.length; index += diff) { 216 lines[index].trim(); 217 String[] toks = lines[index].split(" "); 218 219 // set the start time from the first line 220 // the loop should continue if exception occurs, else it can break 221 if (toks.length < 3) { 222 continue; 223 } 224 String time = toks[2]; 225 SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS"); 226 try { 227 date = sdf.parse(time); 228 } catch (ParseException e) { 229 continue; 230 } 231 break; 232 } 233 return date; 234 } 235 } 236