]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/test/intltest/callimts.cpp
ICU-57131.0.1.tar.gz
[apple/icu.git] / icuSources / test / intltest / callimts.cpp
index afe6ac32c3c6ac5f6ba84b611db96f2e24b13373..fa80053b1ed647e21ffdd5a4f77b6f5287e9da8e 100644 (file)
@@ -1,6 +1,6 @@
 /***********************************************************************
  * COPYRIGHT: 
- * Copyright (c) 1997-2008, International Business Machines Corporation
+ * Copyright (c) 1997-2015, International Business Machines Corporation
  * and others. All Rights Reserved.
  ***********************************************************************/
 
 #include "unicode/gregocal.h"
 #include "unicode/datefmt.h"
 #include "unicode/smpdtfmt.h"
-#include "putilimp.h"
 #include "cstring.h"
+#include "mutex.h"
+#include "putilimp.h"
+#include "simplethread.h"
 
 U_NAMESPACE_USE
 void CalendarLimitTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
@@ -49,7 +51,7 @@ void CalendarLimitTest::runIndexedTest( int32_t index, UBool exec, const char* &
 
 // -------------------------------------
 void
-CalendarLimitTest::test(UDate millis, U_NAMESPACE_QUALIFIER Calendar* cal, U_NAMESPACE_QUALIFIER DateFormat* fmt)
+CalendarLimitTest::test(UDate millis, icu::Calendar* cal, icu::DateFormat* fmt)
 {
   static const UDate kDrift = 1e-10;
     UErrorCode exception = U_ZERO_ERROR;
@@ -97,7 +99,7 @@ CalendarLimitTest::TestCalendarExtremeLimit()
 {
     UErrorCode status = U_ZERO_ERROR;
     Calendar *cal = Calendar::createInstance(status);
-    if (failure(status, "Calendar::createInstance")) return;
+    if (failure(status, "Calendar::createInstance", TRUE)) return;
     cal->adoptTimeZone(TimeZone::createTimeZone("GMT"));
     DateFormat *fmt = DateFormat::createDateTimeInstance();
     if(!fmt || !cal) {
@@ -105,7 +107,7 @@ CalendarLimitTest::TestCalendarExtremeLimit()
        return;
     }
     fmt->adoptCalendar(cal);
-    ((SimpleDateFormat*) fmt)->applyPattern("HH:mm:ss.SSS zzz, EEEE, MMMM d, yyyy G");
+    ((SimpleDateFormat*) fmt)->applyPattern("HH:mm:ss.SSS Z, EEEE, MMMM d, yyyy G");
 
 
     // This test used to test the algorithmic limits of the dates that
@@ -139,55 +141,90 @@ CalendarLimitTest::TestCalendarExtremeLimit()
     delete fmt;
 }
 
+namespace {
+
+struct TestCase {
+    const char *type;
+    UBool hasLeapMonth;
+    UDate actualTestStart;
+    int32_t actualTestEnd;
+};
+    
+const UDate DEFAULT_START = 944006400000.0; // 1999-12-01T00:00Z
+const int32_t DEFAULT_END = -120; // Default for non-quick is run 2 minutes
+
+TestCase TestCases[] = {
+        {"gregorian",       FALSE,      DEFAULT_START, DEFAULT_END},
+        {"japanese",        FALSE,      596937600000.0, DEFAULT_END}, // 1988-12-01T00:00Z, Showa 63
+        {"buddhist",        FALSE,      DEFAULT_START, DEFAULT_END},
+        {"roc",             FALSE,      DEFAULT_START, DEFAULT_END},
+        {"persian",         FALSE,      DEFAULT_START, DEFAULT_END},
+        {"islamic-civil",   FALSE,      DEFAULT_START, DEFAULT_END},
+        {"islamic",         FALSE,      DEFAULT_START, 800000}, // Approx. 2250 years from now, after which 
+                                                                // some rounding errors occur in Islamic calendar
+        {"hebrew",          TRUE,       DEFAULT_START, DEFAULT_END},
+        {"chinese",         TRUE,       DEFAULT_START, DEFAULT_END},
+        {"dangi",           TRUE,       DEFAULT_START, DEFAULT_END},
+        {"indian",          FALSE,      DEFAULT_START, DEFAULT_END},
+        {"coptic",          FALSE,      DEFAULT_START, DEFAULT_END},
+        {"ethiopic",        FALSE,      DEFAULT_START, DEFAULT_END},
+        {"ethiopic-amete-alem", FALSE,  DEFAULT_START, DEFAULT_END}
+};
+    
+struct {
+    int32_t fIndex;
+    UBool next (int32_t &rIndex) {
+        Mutex lock;
+        if (fIndex >= UPRV_LENGTHOF(TestCases)) {
+            return FALSE;
+        }
+        rIndex = fIndex++;
+        return TRUE;
+    }
+    void reset() {
+        fIndex = 0;
+    }
+} gTestCaseIterator;
+
+}  // anonymous name space
+
 void
 CalendarLimitTest::TestLimits(void) {
-    static const UDate DEFAULT_START = 944006400000.0; // 1999-12-01T00:00Z
-
-    static const struct {
-        const char *type;
-        UBool hasLeapMonth;
-        UDate actualTestStart;
-    } TestCases[] = {
-        {"gregorian",       FALSE,      DEFAULT_START},
-        {"japanese",        FALSE,      596937600000.0}, // 1988-12-01T00:00Z, Showa 63
-        {"buddhist",        FALSE,      DEFAULT_START},
-        {"roc",             FALSE,      DEFAULT_START},
-        {"persian",         FALSE,      DEFAULT_START},
-        {"islamic-civil",   FALSE,      DEFAULT_START},
-        //{"islamic",         FALSE,      DEFAULT_START}, // TODO: there is a bug in monthlength calculation
-        {"hebrew",          TRUE,       DEFAULT_START},
-        {"chinese",         TRUE,       DEFAULT_START},
-        {"indian",          FALSE,      DEFAULT_START},
-        {"coptic",          FALSE,      DEFAULT_START},
-        {"ethiopic",        FALSE,      DEFAULT_START},
-        {"ethiopic-amete-alem", FALSE,  DEFAULT_START},
-        {NULL,              FALSE,      0.0}
-    };
+    gTestCaseIterator.reset();
+
+    ThreadPool<CalendarLimitTest> threads(this, threadCount, &CalendarLimitTest::TestLimitsThread);
+    threads.start();
+    threads.join();
+}
 
-    int16_t i = 0;
-    char buf[64];
 
-    for (i = 0; TestCases[i].type; i++) {
+void CalendarLimitTest::TestLimitsThread(int32_t threadNum) {
+    logln("thread %d starting", threadNum);
+    int32_t testIndex = 0;
+    LocalPointer<Calendar> cal;
+    while (gTestCaseIterator.next(testIndex)) {
+        TestCase &testCase = TestCases[testIndex];
+        logln("begin test of %s calendar.", testCase.type);
         UErrorCode status = U_ZERO_ERROR;
+        char buf[64];
         uprv_strcpy(buf, "root@calendar=");
-        strcat(buf, TestCases[i].type);
-        Calendar *cal = Calendar::createInstance(buf, status);
-        if (failure(status, "Calendar::createInstance")) {
+        strcat(buf, testCase.type);
+        cal.adoptInstead(Calendar::createInstance(buf, status));
+        if (failure(status, "Calendar::createInstance", TRUE)) {
             continue;
         }
-        if (uprv_strcmp(cal->getType(), TestCases[i].type) != 0) {
+        if (uprv_strcmp(cal->getType(), testCase.type) != 0) {
             errln((UnicodeString)"FAIL: Wrong calendar type: " + cal->getType()
-                + " Requested: " + TestCases[i].type);
-            delete cal;
+                + " Requested: " + testCase.type);
             continue;
         }
-        // Do the test
-        doTheoreticalLimitsTest(*cal, TestCases[i].hasLeapMonth);
-        doLimitsTest(*cal, TestCases[i].actualTestStart);
-        delete cal;
+        doTheoreticalLimitsTest(*(cal.getAlias()), testCase.hasLeapMonth);
+        doLimitsTest(*(cal.getAlias()), testCase.actualTestStart, testCase.actualTestEnd);
+        logln("end test of %s calendar.", testCase.type);
     }
 }
 
+    
 void
 CalendarLimitTest::doTheoreticalLimitsTest(Calendar& cal, UBool leapMonth) {
     const char* calType = cal.getType();
@@ -260,8 +297,8 @@ CalendarLimitTest::doTheoreticalLimitsTest(Calendar& cal, UBool leapMonth) {
 }
 
 void
-CalendarLimitTest::doLimitsTest(Calendar& cal, UDate startDate) {
-    int32_t testTime = quick ? -3 : -120;
+CalendarLimitTest::doLimitsTest(Calendar& cal, UDate startDate, int32_t endTime) {
+    int32_t testTime = quick ? ( endTime / 40 ) : endTime;
     doLimitsTest(cal, NULL /*default fields*/, startDate, testTime);
 }
 
@@ -336,7 +373,17 @@ CalendarLimitTest::doLimitsTest(Calendar& cal,
             logln((UnicodeString)"(" + i + " days)");
             mark += 5000; // 5 sec
         }
-        cal.setTime(greg.getTime(status), status);
+        UDate testMillis = greg.getTime(status);
+
+        if (testMillis == 2768943600000.0) {
+            // unusual failure, get day of month 0.
+            // doesn't happen with runConfigure and make check inside
+            // icuSources directory (i.e. using ICU build without wrapper makefile)
+            continue;
+        }
+
+        cal.setTime(testMillis, status);
+        cal.setMinimalDaysInFirstWeek(1);
         if (failure(status, "Calendar set/getTime")) {
             return;
         }
@@ -382,12 +429,24 @@ CalendarLimitTest::doLimitsTest(Calendar& cal,
                       ", actual_max=" + maxActual);
             }
             if (v < minActual || v > maxActual) {
-                errln((UnicodeString)"Fail: [" + cal.getType() + "] " +
-                      ymdToString(cal, ymd) +
-                      " " + FIELD_NAME[f] + "(" + f + ")=" + v +
-                      ", actual range=" + minActual + ".." + maxActual +
-                      ", allowed=(" + minLow + ".." + minHigh + ")..(" +
-                      maxLow + ".." + maxHigh + ")");
+                // timebomb per #9967, fix with #9972
+                if ( uprv_strcmp(cal.getType(), "dangi") == 0 &&
+                        testMillis >= 1865635198000.0  &&
+                     logKnownIssue("9972", "as per #9967")) { // Feb 2029 gregorian, end of dangi 4361
+                    logln((UnicodeString)"Fail: [" + cal.getType() + "] " +
+                          ymdToString(cal, ymd) +
+                          " " + FIELD_NAME[f] + "(" + f + ")=" + v +
+                          ", actual=" + minActual + ".." + maxActual +
+                          ", allowed=(" + minLow + ".." + minHigh + ")..(" +
+                          maxLow + ".." + maxHigh + ")");
+                } else {
+                    errln((UnicodeString)"Fail: [" + cal.getType() + "] " +
+                          ymdToString(cal, ymd) +
+                          " " + FIELD_NAME[f] + "(" + f + ")=" + v +
+                          ", actual=" + minActual + ".." + maxActual +
+                          ", allowed=(" + minLow + ".." + minHigh + ")..(" +
+                          maxLow + ".." + maxHigh + ")");
+                }
             }
         }
         greg.add(UCAL_DAY_OF_YEAR, 1, status);
@@ -446,7 +505,11 @@ CalendarLimitTest::ymdToString(const Calendar& cal, UnicodeString& str) {
         + "/" + (cal.get(UCAL_MONTH, status) + 1)
         + (cal.get(UCAL_IS_LEAP_MONTH, status) == 1 ? "(leap)" : "")
         + "/" + cal.get(UCAL_DATE, status)
-        + ", time=" + cal.getTime(status));
+        + " " + cal.get(UCAL_HOUR_OF_DAY, status)
+        + ":" + cal.get(UCAL_MINUTE, status)
+        + " zone(hrs) " + cal.get(UCAL_ZONE_OFFSET, status)/(60.0*60.0*1000.0)
+        + " dst(hrs) " + cal.get(UCAL_DST_OFFSET, status)/(60.0*60.0*1000.0)
+        + ", time(millis)=" + cal.getTime(status));
     return str;
 }