nsprpub/pr/tests/timetest.c

Fri, 16 Jan 2015 04:50:19 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 16 Jan 2015 04:50:19 +0100
branch
TOR_BUG_9701
changeset 13
44a2da4a2ab2
permissions
-rw-r--r--

Replace accessor implementation with direct member state manipulation, by
request https://trac.torproject.org/projects/tor/ticket/9701#comment:32

     1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 /*
     7  * file: timetest.c
     8  * description: test time and date routines
     9  */
    10 /***********************************************************************
    11 ** Includes
    12 ***********************************************************************/
    13 /* Used to get the command line option */
    14 #include "plgetopt.h"
    16 #include "prinit.h"
    17 #include "prtime.h"
    18 #include "prprf.h"
    20 #include <stdio.h>
    21 #include <stdlib.h>
    22 #include <string.h>
    24 int failed_already=0;
    25 PRBool debug_mode = PR_FALSE;
    27 static char *dayOfWeek[] =
    28 	{ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "???" };
    29 static char *month[] =
    30 	{ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
    31 	  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "???" };
    33 static void PrintExplodedTime(const PRExplodedTime *et) {
    34     PRInt32 totalOffset;
    35     PRInt32 hourOffset, minOffset;
    36     const char *sign;
    38     /* Print day of the week, month, day, hour, minute, and second */
    39     if (debug_mode) printf("%s %s %ld %02ld:%02ld:%02ld ",
    40 	    dayOfWeek[et->tm_wday], month[et->tm_month], et->tm_mday,
    41 	    et->tm_hour, et->tm_min, et->tm_sec);
    43     /* Print time zone */
    44     totalOffset = et->tm_params.tp_gmt_offset + et->tm_params.tp_dst_offset;
    45     if (totalOffset == 0) {
    46 	if (debug_mode) printf("UTC ");
    47     } else {
    48         sign = "+";
    49         if (totalOffset < 0) {
    50 	    totalOffset = -totalOffset;
    51 	    sign = "-";
    52         }
    53         hourOffset = totalOffset / 3600;
    54         minOffset = (totalOffset % 3600) / 60;
    55         if (debug_mode) 
    56             printf("%s%02ld%02ld ", sign, hourOffset, minOffset);
    57     }
    59     /* Print year */
    60     if (debug_mode) printf("%hd", et->tm_year);
    61 }
    63 static int ExplodedTimeIsEqual(const PRExplodedTime *et1,
    64 	const PRExplodedTime *et2)
    65 {
    66     if (et1->tm_usec == et2->tm_usec &&
    67 	    et1->tm_sec == et2->tm_sec &&
    68 	    et1->tm_min == et2->tm_min &&
    69 	    et1->tm_hour == et2->tm_hour &&
    70 	    et1->tm_mday == et2->tm_mday &&
    71 	    et1->tm_month == et2->tm_month &&
    72 	    et1->tm_year == et2->tm_year &&
    73 	    et1->tm_wday == et2->tm_wday &&
    74 	    et1->tm_yday == et2->tm_yday &&
    75 	    et1->tm_params.tp_gmt_offset == et2->tm_params.tp_gmt_offset &&
    76 	    et1->tm_params.tp_dst_offset == et2->tm_params.tp_dst_offset) {
    77         return 1;
    78     } else {
    79 	return 0;
    80     }
    81 }
    83 static void
    84 testParseTimeString(PRTime t)
    85 {
    86     PRExplodedTime et;
    87     PRTime t2;
    88     char timeString[128];
    89     char buf[128];
    90     PRInt32 totalOffset;
    91     PRInt32 hourOffset, minOffset;
    92     const char *sign;
    93     PRInt64 usec_per_sec;
    95     /* Truncate the microsecond part of PRTime */
    96     LL_I2L(usec_per_sec, PR_USEC_PER_SEC);
    97     LL_DIV(t, t, usec_per_sec);
    98     LL_MUL(t, t, usec_per_sec);
   100     PR_ExplodeTime(t, PR_LocalTimeParameters, &et);
   102     /* Print day of the week, month, day, hour, minute, and second */
   103     PR_snprintf(timeString, 128, "%s %s %ld %02ld:%02ld:%02ld ",
   104 	    dayOfWeek[et.tm_wday], month[et.tm_month], et.tm_mday,
   105 	    et.tm_hour, et.tm_min, et.tm_sec);
   106     /* Print time zone */
   107     totalOffset = et.tm_params.tp_gmt_offset + et.tm_params.tp_dst_offset;
   108     if (totalOffset == 0) {
   109 	strcat(timeString, "GMT ");  /* I wanted to use "UTC" here, but
   110                                       * PR_ParseTimeString doesn't 
   111                                       * understand "UTC".  */
   112     } else {
   113         sign = "+";
   114         if (totalOffset < 0) {
   115 	    totalOffset = -totalOffset;
   116 	    sign = "-";
   117         }
   118         hourOffset = totalOffset / 3600;
   119         minOffset = (totalOffset % 3600) / 60;
   120         PR_snprintf(buf, 128, "%s%02ld%02ld ", sign, hourOffset, minOffset);
   121 	strcat(timeString, buf);
   122     }
   123     /* Print year */
   124     PR_snprintf(buf, 128, "%hd", et.tm_year);
   125     strcat(timeString, buf);
   127     if (PR_ParseTimeString(timeString, PR_FALSE, &t2) == PR_FAILURE) {
   128 	fprintf(stderr, "PR_ParseTimeString() failed\n");
   129 	exit(1);
   130     }
   131     if (LL_NE(t, t2)) {
   132 	fprintf(stderr, "PR_ParseTimeString() incorrect\n");
   133 	PR_snprintf(buf, 128, "t is %lld, t2 is %lld, time string is %s\n",
   134                 t, t2, timeString);
   135 	fprintf(stderr, "%s\n", buf);
   136 	exit(1);
   137     }
   138 }
   140 int main(int argc, char** argv)
   141 {
   142 	/* The command line argument: -d is used to determine if the test is being run
   143 	in debug mode. The regress tool requires only one line output:PASS or FAIL.
   144 	All of the printfs associated with this test has been handled with a if (debug_mode)
   145 	test.
   146 	Usage: test_name -d
   147 	*/
   148 	PLOptStatus os;
   149 	PLOptState *opt;
   151     PR_STDIO_INIT();
   152 	opt = PL_CreateOptState(argc, argv, "d");
   153 	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
   154     {
   155 		if (PL_OPT_BAD == os) continue;
   156         switch (opt->option)
   157         {
   158         case 'd':  /* debug mode */
   159 			debug_mode = PR_TRUE;
   160             break;
   161          default:
   162             break;
   163         }
   164     }
   165 	PL_DestroyOptState(opt);
   167  /* main test */
   169     PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
   171     /* Testing zero PRTime (the epoch) */
   172     {
   173 	PRTime t;
   174 	PRExplodedTime et;
   176 	LL_I2L(t, 0);
   177 	if (debug_mode) printf("The NSPR epoch is:\n");
   178         PR_ExplodeTime(t, PR_LocalTimeParameters, &et);
   179 	PrintExplodedTime(&et);
   180 	if (debug_mode) printf("\n");
   181 	PR_ExplodeTime(t, PR_GMTParameters, &et);
   182 	PrintExplodedTime(&et);
   183 	if (debug_mode) printf("\n\n");
   184 	testParseTimeString(t);
   185     }
   187     /*
   188      *************************************************************
   189      **
   190      **  Testing PR_Now(), PR_ExplodeTime, and PR_ImplodeTime
   191      **  on the current time
   192      **
   193      *************************************************************
   194      */
   196     {
   197 	PRTime t1, t2;
   198 	PRExplodedTime et;
   200 	if (debug_mode) {
   201 	printf("*********************************************\n");
   202 	printf("**                                         **\n");
   203     printf("** Testing PR_Now(), PR_ExplodeTime, and   **\n");
   204 	printf("** PR_ImplodeTime on the current time      **\n");
   205 	printf("**                                         **\n");
   206 	printf("*********************************************\n\n");
   207 	}
   208 	t1 = PR_Now();
   210         /* First try converting to UTC */
   212         PR_ExplodeTime(t1, PR_GMTParameters, &et);
   213         if (et.tm_params.tp_gmt_offset || et.tm_params.tp_dst_offset) {
   214 	    if (debug_mode) printf("ERROR: UTC has nonzero gmt or dst offset.\n");
   215 		else failed_already=1;
   216 	    return 1;
   217         }
   218         if (debug_mode) printf("Current UTC is ");
   219 	PrintExplodedTime(&et);
   220 	if (debug_mode) printf("\n");
   222         t2 = PR_ImplodeTime(&et);
   223         if (LL_NE(t1, t2)) {
   224 	    if (debug_mode) printf("ERROR: Explode and implode are NOT inverse.\n");
   225 		else printf("FAIL\n");
   226 	    return 1;
   227         }
   229         /* Next, try converting to local (US Pacific) time */
   231         PR_ExplodeTime(t1, PR_LocalTimeParameters, &et);
   232         if (debug_mode) printf("Current local time is ");
   233 	PrintExplodedTime(&et);
   234 	if (debug_mode) printf("\n");
   235 	if (debug_mode) printf("GMT offset is %ld, DST offset is %ld\n",
   236 		et.tm_params.tp_gmt_offset, et.tm_params.tp_dst_offset);
   237         t2 = PR_ImplodeTime(&et);
   238         if (LL_NE(t1, t2)) {
   239 	    if (debug_mode) printf("ERROR: Explode and implode are NOT inverse.\n");
   240 	    return 1;
   241 	}
   243 	if (debug_mode) printf("Please examine the results\n");
   244 	testParseTimeString(t1);
   245     }
   248     /*
   249      *******************************************
   250      **
   251      ** Testing PR_NormalizeTime()
   252      **
   253      *******************************************
   254      */
   256     /* July 4, 2001 is Wednesday */
   257     {
   258 	PRExplodedTime et;
   260 	if (debug_mode)  {
   261 	printf("\n");
   262 	printf("**********************************\n");
   263 	printf("**                              **\n");
   264 	printf("** Testing PR_NormalizeTime()   **\n");
   265 	printf("**                              **\n");
   266 	printf("**********************************\n\n");
   267 	}
   268         et.tm_year    = 2001;
   269         et.tm_month   = 7 - 1;
   270         et.tm_mday    = 4;
   271         et.tm_hour    = 0;
   272         et.tm_min     = 0;
   273         et.tm_sec     = 0;
   274 	et.tm_usec    = 0;
   275         et.tm_params  = PR_GMTParameters(&et);
   277 	PR_NormalizeTime(&et, PR_GMTParameters);
   279 	if (debug_mode) printf("July 4, 2001 is %s.\n", dayOfWeek[et.tm_wday]);
   280 	if (et.tm_wday == 3) {
   281 	    if (debug_mode) printf("PASS\n");
   282         } else {
   283             if (debug_mode) printf("ERROR: It should be Wednesday\n");
   284 			else failed_already=1;
   285 	    return 1;
   286 	}
   287 	testParseTimeString(PR_ImplodeTime(&et));
   289         /* June 12, 1997 23:00 PST == June 13, 1997 00:00 PDT */
   290         et.tm_year    = 1997;
   291         et.tm_month   = 6 - 1;
   292         et.tm_mday    = 12;
   293         et.tm_hour    = 23;
   294         et.tm_min     = 0;
   295         et.tm_sec     = 0;
   296 	et.tm_usec    = 0;
   297         et.tm_params.tp_gmt_offset = -8 * 3600;
   298 	et.tm_params.tp_dst_offset = 0;
   300 	PR_NormalizeTime(&et, PR_USPacificTimeParameters);
   302 	if (debug_mode) {
   303 	    printf("Thu Jun 12, 1997 23:00:00 PST is ");
   304 	}
   305 	PrintExplodedTime(&et);
   306 	if (debug_mode) printf(".\n");
   307 	if (et.tm_wday == 5) {
   308 	    if (debug_mode) printf("PASS\n");
   309         } else {
   310             if (debug_mode) printf("ERROR: It should be Friday\n");
   311 			else failed_already=1;
   312 	    return 1;
   313 	}
   314 	testParseTimeString(PR_ImplodeTime(&et));
   316         /* Feb 14, 1997 00:00:00 PDT == Feb 13, 1997 23:00:00 PST */
   317         et.tm_year    = 1997;
   318         et.tm_month   = 2 - 1;
   319         et.tm_mday    = 14;
   320         et.tm_hour    = 0;
   321         et.tm_min     = 0;
   322         et.tm_sec     = 0;
   323 	et.tm_usec    = 0;
   324         et.tm_params.tp_gmt_offset = -8 * 3600;
   325 	et.tm_params.tp_dst_offset = 3600;
   327 	PR_NormalizeTime(&et, PR_USPacificTimeParameters);
   329 	if (debug_mode) {
   330 	    printf("Fri Feb 14, 1997 00:00:00 PDT is ");
   331 	}
   332 	PrintExplodedTime(&et);
   333 	if (debug_mode) printf(".\n");
   334 	if (et.tm_wday == 4) {
   335 	    if (debug_mode) printf("PASS\n");
   336         } else {
   337             if (debug_mode) printf("ERROR: It should be Thursday\n");
   338 			else failed_already=1;
   339 	    return 1;
   340 	}
   341 	testParseTimeString(PR_ImplodeTime(&et));
   343         /* What time is Nov. 7, 1996, 18:29:23 PDT? */
   344         et.tm_year    = 1996;
   345         et.tm_month   = 11 - 1;
   346         et.tm_mday    = 7;
   347         et.tm_hour    = 18;
   348         et.tm_min     = 29;
   349         et.tm_sec     = 23;
   350 	et.tm_usec    = 0;
   351         et.tm_params.tp_gmt_offset = -8 * 3600;  /* PDT */
   352 	et.tm_params.tp_dst_offset = 3600; 
   354 	PR_NormalizeTime(&et, PR_LocalTimeParameters);
   355         if (debug_mode) printf("Nov 7 18:29:23 PDT 1996 is ");
   356 	PrintExplodedTime(&et);
   357 	if (debug_mode) printf(".\n");
   358 	testParseTimeString(PR_ImplodeTime(&et));
   360         /* What time is Oct. 7, 1995, 18:29:23 PST? */
   361         et.tm_year    = 1995;
   362         et.tm_month   = 10 - 1;
   363         et.tm_mday    = 7;
   364         et.tm_hour    = 18;
   365         et.tm_min     = 29;
   366         et.tm_sec     = 23;
   367         et.tm_params.tp_gmt_offset = -8 * 3600;  /* PST */
   368 	et.tm_params.tp_dst_offset = 0;
   370 	PR_NormalizeTime(&et, PR_LocalTimeParameters);
   371         if (debug_mode) printf("Oct 7 18:29:23 PST 1995 is ");
   372 	PrintExplodedTime(&et);
   373 	if (debug_mode) printf(".\n");
   374 	testParseTimeString(PR_ImplodeTime(&et));
   376 	if (debug_mode) printf("Please examine the results\n");
   377     }
   379     /*
   380      **************************************************************
   381      **
   382      ** Testing range of years
   383      **
   384      **************************************************************
   385      */
   387     {
   388 	PRExplodedTime et1, et2;
   389     PRTime  ttt;
   390 	PRTime secs;
   392 	if (debug_mode) {
   393 	printf("\n");
   394 	printf("***************************************\n");
   395 	printf("**                                   **\n");
   396 	printf("**  Testing range of years           **\n");
   397 	printf("**                                   **\n");
   398 	printf("***************************************\n\n");
   399 	}
   400 	/* April 4, 1917 GMT */
   401 	et1.tm_usec = 0;
   402 	et1.tm_sec = 0;
   403 	et1.tm_min = 0;
   404 	et1.tm_hour = 0;
   405 	et1.tm_mday = 4;
   406 	et1.tm_month = 4 - 1;
   407 	et1.tm_year = 1917;
   408 	et1.tm_params = PR_GMTParameters(&et1);
   409 	PR_NormalizeTime(&et1, PR_LocalTimeParameters);
   410 	secs = PR_ImplodeTime(&et1);
   411 	if (LL_GE_ZERO(secs)) {
   412 	    if (debug_mode)
   413 		printf("ERROR: April 4, 1917 GMT returns a nonnegative second count\n");
   414 		failed_already = 1;
   415 	    return 1;
   416         }
   417 	PR_ExplodeTime(secs, PR_LocalTimeParameters, &et2);
   418 	if (!ExplodedTimeIsEqual(&et1, &et2)) {
   419 		if (debug_mode)
   420 		printf("ERROR: PR_ImplodeTime and PR_ExplodeTime are not inverse for April 4, 1917 GMT\n");
   421 		failed_already=1;
   422 	    return 1;
   423         }
   424     ttt = PR_ImplodeTime(&et1);
   425 	testParseTimeString( ttt );
   427 	if (debug_mode) printf("Test passed for April 4, 1917\n");
   429 	/* July 4, 2050 */
   430 	et1.tm_usec = 0;
   431 	et1.tm_sec = 0;
   432 	et1.tm_min = 0;
   433 	et1.tm_hour = 0;
   434 	et1.tm_mday = 4;
   435 	et1.tm_month = 7 - 1;
   436 	et1.tm_year = 2050;
   437 	et1.tm_params = PR_GMTParameters(&et1);
   438 	PR_NormalizeTime(&et1, PR_LocalTimeParameters);
   439 	secs = PR_ImplodeTime(&et1);
   440 	if (!LL_GE_ZERO(secs)) {
   441 	    if (debug_mode)
   442 			printf("ERROR: July 4, 2050 GMT returns a negative second count\n");
   443 		failed_already = 1;
   444 	    return 1;
   445         }
   446 	PR_ExplodeTime(secs, PR_LocalTimeParameters, &et2);
   447 	if (!ExplodedTimeIsEqual(&et1, &et2)) {
   448 	    if (debug_mode)
   449 		printf("ERROR: PR_ImplodeTime and PR_ExplodeTime are not inverse for July 4, 2050 GMT\n");
   450 		failed_already=1;
   451 	    return 1;
   452         }
   453 	testParseTimeString(PR_ImplodeTime(&et1));
   455 	if (debug_mode) printf("Test passed for July 4, 2050\n");
   457     }
   459     /*
   460      **************************************************************
   461      **
   462      **  Stress test
   463      *
   464      **      Go through four years, starting from
   465      **      00:00:00 PST Jan. 1, 2005, incrementing
   466      **      every 10 minutes.
   467      **
   468      **************************************************************
   469      */
   471     {
   472 	PRExplodedTime et, et1, et2;
   473 	PRInt64 usecPer10Min;
   474 	int day, hour, min;
   475 	PRTime usecs;
   476 	int dstInEffect = 0;
   478 	if (debug_mode) {
   479 	printf("\n");
   480 	printf("*******************************************************\n");
   481 	printf("**                                                   **\n");
   482 	printf("**        Stress test  Pacific Time                  **\n");
   483 	printf("**  Starting from midnight Jan. 1, 2005 PST,         **\n");
   484 	printf("**  going through four years in 10-minute increment  **\n");
   485 	printf("**                                                   **\n");
   486 	printf("*******************************************************\n\n");
   487 	}
   488 	LL_I2L(usecPer10Min, 600000000L);
   490 	/* 00:00:00 PST Jan. 1, 2005 */
   491 	et.tm_usec = 0;
   492 	et.tm_sec = 0;
   493 	et.tm_min = 0;
   494 	et.tm_hour = 0;
   495 	et.tm_mday = 1;
   496 	et.tm_month = 0;
   497 	et.tm_year = 2005;
   498 	et.tm_params.tp_gmt_offset = -8 * 3600;
   499 	et.tm_params.tp_dst_offset = 0;
   500 	usecs = PR_ImplodeTime(&et);
   502         for (day = 0; day < 4 * 365 + 1; day++) {
   503 	    for (hour = 0; hour < 24; hour++) {
   504 		for (min = 0; min < 60; min += 10) {
   505 	            LL_ADD(usecs, usecs, usecPer10Min);
   506 		    PR_ExplodeTime(usecs, PR_USPacificTimeParameters, &et1);
   508 		    et2 = et;
   509 		    et2.tm_usec += 600000000L;
   510 		    PR_NormalizeTime(&et2, PR_USPacificTimeParameters);
   512 		    if (!ExplodedTimeIsEqual(&et1, &et2)) {
   513 			printf("ERROR: componentwise comparison failed\n");
   514 			PrintExplodedTime(&et1);
   515 			printf("\n");
   516 			PrintExplodedTime(&et2);
   517 			printf("\n");
   518 			failed_already=1;
   519 		        return 1;
   520 		    }
   522 		    if (LL_NE(usecs, PR_ImplodeTime(&et1))) { 
   523 			printf("ERROR: PR_ExplodeTime and PR_ImplodeTime are not inverse\n");
   524 			PrintExplodedTime(&et1);
   525 			printf("\n");
   526 			failed_already=1;
   527 		        return 1;
   528 		    }
   529 		    testParseTimeString(usecs);
   531 		    if (!dstInEffect && et1.tm_params.tp_dst_offset) {
   532 		        dstInEffect = 1;
   533 		        if (debug_mode) {
   534 			    printf("DST changeover from ");
   535 			    PrintExplodedTime(&et);
   536 			    printf(" to ");
   537 			    PrintExplodedTime(&et1);
   538 			    printf(".\n");
   539 		    	}
   540                     } else if (dstInEffect && !et1.tm_params.tp_dst_offset) {
   541 		        dstInEffect = 0;
   542 			if (debug_mode) {
   543 			    printf("DST changeover from ");
   544 			    PrintExplodedTime(&et);
   545 			    printf(" to ");
   546 			    PrintExplodedTime(&et1);
   547 			    printf(".\n");
   548 			}
   549                     }
   551 		    et = et1;
   552 		}
   553 	    }
   554         }
   555 	if (debug_mode) printf("Test passed\n");
   556     }
   559     /* Same stress test, but with PR_LocalTimeParameters */
   561     {
   562 	PRExplodedTime et, et1, et2;
   563 	PRInt64 usecPer10Min;
   564 	int day, hour, min;
   565 	PRTime usecs;
   566 	int dstInEffect = 0;
   568 	if (debug_mode) {
   569 	printf("\n");
   570 	printf("*******************************************************\n");
   571 	printf("**                                                   **\n");
   572 	printf("**         Stress test    Local Time                 **\n");
   573 	printf("**  Starting from midnight Jan. 1, 2005 PST,         **\n");
   574 	printf("**  going through four years in 10-minute increment  **\n");
   575 	printf("**                                                   **\n");
   576 	printf("*******************************************************\n\n");
   577 	}
   579 	LL_I2L(usecPer10Min, 600000000L);
   581 	/* 00:00:00 PST Jan. 1, 2005 */
   582 	et.tm_usec = 0;
   583 	et.tm_sec = 0;
   584 	et.tm_min = 0;
   585 	et.tm_hour = 0;
   586 	et.tm_mday = 1;
   587 	et.tm_month = 0;
   588 	et.tm_year = 2005;
   589 	et.tm_params.tp_gmt_offset = -8 * 3600;
   590 	et.tm_params.tp_dst_offset = 0;
   591 	usecs = PR_ImplodeTime(&et);
   593         for (day = 0; day < 4 * 365 + 1; day++) {
   594 	    for (hour = 0; hour < 24; hour++) {
   595 		for (min = 0; min < 60; min += 10) {
   596 	            LL_ADD(usecs, usecs, usecPer10Min);
   597 		    PR_ExplodeTime(usecs, PR_LocalTimeParameters, &et1);
   599 		    et2 = et;
   600 		    et2.tm_usec += 600000000L;
   601 		    PR_NormalizeTime(&et2, PR_LocalTimeParameters);
   603 		    if (!ExplodedTimeIsEqual(&et1, &et2)) {
   604 			printf("ERROR: componentwise comparison failed\n");
   605 			PrintExplodedTime(&et1);
   606 			printf("\n");
   607 			PrintExplodedTime(&et2);
   608 			printf("\n");
   609 		        return 1;
   610 		    }
   612 		    if (LL_NE(usecs, PR_ImplodeTime(&et1))) {
   613                         printf("ERROR: PR_ExplodeTime and PR_ImplodeTime are not inverse\n");
   614 			PrintExplodedTime(&et1);
   615 			printf("\n");
   616 			failed_already=1;
   617 		        return 1;
   618 		    }
   619 		    testParseTimeString(usecs);
   621 		    if (!dstInEffect && et1.tm_params.tp_dst_offset) {
   622 		        dstInEffect = 1;
   623 		        if (debug_mode) {
   624 			    printf("DST changeover from ");
   625 			    PrintExplodedTime(&et);
   626 			    printf(" to ");
   627 			    PrintExplodedTime(&et1);
   628 			    printf(".\n");
   629 			}
   630                     } else if (dstInEffect && !et1.tm_params.tp_dst_offset) {
   631 		        dstInEffect = 0;
   632 			if (debug_mode) {
   633 			    printf("DST changeover from ");
   634 			    PrintExplodedTime(&et);
   635 			    printf(" to ");
   636 			    PrintExplodedTime(&et1);
   637 			    printf(".\n");
   638 			}
   639                     }
   641 		    et = et1;
   642 		}
   643 	    }
   644         }
   645 	if (debug_mode) printf("Test passed\n");
   646     }
   648     /* Same stress test, but with PR_LocalTimeParameters and going backward */
   650     {
   651 	PRExplodedTime et, et1, et2;
   652 	PRInt64 usecPer10Min;
   653 	int day, hour, min;
   654 	PRTime usecs;
   655 	int dstInEffect = 0;
   657 	if (debug_mode) {
   658 	printf("\n");
   659 	printf("*******************************************************\n");
   660 	printf("**                                                   **\n");
   661 	printf("**           Stress test    Local Time               **\n");
   662 	printf("**  Starting from midnight Jan. 1, 2009 PST,         **\n");
   663 	printf("**  going back four years in 10-minute increment     **\n");
   664 	printf("**                                                   **\n");
   665 	printf("*******************************************************\n\n");
   666 	}
   668 	LL_I2L(usecPer10Min, 600000000L);
   670 	/* 00:00:00 PST Jan. 1, 2009 */
   671 	et.tm_usec = 0;
   672 	et.tm_sec = 0;
   673 	et.tm_min = 0;
   674 	et.tm_hour = 0;
   675 	et.tm_mday = 1;
   676 	et.tm_month = 0;
   677 	et.tm_year = 2009;
   678 	et.tm_params.tp_gmt_offset = -8 * 3600;
   679 	et.tm_params.tp_dst_offset = 0;
   680 	usecs = PR_ImplodeTime(&et);
   682         for (day = 0; day < 4 * 365 + 1; day++) {
   683 	    for (hour = 0; hour < 24; hour++) {
   684 		for (min = 0; min < 60; min += 10) {
   685 	            LL_SUB(usecs, usecs, usecPer10Min);
   686 		    PR_ExplodeTime(usecs, PR_LocalTimeParameters, &et1);
   688 		    et2 = et;
   689 		    et2.tm_usec -= 600000000L;
   690 		    PR_NormalizeTime(&et2, PR_LocalTimeParameters);
   692 		    if (!ExplodedTimeIsEqual(&et1, &et2)) {
   693 		        printf("ERROR: componentwise comparison failed\n");
   694 			PrintExplodedTime(&et1);
   695 			printf("\n");
   696 			PrintExplodedTime(&et2);
   697 			printf("\n");
   698 		        return 1;
   699 		    }
   701 		    if (LL_NE(usecs, PR_ImplodeTime(&et1))) {
   702 			printf("ERROR: PR_ExplodeTime and PR_ImplodeTime are not inverse\n");
   703 			PrintExplodedTime(&et1);
   704 			printf("\n");
   705 			failed_already=1;
   706 		        return 1;
   707 		    }
   708 		    testParseTimeString(usecs);
   710 		    if (!dstInEffect && et1.tm_params.tp_dst_offset) {
   711 		        dstInEffect = 1;
   712 		        if (debug_mode) {
   713 			    printf("DST changeover from ");
   714 			    PrintExplodedTime(&et);
   715 			    printf(" to ");
   716 			    PrintExplodedTime(&et1);
   717 			    printf(".\n");
   718 			}
   719                     } else if (dstInEffect && !et1.tm_params.tp_dst_offset) {
   720 		        dstInEffect = 0;
   721 			if (debug_mode) {
   722 			    printf("DST changeover from ");
   723 			    PrintExplodedTime(&et);
   724 			    printf(" to ");
   725 			    PrintExplodedTime(&et1);
   726 			    printf(".\n");
   727 			}
   728                     }
   730 		    et = et1;
   731 		}
   732 	    }
   733         }
   734     }
   736 	if (failed_already) return 1;
   737 	else return 0;
   739 }

mercurial