diff --git a/test/jdk/tools/jlink/plugins/IncludeLocalesPluginTest.java b/test/jdk/tools/jlink/plugins/IncludeLocalesPluginTest.java index f0fe3149247ea..845ca6c01a3a8 100644 --- a/test/jdk/tools/jlink/plugins/IncludeLocalesPluginTest.java +++ b/test/jdk/tools/jlink/plugins/IncludeLocalesPluginTest.java @@ -21,12 +21,14 @@ * questions. */ +import java.io.IOException; import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Locale; import java.util.stream.Collectors; +import java.util.stream.Stream; import jdk.tools.jlink.internal.LinkableRuntimeImage; import jdk.tools.jlink.internal.TaskHelper; @@ -37,6 +39,12 @@ import tests.JImageValidator; import tests.Result; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import static org.junit.jupiter.api.Assertions.fail; /* * @test @@ -56,415 +64,377 @@ * jdk.compiler * @build tests.* * @build tools.jlink.plugins.GetAvailableLocales - * @run main/othervm/timeout=180 -Xmx1g IncludeLocalesPluginTest + * @run junit/othervm/timeout=180 -Xmx1g IncludeLocalesPluginTest */ + public class IncludeLocalesPluginTest { - private static final String moduleName = "IncludeLocalesTest"; + private static final String MODULE_NAME = "IncludeLocalesTest"; private static Helper helper; - private static final int INCLUDE_LOCALES_OPTION = 0; - private static final int ADDMODS_OPTION = 1; - private static final int EXPECTED_LOCATIONS = 2; - private static final int UNEXPECTED_PATHS = 3; - private static final int AVAILABLE_LOCALES = 4; - private static final int ERROR_MESSAGE = 5; - - private static int errors; - - private final static Object[][] testData = { - // Test data should include: - // - --include-locales command line option - // - --add-modules command line option values - // - List of required resources in the result image - // - List of resources that should not exist in the result image - // - List of available locales in the result image - // - Error message - - // without --include-locales option: should include all locales - { - "", - "jdk.localedata", - List.of( - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_zh.class"), - List.of(), - Arrays.stream(Locale.getAvailableLocales()) - // "(root)" for Locale.ROOT rather than "" - .map(loc -> loc.equals(Locale.ROOT) ? "(root)" : loc.toString()) - .collect(Collectors.toList()), - "", - }, - - // Asterisk works exactly the same as above - { - "--include-locales=*", - "jdk.localedata", - List.of( - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_zh.class"), - List.of(), - Arrays.stream(Locale.getAvailableLocales()) - // "(root)" for Locale.ROOT rather than "" - .map(loc -> loc.equals(Locale.ROOT) ? "(root)" : loc.toString()) - .collect(Collectors.toList()), - "", - }, - - // World English/Spanish in Latin America - { - "--include-locales=en-001,es-419", - "jdk.localedata", - List.of( - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_150.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_AT.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_es.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_es_419.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_es_AR.class"), - List.of( - "/jdk.localedata/sun/text/resources/ext/LineBreakIteratorData_th", - "/jdk.localedata/sun/text/resources/ext/thai_dict", - "/jdk.localedata/sun/text/resources/ext/WordBreakIteratorData_th", - "/jdk.localedata/sun/text/resources/ext/BreakIteratorInfo_th.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class"), - List.of( - "(root)", "en", "en_001", "en_150", "en_AG", "en_AI", - "en_AT", "en_AU", "en_BB", "en_BE", "en_BM", "en_BS", "en_BW", "en_BZ", - "en_CC", "en_CH", "en_CK", "en_CM", "en_CX", "en_CY", "en_DE", - "en_DG", "en_DK", "en_DM", "en_ER", "en_FI", "en_FJ", "en_FK", "en_FM", - "en_GB", "en_GD", "en_GG", "en_GH", "en_GI", "en_GM", "en_GY", "en_HK", "en_ID", - "en_IE", "en_IL", "en_IM", "en_IN", "en_IO", "en_JE", "en_JM", "en_KE", - "en_KI", "en_KN", "en_KY", "en_LC", "en_LR", "en_LS", "en_MG", "en_MO", - "en_MS", "en_MT", "en_MU", "en_MV", "en_MW", "en_MY", "en_NA", "en_NF", "en_NG", - "en_NL", "en_NR", "en_NU", "en_NZ", "en_PG", "en_PK", "en_PN", - "en_PW", "en_RW", "en_SB", "en_SC", "en_SD", "en_SE", "en_SG", "en_SH", - "en_SI", "en_SL", "en_SS", "en_SX", "en_SZ", "en_TC", "en_TK", "en_TO", - "en_TT", "en_TV", "en_TZ", "en_UG", "en_US", "en_US_#Latn", "en_US_POSIX", "en_VC", "en_VG", "en_VU", "en_WS", - "en_ZA", "en_ZM", "en_ZW", "es", "es_419", "es_AR", "es_BO", "es_BR", "es_BZ", - "es_CL", "es_CO", "es_CR", "es_CU", "es_DO", "es_EC", "es_GT", "es_HN", - "es_MX", "es_NI", "es_PA", "es_PE", "es_PR", "es_PY", "es_SV", "es_US", - "es_UY", "es_VE", - // CLDR's "hi-Latn" falls back to "en-001", "hi-Latn"/"hi-Latn-IN" are added - // here. Since Locale.Matcher cannot handle such exceptional inheritance, - // allowing to include "hi"/"hi-IN" resource files. - "hi", "hi__#Latn", "hi_IN", "hi_IN_#Latn"), - "", - }, - - // All English and Japanese locales - { - "--include-locales=en,ja", - "jdk.localedata", - List.of( - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class"), - List.of( - "/jdk.localedata/sun/text/resources/ext/LineBreakIteratorData_th", - "/jdk.localedata/sun/text/resources/ext/thai_dict", - "/jdk.localedata/sun/text/resources/ext/WordBreakIteratorData_th", - "/jdk.localedata/sun/text/resources/ext/BreakIteratorInfo_th.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_zh.class"), - List.of( - "(root)", "en", "en_001", "en_150", "en_AE", "en_AG", "en_AI", "en_AS", "en_AT", - "en_AU", "en_BB", "en_BE", "en_BI", "en_BM", "en_BS", "en_BW", "en_BZ", - "en_CA", "en_CC", "en_CH", "en_CK", "en_CM", "en_CX", "en_CY", "en_DE", - "en_DG", "en_DK", "en_DM", "en_ER", "en_FI", "en_FJ", "en_FK", "en_FM", - "en_GB", "en_GD", "en_GG", "en_GH", "en_GI", "en_GM", "en_GU", "en_GY", - "en_HK", "en_ID", "en_IE", "en_IL", "en_IM", "en_IN", "en_IO", "en_JE", "en_JM", - "en_KE", "en_KI", "en_KN", "en_KY", "en_LC", "en_LR", "en_LS", "en_MG", - "en_MH", "en_MO", "en_MP", "en_MS", "en_MT", "en_MU", "en_MV", "en_MW", "en_MY", - "en_NA", "en_NF", "en_NG", "en_NL", "en_NR", "en_NU", "en_NZ", "en_PG", - "en_PH", "en_PK", "en_PN", "en_PR", "en_PW", "en_RW", "en_SB", "en_SC", - "en_SD", "en_SE", "en_SG", "en_SH", "en_SI", "en_SL", "en_SS", "en_SX", - "en_SZ", "en_TC", "en_TK", "en_TO", "en_TT", "en_TV", "en_TZ", "en_UG", - "en_UM", "en_US", "en_US_#Latn", "en_US_POSIX", "en_VC", "en_VG", "en_VI", "en_VU", - "en_WS", "en_ZA", "en_ZM", "en_ZW", "ja", "ja_JP", "ja_JP_#Jpan", - "ja_JP_JP_#u-ca-japanese"), - "", - }, - - // All locales in Austria - { - "--include-locales=*-AT", - "jdk.localedata", - List.of( - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_de.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_de_AT.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_150.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_AT.class"), - List.of( - "/jdk.localedata/sun/text/resources/ext/LineBreakIteratorData_th", - "/jdk.localedata/sun/text/resources/ext/thai_dict", - "/jdk.localedata/sun/text/resources/ext/WordBreakIteratorData_th", - "/jdk.localedata/sun/text/resources/ext/BreakIteratorInfo_th.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class"), - List.of( - "(root)", "en", "en_001", "en_150", "en_AT", "en_US", "en_US_#Latn", "en_US_POSIX", - "de", "de_AT"), - "", - }, - - // All locales in India - { - "--include-locales=*-IN", - "jdk.localedata", - List.of( - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_IN.class"), - List.of( - "/jdk.localedata/sun/text/resources/ext/LineBreakIteratorData_th", - "/jdk.localedata/sun/text/resources/ext/thai_dict", - "/jdk.localedata/sun/text/resources/ext/WordBreakIteratorData_th", - "/jdk.localedata/sun/text/resources/ext/BreakIteratorInfo_th.class", - "/jdk.localedata/sun/text/resources/ext/BreakIteratorResources_th.class", - "/jdk.localedata/sun/util/resources/cldr/ext/CalendarData_as_IN.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_zh.class"), - List.of( - "(root)", "as", "as_IN", "as_IN_#Beng", "bgc", "bgc_IN", "bgc_IN_#Deva", "bho", "bho_IN", "bho_IN_#Deva", - "bn", "bn_IN", "bo", "bo_IN", "brx", "brx_IN", "brx_IN_#Deva", "ccp", "ccp_IN", "doi", "doi_IN", - "doi_IN_#Deva", "en", "en_001", "en_IN", "en_US", "en_US_#Latn", "en_US_POSIX", "gu", "gu_IN", - "gu_IN_#Gujr", "hi", "hi__#Latn", "hi_IN", "hi_IN_#Deva", "hi_IN_#Latn", "kn", "kn_IN", "kn_IN_#Knda", - "kok", "kok__#Deva", "kok__#Latn", "kok_IN", "kok_IN_#Deva", "kok_IN_#Latn", "ks", "ks__#Arab", - "ks__#Deva", "ks_IN", "ks_IN_#Arab", "ks_IN_#Deva", "kxv", "kxv_IN", "kxv_IN_#Deva", "kxv_IN_#Latn", - "kxv_IN_#Orya", "kxv_IN_#Telu", "kxv__#Deva", "kxv__#Latn", "kxv__#Orya", "kxv__#Telu", - "mai", "mai_IN", "mai_IN_#Deva", "mni", "mni__#Beng", "mni_IN", "mni_IN_#Beng", "ml", "ml_IN", - "ml_IN_#Mlym", "mr", "mr_IN", "mr_IN_#Deva", "ne", "ne_IN", "or", "or_IN", "or_IN_#Orya", "pa", - "pa__#Guru", "pa_IN", "pa_IN_#Guru", "raj", "raj_IN", "raj_IN_#Deva", "sa", "sa_IN", "sa_IN_#Deva", - "sat", "sat__#Olck", "sat_IN", "sat_IN_#Olck", "sd", "sd__#Deva", "sd_IN", "sd_IN_#Deva", "ta", "ta_IN", - "ta_IN_#Taml", "te", "te_IN", "te_IN_#Telu", "ur_IN", "ur", "xnr", "xnr_IN", "xnr_IN_#Deva"), - "", - }, - - // Thai - { - "--include-locales=th", - "jdk.localedata", - List.of( - "/jdk.localedata/sun/text/resources/ext/LineBreakIteratorData_th", - "/jdk.localedata/sun/text/resources/ext/thai_dict", - "/jdk.localedata/sun/text/resources/ext/WordBreakIteratorData_th", - "/jdk.localedata/sun/text/resources/ext/BreakIteratorInfo_th.class", - "/jdk.localedata/sun/text/resources/ext/BreakIteratorResources_th.class"), - List.of( - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_zh.class"), - List.of( - "(root)", "en", "en_US", "en_US_#Latn", "en_US_POSIX", "th", "th_TH", - "th_TH_#Thai", "th_TH_TH_#u-nu-thai"), - "", - }, - - // Hong Kong - { - "--include-locales=zh-HK", - "jdk.localedata", - List.of( - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_zh.class"), - List.of( - "/jdk.localedata/sun/text/resources/ext/LineBreakIteratorData_th", - "/jdk.localedata/sun/text/resources/ext/thai_dict", - "/jdk.localedata/sun/text/resources/ext/WordBreakIteratorData_th", - "/jdk.localedata/sun/text/resources/ext/BreakIteratorInfo_th.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class"), - List.of( - "(root)", "en", "en_US", "en_US_#Latn", "en_US_POSIX", "zh", "zh__#Hans", "zh__#Hant", - "zh_HK", "zh_HK_#Hans", "zh_HK_#Hant"), - "", - }, - - // Simplified Chinese - { - "--include-locales=zh-Hans", - "jdk.localedata", - List.of( - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_zh.class"), - List.of( - "/jdk.localedata/sun/text/resources/ext/LineBreakIteratorData_th", - "/jdk.localedata/sun/text/resources/ext/thai_dict", - "/jdk.localedata/sun/text/resources/ext/WordBreakIteratorData_th", - "/jdk.localedata/sun/text/resources/ext/BreakIteratorInfo_th.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class"), - List.of( - "(root)", "en", "en_US", "en_US_#Latn", "en_US_POSIX", "zh", "zh__#Latn", "zh__#Hans", "zh_CN", - "zh_CN_#Latn", "zh_CN_#Hans", "zh_HK", "zh_HK_#Hans", "zh_MO", "zh_MO_#Hans", "zh_MY_#Hans", "zh_SG", - "zh_SG_#Hans"), - "", - }, - // Norwegian - { - "--include-locales=nb,nn,no", - "jdk.localedata", - List.of( - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_nb.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_nn.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_no.class"), - List.of( - "/jdk.localedata/sun/text/resources/ext/LineBreakIteratorData_th", - "/jdk.localedata/sun/text/resources/ext/thai_dict", - "/jdk.localedata/sun/text/resources/ext/WordBreakIteratorData_th", - "/jdk.localedata/sun/text/resources/ext/BreakIteratorInfo_th.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class"), - List.of( - "(root)", "en", "en_US", "en_US_#Latn", "en_US_POSIX", "nb", "nb_NO", - "nb_NO_#Latn", "nb_SJ", "nn", "nn_NO", "nn_NO_#Latn", "no", "no_NO", "no_NO_NY", - "no_NO_#Latn"), - "", - }, - - // Hebrew/Indonesian/Yiddish - { - "--include-locales=he,id,yi", - "jdk.localedata", - List.of( - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_he.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_id.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_yi.class"), - List.of( - "/jdk.localedata/sun/text/resources/ext/LineBreakIteratorData_th", - "/jdk.localedata/sun/text/resources/ext/thai_dict", - "/jdk.localedata/sun/text/resources/ext/WordBreakIteratorData_th", - "/jdk.localedata/sun/text/resources/ext/BreakIteratorInfo_th.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class"), - List.of( - "(root)", "en", "en_US", "en_US_#Latn", "en_US_POSIX", "id", "id_ID", - "id_ID_#Latn", "he", "he_IL", "he_IL_#Hebr", "yi", "yi_UA", "yi_UA_#Hebr"), - "", - }, - - // Langtag including extensions. Should be ignored. - { - "--include-locales=en,ja-u-nu-thai", - "jdk.localedata", - List.of( - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class"), - List.of(), - List.of( - "(root)", "en", "en_001", "en_150", "en_AE", "en_AG", "en_AI", "en_AS", "en_AT", - "en_AU", "en_BB", "en_BE", "en_BI", "en_BM", "en_BS", "en_BW", "en_BZ", - "en_CA", "en_CC", "en_CH", "en_CK", "en_CM", "en_CX", "en_CY", "en_DE", - "en_DG", "en_DK", "en_DM", "en_ER", "en_FI", "en_FJ", "en_FK", "en_FM", - "en_GB", "en_GD", "en_GG", "en_GH", "en_GI", "en_GM", "en_GU", "en_GY", - "en_HK", "en_ID", "en_IE", "en_IL", "en_IM", "en_IN", "en_IO", "en_JE", "en_JM", - "en_KE", "en_KI", "en_KN", "en_KY", "en_LC", "en_LR", "en_LS", "en_MG", - "en_MH", "en_MO", "en_MP", "en_MS", "en_MT", "en_MU", "en_MV", "en_MW", "en_MY", - "en_NA", "en_NF", "en_NG", "en_NL", "en_NR", "en_NU", "en_NZ", "en_PG", - "en_PH", "en_PK", "en_PN", "en_PR", "en_PW", "en_RW", "en_SB", "en_SC", - "en_SD", "en_SE", "en_SG", "en_SH", "en_SI", "en_SL", "en_SS", "en_SX", - "en_SZ", "en_TC", "en_TK", "en_TO", "en_TT", "en_TV", "en_TZ", "en_UG", - "en_UM", "en_US", "en_US_#Latn", "en_US_POSIX", "en_VC", "en_VG", "en_VI", "en_VU", - "en_WS", "en_ZA", "en_ZM", "en_ZW"), - "", - }, - - // Error case: No matching locales - { - "--include-locales=xyz", - "jdk.localedata", - null, - null, - null, - new PluginException(String.format( - PluginsResourceBundle.getMessage("include-locales.nomatchinglocales"), "xyz")) - .getMessage(), - }, - - // Error case: Invalid argument - { - "--include-locales=en,zh_HK", - "jdk.localedata", - null, - null, - null, - new PluginException(String.format( - PluginsResourceBundle.getMessage("include-locales.invalidtag"), "zh_hk")) - .getMessage(), - }, - - // Error case: jdk.localedata is not added - { - "--include-locales=en-US", - "java.base", - null, - null, - null, - new PluginException( - PluginsResourceBundle.getMessage("include-locales.localedatanotfound")) - .getMessage(), - }, - }; + // Test data should include: + // - --include-locales command line option + // - --add-modules command line option values + // - List of required resources in the result image + // - List of resources that should not exist in the result image + // - List of available locales in the result image + // - Error message + private static Stream testData() { + return Stream.of( + // without --include-locales option: should include all locales + Arguments.of( + "", + "jdk.localedata", + List.of( + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_zh.class"), + List.of(), + Arrays.stream(Locale.getAvailableLocales()) + // "(root)" for Locale.ROOT rather than "" + .map(loc -> loc.equals(Locale.ROOT) ? "(root)" : loc.toString()) + .collect(Collectors.toList()), + ""), + // Asterisk works exactly the same as above + Arguments.of( + "--include-locales=*", + "jdk.localedata", + List.of( + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_zh.class"), + List.of(), + Arrays.stream(Locale.getAvailableLocales()) + // "(root)" for Locale.ROOT rather than "" + .map(loc -> loc.equals(Locale.ROOT) ? "(root)" : loc.toString()) + .collect(Collectors.toList()), + ""), + // World English/Spanish in Latin America + Arguments.of( + "--include-locales=en-001,es-419", + "jdk.localedata", + List.of( + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_150.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_AT.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_es.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_es_419.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_es_AR.class"), + List.of( + "/jdk.localedata/sun/text/resources/ext/LineBreakIteratorData_th", + "/jdk.localedata/sun/text/resources/ext/thai_dict", + "/jdk.localedata/sun/text/resources/ext/WordBreakIteratorData_th", + "/jdk.localedata/sun/text/resources/ext/BreakIteratorInfo_th.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class"), + List.of( + "(root)", "en", "en_001", "en_150", "en_AG", "en_AI", + "en_AT", "en_AU", "en_BB", "en_BE", "en_BM", "en_BS", "en_BW", "en_BZ", + "en_CC", "en_CH", "en_CK", "en_CM", "en_CX", "en_CY", "en_DE", + "en_DG", "en_DK", "en_DM", "en_ER", "en_FI", "en_FJ", "en_FK", "en_FM", + "en_GB", "en_GD", "en_GG", "en_GH", "en_GI", "en_GM", "en_GY", "en_HK", "en_ID", + "en_IE", "en_IL", "en_IM", "en_IN", "en_IO", "en_JE", "en_JM", "en_KE", + "en_KI", "en_KN", "en_KY", "en_LC", "en_LR", "en_LS", "en_MG", "en_MO", + "en_MS", "en_MT", "en_MU", "en_MV", "en_MW", "en_MY", "en_NA", "en_NF", "en_NG", + "en_NL", "en_NR", "en_NU", "en_NZ", "en_PG", "en_PK", "en_PN", + "en_PW", "en_RW", "en_SB", "en_SC", "en_SD", "en_SE", "en_SG", "en_SH", + "en_SI", "en_SL", "en_SS", "en_SX", "en_SZ", "en_TC", "en_TK", "en_TO", + "en_TT", "en_TV", "en_TZ", "en_UG", "en_US", "en_US_#Latn", "en_US_POSIX", "en_VC", "en_VG", "en_VU", "en_WS", + "en_ZA", "en_ZM", "en_ZW", "es", "es_419", "es_AR", "es_BO", "es_BR", "es_BZ", + "es_CL", "es_CO", "es_CR", "es_CU", "es_DO", "es_EC", "es_GT", "es_HN", + "es_MX", "es_NI", "es_PA", "es_PE", "es_PR", "es_PY", "es_SV", "es_US", + "es_UY", "es_VE", + // CLDR's "hi-Latn" falls back to "en-001", "hi-Latn"/"hi-Latn-IN" are added + // here. Since Locale.Matcher cannot handle such exceptional inheritance, + // allowing to include "hi"/"hi-IN" resource files. + "hi", "hi__#Latn", "hi_IN", "hi_IN_#Latn"), + ""), + // All English and Japanese locales + Arguments.of( + "--include-locales=en,ja", + "jdk.localedata", + List.of( + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class"), + List.of( + "/jdk.localedata/sun/text/resources/ext/LineBreakIteratorData_th", + "/jdk.localedata/sun/text/resources/ext/thai_dict", + "/jdk.localedata/sun/text/resources/ext/WordBreakIteratorData_th", + "/jdk.localedata/sun/text/resources/ext/BreakIteratorInfo_th.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_zh.class"), + List.of( + "(root)", "en", "en_001", "en_150", "en_AE", "en_AG", "en_AI", "en_AS", "en_AT", + "en_AU", "en_BB", "en_BE", "en_BI", "en_BM", "en_BS", "en_BW", "en_BZ", + "en_CA", "en_CC", "en_CH", "en_CK", "en_CM", "en_CX", "en_CY", "en_DE", + "en_DG", "en_DK", "en_DM", "en_ER", "en_FI", "en_FJ", "en_FK", "en_FM", + "en_GB", "en_GD", "en_GG", "en_GH", "en_GI", "en_GM", "en_GU", "en_GY", + "en_HK", "en_ID", "en_IE", "en_IL", "en_IM", "en_IN", "en_IO", "en_JE", "en_JM", + "en_KE", "en_KI", "en_KN", "en_KY", "en_LC", "en_LR", "en_LS", "en_MG", + "en_MH", "en_MO", "en_MP", "en_MS", "en_MT", "en_MU", "en_MV", "en_MW", "en_MY", + "en_NA", "en_NF", "en_NG", "en_NL", "en_NR", "en_NU", "en_NZ", "en_PG", + "en_PH", "en_PK", "en_PN", "en_PR", "en_PW", "en_RW", "en_SB", "en_SC", + "en_SD", "en_SE", "en_SG", "en_SH", "en_SI", "en_SL", "en_SS", "en_SX", + "en_SZ", "en_TC", "en_TK", "en_TO", "en_TT", "en_TV", "en_TZ", "en_UG", + "en_UM", "en_US", "en_US_#Latn", "en_US_POSIX", "en_VC", "en_VG", "en_VI", "en_VU", + "en_WS", "en_ZA", "en_ZM", "en_ZW", "ja", "ja_JP", "ja_JP_#Jpan", + "ja_JP_JP_#u-ca-japanese"), + ""), + // All locales in Austria + Arguments.of( + "--include-locales=*-AT", + "jdk.localedata", + List.of( + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_de.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_de_AT.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_150.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_AT.class"), + List.of( + "/jdk.localedata/sun/text/resources/ext/LineBreakIteratorData_th", + "/jdk.localedata/sun/text/resources/ext/thai_dict", + "/jdk.localedata/sun/text/resources/ext/WordBreakIteratorData_th", + "/jdk.localedata/sun/text/resources/ext/BreakIteratorInfo_th.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class"), + List.of( + "(root)", "en", "en_001", "en_150", "en_AT", "en_US", "en_US_#Latn", "en_US_POSIX", + "de", "de_AT"), + ""), + // All locales in India + Arguments.of( + "--include-locales=*-IN", + "jdk.localedata", + List.of( + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_IN.class"), + List.of( + "/jdk.localedata/sun/text/resources/ext/LineBreakIteratorData_th", + "/jdk.localedata/sun/text/resources/ext/thai_dict", + "/jdk.localedata/sun/text/resources/ext/WordBreakIteratorData_th", + "/jdk.localedata/sun/text/resources/ext/BreakIteratorInfo_th.class", + "/jdk.localedata/sun/text/resources/ext/BreakIteratorResources_th.class", + "/jdk.localedata/sun/util/resources/cldr/ext/CalendarData_as_IN.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_zh.class"), + List.of( + "(root)", "as", "as_IN", "as_IN_#Beng", "bgc", "bgc_IN", "bgc_IN_#Deva", "bho", "bho_IN", "bho_IN_#Deva", + "bn", "bn_IN", "bo", "bo_IN", "brx", "brx_IN", "brx_IN_#Deva", "ccp", "ccp_IN", "doi", "doi_IN", + "doi_IN_#Deva", "en", "en_001", "en_IN", "en_US", "en_US_#Latn", "en_US_POSIX", "gu", "gu_IN", + "gu_IN_#Gujr", "hi", "hi__#Latn", "hi_IN", "hi_IN_#Deva", "hi_IN_#Latn", "kn", "kn_IN", "kn_IN_#Knda", + "kok", "kok__#Deva", "kok__#Latn", "kok_IN", "kok_IN_#Deva", "kok_IN_#Latn", "ks", "ks__#Arab", + "ks__#Deva", "ks_IN", "ks_IN_#Arab", "ks_IN_#Deva", "kxv", "kxv_IN", "kxv_IN_#Deva", "kxv_IN_#Latn", + "kxv_IN_#Orya", "kxv_IN_#Telu", "kxv__#Deva", "kxv__#Latn", "kxv__#Orya", "kxv__#Telu", + "mai", "mai_IN", "mai_IN_#Deva", "mni", "mni__#Beng", "mni_IN", "mni_IN_#Beng", "ml", "ml_IN", + "ml_IN_#Mlym", "mr", "mr_IN", "mr_IN_#Deva", "ne", "ne_IN", "or", "or_IN", "or_IN_#Orya", "pa", + "pa__#Guru", "pa_IN", "pa_IN_#Guru", "raj", "raj_IN", "raj_IN_#Deva", "sa", "sa_IN", "sa_IN_#Deva", + "sat", "sat__#Olck", "sat_IN", "sat_IN_#Olck", "sd", "sd__#Deva", "sd_IN", "sd_IN_#Deva", "ta", "ta_IN", + "ta_IN_#Taml", "te", "te_IN", "te_IN_#Telu", "ur_IN", "ur", "xnr", "xnr_IN", "xnr_IN_#Deva"), + ""), + // Thai + Arguments.of( + "--include-locales=th", + "jdk.localedata", + List.of( + "/jdk.localedata/sun/text/resources/ext/LineBreakIteratorData_th", + "/jdk.localedata/sun/text/resources/ext/thai_dict", + "/jdk.localedata/sun/text/resources/ext/WordBreakIteratorData_th", + "/jdk.localedata/sun/text/resources/ext/BreakIteratorInfo_th.class", + "/jdk.localedata/sun/text/resources/ext/BreakIteratorResources_th.class"), + List.of( + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_zh.class"), + List.of( + "(root)", "en", "en_US", "en_US_#Latn", "en_US_POSIX", "th", "th_TH", + "th_TH_#Thai", "th_TH_TH_#u-nu-thai"), + ""), + // Hong Kong + Arguments.of( + "--include-locales=zh-HK", + "jdk.localedata", + List.of( + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_zh.class"), + List.of( + "/jdk.localedata/sun/text/resources/ext/LineBreakIteratorData_th", + "/jdk.localedata/sun/text/resources/ext/thai_dict", + "/jdk.localedata/sun/text/resources/ext/WordBreakIteratorData_th", + "/jdk.localedata/sun/text/resources/ext/BreakIteratorInfo_th.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class"), + List.of( + "(root)", "en", "en_US", "en_US_#Latn", "en_US_POSIX", "zh", "zh__#Hans", "zh__#Hant", + "zh_HK", "zh_HK_#Hans", "zh_HK_#Hant"), + ""), + // Simplified Chinese + Arguments.of( + "--include-locales=zh-Hans", + "jdk.localedata", + List.of( + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_zh.class"), + List.of( + "/jdk.localedata/sun/text/resources/ext/LineBreakIteratorData_th", + "/jdk.localedata/sun/text/resources/ext/thai_dict", + "/jdk.localedata/sun/text/resources/ext/WordBreakIteratorData_th", + "/jdk.localedata/sun/text/resources/ext/BreakIteratorInfo_th.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class"), + List.of( + "(root)", "en", "en_US", "en_US_#Latn", "en_US_POSIX", "zh", "zh__#Latn", "zh__#Hans", "zh_CN", + "zh_CN_#Latn", "zh_CN_#Hans", "zh_HK", "zh_HK_#Hans", "zh_MO", "zh_MO_#Hans", "zh_MY_#Hans", "zh_SG", + "zh_SG_#Hans"), + ""), + // Norwegian + Arguments.of( + "--include-locales=nb,nn,no", + "jdk.localedata", + List.of( + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_nb.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_nn.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_no.class"), + List.of( + "/jdk.localedata/sun/text/resources/ext/LineBreakIteratorData_th", + "/jdk.localedata/sun/text/resources/ext/thai_dict", + "/jdk.localedata/sun/text/resources/ext/WordBreakIteratorData_th", + "/jdk.localedata/sun/text/resources/ext/BreakIteratorInfo_th.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class"), + List.of( + "(root)", "en", "en_US", "en_US_#Latn", "en_US_POSIX", "nb", "nb_NO", + "nb_NO_#Latn", "nb_SJ", "nn", "nn_NO", "nn_NO_#Latn", "no", "no_NO", "no_NO_NY", + "no_NO_#Latn"), + ""), + // Hebrew/Indonesian/Yiddish + Arguments.of( + "--include-locales=he,id,yi", + "jdk.localedata", + List.of( + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_he.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_id.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_yi.class"), + List.of( + "/jdk.localedata/sun/text/resources/ext/LineBreakIteratorData_th", + "/jdk.localedata/sun/text/resources/ext/thai_dict", + "/jdk.localedata/sun/text/resources/ext/WordBreakIteratorData_th", + "/jdk.localedata/sun/text/resources/ext/BreakIteratorInfo_th.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class"), + List.of( + "(root)", "en", "en_US", "en_US_#Latn", "en_US_POSIX", "id", "id_ID", + "id_ID_#Latn", "he", "he_IL", "he_IL_#Hebr", "yi", "yi_UA", "yi_UA_#Hebr"), + ""), + // Langtag including extensions. Should be ignored. + Arguments.of( + "--include-locales=en,ja-u-nu-thai", + "jdk.localedata", + List.of( + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class"), + List.of(), + List.of( + "(root)", "en", "en_001", "en_150", "en_AE", "en_AG", "en_AI", "en_AS", "en_AT", + "en_AU", "en_BB", "en_BE", "en_BI", "en_BM", "en_BS", "en_BW", "en_BZ", + "en_CA", "en_CC", "en_CH", "en_CK", "en_CM", "en_CX", "en_CY", "en_DE", + "en_DG", "en_DK", "en_DM", "en_ER", "en_FI", "en_FJ", "en_FK", "en_FM", + "en_GB", "en_GD", "en_GG", "en_GH", "en_GI", "en_GM", "en_GU", "en_GY", + "en_HK", "en_ID", "en_IE", "en_IL", "en_IM", "en_IN", "en_IO", "en_JE", "en_JM", + "en_KE", "en_KI", "en_KN", "en_KY", "en_LC", "en_LR", "en_LS", "en_MG", + "en_MH", "en_MO", "en_MP", "en_MS", "en_MT", "en_MU", "en_MV", "en_MW", "en_MY", + "en_NA", "en_NF", "en_NG", "en_NL", "en_NR", "en_NU", "en_NZ", "en_PG", + "en_PH", "en_PK", "en_PN", "en_PR", "en_PW", "en_RW", "en_SB", "en_SC", + "en_SD", "en_SE", "en_SG", "en_SH", "en_SI", "en_SL", "en_SS", "en_SX", + "en_SZ", "en_TC", "en_TK", "en_TO", "en_TT", "en_TV", "en_TZ", "en_UG", + "en_UM", "en_US", "en_US_#Latn", "en_US_POSIX", "en_VC", "en_VG", "en_VI", "en_VU", + "en_WS", "en_ZA", "en_ZM", "en_ZW"), + ""), + // Error case: No matching locales + Arguments.of( + "--include-locales=xyz", + "jdk.localedata", + null, + null, + null, + new PluginException(String.format( + PluginsResourceBundle.getMessage("include-locales.nomatchinglocales"), "xyz")) + .getMessage()), + // Error case: Invalid argument + Arguments.of( + "--include-locales=en,zh_HK", + "jdk.localedata", + null, + null, + null, + new PluginException(String.format( + PluginsResourceBundle.getMessage("include-locales.invalidtag"), "zh_hk")) + .getMessage()), + // Error case: jdk.localedata is not added + Arguments.of( + "--include-locales=en-US", + "java.base", + null, + null, + null, + new PluginException( + PluginsResourceBundle.getMessage("include-locales.localedatanotfound")) + .getMessage()) + ); + } - public static void main(String[] args) throws Exception { + @BeforeAll + public static void setup() throws IOException { boolean isLinkableRuntime = LinkableRuntimeImage.isLinkableRuntime(); System.out.println("Running test on " + - (isLinkableRuntime ? "enabled" : "disabled") + - " capability of linking from the run-time image."); + (isLinkableRuntime ? "enabled" : "disabled") + + " capability of linking from the run-time image."); System.out.println("Default module-path, 'jmods', " + - (Helper.jdkHasPackagedModules() ? "" : "NOT ") + - "present."); + (Helper.jdkHasPackagedModules() ? "" : "NOT ") + + "present."); helper = Helper.newHelper(isLinkableRuntime); if (helper == null) { - throw new RuntimeException("Helper could not be initialized"); + fail("Helper could not be initialized"); } + } - for (Object[] data : testData) { - // create image for each test data - Result result; - if (data[INCLUDE_LOCALES_OPTION].toString().isEmpty()) { - System.out.println("Invoking jlink with no --include-locales option"); - result = JImageGenerator.getJLinkTask() - .output(helper.createNewImageDir(moduleName)) - .addMods((String) data[ADDMODS_OPTION]) - .call(); - } else { - System.out.println("Invoking jlink with \"" + data[INCLUDE_LOCALES_OPTION] + "\""); - result = JImageGenerator.getJLinkTask() - .output(helper.createNewImageDir(moduleName)) - .addMods((String) data[ADDMODS_OPTION]) - .option((String) data[INCLUDE_LOCALES_OPTION]) - .call(); - } - - String errorMsg = (String) data[ERROR_MESSAGE]; - if (errorMsg.isEmpty()) { - Path image = result.assertSuccess(); + @ParameterizedTest + @MethodSource("testData") + public void launch(String optIncludeLocales, String optAddModules, List requiredRes, + List shouldNotExistRes, List availableLocs, String errorMsg) throws Exception { + // create image for each test data + Result result; + if (optIncludeLocales.isEmpty()) { + System.out.println("Invoking jlink with no --include-locales option"); + result = JImageGenerator.getJLinkTask() + .output(helper.createNewImageDir(MODULE_NAME)) + .addMods(optAddModules) + .call(); + } else { + System.out.println("Invoking jlink with \"" + optIncludeLocales + "\""); + result = JImageGenerator.getJLinkTask() + .output(helper.createNewImageDir(MODULE_NAME)) + .addMods(optAddModules) + .option(optIncludeLocales) + .call(); + } - // test locale data entries - testLocaleDataEntries(image, - (List) data[EXPECTED_LOCATIONS], - (List) data[UNEXPECTED_PATHS]); + if (errorMsg.isEmpty()) { + Path image = result.assertSuccess(); - // test available locales - testAvailableLocales(image, (List) data[AVAILABLE_LOCALES]); - } else { - result.assertFailure(new TaskHelper(TaskHelper.JLINK_BUNDLE) - .getMessage("error.prefix") + " " +errorMsg); - System.out.println("\tExpected failure: " + result.getMessage()); - } - } + // test locale data entries + testLocaleDataEntries(image, requiredRes, shouldNotExistRes); - if (errors > 0) { - throw new RuntimeException("Test failed"); + // test available locales + testAvailableLocales(image, availableLocs); + } else { + result.assertFailure(new TaskHelper(TaskHelper.JLINK_BUNDLE) + .getMessage("error.prefix") + " " +errorMsg); + System.out.println("\tExpected failure: " + result.getMessage()); } } @@ -476,9 +446,7 @@ private static void testLocaleDataEntries(Path image, List expectedLocat image.resolve("lib").resolve("modules"), expectedLocations, unexpectedPaths); } catch (Exception e) { - System.out.println("\tFailed with: " + e); - e.printStackTrace(); - errors++; + fail("\tFailed with: " + e); } } @@ -500,8 +468,7 @@ private static void testAvailableLocales(Path image, List availableLocal if (status == 0) { System.out.println("\tDone\t" + command); } else { - System.out.println("\tExit " + status + "\t" + command); - errors++; + fail("\tExit " + status + "\t" + command); } System.out.println(); }