toolsandutils/e32tools/eruntest/eruntest.cpp
changeset 0 83f4b4db085c
child 1 d4b442d23379
equal deleted inserted replaced
-1:000000000000 0:83f4b4db085c
       
     1 // Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include <windows.h>
       
    17 
       
    18 #ifdef __MSVCDOTNET__
       
    19  #include <iostream>
       
    20  #include <fstream>
       
    21  using namespace std;
       
    22 #else //!__MSVCDOTNET__
       
    23  #include <iostream.h>
       
    24  #include <fstream.h>
       
    25 #endif //__MSVCDOTNET__
       
    26 
       
    27 #include <stdio.h>
       
    28 #include <errno.h>
       
    29 
       
    30 #if defined(__VC32__) && !defined(__MSVCDOTNET__)
       
    31 #pragma warning( disable : 4710 )	// 'fn': function not inlined
       
    32 #endif // old MSVC
       
    33 
       
    34 const unsigned int KMaxLineLen=256;
       
    35 const unsigned int KTimeout=600000; // 10 minutes
       
    36 
       
    37 
       
    38 void NumFileLines(ifstream& inStream, unsigned int &aNumLines)
       
    39 	{
       
    40 	// finds out how many lines are in the file specified
       
    41 
       
    42 	aNumLines=0;
       
    43 	inStream.clear();
       
    44 	inStream.seekg(0);
       
    45 
       
    46 	char str[KMaxLineLen];
       
    47 	while (!inStream.eof())
       
    48 		{
       
    49 		inStream.getline(str, KMaxLineLen);
       
    50 		aNumLines++;
       
    51 		}
       
    52 	}
       
    53 
       
    54 void GetTestData(ifstream& inStream, char (*aDataArray)[KMaxLineLen], unsigned int &aNumTests)
       
    55 	{
       
    56 	// fill the test data structure from the file stream
       
    57 
       
    58 	aNumTests=0;
       
    59 	inStream.clear();
       
    60 	inStream.seekg(0);
       
    61 
       
    62 	char str[KMaxLineLen]="";
       
    63 	while (!inStream.eof())
       
    64 		{
       
    65 		bool charsPresent=0;
       
    66 		inStream.getline(str, KMaxLineLen);
       
    67 		if (strlen(str))
       
    68 			{
       
    69 			unsigned int len=strlen(str);
       
    70 			for (unsigned int i=0; i<len; i++)
       
    71 				{
       
    72 				if (!isspace(str[i]))
       
    73 					{
       
    74 					charsPresent=1;
       
    75 					break;
       
    76 					}
       
    77 				}
       
    78 			if (charsPresent)
       
    79 				{
       
    80 				strcpy(aDataArray[aNumTests], str);
       
    81 				aNumTests++;
       
    82 				}
       
    83 			}
       
    84 		}
       
    85 	}
       
    86 
       
    87 int GetTestOutFileName(char* aOutFile)
       
    88 	{
       
    89 	// Gets the temporary file in which RTest puts its output
       
    90 		
       
    91 	const char KTestOutFileName[16]="epocwind.out";
       
    92 	char tmpDir[KMaxLineLen]="";
       
    93 	int r=0;
       
    94 
       
    95 	aOutFile[0]='\0';
       
    96 	int len=GetTempPath(KMaxLineLen, tmpDir);
       
    97 	if (len==0||len>KMaxLineLen)
       
    98 		r=1;
       
    99 	
       
   100 	if (!r)
       
   101 		if (KMaxLineLen > (strlen(KTestOutFileName)+strlen(tmpDir)))
       
   102 			{
       
   103 			strcpy(aOutFile, tmpDir);
       
   104 			strcat(aOutFile, KTestOutFileName);
       
   105 			}
       
   106 		else
       
   107 			r=1;
       
   108 	return(r);
       
   109 	}
       
   110 
       
   111 void RemoveLeadingSpaces(char* aStr)
       
   112 	{
       
   113 	// removes leading whitespace from a string
       
   114 
       
   115 	int spaces=0;
       
   116 	while (isspace(aStr[spaces]))
       
   117 		spaces++;
       
   118 	int newLen=strlen(aStr)-spaces;
       
   119 	for (int j=0;j<=newLen;j++)
       
   120 		aStr[j]=aStr[j+spaces];
       
   121 	}
       
   122 
       
   123 int TestSucceeded(char* aLastLineBut1)
       
   124 	{
       
   125 	// checks whether an EPOC RTest has succeeded by comparing the
       
   126 	// last line but 1 in the EPOCWIND.OUT file with a template success
       
   127 	// string
       
   128 
       
   129 	int r=0;
       
   130 	const char KSuccessResult[20]="RTEST: SUCCESS :";
       
   131 
       
   132 	char testStr[KMaxLineLen];
       
   133 	strcpy(testStr,aLastLineBut1);
       
   134 	RemoveLeadingSpaces(testStr);
       
   135 	testStr[strlen(KSuccessResult)]='\0';
       
   136 	if (strcmp(testStr, KSuccessResult)==0)
       
   137 		r=1;
       
   138 	return(r);
       
   139 	}
       
   140 
       
   141 int GetPenultimateLines(char* aFile, char* aLastLineBut1, char* aLastLineBut2)
       
   142 	{
       
   143 	// Gets the two penultimate lines in a file.
       
   144 	// Returns 0 if successful, 1 otherwise.
       
   145 
       
   146 	int r=0;
       
   147 
       
   148 	aLastLineBut1[0]='\0';
       
   149 	aLastLineBut2[0]='\0';
       
   150 
       
   151 	ifstream fileStream(aFile);
       
   152 	if (!fileStream)
       
   153 		r=1;
       
   154 
       
   155 	if (!r)
       
   156 		{
       
   157 		char lastLine[KMaxLineLen]="";
       
   158 		while (!fileStream.eof())
       
   159 			{
       
   160 			strcpy(aLastLineBut2, aLastLineBut1);
       
   161 			strcpy(aLastLineBut1, lastLine);
       
   162 			fileStream.getline(lastLine, KMaxLineLen);
       
   163 			}
       
   164 		}
       
   165 	return(r);	
       
   166 	}
       
   167 
       
   168 int main(int argc, char *argv[])
       
   169 	{
       
   170 	FILE *stream = NULL;
       
   171 	if (argc != 2)
       
   172 		{
       
   173 		cerr << "Syntax: eruntest <batch_file>" << endl;
       
   174 		return(1);
       
   175 		}
       
   176 	// Check if input file exists
       
   177 	if( (stream  = fopen(argv[1], "r" )) == NULL)
       
   178 		{
       
   179 		cerr << "ERROR: Cannot open input file " << argv[1] << endl;
       
   180 		return(1);
       
   181 		}
       
   182 	else 
       
   183 		fclose(stream); 
       
   184 //	stream the input file
       
   185 	ifstream inFile(argv[1]);
       
   186 	
       
   187 	// get the number of lines in the input file
       
   188 	unsigned int numLines=0;
       
   189 	NumFileLines(inFile, numLines);
       
   190 	
       
   191 	// allocate space for the tests names
       
   192 	char (*pTests)[KMaxLineLen];
       
   193 	pTests = new char[numLines][KMaxLineLen];
       
   194 	if (!pTests)
       
   195 		{
       
   196 		cerr << "ERROR: Out of memory" << endl;
       
   197 		return(1);
       
   198 		}
       
   199 
       
   200 	// populate the data structure for the tests
       
   201 	unsigned int numTests=0;
       
   202 	GetTestData(inFile, pTests, numTests);
       
   203 
       
   204 	// Get the test output file name
       
   205 	char testOutFile[KMaxLineLen];
       
   206 	if (GetTestOutFileName(testOutFile)!=0)
       
   207 		{
       
   208 		cerr << "Error getting temporary path" << endl;
       
   209 		return(1);
       
   210 		}
       
   211 
       
   212 	// Get the current directory
       
   213 	char currentDir[KMaxLineLen]="";
       
   214 	GetCurrentDirectory(KMaxLineLen, currentDir);
       
   215 	strcat(currentDir, "\\");
       
   216 
       
   217 	// Retrieve the STARTUPINFO structure for the current process
       
   218 	STARTUPINFO startUpInfo;
       
   219 	PROCESS_INFORMATION procInfo;
       
   220 	GetStartupInfo(&startUpInfo);
       
   221 	
       
   222 	unsigned failCount=0;
       
   223 	unsigned timeoutCount=0;
       
   224 	unsigned cantStartCount=0;
       
   225 	unsigned unknownCount=0;
       
   226 
       
   227 	// run each test in turn
       
   228 	for (unsigned int i=0; i<numTests; i++)
       
   229 		{
       
   230 
       
   231 		// remove epocwind.out
       
   232 		remove(testOutFile);
       
   233 		if (errno==EACCES)
       
   234 			{
       
   235 			cerr << "Cannot remove " << testOutFile << endl;
       
   236 			return(1);
       
   237 			}
       
   238 
       
   239 		// Create the child process
       
   240 		if (!CreateProcess(0, pTests[i], 0, 0, FALSE, 0,0, 0, &startUpInfo, &procInfo))
       
   241 			{
       
   242 			// int error=GetLastError();
       
   243 			cout << "CAN'T START: " << currentDir << pTests[i] << endl;
       
   244 			cantStartCount++;
       
   245 			continue;
       
   246 			}
       
   247 
       
   248 		// Wait for the child process to complete
       
   249 		int ret=WaitForSingleObject(procInfo.hProcess, KTimeout);
       
   250 		ifstream testOutFileStream(testOutFile);
       
   251 
       
   252 		char lastLineBut1[KMaxLineLen]="";
       
   253 		char lastLineBut2[KMaxLineLen]="";
       
   254 		switch (ret)
       
   255 			{
       
   256 			case WAIT_OBJECT_0:
       
   257 				// find out if the test terminated successfully
       
   258 				if (GetPenultimateLines(testOutFile, lastLineBut1, lastLineBut2)!=0)
       
   259 					{
       
   260 					cout << "UNKNOWN: " << currentDir << pTests[i] << endl;
       
   261 					cout << "  <no test output file>" << endl;
       
   262 					unknownCount++;
       
   263 					}
       
   264 				else
       
   265 					{
       
   266 					// make the comparison
       
   267 					if (TestSucceeded(lastLineBut1))
       
   268 						cout << "PASSED: " << currentDir << pTests[i] << endl;
       
   269 					else
       
   270 						{
       
   271 						cout << "FAILED(RTest): " << currentDir << pTests[i] << endl;
       
   272 						cout << "  " << lastLineBut2 << endl;
       
   273 						cout << "  " << lastLineBut1 << endl;
       
   274 						cout << endl;
       
   275 						failCount++;
       
   276 						}
       
   277 					}
       
   278 				break;
       
   279 			case WAIT_FAILED:
       
   280 				cout << "FAILED: " << currentDir << pTests[i] << endl;
       
   281 				if (GetPenultimateLines(testOutFile, lastLineBut1, lastLineBut2)!=0)
       
   282 					{
       
   283 					cout << "  <no test output file>" << endl;
       
   284 					}
       
   285 				else
       
   286 					{
       
   287 					cout << "  " << lastLineBut2 << endl;
       
   288 					cout << "  " << lastLineBut1 << endl;
       
   289 					cout << endl;
       
   290 					}
       
   291 				failCount++;
       
   292 				break;
       
   293 			case WAIT_TIMEOUT:
       
   294 				cout << "TIMED OUT: " << currentDir << pTests[i] << endl;
       
   295 				if (GetPenultimateLines(testOutFile, lastLineBut1, lastLineBut2)!=0)
       
   296 					{
       
   297 					cout << "  <no test output file>" << endl;
       
   298 					}
       
   299 				else
       
   300 					{
       
   301 					cout << "  " << lastLineBut2 << endl;
       
   302 					cout << "  " << lastLineBut1 << endl;
       
   303 					cout << endl;
       
   304 					}
       
   305 				timeoutCount++;
       
   306 				if (!TerminateProcess(procInfo.hProcess, 1))
       
   307 					{
       
   308 					cout << "FROZEN: " << currentDir << endl;
       
   309 					cout << "  Cannot terminate - kill via Task Manager"  << endl;
       
   310 					cout << endl;
       
   311 					}
       
   312 				break;
       
   313 			}
       
   314 		}
       
   315 
       
   316 	delete [] pTests;
       
   317 
       
   318 	cout << endl;
       
   319 	cout << "TotalErrors   " << dec << (failCount+timeoutCount+unknownCount+cantStartCount) << endl;
       
   320 	cout << "  Failures    " << dec << failCount << endl;
       
   321 	cout << "  Timeouts    " << dec << timeoutCount << endl;
       
   322 	cout << "  Unknown     " << dec << unknownCount << endl;
       
   323 	cout << "  Can't start " << dec << cantStartCount << endl;
       
   324 	cout << endl;
       
   325 
       
   326 	return(0);
       
   327 	}