Home | History | Annotate | Download | only in testercore
      1 /*-------------------------------------------------------------------------
      2  * drawElements Quality Program Tester Core
      3  * ----------------------------------------
      4  *
      5  * Copyright 2014 The Android Open Source Project
      6  *
      7  * Licensed under the Apache License, Version 2.0 (the "License");
      8  * you may not use this file except in compliance with the License.
      9  * You may obtain a copy of the License at
     10  *
     11  *      http://www.apache.org/licenses/LICENSE-2.0
     12  *
     13  * Unless required by applicable law or agreed to in writing, software
     14  * distributed under the License is distributed on an "AS IS" BASIS,
     15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16  * See the License for the specific language governing permissions and
     17  * limitations under the License.
     18  *
     19  *//*!
     20  * \file
     21  * \brief dEQP instrumentation
     22  *//*--------------------------------------------------------------------*/
     23 
     24 package com.drawelements.deqp.testercore;
     25 
     26 import android.app.Instrumentation;
     27 import android.os.Bundle;
     28 
     29 import java.lang.Thread;
     30 import java.io.File;
     31 
     32 public class DeqpInstrumentation extends Instrumentation
     33 {
     34 	private static final String	LOG_TAG					= "dEQP/Instrumentation";
     35 	private static final long	LAUNCH_TIMEOUT_MS		= 10000;
     36 	private static final long	NO_DATA_TIMEOUT_MS		= 5000;
     37 	private static final long	NO_ACTIVITY_SLEEP_MS	= 100;
     38 	private static final long	REMOTE_DEAD_SLEEP_MS	= 100;
     39 
     40 	private String				m_cmdLine;
     41 	private String				m_logFileName;
     42 	private boolean				m_logData;
     43 
     44 	@Override
     45 	public void onCreate (Bundle arguments) {
     46 		super.onCreate(arguments);
     47 
     48 		m_cmdLine		= arguments.getString("deqpCmdLine");
     49 		m_logFileName	= arguments.getString("deqpLogFilename");
     50 
     51 		if (m_cmdLine == null)
     52 			m_cmdLine = "";
     53 
     54 		if (m_logFileName == null)
     55 			m_logFileName = "/sdcard/TestLog.qpa";
     56 
     57 		if (arguments.getString("deqpLogData") != null)
     58 		{
     59 			if (arguments.getString("deqpLogData").compareToIgnoreCase("true") == 0)
     60 				m_logData = true;
     61 			else
     62 				m_logData = false;
     63 		}
     64 		else
     65 			m_logData = false;
     66 
     67 		start();
     68 	}
     69 
     70 	@Override
     71 	public void onStart () {
     72 		super.onStart();
     73 
     74 		final RemoteAPI		remoteApi	= new RemoteAPI(getTargetContext(), m_logFileName);
     75 		final TestLogParser	parser		= new TestLogParser();
     76 
     77 		try
     78 		{
     79 			Log.d(LOG_TAG, "onStart");
     80 
     81 			final String	testerName		= "";
     82 			final File		logFile			= new File(m_logFileName);
     83 
     84 			if (logFile.exists())
     85 				logFile.delete(); // Remove log file left by previous session
     86 
     87 			remoteApi.start(testerName, m_cmdLine, null);
     88 
     89 			{
     90 				final long startTimeMs = System.currentTimeMillis();
     91 
     92 				while (true)
     93 				{
     94 					final long timeSinceStartMs = System.currentTimeMillis()-startTimeMs;
     95 
     96 					if (logFile.exists())
     97 						break;
     98 					else if (timeSinceStartMs > LAUNCH_TIMEOUT_MS)
     99 					{
    100 						remoteApi.kill();
    101 						throw new Exception("Timeout while waiting for log file");
    102 					}
    103 					else
    104 						Thread.sleep(NO_ACTIVITY_SLEEP_MS);
    105 				}
    106 			}
    107 
    108 			parser.init(this, m_logFileName, m_logData);
    109 
    110 			// parse until tester dies
    111 			{
    112 				while (true)
    113 				{
    114 					if (!parser.parse())
    115 					{
    116 						Thread.sleep(NO_ACTIVITY_SLEEP_MS);
    117 						if (!remoteApi.isRunning())
    118 							break;
    119 					}
    120 				}
    121 			}
    122 
    123 			// parse remaining messages
    124 			{
    125 				long lastDataMs = System.currentTimeMillis();
    126 
    127 				while (true)
    128 				{
    129 					if (parser.parse())
    130 						lastDataMs = System.currentTimeMillis();
    131 					else
    132 					{
    133 						final long timeSinceLastDataMs = System.currentTimeMillis()-lastDataMs;
    134 
    135 						if (timeSinceLastDataMs > NO_DATA_TIMEOUT_MS)
    136 							break; // Assume no data is available for reading any more
    137 
    138 						// Remote is dead, wait a bit until trying to read again
    139 						Thread.sleep(REMOTE_DEAD_SLEEP_MS);
    140 					}
    141 				}
    142 			}
    143 
    144 			finish(0, new Bundle());
    145 		}
    146 		catch (Exception e)
    147 		{
    148 			Log.e(LOG_TAG, "Exception", e);
    149 
    150 			Bundle info = new Bundle();
    151 			info.putString("Exception", e.getMessage());
    152 			finish(1, info);
    153 		}
    154 		finally
    155 		{
    156 			try
    157 			{
    158 				parser.deinit();
    159 			}
    160 			catch (Exception e)
    161 			{
    162 				Log.w(LOG_TAG, "Got exception while closing log", e);
    163 			}
    164 			remoteApi.kill();
    165 		}
    166 	}
    167 
    168 	public void testCaseResult (String code, String details)
    169 	{
    170 		Bundle info = new Bundle();
    171 
    172 		info.putString("dEQP-EventType", "TestCaseResult");
    173 		info.putString("dEQP-TestCaseResult-Code", code);
    174 		info.putString("dEQP-TestCaseResult-Details", details);
    175 
    176 		sendStatus(0, info);
    177 	}
    178 
    179 	public void beginTestCase (String testCase)
    180 	{
    181 		Bundle info = new Bundle();
    182 
    183 		info.putString("dEQP-EventType", "BeginTestCase");
    184 		info.putString("dEQP-BeginTestCase-TestCasePath", testCase);
    185 
    186 		sendStatus(0, info);
    187 	}
    188 
    189 	public void endTestCase ()
    190 	{
    191 		Bundle info = new Bundle();
    192 
    193 		info.putString("dEQP-EventType", "EndTestCase");
    194 		sendStatus(0, info);
    195 	}
    196 
    197 	public void testLogData (String log) throws InterruptedException
    198 	{
    199 		if (m_logData)
    200 		{
    201 			final int chunkSize = 4*1024;
    202 
    203 			while (log != null)
    204 			{
    205 				String message;
    206 
    207 				if (log.length() > chunkSize)
    208 				{
    209 					message = log.substring(0, chunkSize);
    210 					log = log.substring(chunkSize);
    211 				}
    212 				else
    213 				{
    214 					message = log;
    215 					log = null;
    216 				}
    217 
    218 				Bundle info = new Bundle();
    219 
    220 				info.putString("dEQP-EventType", "TestLogData");
    221 				info.putString("dEQP-TestLogData-Log", message);
    222 				sendStatus(0, info);
    223 
    224 				if (log != null)
    225 				{
    226 					Thread.sleep(1); // 1ms
    227 				}
    228 			}
    229 		}
    230 	}
    231 
    232 	public void beginSession ()
    233 	{
    234 		Bundle info = new Bundle();
    235 
    236 		info.putString("dEQP-EventType", "BeginSession");
    237 		sendStatus(0, info);
    238 	}
    239 
    240 	public void endSession ()
    241 	{
    242 		Bundle info = new Bundle();
    243 
    244 		info.putString("dEQP-EventType", "EndSession");
    245 		sendStatus(0, info);
    246 	}
    247 
    248 	public void sessionInfo (String name, String value)
    249 	{
    250 		Bundle info = new Bundle();
    251 
    252 		info.putString("dEQP-EventType", "SessionInfo");
    253 		info.putString("dEQP-SessionInfo-Name", name);
    254 		info.putString("dEQP-SessionInfo-Value", value);
    255 
    256 		sendStatus(0, info);
    257 	}
    258 
    259 	public void terminateTestCase (String reason)
    260 	{
    261 		Bundle info = new Bundle();
    262 
    263 		info.putString("dEQP-EventType", "TerminateTestCase");
    264 		info.putString("dEQP-TerminateTestCase-Reason", reason);
    265 
    266 		sendStatus(0, info);
    267 	}
    268 
    269 	@Override
    270 	public void onDestroy() {
    271 		Log.e(LOG_TAG, "onDestroy");
    272 		super.onDestroy();
    273 		Log.e(LOG_TAG, "onDestroy");
    274 	}
    275 }
    276