<i18n dev> [8]: diff patch for jdk test on a non US platform

Stuart Marks stuart.marks at oracle.com
Mon Nov 4 17:23:58 PST 2013


On 10/31/13 9:44 PM, Francis ANDRE wrote:
> Le 31/10/2013 22:27, Stuart Marks a écrit :
>> It turns out that the debugExec lines emitted by rmid are localized:
> If the lines emitted by rmid are localized, then your test "s.indexOf("rmid:
> debugExec") != -1" should be also localized or did I miss something?

In general we don't localize tests, since they're not delivered to end-users of 
the product. If we were to localize this test, the localization would be a copy 
of the localization of rmid, and I don't want to have redundant copies of 
localization strings spread around the system.

>> All locales except the French have no space between "rmid" and the trailing
>> colon (":"). It appears that having the space before the colon is proper
>> French usage (at least, the other French localizations all appear similar).
>> But adding the space to the search string will fix the French locale but will
>> break all the other locales.
>  From my French perspective -- ie, my mother's language -- , I would not add a
> space between rmid and the colon...

I'm not sure you and I can resolve the correctness of this localization. I'm 
presuming it's correct, since all the French localizations (at least the ones I 
found during a brief search) were consistent about this spacing.

>> Forcing the test to run in the US locale seems preferable to adding logic to
>> deal with different localizations. Since these tests fork JVMs in
>> subprocesses, it's probably necessary to do something special to make sure the
>> sub-JVMs are in the US locale. This probably involves setting an environment
>> variable or a system property. I'm sure others on this list can provide advice.
> I think that the best thing to do is removing the space " " before the colon ":"
> so that your code will work in any localisation. If it is not possible to remove
> this space, then you have to fix the test, taking care the localisation you
> mention in the rmid_fr.properties.

I don't think we should change the French localizations, unless someone pops up 
and says "oh yes, these were consistently all done with the wrong spacing." Even 
if we did, if another locale were to come along that were to change the message 
so that the test couldn't find the string it's looking for, that would break the 
test. It's improper for the test to make requirements about how the message 
string is formatted.

Since this test doesn't have anything to do with localization, it seems most 
sensible for the test to force itself into the US locale, and to force all JVM 
subprocesses into the US locale as well.

> Your test is about the usage message in a localized language, so IMHO, it should
> take care of the localization message otherwise I do not understand this code:
> TestLibrary.bomb("rmid has incorrect usage message");

Well, this test (CheckUsage) is highly questionable. If you look at the original 
bug report,

https://bugs.openjdk.java.net/browse/jdk-4259564

the bug was that the usage message didn't have a -J option, even though this 
option was supported in the code. (Also that the usage message was somewhat 
terse.) In my opinion it was silly for someone to have written a test for a 
usage message, but it got written anyway.

Now, if we were to support running this test under any locale, then the 
localized usage message (or a portion of it) would have to be copied into the 
test's resource bundle, or into the test's code itself. Again, this would be 
bad, because it would replicate localization information in different places in 
the repository.

Worse, since we don't run the test suite in different locales regularly, any 
divergence between the product's localized messages and the test's localized 
messages might not be caught for a long time, or the test would pass in some 
locales but fail in others.

The solution here is not to localize the test, or to add logic to the test to 
look for different messages, but instead to have the test force the JVMs into a 
known locale so that it doesn't fail when run in an unexpected locale.

But for CheckUsage, it's not clear that even doing this is worth the effort. I'd 
rather just remove this test.

There is also another, similar test in test/java/rmi/registry/checkusage. I 
wouldn't be surprised if it has exactly the same problem. It should be removed 
too. I've filed

https://bugs.openjdk.java.net/browse/JDK-8027810

for removing these tests.

Bottom line is that I do not think it makes sense to localize these tests.

s'marks


>> We test on several platforms as it is; I don't think we'll want to have
>> separate test runs for all eleven (or however many) different localizations.
>>
>> I can see adding code (or test configuration properties or environment
>> variables) to ensure that tests are run in the US locale, unless this is
>> specifically overridden by the test. It doesn't seem appropriate to add
>> locale-specific logic or data structures to the tests, though.
> If purpose of the test is to check the localization message, you would have no
> other choice to use properties like the previous rmid test.
>
> Francis
>>
>> s'marks
>>
>>
>>> diff --git a/test/java/util/Formattable/StockName.java
>>> b/test/java/util/Formattable/StockName.java
>>> --- a/test/java/util/Formattable/StockName.java
>>> +++ b/test/java/util/Formattable/StockName.java
>>> @@ -33,83 +33,90 @@
>>>   import static java.util.FormattableFlags.*;
>>>
>>>   public class StockName implements Formattable {
>>> -    private String symbol, companyName, frenchCompanyName;
>>> +    private String symbol, companyName, frenchCompanyName;
>>>
>>> -    public StockName(String symbol, String companyName,
>>> -                     String frenchCompanyName)
>>> -    {
>>> -        this.symbol = symbol;
>>> -        this.companyName = companyName;
>>> -        this.frenchCompanyName = frenchCompanyName;
>>> -    }
>>> +    public StockName(String symbol, String companyName, String
>>> frenchCompanyName) {
>>> +        this.symbol = symbol;
>>> +        this.companyName = companyName;
>>> +        this.frenchCompanyName = frenchCompanyName;
>>> +    }
>>>
>>> -    public void formatTo(Formatter fmt, int f, int width, int precision){
>>> -        StringBuilder sb = new StringBuilder();
>>> +    public void formatTo(Formatter fmt, int f, int width, int precision){
>>> +        StringBuilder sb = new StringBuilder();
>>>
>>> -        // decide form of name
>>> -        String name = companyName;
>>> -        if (fmt.locale().equals(Locale.FRANCE))
>>> -            name = frenchCompanyName;
>>> -        boolean alternate = (f & ALTERNATE) == ALTERNATE;
>>> -        boolean usesymbol = alternate || (precision != -1 && precision < 10);
>>> -        String out = (usesymbol ? symbol : name);
>>> +        // decide form of name
>>> +        String name = companyName;
>>> +        if (fmt.locale().equals(Locale.FRANCE))
>>> +            name = frenchCompanyName;
>>> +        boolean alternate = (f & ALTERNATE) == ALTERNATE;
>>> +        boolean usesymbol = alternate || (precision != -1 && precision < 10);
>>> +        String out = (usesymbol ? symbol : name);
>>>
>>> -        // apply precision
>>> -        if (precision == -1 || out.length() < precision) {
>>> -            // write it all
>>> -            sb.append(out);
>>> -        } else {
>>> -            sb.append(out.substring(0, precision - 1)).append('*');
>>> -        }
>>> +        // apply precision
>>> +        if (precision == -1 || out.length() < precision) {
>>> +            // write it all
>>> +            sb.append(out);
>>> +        } else {
>>> +            sb.append(out.substring(0, precision - 1)).append('*');
>>> +        }
>>>
>>> -        // apply width and justification
>>> -        int len = sb.length();
>>> -        if (len < width)
>>> -            for (int i = 0; i < width - len; i++)
>>> -                if ((f & LEFT_JUSTIFY) == LEFT_JUSTIFY)
>>> -                    sb.append(' ');
>>> -                else
>>> -                    sb.insert(0, ' ');
>>> +        // apply width and justification
>>> +        int len = sb.length();
>>> +        if (len < width)
>>> +            for (int i = 0; i < width - len; i++)
>>> +                if ((f & LEFT_JUSTIFY) == LEFT_JUSTIFY)
>>> +                    sb.append(' ');
>>> +                else
>>> +                    sb.insert(0, ' ');
>>>
>>> -        fmt.format(sb.toString());
>>> -    }
>>> +        fmt.format(sb.toString());
>>> +    }
>>>
>>> -    public String toString() {
>>> -        return String.format("%s - %s", symbol, companyName);
>>> -    }
>>> +    public String toString() {
>>> +        return String.format("%s - %s", symbol, companyName);
>>> +    }
>>>
>>> -    public static void main(String [] args) {
>>> -        StockName sn = new StockName("HUGE", "Huge Fruit, Inc.",
>>> -                                     "Fruit Titanesque, Inc.");
>>> -        CharBuffer cb = CharBuffer.allocate(128);
>>> -        Formatter fmt = new Formatter(cb);
>>> +    public static void main(String[] args) {
>>> +        StockName sn = new StockName("HUGE", "Huge Fruit, Inc.",
>>> +                "Fruit Titanesque, Inc.");
>>> +        CharBuffer cb = CharBuffer.allocate(128);
>>> +        Formatter fmt = new Formatter(cb);
>>>
>>> -        fmt.format("%s", sn);            //   -> "Huge Fruit, Inc."
>>> -        test(cb, "Huge Fruit, Inc.");
>>> +        if (fmt.locale().equals(Locale.FRANCE)) {
>>> +            fmt.format("%s", sn); // -> "Fruit Titanesque, Inc."
>>> +            test(cb, "Fruit Titanesque, Inc.");
>>> +        } else {
>>> +            fmt.format("%s", sn); // -> "Huge Fruit, Inc."
>>> +            test(cb, "Huge Fruit, Inc.");
>>> +        }
>>> +        fmt.format("%s", sn.toString()); // -> "HUGE - Huge Fruit, Inc."
>>> +        test(cb, "HUGE - Huge Fruit, Inc.");
>>>
>>> -        fmt.format("%s", sn.toString()); //   -> "HUGE - Huge Fruit, Inc."
>>> -        test(cb, "HUGE - Huge Fruit, Inc.");
>>> +        fmt.format("%#s", sn); // -> "HUGE"
>>> +        test(cb, "HUGE");
>>>
>>> -        fmt.format("%#s", sn);           //   -> "HUGE"
>>> -        test(cb, "HUGE");
>>> +        fmt.format("%-10.8s", sn); // -> "HUGE      "
>>> +        test(cb, "HUGE      ");
>>>
>>> -        fmt.format("%-10.8s", sn);       //   -> "HUGE "
>>> -        test(cb, "HUGE      ");
>>> +        if (fmt.locale().equals(Locale.FRANCE)) {
>>> +            fmt.format("%.12s", sn); // -> "Fruit Titan*"
>>> +            test(cb, "Fruit Titan*");
>>> +        } else {
>>> +            fmt.format("%.12s", sn); // -> "Huge Fruit,*"
>>> +            test(cb, "Huge Fruit,*");
>>> +        }
>>>
>>> -        fmt.format("%.12s", sn);         //   -> "Huge Fruit,*"
>>> -        test(cb, "Huge Fruit,*");
>>> +        fmt.format(Locale.FRANCE, "%25s", sn);
>>> +        // -> "   Fruit Titanesque, Inc."
>>> +        test(cb, "   Fruit Titanesque, Inc.");
>>> +    }
>>>
>>> -        fmt.format(Locale.FRANCE, "%25s", sn);
>>> -                                         //   -> "   Fruit Titanesque, Inc."
>>> -        test(cb, "   Fruit Titanesque, Inc.");
>>> -    }
>>> -
>>> -    private static void test(CharBuffer cb, String exp) {
>>> -        cb.limit(cb.position());
>>> -        cb.rewind();
>>> -        if (!cb.toString().equals(exp))
>>> -            throw new RuntimeException("expect: '" + exp + "'; got: '"
>>> -                                       + cb.toString() + "'");
>>> -        cb.clear();
>>> -    }
>>> +    private static void test(CharBuffer cb, String exp) {
>>> +        cb.limit(cb.position());
>>> +        cb.rewind();
>>> +        if (!cb.toString().equals(exp))
>>> +            throw new RuntimeException("expect: '" + exp + "'; got: '"
>>> +                    + cb.toString() + "'");
>>> +        cb.clear();
>>> +    }
>>>   }
>>> diff --git a/test/java/util/ResourceBundle/ResourceBundleTest.java
>>> b/test/java/util/ResourceBundle/ResourceBundleTest.java
>>> --- a/test/java/util/ResourceBundle/ResourceBundleTest.java
>>> +++ b/test/java/util/ResourceBundle/ResourceBundleTest.java
>>> @@ -67,6 +67,7 @@
>>>
>>>   public class ResourceBundleTest extends RBTestFmwk {
>>>       public static void main(String[] args) throws Exception {
>>> +        Locale.setDefault(Locale.US);
>>>           new ResourceBundleTest().run(args);
>>>       }
>>>
>>> diff --git
>>> a/test/java/util/ResourceBundle/getBaseBundleName/TestGetBaseBundleName.java
>>> b/test/java/util/ResourceBundle/getBaseBundleName/TestGetBaseBundleName.java
>>> --- a/test/java/util/ResourceBundle/getBaseBundleName/TestGetBaseBundleName.java
>>> +++ b/test/java/util/ResourceBundle/getBaseBundleName/TestGetBaseBundleName.java
>>> @@ -45,6 +45,7 @@
>>>       }
>>>
>>>       public static void main(String... args) throws Exception {
>>> +        Locale.setDefault(Locale.US);
>>>
>>>           Locale defaultLocale = Locale.getDefault();
>>>           System.out.println("Default locale is: " + defaultLocale);
>>> diff --git a/test/java/util/logging/LocalizedLevelName.java
>>> b/test/java/util/logging/LocalizedLevelName.java
>>> --- a/test/java/util/logging/LocalizedLevelName.java
>>> +++ b/test/java/util/logging/LocalizedLevelName.java
>>> @@ -49,6 +49,7 @@
>>>       };
>>>
>>>       public static void main(String args[]) throws Exception {
>>> +        Locale.setDefault(Locale.US);
>>>           Locale defaultLocale = Locale.getDefault();
>>>           for (int i=0; i<namesMap.length; i += 4) {
>>>               final String key = (String) namesMap[i];
>>> diff --git a/test/java/util/logging/SimpleFormatterFormat.java
>>> b/test/java/util/logging/SimpleFormatterFormat.java
>>> --- a/test/java/util/logging/SimpleFormatterFormat.java
>>> +++ b/test/java/util/logging/SimpleFormatterFormat.java
>>> @@ -30,6 +30,7 @@
>>>    */
>>>
>>>   import java.io.*;
>>> +import java.util.Locale;
>>>   import java.util.logging.*;
>>>   import java.util.regex.*;
>>>
>>> @@ -38,7 +39,8 @@
>>>       private static final String origFormat = System.getProperty(key);
>>>       private static final PrintStream err = System.err;
>>>       public static void main(String[] args) throws Exception {
>>> -        try {
>>> +       Locale.setDefault(Locale.US);
>>> +       try {
>>>               File dir = new File(System.getProperty("user.dir", "."));
>>>               File log = new File(dir, "simpleformat.txt");
>>>               java.nio.file.Files.deleteIfExists(log.toPath());
>>> diff --git a/test/sun/util/logging/SourceClassName.java
>>> b/test/sun/util/logging/SourceClassName.java
>>> --- a/test/sun/util/logging/SourceClassName.java
>>> +++ b/test/sun/util/logging/SourceClassName.java
>>> @@ -31,12 +31,14 @@
>>>    * @run main/othervm SourceClassName
>>>    */
>>>
>>> +import java.util.Locale;
>>>   import java.util.logging.*;
>>>   import java.io.*;
>>>   import sun.util.logging.PlatformLogger;
>>>
>>>   public class SourceClassName {
>>>       public static void main(String[] args) throws Exception {
>>> +        Locale.setDefault(Locale.US);
>>>           File dir = new File(System.getProperty("user.dir", "."));
>>>           File log = new File(dir, "testlog.txt");
>>>           PrintStream logps = new PrintStream(log);
>>>
>>
>


More information about the i18n-dev mailing list