mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-13 08:53:20 +00:00
ICU-6052 Applied multithreading to testing time zones on differing locales.
X-SVN-Rev: 26489
This commit is contained in:
parent
be4903380b
commit
406bb9dff0
3 changed files with 306 additions and 189 deletions
|
@ -508,6 +508,7 @@ IntlTest::IntlTest()
|
|||
warn_on_missing_data = FALSE;
|
||||
quick = FALSE;
|
||||
leaks = FALSE;
|
||||
threadCount = 1;
|
||||
testoutfp = stdout;
|
||||
LL_indentlevel = indentLevel_offset;
|
||||
numProps = 0;
|
||||
|
@ -577,6 +578,13 @@ UBool IntlTest::setLeaks( UBool leaksVal )
|
|||
return rval;
|
||||
}
|
||||
|
||||
int32_t IntlTest::setThreadCount( int32_t count )
|
||||
{
|
||||
int32_t rval = this->threadCount;
|
||||
this->threadCount = count;
|
||||
return rval;
|
||||
}
|
||||
|
||||
int32_t IntlTest::getErrors( void )
|
||||
{
|
||||
return errorCount;
|
||||
|
@ -1016,6 +1024,7 @@ main(int argc, char* argv[])
|
|||
UBool leaks = FALSE;
|
||||
UBool warnOnMissingData = FALSE;
|
||||
UBool defaultDataFound = FALSE;
|
||||
int32_t threadCount = 1;
|
||||
UErrorCode errorCode = U_ZERO_ERROR;
|
||||
UConverter *cnv = NULL;
|
||||
const char *warnOrErr = "Failure";
|
||||
|
@ -1050,6 +1059,9 @@ main(int argc, char* argv[])
|
|||
warnOnMissingData = TRUE;
|
||||
warnOrErr = "WARNING";
|
||||
}
|
||||
else if (strncmp("threads:", str, 8) == 0) {
|
||||
threadCount = atoi(str + 8);
|
||||
}
|
||||
else if (strncmp("prop:", str, 5) == 0) {
|
||||
if (nProps < IntlTest::kMaxProps) {
|
||||
props[nProps] = str + 5;
|
||||
|
@ -1074,8 +1086,12 @@ main(int argc, char* argv[])
|
|||
fprintf(stdout,
|
||||
"### Syntax:\n"
|
||||
"### IntlTest [-option1 -option2 ...] [testname1 testname2 ...] \n"
|
||||
"### where options are: verbose (v), all (a), noerrormsg (n), \n"
|
||||
"### \n"
|
||||
"### Options are: verbose (v), all (a), noerrormsg (n), \n"
|
||||
"### exhaustive (e), leaks (l), prop:<propery>=<value>, \n"
|
||||
"### threads:<threadCount> (Mulithreading must first be \n"
|
||||
"### enabled otherwise this will be ignored. \n"
|
||||
"### The default thread count is 1.),\n"
|
||||
"### (Specify either -all (shortcut -a) or a test name). \n"
|
||||
"### -all will run all of the tests.\n"
|
||||
"### \n"
|
||||
|
@ -1101,6 +1117,7 @@ main(int argc, char* argv[])
|
|||
major.setNoErrMsg( no_err_msg );
|
||||
major.setQuick( quick );
|
||||
major.setLeaks( leaks );
|
||||
major.setThreadCount( threadCount );
|
||||
major.setWarnOnMissingData( warnOnMissingData );
|
||||
for (int32_t i = 0; i < nProps; i++) {
|
||||
major.setProperty(props[i]);
|
||||
|
@ -1130,6 +1147,11 @@ main(int argc, char* argv[])
|
|||
fprintf(stdout, " Exhaustive (e) : %s\n", (!quick? "On" : "Off"));
|
||||
fprintf(stdout, " Leaks (l) : %s\n", (leaks? "On" : "Off"));
|
||||
fprintf(stdout, " Warn on missing data (w) : %s\n", (warnOnMissingData? "On" : "Off"));
|
||||
#if (ICU_USE_THREADS==0)
|
||||
fprintf(stdout, " Threads : Disabled\n");
|
||||
#else
|
||||
fprintf(stdout, " Threads : %d\n", threadCount);
|
||||
#endif
|
||||
for (int32_t i = 0; i < nProps; i++) {
|
||||
fprintf(stdout, " Custom property (prop:) : %s\n", props[i]);
|
||||
}
|
||||
|
@ -1441,8 +1463,7 @@ const char * IntlTest::pathToDataDirectory()
|
|||
* It converts a character string into a UnicodeString, with
|
||||
* unescaping \u sequences.
|
||||
*/
|
||||
UnicodeString CharsToUnicodeString(const char* chars)
|
||||
{
|
||||
UnicodeString CharsToUnicodeString(const char* chars){
|
||||
UnicodeString str(chars, ""); // Invariant conversion
|
||||
return str.unescape();
|
||||
}
|
||||
|
|
|
@ -79,6 +79,7 @@ public:
|
|||
virtual UBool setQuick( UBool quick = TRUE );
|
||||
virtual UBool setLeaks( UBool leaks = TRUE );
|
||||
virtual UBool setWarnOnMissingData( UBool warn_on_missing_data = TRUE );
|
||||
virtual int32_t setThreadCount( int32_t count = 1);
|
||||
|
||||
virtual int32_t getErrors( void );
|
||||
virtual int32_t getDataErrors (void );
|
||||
|
@ -192,6 +193,7 @@ protected:
|
|||
UBool quick;
|
||||
UBool leaks;
|
||||
UBool warn_on_missing_data;
|
||||
int32_t threadCount;
|
||||
|
||||
private:
|
||||
UBool LL_linestart;
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include "tzfmttst.h"
|
||||
|
||||
#include "simplethread.h"
|
||||
#include "unicode/timezone.h"
|
||||
#include "unicode/simpletz.h"
|
||||
#include "unicode/calendar.h"
|
||||
|
@ -238,56 +239,253 @@ TimeZoneFormatTest::TestTimeZoneRoundTrip(void) {
|
|||
delete tzids;
|
||||
}
|
||||
|
||||
struct LocaleData{
|
||||
int32_t index;
|
||||
int32_t testCounts;
|
||||
UDate *times;
|
||||
const Locale* locales; // Static
|
||||
int32_t nLocales; // Static
|
||||
UBool quick; // Static
|
||||
UDate START_TIME; // Static
|
||||
UDate END_TIME; // Static
|
||||
int32_t numDone;
|
||||
};
|
||||
|
||||
class TestTimeRoundTripThread : public SimpleThread {
|
||||
public:
|
||||
TestTimeRoundTripThread(IntlTest& tlog, LocaleData &ld, int32_t i)
|
||||
: log(tlog), data(ld), index(i){}
|
||||
virtual void run(){
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
UBool REALLY_VERBOSE = FALSE;
|
||||
|
||||
// Whether each pattern is ambiguous at DST->STD local time overlap
|
||||
UBool AMBIGUOUS_DST_DECESSION[] = {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE};
|
||||
// Whether each pattern is ambiguous at STD->STD/DST->DST local time overlap
|
||||
UBool AMBIGUOUS_NEGATIVE_SHIFT[] = {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE};
|
||||
|
||||
// Workaround for #6338
|
||||
//UnicodeString BASEPATTERN("yyyy-MM-dd'T'HH:mm:ss.SSS");
|
||||
UnicodeString BASEPATTERN("yyyy.MM.dd HH:mm:ss.SSS");
|
||||
|
||||
// timer for performance analysis
|
||||
UDate timer;
|
||||
UDate testTimes[4];
|
||||
UBool expectedRoundTrip[4];
|
||||
int32_t testLen = 0;
|
||||
|
||||
StringEnumeration *tzids = TimeZone::createEnumeration();
|
||||
if (U_FAILURE(status)) {
|
||||
log.errln("tzids->count failed");
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t locidx = -1;
|
||||
UDate times[NUM_PATTERNS];
|
||||
for(int32_t i=0; i < NUM_PATTERNS; i++){
|
||||
times[i] = 0;
|
||||
}
|
||||
|
||||
int32_t testCounts = 0;
|
||||
UBool done = false;
|
||||
|
||||
while(true){
|
||||
umtx_lock(NULL); // Lock to increment the index
|
||||
for(int32_t i=0; i < NUM_PATTERNS; i++){
|
||||
data.times[i] += times[i];
|
||||
data.testCounts += testCounts;
|
||||
}
|
||||
if(data.index < data.nLocales){
|
||||
locidx = data.index;
|
||||
data.index++;
|
||||
} else {
|
||||
locidx = -1;
|
||||
}
|
||||
umtx_unlock(NULL); // Unlock for other threads to use
|
||||
|
||||
if(locidx == -1){
|
||||
log.logln((UnicodeString) "Thread " + index + " is done.");
|
||||
break;
|
||||
}
|
||||
|
||||
log.logln((UnicodeString)"\nThread " + index + ": Locale: " + UnicodeString(data.locales[locidx].getName()));
|
||||
|
||||
for (int32_t patidx = 0; patidx < NUM_PATTERNS; patidx++) {
|
||||
log.logln((UnicodeString)" Pattern: " + PATTERNS[patidx]);
|
||||
times[patidx] = 0;
|
||||
|
||||
UnicodeString pattern(BASEPATTERN);
|
||||
pattern.append(" ").append(PATTERNS[patidx]);
|
||||
|
||||
SimpleDateFormat *sdf = new SimpleDateFormat(pattern, data.locales[locidx], status);
|
||||
if (U_FAILURE(status)) {
|
||||
log.errcheckln(status, (UnicodeString)"new SimpleDateFormat failed for pattern " +
|
||||
pattern + " for locale " + data.locales[locidx].getName() + " - " + u_errorName(status));
|
||||
status = U_ZERO_ERROR;
|
||||
continue;
|
||||
}
|
||||
|
||||
tzids->reset(status);
|
||||
const UnicodeString *tzid;
|
||||
|
||||
timer = Calendar::getNow();
|
||||
|
||||
while ((tzid = tzids->snext(status))) {
|
||||
UnicodeString canonical;
|
||||
TimeZone::getCanonicalID(*tzid, canonical, status);
|
||||
if (U_FAILURE(status)) {
|
||||
// Unknown ID - we should not get here
|
||||
status = U_ZERO_ERROR;
|
||||
continue;
|
||||
}
|
||||
if (*tzid != canonical) {
|
||||
// Skip aliases
|
||||
continue;
|
||||
}
|
||||
BasicTimeZone *tz = (BasicTimeZone*)TimeZone::createTimeZone(*tzid);
|
||||
sdf->setTimeZone(*tz);
|
||||
|
||||
UDate t = data.START_TIME;
|
||||
TimeZoneTransition tzt;
|
||||
UBool tztAvail = FALSE;
|
||||
UBool middle = TRUE;
|
||||
|
||||
while (t < data.END_TIME) {
|
||||
if (!tztAvail) {
|
||||
testTimes[0] = t;
|
||||
expectedRoundTrip[0] = TRUE;
|
||||
testLen = 1;
|
||||
} else {
|
||||
int32_t fromOffset = tzt.getFrom()->getRawOffset() + tzt.getFrom()->getDSTSavings();
|
||||
int32_t toOffset = tzt.getTo()->getRawOffset() + tzt.getTo()->getDSTSavings();
|
||||
int32_t delta = toOffset - fromOffset;
|
||||
if (delta < 0) {
|
||||
UBool isDstDecession = tzt.getFrom()->getDSTSavings() > 0 && tzt.getTo()->getDSTSavings() == 0;
|
||||
testTimes[0] = t + delta - 1;
|
||||
expectedRoundTrip[0] = TRUE;
|
||||
testTimes[1] = t + delta;
|
||||
expectedRoundTrip[1] = isDstDecession ?
|
||||
!AMBIGUOUS_DST_DECESSION[patidx] : !AMBIGUOUS_NEGATIVE_SHIFT[patidx];
|
||||
testTimes[2] = t - 1;
|
||||
expectedRoundTrip[2] = isDstDecession ?
|
||||
!AMBIGUOUS_DST_DECESSION[patidx] : !AMBIGUOUS_NEGATIVE_SHIFT[patidx];
|
||||
testTimes[3] = t;
|
||||
expectedRoundTrip[3] = TRUE;
|
||||
testLen = 4;
|
||||
} else {
|
||||
testTimes[0] = t - 1;
|
||||
expectedRoundTrip[0] = TRUE;
|
||||
testTimes[1] = t;
|
||||
expectedRoundTrip[1] = TRUE;
|
||||
testLen = 2;
|
||||
}
|
||||
}
|
||||
for (int32_t testidx = 0; testidx < testLen; testidx++) {
|
||||
if (data.quick) {
|
||||
// reduce regular test time
|
||||
if (!expectedRoundTrip[testidx]) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
testCounts++;
|
||||
|
||||
UnicodeString text;
|
||||
FieldPosition fpos(0);
|
||||
sdf->format(testTimes[testidx], text, fpos);
|
||||
|
||||
UDate parsedDate = sdf->parse(text, status);
|
||||
if (U_FAILURE(status)) {
|
||||
log.errln((UnicodeString)"Failed to parse " + text);
|
||||
status = U_ZERO_ERROR;
|
||||
continue;
|
||||
}
|
||||
if (parsedDate != testTimes[testidx]) {
|
||||
UnicodeString msg = (UnicodeString)"Time round trip failed for "
|
||||
+ "tzid=" + *tzid
|
||||
+ ", locale=" + data.locales[locidx].getName()
|
||||
+ ", pattern=" + PATTERNS[patidx]
|
||||
+ ", text=" + text
|
||||
+ ", time=" + testTimes[testidx]
|
||||
+ ", restime=" + parsedDate
|
||||
+ ", diff=" + (parsedDate - testTimes[testidx]);
|
||||
if (expectedRoundTrip[testidx]) {
|
||||
log.errln((UnicodeString)"FAIL: " + msg);
|
||||
} else if (REALLY_VERBOSE) {
|
||||
log.logln(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
tztAvail = tz->getNextTransition(t, FALSE, tzt);
|
||||
if (!tztAvail) {
|
||||
break;
|
||||
}
|
||||
if (middle) {
|
||||
// Test the date in the middle of two transitions.
|
||||
t += (int64_t)((tzt.getTime() - t)/2);
|
||||
middle = FALSE;
|
||||
tztAvail = FALSE;
|
||||
} else {
|
||||
t = tzt.getTime();
|
||||
}
|
||||
}
|
||||
delete tz;
|
||||
}
|
||||
times[patidx] += (Calendar::getNow() - timer);
|
||||
delete sdf;
|
||||
}
|
||||
umtx_lock(NULL);
|
||||
data.numDone++;
|
||||
umtx_unlock(NULL);
|
||||
}
|
||||
delete tzids;
|
||||
}
|
||||
private:
|
||||
IntlTest& log;
|
||||
LocaleData& data;
|
||||
int32_t index;
|
||||
};
|
||||
|
||||
void
|
||||
TimeZoneFormatTest::TestTimeRoundTrip(void) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
int32_t nThreads = threadCount;
|
||||
const Locale *LOCALES;
|
||||
int32_t nLocales;
|
||||
int32_t testCounts = 0;
|
||||
|
||||
Calendar *cal = Calendar::createInstance(TimeZone::createTimeZone((UnicodeString)"UTC"), status);
|
||||
if (U_FAILURE(status)) {
|
||||
errln("Calendar::createInstance failed");
|
||||
return;
|
||||
}
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
Calendar *cal = Calendar::createInstance(TimeZone::createTimeZone((UnicodeString)"UTC"), status);
|
||||
if (U_FAILURE(status)) {
|
||||
errln("Calendar::createInstance failed");
|
||||
return;
|
||||
}
|
||||
|
||||
UDate START_TIME, END_TIME;
|
||||
const char* testAllProp = getProperty("TimeZoneRoundTripAll");
|
||||
UBool bTestAll = (testAllProp && uprv_strcmp(testAllProp, "true") == 0);
|
||||
|
||||
if (bTestAll || !quick) {
|
||||
cal->set(1900, UCAL_JANUARY, 1);
|
||||
} else {
|
||||
cal->set(1990, UCAL_JANUARY, 1);
|
||||
}
|
||||
START_TIME = cal->getTime(status);
|
||||
UDate START_TIME, END_TIME;
|
||||
if (bTestAll || !quick) {
|
||||
cal->set(1900, UCAL_JANUARY, 1);
|
||||
} else {
|
||||
cal->set(1990, UCAL_JANUARY, 1);
|
||||
}
|
||||
START_TIME = cal->getTime(status);
|
||||
|
||||
cal->set(2015, UCAL_JANUARY, 1);
|
||||
END_TIME = cal->getTime(status);
|
||||
if (U_FAILURE(status)) {
|
||||
errln("getTime failed");
|
||||
return;
|
||||
}
|
||||
cal->set(2015, UCAL_JANUARY, 1);
|
||||
END_TIME = cal->getTime(status);
|
||||
|
||||
// Whether each pattern is ambiguous at DST->STD local time overlap
|
||||
UBool AMBIGUOUS_DST_DECESSION[] = {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE};
|
||||
// Whether each pattern is ambiguous at STD->STD/DST->DST local time overlap
|
||||
UBool AMBIGUOUS_NEGATIVE_SHIFT[] = {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE};
|
||||
if (U_FAILURE(status)) {
|
||||
errln("getTime failed");
|
||||
return;
|
||||
}
|
||||
|
||||
// Workaround for #6338
|
||||
//UnicodeString BASEPATTERN("yyyy-MM-dd'T'HH:mm:ss.SSS");
|
||||
UnicodeString BASEPATTERN("yyyy.MM.dd HH:mm:ss.SSS");
|
||||
|
||||
// timer for performance analysis
|
||||
UDate timer;
|
||||
UDate times[NUM_PATTERNS];
|
||||
for (int32_t i = 0; i < NUM_PATTERNS; i++) {
|
||||
times[i] = 0;
|
||||
}
|
||||
|
||||
UBool REALLY_VERBOSE = FALSE;
|
||||
UDate times[NUM_PATTERNS];
|
||||
for (int32_t i = 0; i < NUM_PATTERNS; i++) {
|
||||
times[i] = 0;
|
||||
}
|
||||
|
||||
// Set up test locales
|
||||
const Locale locales1[] = {
|
||||
Locale("en")
|
||||
};
|
||||
const Locale locales1[] = {Locale("en")};
|
||||
const Locale locales2[] = {
|
||||
Locale("ar_EG"), Locale("bg_BG"), Locale("ca_ES"), Locale("da_DK"), Locale("de"),
|
||||
Locale("de_DE"), Locale("el_GR"), Locale("en"), Locale("en_AU"), Locale("en_CA"),
|
||||
|
@ -300,8 +498,6 @@ TimeZoneFormatTest::TestTimeRoundTrip(void) {
|
|||
Locale("zh_Hant"), Locale("zh_Hant_TW")
|
||||
};
|
||||
|
||||
const Locale *LOCALES;
|
||||
int32_t nLocales;
|
||||
if (bTestAll) {
|
||||
LOCALES = Locale::getAvailableLocales(nLocales);
|
||||
} else if (quick) {
|
||||
|
@ -312,157 +508,55 @@ TimeZoneFormatTest::TestTimeRoundTrip(void) {
|
|||
nLocales = sizeof(locales2)/sizeof(Locale);
|
||||
}
|
||||
|
||||
StringEnumeration *tzids = TimeZone::createEnumeration();
|
||||
if (U_FAILURE(status)) {
|
||||
errln("tzids->count failed");
|
||||
return;
|
||||
LocaleData data;
|
||||
data.index = 0;
|
||||
data.testCounts = testCounts;
|
||||
data.times = times;
|
||||
data.locales = LOCALES;
|
||||
data.nLocales = nLocales;
|
||||
data.quick = quick;
|
||||
data.START_TIME = START_TIME;
|
||||
data.END_TIME = END_TIME;
|
||||
data.numDone = 0;
|
||||
|
||||
#if (ICU_USE_THREADS==0)
|
||||
TestTimeRoundTripThread fakeThread(*this, data, 0);
|
||||
fakeThread.run();
|
||||
#else
|
||||
TestTimeRoundTripThread **threads = new TestTimeRoundTripThread*[threadCount];
|
||||
int32_t i;
|
||||
for(i=0; i<nThreads; i++){
|
||||
threads[i] = new TestTimeRoundTripThread(*this, data, i);
|
||||
if(threads[i]->start() != 0){
|
||||
errln("Error starting thread %d", i);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t testCounts = 0;
|
||||
UDate testTimes[4];
|
||||
UBool expectedRoundTrip[4];
|
||||
int32_t testLen = 0;
|
||||
|
||||
for (int32_t locidx = 0; locidx < nLocales; locidx++) {
|
||||
logln((UnicodeString)"Locale: " + LOCALES[locidx].getName());
|
||||
|
||||
for (int32_t patidx = 0; patidx < NUM_PATTERNS; patidx++) {
|
||||
logln((UnicodeString)" pattern: " + PATTERNS[patidx]);
|
||||
|
||||
//DEBUG static const char* PATTERNS[] = {"z", "zzzz", "Z", "ZZZZ", "v", "vvvv", "V", "VVVV"};
|
||||
//if (patidx != 1) continue;
|
||||
|
||||
UnicodeString pattern(BASEPATTERN);
|
||||
pattern.append(" ").append(PATTERNS[patidx]);
|
||||
|
||||
SimpleDateFormat *sdf = new SimpleDateFormat(pattern, LOCALES[locidx], status);
|
||||
if (U_FAILURE(status)) {
|
||||
errcheckln(status, (UnicodeString)"new SimpleDateFormat failed for pattern " +
|
||||
pattern + " for locale " + LOCALES[locidx].getName() + " - " + u_errorName(status));
|
||||
status = U_ZERO_ERROR;
|
||||
continue;
|
||||
}
|
||||
|
||||
tzids->reset(status);
|
||||
const UnicodeString *tzid;
|
||||
|
||||
timer = Calendar::getNow();
|
||||
|
||||
while ((tzid = tzids->snext(status))) {
|
||||
UnicodeString canonical;
|
||||
TimeZone::getCanonicalID(*tzid, canonical, status);
|
||||
if (U_FAILURE(status)) {
|
||||
// Unknown ID - we should not get here
|
||||
status = U_ZERO_ERROR;
|
||||
continue;
|
||||
}
|
||||
if (*tzid != canonical) {
|
||||
// Skip aliases
|
||||
continue;
|
||||
}
|
||||
BasicTimeZone *tz = (BasicTimeZone*)TimeZone::createTimeZone(*tzid);
|
||||
sdf->setTimeZone(*tz);
|
||||
|
||||
UDate t = START_TIME;
|
||||
TimeZoneTransition tzt;
|
||||
UBool tztAvail = FALSE;
|
||||
UBool middle = TRUE;
|
||||
|
||||
while (t < END_TIME) {
|
||||
if (!tztAvail) {
|
||||
testTimes[0] = t;
|
||||
expectedRoundTrip[0] = TRUE;
|
||||
testLen = 1;
|
||||
} else {
|
||||
int32_t fromOffset = tzt.getFrom()->getRawOffset() + tzt.getFrom()->getDSTSavings();
|
||||
int32_t toOffset = tzt.getTo()->getRawOffset() + tzt.getTo()->getDSTSavings();
|
||||
int32_t delta = toOffset - fromOffset;
|
||||
if (delta < 0) {
|
||||
UBool isDstDecession = tzt.getFrom()->getDSTSavings() > 0 && tzt.getTo()->getDSTSavings() == 0;
|
||||
testTimes[0] = t + delta - 1;
|
||||
expectedRoundTrip[0] = TRUE;
|
||||
testTimes[1] = t + delta;
|
||||
expectedRoundTrip[1] = isDstDecession ?
|
||||
!AMBIGUOUS_DST_DECESSION[patidx] : !AMBIGUOUS_NEGATIVE_SHIFT[patidx];
|
||||
testTimes[2] = t - 1;
|
||||
expectedRoundTrip[2] = isDstDecession ?
|
||||
!AMBIGUOUS_DST_DECESSION[patidx] : !AMBIGUOUS_NEGATIVE_SHIFT[patidx];
|
||||
testTimes[3] = t;
|
||||
expectedRoundTrip[3] = TRUE;
|
||||
testLen = 4;
|
||||
} else {
|
||||
testTimes[0] = t - 1;
|
||||
expectedRoundTrip[0] = TRUE;
|
||||
testTimes[1] = t;
|
||||
expectedRoundTrip[1] = TRUE;
|
||||
testLen = 2;
|
||||
}
|
||||
}
|
||||
for (int32_t testidx = 0; testidx < testLen; testidx++) {
|
||||
if (quick) {
|
||||
// reduce regular test time
|
||||
if (!expectedRoundTrip[testidx]) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
testCounts++;
|
||||
|
||||
UnicodeString text;
|
||||
FieldPosition fpos(0);
|
||||
sdf->format(testTimes[testidx], text, fpos);
|
||||
|
||||
UDate parsedDate = sdf->parse(text, status);
|
||||
if (U_FAILURE(status)) {
|
||||
errln((UnicodeString)"Failed to parse " + text);
|
||||
status = U_ZERO_ERROR;
|
||||
continue;
|
||||
}
|
||||
if (parsedDate != testTimes[testidx]) {
|
||||
UnicodeString msg = (UnicodeString)"Time round trip failed for "
|
||||
+ "tzid=" + *tzid
|
||||
+ ", locale=" + LOCALES[locidx].getName()
|
||||
+ ", pattern=" + PATTERNS[patidx]
|
||||
+ ", text=" + text
|
||||
+ ", time=" + testTimes[testidx]
|
||||
+ ", restime=" + parsedDate
|
||||
+ ", diff=" + (parsedDate - testTimes[testidx]);
|
||||
if (expectedRoundTrip[testidx]) {
|
||||
errln((UnicodeString)"FAIL: " + msg);
|
||||
} else if (REALLY_VERBOSE) {
|
||||
logln(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
tztAvail = tz->getNextTransition(t, FALSE, tzt);
|
||||
if (!tztAvail) {
|
||||
break;
|
||||
}
|
||||
if (middle) {
|
||||
// Test the date in the middle of two transitions.
|
||||
t += (int64_t)((tzt.getTime() - t)/2);
|
||||
middle = FALSE;
|
||||
tztAvail = FALSE;
|
||||
} else {
|
||||
t = tzt.getTime();
|
||||
}
|
||||
}
|
||||
delete tz;
|
||||
}
|
||||
times[patidx] += (Calendar::getNow() - timer);
|
||||
delete sdf;
|
||||
UBool done = false;
|
||||
while(true){
|
||||
umtx_lock(NULL);
|
||||
if(data.numDone == nLocales) {
|
||||
done = true;
|
||||
}
|
||||
umtx_unlock(NULL);
|
||||
if(done) break;
|
||||
SimpleThread::sleep(1000);
|
||||
}
|
||||
UDate total = 0;
|
||||
logln("### Elapsed time by patterns ###");
|
||||
for (int32_t i = 0; i < NUM_PATTERNS; i++) {
|
||||
logln(UnicodeString("") + times[i] + "ms (" + PATTERNS[i] + ")");
|
||||
total += times[i];
|
||||
}
|
||||
logln((UnicodeString)"Total: " + total + "ms");
|
||||
logln((UnicodeString)"Iteration: " + testCounts);
|
||||
#endif
|
||||
UDate total = 0;
|
||||
logln("### Elapsed time by patterns ###");
|
||||
for (int32_t i = 0; i < NUM_PATTERNS; i++) {
|
||||
logln(UnicodeString("") + data.times[i] + "ms (" + PATTERNS[i] + ")");
|
||||
total += data.times[i];
|
||||
}
|
||||
logln((UnicodeString)"Total: " + total + "ms");
|
||||
logln((UnicodeString)"Iteration: " + data.testCounts);
|
||||
|
||||
delete cal;
|
||||
delete tzids;
|
||||
delete cal;
|
||||
|
||||
}
|
||||
|
||||
#endif /* #if !UCONFIG_NO_FORMATTING */
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue