• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
dm_ParseCommandLineOptions(int argc,char ** argv)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 
dm_GetCommandLineOption(char * option)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 
dm_StartLogging(void)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 
dm_StopLogging(void)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 
dm_Error(char * format,...)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 
dm_LogPrintf(u_int level,char * format,...)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 
dm_ExecuteVariation(int var)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 
dm_PassVariation(void)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 
dm_FailVariation(void)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 
dm_SkipVariation(void)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 
dm_EndVariation_SuccessExpected(char * funcname,int expectedRC,int actualRC)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 
dm_EndVariation_FailureExpected(char * funcname,int expectedRC,int actualRC,int expectedErrno)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 
dm_CheckVariation_SuccessExpected(int expectedRC,int actualRC,dm_eventtype_t expectedEvent,dm_eventtype_t actualEvent)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 
dm_CheckVariation_FailureExpected(int expectedRC,int actualRC,int expectedErrno,dm_eventtype_t expectedEvent,dm_eventtype_t actualEvent)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 
dm_LogHandle(char * hdl,int len)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