LUCENE-4020: Tests may not be repeatable across different platforms/ JVMs due to different locale/ timezone being picked.

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1330585 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Dawid Weiss 2012-04-25 22:18:13 +00:00
parent 1dedf205c6
commit 805ccb6006
2 changed files with 109 additions and 9 deletions

View File

@ -0,0 +1,89 @@
package org.apache.lucene.util.junitcompat;
import java.util.Locale;
import java.util.Random;
import java.util.TimeZone;
import org.apache.lucene.util.LuceneTestCase;
import org.apache.lucene.util.SystemPropertiesRestoreRule;
import org.apache.lucene.util._TestUtil;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.RuleChain;
import org.junit.rules.TestRule;
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import com.carrotsearch.randomizedtesting.RandomizedContext;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
public class TestSameRandomnessLocalePassedOrNot extends WithNestedTests {
@ClassRule
public static TestRule solrClassRules =
RuleChain.outerRule(new SystemPropertiesRestoreRule());
@Rule
public TestRule solrTestRules =
RuleChain.outerRule(new SystemPropertiesRestoreRule());
public TestSameRandomnessLocalePassedOrNot() {
super(false);
}
public static class Nested extends WithNestedTests.AbstractNestedTest {
public static String pickString;
public static Locale defaultLocale;
public static TimeZone defaultTimeZone;
public static String seed;
@BeforeClass
public static void setup() {
seed = RandomizedContext.current().getRunnerSeedAsString();
Random rnd = random();
pickString = _TestUtil.randomSimpleString(rnd);
defaultLocale = Locale.getDefault();
defaultTimeZone = TimeZone.getDefault();
}
public void testPassed() {
System.out.println("Picked locale: " + defaultLocale);
System.out.println("Picked timezone: " + defaultTimeZone.getID());
}
}
@Test
public void testSetupWithoutLocale() {
Result runClasses = JUnitCore.runClasses(Nested.class);
Assert.assertEquals(0, runClasses.getFailureCount());
String s1 = Nested.pickString;
System.setProperty("tests.seed", Nested.seed);
System.setProperty("tests.timezone", Nested.defaultTimeZone.getID());
System.setProperty("tests.locale", Nested.defaultLocale.toString());
JUnitCore.runClasses(Nested.class);
String s2 = Nested.pickString;
Assert.assertEquals(s1, s2);
}
}

View File

@ -178,6 +178,9 @@ public abstract class LuceneTestCase extends Assert {
/** set of directories we created, in afterclass we try to clean these up */
private static final Map<File, StackTraceElement[]> tempDirs = Collections.synchronizedMap(new HashMap<File, StackTraceElement[]>());
// TODO: the fact these are static final means they're initialized on class load and they should
// be reinitialized on before suite hooks (to allow proper tests).
// by default we randomly pick a different codec for
// each test case (non-J4 tests) and each test class (J4
// tests)
@ -185,10 +188,6 @@ public abstract class LuceneTestCase extends Assert {
public static final String TEST_CODEC = System.getProperty("tests.codec", "random");
/** Gets the postingsFormat to run tests with. */
public static final String TEST_POSTINGSFORMAT = System.getProperty("tests.postingsformat", "random");
/** Gets the locale to run tests with */
public static final String TEST_LOCALE = System.getProperty("tests.locale", "random");
/** Gets the timezone to run tests with */
public static final String TEST_TIMEZONE = System.getProperty("tests.timezone", "random");
/** Gets the directory to run tests with */
public static final String TEST_DIRECTORY = System.getProperty("tests.directory", "random");
/** Get the number of times to run tests */
@ -204,6 +203,11 @@ public abstract class LuceneTestCase extends Assert {
/** whether or not to clean threads between test invocations: "false", "perMethod", "perClass" */
public static final Throttling TEST_THROTTLING = TEST_NIGHTLY ? Throttling.SOMETIMES : Throttling.NEVER;
/** Gets the locale to run tests with */
public static String TEST_LOCALE;
/** Gets the timezone to run tests with */
public static String TEST_TIMEZONE;
/**
* A random multiplier which you should use when writing random tests:
* multiply it by the number of iterations
@ -453,14 +457,21 @@ public abstract class LuceneTestCase extends Assert {
}
}
// END hack
locale = TEST_LOCALE.equals("random") ? randomLocale(random()) : localeForName(TEST_LOCALE);
// Initialize locale/ timezone.
TEST_LOCALE = System.getProperty("tests.locale", "random");
TEST_TIMEZONE = System.getProperty("tests.timezone", "random");
// Always pick a random one for consistency (whether TEST_LOCALE was specified or not).
Locale randomLocale = randomLocale(random());
locale = TEST_LOCALE.equals("random") ? randomLocale : localeForName(TEST_LOCALE);
Locale.setDefault(locale);
// TimeZone.getDefault will set user.timezone to the default timezone of the user's locale.
// So store the original property value and restore it at end.
restoreProperties.put("user.timezone", System.getProperty("user.timezone"));
savedTimeZone = TimeZone.getDefault();
timeZone = TEST_TIMEZONE.equals("random") ? randomTimeZone(random()) : TimeZone.getTimeZone(TEST_TIMEZONE);
TimeZone randomTimeZone = randomTimeZone(random());
timeZone = TEST_TIMEZONE.equals("random") ? randomTimeZone : TimeZone.getTimeZone(TEST_TIMEZONE);
TimeZone.setDefault(timeZone);
similarity = random().nextBoolean() ? new DefaultSimilarity() : new RandomSimilarityProvider(random());
testsFailed = false;
@ -1570,10 +1581,10 @@ public abstract class LuceneTestCase extends Assert {
// extra params that were overridden needed to reproduce the command
private static String reproduceWithExtraParams() {
StringBuilder sb = new StringBuilder();
if (locale != null) sb.append(" -Dtests.locale=").append(locale);
if (timeZone != null) sb.append(" -Dtests.timezone=").append(timeZone.getID());
if (!TEST_CODEC.equals("random")) sb.append(" -Dtests.codec=").append(TEST_CODEC);
if (!TEST_POSTINGSFORMAT.equals("random")) sb.append(" -Dtests.postingsformat=").append(TEST_POSTINGSFORMAT);
if (!TEST_LOCALE.equals("random")) sb.append(" -Dtests.locale=").append(TEST_LOCALE);
if (!TEST_TIMEZONE.equals("random")) sb.append(" -Dtests.timezone=").append(TEST_TIMEZONE);
if (!TEST_DIRECTORY.equals("random")) sb.append(" -Dtests.directory=").append(TEST_DIRECTORY);
if (RANDOM_MULTIPLIER > 1) sb.append(" -Dtests.multiplier=").append(RANDOM_MULTIPLIER);
if (TEST_NIGHTLY) sb.append(" -Dtests.nightly=true");