Home | History | Annotate | Download | only in dmapi
      1 /*
      2  *   Copyright (c) International Business Machines  Corp., 2004
      3  *
      4  *   This program is free software;  you can redistribute it and/or modify
      5  *   it under the terms of the GNU General Public License as published by
      6  *   the Free Software Foundation; either version 2 of the License, or
      7  *   (at your option) any later version.
      8  *
      9  *   This program is distributed in the hope that it will be useful,
     10  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
     11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
     12  *   the GNU General Public License for more details.
     13  *
     14  *   You should have received a copy of the GNU General Public License
     15  *   along with this program;  if not, write to the Free Software
     16  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
     17  */
     18 
     19 /*
     20  * FILE NAME	: dm_test.c
     21  *
     22  * PURPOSE	: Define functions and variables common to all DMAPI test cases
     23  *
     24  */
     25 
     26 #include <stdio.h>
     27 #include <string.h>
     28 #include <stdlib.h>
     29 #include <stdarg.h>
     30 #include <stdint.h>
     31 #include <errno.h>
     32 #include <time.h>
     33 #include <fcntl.h>
     34 #include <unistd.h>
     35 #include <sys/time.h>
     36 #include <sys/stat.h>
     37 #include <sys/utsname.h>
     38 #include "dm_test.h"
     39 
     40 #define TEST_NAME "dm_test"
     41 
     42 int dm_StartingVariation = 0;
     43 int dm_StoppingVariation = INT32_MAX;
     44 int dm_CurrentVariation = 0;
     45 u_int dm_FileLoggingLevel = 0;
     46 u_int dm_TerminalLoggingLevel = 0;
     47 char *dm_LogFileName = "dm_logfile";
     48 u_int dm_PassedVariations = 0;
     49 u_int dm_FailedVariations = 0;
     50 u_int dm_SkippedVariations = 0;
     51 char *dm_TestCaseName = TEST_NAME;
     52 int dm_fdLogFile;
     53 FILE *dm_fpLogFile;
     54 int dm_argc = 0;
     55 char **dm_argv = NULL;
     56 int dm_FileNewlineNeeded;
     57 int dm_TerminalNewlineNeeded;
     58 
     59 void dm_ParseCommandLineOptions(int argc, char **argv)
     60 {
     61 
     62 	int i;
     63 	char *p;
     64 
     65 	if ((p = strrchr(argv[0], '/')) != NULL)
     66 		dm_TestCaseName = ++p;
     67 
     68 	for (i = 1; i < argc; i++) {
     69 		if (argv[i][0] == '-') {
     70 			if (strcmp(&argv[i][1], "runfrom") == 0) {
     71 				if (i < argc - 1 && argv[i + 1][0] != '-')
     72 					dm_StartingVariation = atoi(argv[++i]);
     73 				else
     74 					dm_Error
     75 					    ("invalid/missing runfrom argument\n");
     76 			} else if (strcmp(&argv[i][1], "runto") == 0) {
     77 				if (i < argc - 1 && argv[i + 1][0] != '-')
     78 					dm_StoppingVariation = atoi(argv[++i]);
     79 				else
     80 					dm_Error
     81 					    ("invalid/missing runto argument\n");
     82 			} else if (strcmp(&argv[i][1], "runonly") == 0) {
     83 				if (i < argc - 1 && argv[i + 1][0] != '-') {
     84 					dm_StartingVariation = atoi(argv[++i]);
     85 					dm_StoppingVariation =
     86 					    dm_StartingVariation;
     87 				} else
     88 					dm_Error
     89 					    ("invalid/missing runonly argument\n");
     90 			} else if (strcmp(&argv[i][1], "loglevel") == 0) {
     91 				if (i < argc - 1 && argv[i + 1][0] != '-')
     92 					dm_FileLoggingLevel = atoi(argv[++i]);
     93 				else
     94 					dm_Error
     95 					    ("invalid/missing loglevel argument\n");
     96 			} else if (strcmp(&argv[i][1], "termlevel") == 0) {
     97 				if (i < argc - 1 && argv[i + 1][0] != '-')
     98 					dm_TerminalLoggingLevel =
     99 					    atoi(argv[++i]);
    100 				else
    101 					dm_Error
    102 					    ("invalid/missing termlevel argument\n");
    103 			} else if (strcmp(&argv[i][1], "logname") == 0) {
    104 				if (i < argc - 1 && argv[i + 1][0] != '-')
    105 					dm_LogFileName = argv[++i];
    106 				else
    107 					dm_Error
    108 					    ("invalid/missing filename argument\n");
    109 			} else if (strcmp(&argv[i][1], "?") == 0
    110 				   || strcmp(&argv[i][1], "help") == 0
    111 				   || strcmp(&argv[i][1], "-help") == 0) {
    112 				printf("%s usage:\n", argv[0]);
    113 				printf
    114 				    ("\t-runfrom n: set starting variation to n\n");
    115 				printf
    116 				    ("\t-runto n: set stopping variation to n\n");
    117 				printf("\t-runonly n: run only variation n\n");
    118 				printf
    119 				    ("\t-loglevel n: set file logging level to n\n");
    120 				printf
    121 				    ("\t-termlevel n: set terminal logging level to n\n");
    122 				printf
    123 				    ("\t-logname s: set file log name to s\n");
    124 				exit(0);
    125 			} else if (i < argc - 1 && argv[i + 1][0] != '-')
    126 				i++;
    127 		}
    128 	}
    129 
    130 	dm_argc = argc;
    131 	dm_argv = argv;
    132 
    133 }
    134 
    135 char *dm_GetCommandLineOption(char *option)
    136 {
    137 
    138 	int i;
    139 
    140 	if (!dm_argc)
    141 		dm_Error
    142 		    ("Cannot get command line option without calling DMOPT_PARSE");
    143 
    144 	for (i = 1; i < dm_argc; i++)
    145 		if (dm_argv[i][0] == '-' &&
    146 		    strcmp(&dm_argv[i][1], option) == 0 &&
    147 		    i < dm_argc - 1 && dm_argv[i + 1][0] != '-')
    148 			return dm_argv[i + 1];
    149 	return NULL;
    150 
    151 }
    152 
    153 void dm_StartLogging(void)
    154 {
    155 
    156 	struct utsname buf;
    157 	char version[256];
    158 	struct timeval tv;
    159 	struct tm *pDT = NULL;
    160 	struct tm sDT;
    161 	int i;
    162 
    163 	if (dm_fpLogFile)
    164 		dm_Error("Cannot start logging when log file already open");
    165 
    166 	dm_fdLogFile =
    167 	    open(dm_LogFileName, O_CREAT | O_APPEND | O_SYNC | O_WRONLY,
    168 		 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
    169 
    170 	if (dm_fdLogFile == -1)
    171 		dm_Error("Unable to open log file %s", dm_LogFileName);
    172 
    173 	dm_fpLogFile = fdopen(dm_fdLogFile, "a");
    174 
    175 	if (dm_fpLogFile == NULL)
    176 		dm_Error("Unable to fdopen log file %s", dm_LogFileName);
    177 
    178 	if (uname(&buf) == -1)
    179 		strcpy(version, "Unknown Linux version");
    180 	else
    181 		sprintf(version, "%s %s", buf.sysname, buf.release);
    182 
    183 	if (gettimeofday(&tv, NULL) != -1)
    184 		pDT = (struct tm *)localtime_r(&tv.tv_sec, &sDT);
    185 
    186 	if (dm_FileLoggingLevel) {
    187 		fprintf(dm_fpLogFile, "%s running on %s\n", TEST_NAME, version);
    188 		fprintf(dm_fpLogFile, "%s invoked with ", dm_TestCaseName);
    189 		for (i = 1; i < dm_argc; i++)
    190 			fprintf(dm_fpLogFile, "%s ", dm_argv[i]);
    191 		if (pDT)
    192 			fprintf(dm_fpLogFile,
    193 				"\n%s starting at %02u:%02u:%02u on %02u/%02u/%04u\n",
    194 				dm_TestCaseName, pDT->tm_hour, pDT->tm_min,
    195 				pDT->tm_sec, pDT->tm_mon + 1, pDT->tm_mday,
    196 				pDT->tm_year + 1900);
    197 		else
    198 			fprintf(dm_fpLogFile, "\n%s starting\n",
    199 				dm_TestCaseName);
    200 
    201 	}
    202 
    203 	if (dm_TerminalLoggingLevel) {
    204 		printf("%s running on %s\n", TEST_NAME, version);
    205 		printf("%s invoked with ", dm_TestCaseName);
    206 		for (i = 1; i < dm_argc; i++)
    207 			printf("%s ", dm_argv[i]);
    208 		if (pDT)
    209 			printf
    210 			    ("\n%s starting at %02u:%02u:%02u on %02u/%02u/%04u\n",
    211 			     dm_TestCaseName, pDT->tm_hour, pDT->tm_min,
    212 			     pDT->tm_sec, pDT->tm_mon + 1, pDT->tm_mday,
    213 			     pDT->tm_year + 1900);
    214 		else
    215 			printf("\n%s starting\n", dm_TestCaseName);
    216 	}
    217 
    218 }
    219 
    220 void dm_StopLogging(void)
    221 {
    222 
    223 	struct timeval tv;
    224 	struct tm *pDT = NULL;
    225 	struct tm sDT;
    226 	int ranVariations = 0;
    227 	int percentSuccess = 0;
    228 
    229 	if (!dm_fpLogFile)
    230 		dm_Error("Cannot stop logging when log file not already open");
    231 
    232 	ranVariations = dm_PassedVariations + dm_FailedVariations;
    233 
    234 	if (dm_PassedVariations)
    235 		percentSuccess = (dm_PassedVariations * 100) / ranVariations;
    236 
    237 	if (gettimeofday(&tv, NULL) != -1)
    238 		pDT = (struct tm *)localtime_r(&tv.tv_sec, &sDT);
    239 
    240 	if (dm_FileLoggingLevel) {
    241 		if (pDT)
    242 			fprintf(dm_fpLogFile,
    243 				"%s stopping at %02u:%02u:%02u on %02u/%02u/%04u\n",
    244 				dm_TestCaseName, pDT->tm_hour, pDT->tm_min,
    245 				pDT->tm_sec, pDT->tm_mon + 1, pDT->tm_mday,
    246 				pDT->tm_year + 1900);
    247 		else
    248 			fprintf(dm_fpLogFile, "%s stopping\n", dm_TestCaseName);
    249 
    250 		fprintf(dm_fpLogFile,
    251 			"%s status: %u executed, %u passed, %u failed, %u skipped (%u%%)\n",
    252 			dm_TestCaseName, ranVariations, dm_PassedVariations,
    253 			dm_FailedVariations, dm_SkippedVariations,
    254 			percentSuccess);
    255 	}
    256 
    257 	if (dm_TerminalLoggingLevel) {
    258 		if (pDT)
    259 			printf
    260 			    ("%s stopping at %02u:%02u:%02u on %02u/%02u/%04u\n",
    261 			     dm_TestCaseName, pDT->tm_hour, pDT->tm_min,
    262 			     pDT->tm_sec, pDT->tm_mon + 1, pDT->tm_mday,
    263 			     pDT->tm_year + 1900);
    264 		else
    265 			printf("%s stopping\n", dm_TestCaseName);
    266 
    267 		printf
    268 		    ("%s status: %u executed, %u passed, %u failed, %u skipped (%u%%)\n",
    269 		     dm_TestCaseName, ranVariations, dm_PassedVariations,
    270 		     dm_FailedVariations, dm_SkippedVariations, percentSuccess);
    271 	}
    272 
    273 	fclose(dm_fpLogFile);
    274 	close(dm_fdLogFile);
    275 
    276 }
    277 
    278 void dm_Error(char *format, ...)
    279 {
    280 	va_list args;
    281 	char fmtmsg[256];
    282 
    283 	/*
    284 	 * Format error message including message inserts
    285 	 */
    286 	va_start(args, format);
    287 	vsprintf(fmtmsg, format, args);
    288 	va_end(args);
    289 
    290 	/*
    291 	 * Display error message if not detached or Presentation Manager process
    292 	 */
    293 	printf("\n%s fatal error: %s\n", TEST_NAME, fmtmsg);
    294 
    295 }
    296 
    297 void dm_LogPrintf(u_int level, char *format, ...)
    298 {
    299 
    300 	va_list args;
    301 
    302 	va_start(args, format);
    303 	if (level <= dm_FileLoggingLevel) {
    304 		fprintf(dm_fpLogFile, "[%s %d %d] ", dm_TestCaseName, getpid(),
    305 			level);
    306 		vfprintf(dm_fpLogFile, format, args);
    307 		dm_FileNewlineNeeded = 1;
    308 	}
    309 	va_end(args);
    310 	va_start(args, format);
    311 	if (level <= dm_TerminalLoggingLevel) {
    312 		printf("[%s %d %d] ", dm_TestCaseName, getpid(), level);
    313 		vprintf(format, args);
    314 		dm_TerminalNewlineNeeded = 1;
    315 	}
    316 	va_end(args);
    317 
    318 }
    319 
    320 int dm_ExecuteVariation(int var)
    321 {
    322 
    323 	if (dm_CurrentVariation)
    324 		dm_Error("Cannot execute variation while variation active\n");
    325 	if (var < dm_StartingVariation || var > dm_StoppingVariation)
    326 		return 0;
    327 
    328 	dm_CurrentVariation = var;
    329 
    330 	if (dm_FileNewlineNeeded)
    331 		fputc('\n', dm_fpLogFile);
    332 	if (dm_TerminalNewlineNeeded)
    333 		putchar('\n');
    334 
    335 	dm_LogPrintf(DMLVL_DEBUG, "Variation %d starting\n", var);
    336 
    337 	return 1;
    338 
    339 }
    340 
    341 void dm_PassVariation(void)
    342 {
    343 
    344 	if (!dm_CurrentVariation)
    345 		dm_Error("Cannot pass variation while variation not active\n");
    346 
    347 	dm_LogPrintf(DMLVL_DEBUG, "Variation %d passed\n\n",
    348 		     dm_CurrentVariation);
    349 	dm_FileNewlineNeeded = dm_TerminalNewlineNeeded = 0;
    350 
    351 	dm_PassedVariations++;
    352 
    353 	dm_CurrentVariation = 0;
    354 
    355 }
    356 
    357 void dm_FailVariation(void)
    358 {
    359 
    360 	if (!dm_CurrentVariation)
    361 		dm_Error("Cannot fail variation while variation not active\n");
    362 
    363 	dm_LogPrintf(DMLVL_DEBUG, "Variation %d failed\n\n",
    364 		     dm_CurrentVariation);
    365 	dm_FileNewlineNeeded = dm_TerminalNewlineNeeded = 0;
    366 
    367 	dm_FailedVariations++;
    368 
    369 	dm_CurrentVariation = 0;
    370 
    371 }
    372 
    373 void dm_SkipVariation(void)
    374 {
    375 
    376 	if (!dm_CurrentVariation)
    377 		dm_Error("Cannot skip variation while variation not active\n");
    378 
    379 	dm_LogPrintf(DMLVL_DEBUG, "Variation %d skipped\n\n",
    380 		     dm_CurrentVariation);
    381 	dm_FileNewlineNeeded = dm_TerminalNewlineNeeded = 0;
    382 
    383 	dm_SkippedVariations++;
    384 
    385 	dm_CurrentVariation = 0;
    386 
    387 }
    388 
    389 void dm_EndVariation_SuccessExpected(char *funcname, int expectedRC,
    390 				     int actualRC)
    391 {
    392 
    393 	if (actualRC == expectedRC) {
    394 		DMLOG_PRINT(DMLVL_DEBUG, "%s passed with expected rc = %d\n",
    395 			    funcname, expectedRC);
    396 		DMVAR_PASS();
    397 	} else {
    398 		DMLOG_PRINT(DMLVL_ERR,
    399 			    "%s failed with unexpected rc = %d (errno = %d)\n",
    400 			    funcname, actualRC, errno);
    401 		DMVAR_FAIL();
    402 	}
    403 
    404 }
    405 
    406 void dm_EndVariation_FailureExpected(char *funcname, int expectedRC,
    407 				     int actualRC, int expectedErrno)
    408 {
    409 
    410 	if (actualRC == expectedRC) {
    411 		if (errno == expectedErrno) {
    412 			DMLOG_PRINT(DMLVL_DEBUG,
    413 				    "%s passed with expected rc = %d and expected errno = %d\n",
    414 				    funcname, expectedRC, expectedErrno);
    415 			DMVAR_PASS();
    416 		} else {
    417 			DMLOG_PRINT(DMLVL_ERR,
    418 				    "%s failed with expected rc = %d but unexpected errno = %d (expected %d)\n",
    419 				    funcname, expectedRC, errno, expectedErrno);
    420 			DMVAR_FAIL();
    421 		}
    422 	} else {
    423 		DMLOG_PRINT(DMLVL_ERR, "%s failed with unexpected rc = %d\n",
    424 			    funcname, actualRC);
    425 		DMVAR_FAIL();
    426 	}
    427 
    428 }
    429 
    430 int dm_CheckVariation_SuccessExpected(int expectedRC, int actualRC,
    431 				      dm_eventtype_t expectedEvent,
    432 				      dm_eventtype_t actualEvent)
    433 {
    434 
    435 	if (expectedEvent == actualEvent) {
    436 		if (actualRC == expectedRC) {
    437 			DMLOG_PRINT(DMLVL_DEBUG,
    438 				    "Passed, received expected event %d\n",
    439 				    expectedEvent);
    440 			return DMSTAT_PASS;
    441 		} else {
    442 			DMLOG_PRINT(DMLVL_ERR,
    443 				    "Failed, received expected event %d but unexpected rc = %d (expected %d)\n",
    444 				    expectedEvent, actualRC, expectedRC);
    445 			return DMSTAT_FAIL;
    446 		}
    447 	} else {
    448 		DMLOG_PRINT(DMLVL_ERR,
    449 			    "Failed, received unexpected event %d (expected %d)\n",
    450 			    actualEvent, expectedEvent);
    451 		return DMSTAT_FAIL;
    452 	}
    453 
    454 }
    455 
    456 int dm_CheckVariation_FailureExpected(int expectedRC, int actualRC,
    457 				      int expectedErrno,
    458 				      dm_eventtype_t expectedEvent,
    459 				      dm_eventtype_t actualEvent)
    460 {
    461 
    462 	if (expectedEvent == actualEvent) {
    463 		if (actualRC == expectedRC) {
    464 			if (errno == expectedErrno) {
    465 				DMLOG_PRINT(DMLVL_DEBUG,
    466 					    "Passed, received expected event %d\n",
    467 					    expectedEvent);
    468 				return DMSTAT_PASS;
    469 			} else {
    470 				DMLOG_PRINT(DMLVL_ERR,
    471 					    "Failed, received expected event %d but unexpected errno = %d (expected %d)\n",
    472 					    expectedEvent, errno,
    473 					    expectedErrno);
    474 				return DMSTAT_FAIL;
    475 			}
    476 		} else {
    477 			DMLOG_PRINT(DMLVL_ERR,
    478 				    "Failed, received expected event %d but unexpected rc = %d (expected %d)\n",
    479 				    expectedEvent, actualRC, expectedRC);
    480 			return DMSTAT_FAIL;
    481 		}
    482 	} else {
    483 		DMLOG_PRINT(DMLVL_ERR,
    484 			    "Failed, received unexpected event %d (expected %d)\n",
    485 			    actualEvent, expectedEvent);
    486 		return DMSTAT_FAIL;
    487 	}
    488 
    489 }
    490 
    491 void dm_LogHandle(char *hdl, int len)
    492 {
    493 
    494 	int i;
    495 	char outbuf[256], *pch;
    496 
    497 	memset(outbuf, 0, sizeof(outbuf));
    498 
    499 	for (i = 0, pch = outbuf; i < len; i++, pch += 3)
    500 		sprintf(pch, " %02X", hdl[i]);
    501 
    502 	DMLOG_PRINT(DMLVL_DEBUG, "Handle: %s\n", outbuf);
    503 
    504 }
    505 
    506 /* This static array is for the persistent managed region test */
    507 dm_region_t dm_PMR_regbuf[PMR_NUM_REGIONS] = {
    508 #ifdef MULTIPLE_REGIONS
    509 	{0, 1000, DM_REGION_WRITE}
    510 	,
    511 	{2000, 1000, DM_REGION_TRUNCATE}
    512 	,
    513 	{3005, 995, DM_REGION_READ}
    514 	,
    515 	{5432, 2345, DM_REGION_NOEVENT}
    516 	,
    517 #endif
    518 	{8000, 0, DM_REGION_READ | DM_REGION_WRITE | DM_REGION_TRUNCATE}
    519 };
    520 
    521 /* Include implementation-dependent functions and variables */
    522 #include "dm_impl.h"
    523