From 805ccb6006a80962998136d7982a8b6d78ce3203 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Wed, 25 Apr 2012 22:18:13 +0000 Subject: [PATCH] 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 --- .../TestSameRandomnessLocalePassedOrNot.java | 89 +++++++++++++++++++ .../apache/lucene/util/LuceneTestCase.java | 29 ++++-- 2 files changed, 109 insertions(+), 9 deletions(-) create mode 100644 lucene/core/src/test/org/apache/lucene/util/junitcompat/TestSameRandomnessLocalePassedOrNot.java diff --git a/lucene/core/src/test/org/apache/lucene/util/junitcompat/TestSameRandomnessLocalePassedOrNot.java b/lucene/core/src/test/org/apache/lucene/util/junitcompat/TestSameRandomnessLocalePassedOrNot.java new file mode 100644 index 00000000000..1d381c5797a --- /dev/null +++ b/lucene/core/src/test/org/apache/lucene/util/junitcompat/TestSameRandomnessLocalePassedOrNot.java @@ -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); + } +} diff --git a/lucene/test-framework/src/java/org/apache/lucene/util/LuceneTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/util/LuceneTestCase.java index 17ad41e67b1..afee33a5712 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/util/LuceneTestCase.java +++ b/lucene/test-framework/src/java/org/apache/lucene/util/LuceneTestCase.java @@ -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 tempDirs = Collections.synchronizedMap(new HashMap()); + // 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");