Home | History | Annotate | Download | only in util
      1 /* GENERATED SOURCE. DO NOT MODIFY. */
      2 //  2016 and later: Unicode, Inc. and others.
      3 // License & terms of use: http://www.unicode.org/copyright.html#License
      4 /**
      5  *******************************************************************************
      6  * Copyright (C) 2001-2013, International Business Machines Corporation and    *
      7  * others. All Rights Reserved.                                                *
      8  *******************************************************************************
      9  */
     10 package android.icu.dev.test.util;
     11 
     12 import java.text.Collator;
     13 import java.util.ArrayList;
     14 import java.util.Arrays;
     15 import java.util.Collection;
     16 import java.util.Comparator;
     17 import java.util.HashSet;
     18 import java.util.Iterator;
     19 import java.util.List;
     20 import java.util.Locale;
     21 import java.util.Map;
     22 import java.util.Map.Entry;
     23 import java.util.MissingResourceException;
     24 import java.util.Random;
     25 import java.util.Set;
     26 import java.util.SortedMap;
     27 
     28 import org.junit.Test;
     29 import org.junit.runner.RunWith;
     30 import org.junit.runners.JUnit4;
     31 
     32 import android.icu.dev.test.TestFmwk;
     33 import android.icu.impl.ICULocaleService;
     34 import android.icu.impl.ICUService;
     35 import android.icu.impl.ICUService.Factory;
     36 import android.icu.impl.ICUService.SimpleFactory;
     37 import android.icu.util.ULocale;
     38 import android.icu.testsharding.MainTestShard;
     39 
     40 @MainTestShard
     41 @RunWith(JUnit4.class)
     42 public class ICUServiceThreadTest extends TestFmwk
     43 {
     44     private static final boolean PRINTSTATS = false;
     45 
     46     private static final String[] countries = {
     47         "ab", "bc", "cd", "de", "ef", "fg", "gh", "ji", "ij", "jk"
     48     };
     49     private static final String[] languages = {
     50         "", "ZY", "YX", "XW", "WV", "VU", "UT", "TS", "SR", "RQ", "QP"
     51     };
     52     private static final String[] variants = {
     53         "", "", "", "GOLD", "SILVER", "BRONZE"
     54     };
     55 
     56     private static class TestFactory extends SimpleFactory {
     57         TestFactory(String id) {
     58             super(new ULocale(id), id, true);
     59         }
     60 
     61         @Override
     62         public String getDisplayName(String idForDisplay, ULocale locale) {
     63             return (visible && idForDisplay.equals(this.id)) ? "(" + locale.toString() + ") " + idForDisplay : null;
     64         }
     65 
     66         @Override
     67         public String toString() {
     68             return "Factory_" + id;
     69         }
     70     }
     71     /**
     72      * Convenience override of getDisplayNames(ULocale, Comparator, String) that
     73      * uses the default collator for the locale as the comparator to
     74      * sort the display names, and null for the matchID.
     75      */
     76     public static SortedMap getDisplayNames(ICUService service, ULocale locale) {
     77         Collator col;
     78         try {
     79             col = Collator.getInstance(locale.toLocale());
     80         }
     81         catch (MissingResourceException e) {
     82             // if no collator resources, we can't collate
     83             col = null;
     84         }
     85         return service.getDisplayNames(locale, col, null);
     86     }
     87     private static final Random r = new Random(); // this is a multi thread test, can't 'unrandomize'
     88 
     89     private static String getCLV() {
     90         String c = countries[r.nextInt(countries.length)];
     91         String l = languages[r.nextInt(languages.length)];
     92         String v = variants[r.nextInt(variants.length)];
     93         return new Locale(c, l, v).toString();
     94     }
     95 
     96     private static boolean WAIT = true;
     97     private static boolean GO = false;
     98     private static long TIME = 5000;
     99 
    100     public static void runThreads() {
    101         runThreads(TIME);
    102     }
    103 
    104     public static void runThreads(long time) {
    105         try {
    106             GO = true;
    107             WAIT = false;
    108 
    109             Thread.sleep(time);
    110 
    111             WAIT = true;
    112             GO = false;
    113 
    114             Thread.sleep(300);
    115         }
    116         catch (InterruptedException e) {
    117         }
    118     }
    119 
    120     static class TestThread extends Thread {
    121         //private final String name;
    122         protected ICUService service;
    123         private final long delay;
    124 
    125         public TestThread(String name, ICUService service, long delay) {
    126             //this.name = name + " ";
    127             this.service = service;
    128             this.delay = delay;
    129             this.setDaemon(true);
    130         }
    131 
    132         @Override
    133         public void run() {
    134             while (WAIT) {
    135                 Thread.yield();
    136             }
    137 
    138             try {
    139                 while (GO) {
    140                     iterate();
    141                     if (delay > 0) {
    142                         Thread.sleep(delay);
    143                     }
    144                 }
    145             }
    146             catch (InterruptedException e) {
    147             }
    148         }
    149 
    150         protected void iterate() {
    151         }
    152 
    153         /*
    154           public boolean logging() {
    155           return log != null;
    156           }
    157 
    158           public void log(String msg) {
    159           if (logging()) {
    160           log.log(name + msg);
    161           }
    162           }
    163 
    164           public void logln(String msg) {
    165           if (logging()) {
    166           log.logln(name + msg);
    167           }
    168           }
    169 
    170           public void err(String msg) {
    171           if (logging()) {
    172           log.err(name + msg);
    173           }
    174           }
    175 
    176           public void errln(String msg) {
    177           if (logging()) {
    178           log.errln(name + msg);
    179           }
    180           }
    181 
    182           public void warn(String msg) {
    183           if (logging()) {
    184           log.info(name + msg);
    185           }
    186           }
    187 
    188           public void warnln(String msg) {
    189           if (logging()) {
    190           log.infoln(name + msg);
    191           }
    192           }
    193         */
    194     }
    195 
    196     static class RegisterFactoryThread extends TestThread {
    197         RegisterFactoryThread(String name, ICUService service, long delay) {
    198             super("REG " + name, service, delay);
    199         }
    200 
    201         @Override
    202         protected void iterate() {
    203             Factory f = new TestFactory(getCLV());
    204             service.registerFactory(f);
    205             TestFmwk.logln(f.toString());
    206         }
    207     }
    208 
    209     static class UnregisterFactoryThread extends TestThread {
    210         private Random r;
    211         List factories;
    212 
    213         UnregisterFactoryThread(String name, ICUService service, long delay) {
    214             super("UNREG " + name, service, delay);
    215 
    216             r = new Random();
    217             factories = service.factories();
    218         }
    219 
    220         @Override
    221         public void iterate() {
    222             int s = factories.size();
    223             if (s == 0) {
    224                 factories = service.factories();
    225             } else {
    226                 int n = r.nextInt(s);
    227                 Factory f = (Factory)factories.remove(n);
    228                 boolean success = service.unregisterFactory(f);
    229                 TestFmwk.logln("factory: " + f + (success ? " succeeded." : " *** failed."));
    230             }
    231         }
    232     }
    233 
    234     static class UnregisterFactoryListThread extends TestThread {
    235         Factory[] factories;
    236         int n;
    237 
    238         UnregisterFactoryListThread(String name, ICUService service, long delay, Factory[] factories) {
    239             super("UNREG " + name, service, delay);
    240 
    241             this.factories = factories;
    242         }
    243 
    244         @Override
    245         public void iterate() {
    246             if (n < factories.length) {
    247                 Factory f = factories[n++];
    248                 boolean success = service.unregisterFactory(f);
    249                 TestFmwk.logln("factory: " + f + (success ? " succeeded." : " *** failed."));
    250             }
    251         }
    252     }
    253 
    254 
    255     static class GetVisibleThread extends TestThread {
    256         GetVisibleThread(String name, ICUService service, long delay) {
    257             super("VIS " + name, service, delay);
    258         }
    259 
    260         @Override
    261         protected void iterate() {
    262             Set ids = service.getVisibleIDs();
    263             Iterator iter = ids.iterator();
    264             int n = 10;
    265             while (--n >= 0 && iter.hasNext()) {
    266                 String id = (String)iter.next();
    267                 Object result = service.get(id);
    268                 TestFmwk.logln("iter: " + n + " id: " + id + " result: " + result);
    269             }
    270         }
    271     }
    272 
    273     static class GetDisplayThread extends TestThread {
    274         ULocale locale;
    275 
    276         GetDisplayThread(String name, ICUService service, long delay, ULocale locale) {
    277             super("DIS " + name, service, delay);
    278 
    279             this.locale = locale;
    280         }
    281 
    282         @Override
    283         protected void iterate() {
    284             Map names = getDisplayNames(service,locale);
    285             Iterator iter = names.entrySet().iterator();
    286             int n = 10;
    287             while (--n >= 0 && iter.hasNext()) {
    288                 Entry e = (Entry)iter.next();
    289                 String dname = (String)e.getKey();
    290                 String id = (String)e.getValue();
    291                 Object result = service.get(id);
    292 
    293                 // Note: IllegalMonitorStateException is thrown by the code
    294                 // below on IBM JRE5 for AIX 64bit.  For some reason, converting
    295                 // int to String out of this statement resolves the issue.
    296 
    297                 String num = Integer.toString(n);
    298                 TestFmwk.logln(" iter: " + num +
    299                         " dname: " + dname +
    300                         " id: " + id +
    301                         " result: " + result);
    302             }
    303         }
    304     }
    305 
    306     static class GetThread extends TestThread {
    307         private String[] actualID;
    308 
    309         GetThread(String name, ICUService service, long delay) {
    310             super("GET " + name, service, delay);
    311 
    312             actualID = new String[1];
    313         }
    314 
    315         @Override
    316         protected void iterate() {
    317             String id = getCLV();
    318             Object o = service.get(id, actualID);
    319             if (o != null) {
    320                 TestFmwk.logln(" id: " + id + " actual: " + actualID[0] + " result: " + o);
    321             }
    322         }
    323     }
    324 
    325     static class GetListThread extends TestThread {
    326         private final String[] list;
    327         private int n;
    328 
    329         GetListThread(String name, ICUService service, long delay, String[] list) {
    330             super("GETL " + name, service, delay);
    331 
    332             this.list = list;
    333         }
    334 
    335         @Override
    336         protected void iterate() {
    337             if (--n < 0) {
    338                 n = list.length - 1;
    339             }
    340             String id = list[n];
    341             Object o = service.get(id);
    342             TestFmwk.logln(" id: " + id + " result: " + o);
    343         }
    344     }
    345 
    346     // return a collection of unique factories, might be fewer than requested
    347     Collection getFactoryCollection(int requested) {
    348         Set locales = new HashSet();
    349         for (int i = 0; i < requested; ++i) {
    350             locales.add(getCLV());
    351         }
    352         List factories = new ArrayList(locales.size());
    353         Iterator iter = locales.iterator();
    354         while (iter.hasNext()) {
    355             factories.add(new TestFactory((String)iter.next()));
    356         }
    357         return factories;
    358     }
    359 
    360     void registerFactories(ICUService service, Collection c) {
    361         Iterator iter = c.iterator();
    362         while (iter.hasNext()) {
    363             service.registerFactory((Factory)iter.next());
    364         }
    365     }
    366 
    367     ICUService stableService() {
    368         if (stableService == null) {
    369             stableService = new ICULocaleService();
    370             registerFactories(stableService, getFactoryCollection(50));
    371         }
    372         if (PRINTSTATS) stableService.stats();  // Enable the stats collection
    373         return stableService;
    374     }
    375     private ICUService stableService;
    376 
    377     // run multiple get on a stable service
    378     @Test
    379     public void Test00_ConcurrentGet() {
    380         for(int i = 0; i < 10; ++i) {
    381             new GetThread("[" + Integer.toString(i) + "]",  stableService(), 0).start();
    382         }
    383         runThreads();
    384         if (PRINTSTATS) System.out.println(stableService.stats());
    385     }
    386 
    387     // run multiple getVisibleID on a stable service
    388     @Test
    389     public void Test01_ConcurrentGetVisible() {
    390         for(int i = 0; i < 10; ++i) {
    391             new GetVisibleThread("[" + Integer.toString(i) + "]",  stableService(), 0).start();
    392         }
    393         runThreads();
    394         if (PRINTSTATS) System.out.println(stableService.stats());
    395     }
    396 
    397     // run multiple getDisplayName on a stable service
    398     @Test
    399     public void Test02_ConcurrentGetDisplay() {
    400         String[] localeNames = {
    401             "en", "es", "de", "fr", "zh", "it", "no", "sv"
    402         };
    403         for(int i = 0; i < localeNames.length; ++i) {
    404             String locale = localeNames[i];
    405             new GetDisplayThread("[" + locale + "]",
    406                                  stableService(),
    407                                  0,
    408                                  new ULocale(locale)).start();
    409         }
    410         runThreads();
    411         if (PRINTSTATS) System.out.println(stableService.stats());
    412     }
    413 
    414     // run register/unregister on a service
    415     @Test
    416     public void Test03_ConcurrentRegUnreg() {
    417         ICUService service = new ICULocaleService();
    418         if (PRINTSTATS) service.stats();    // Enable the stats collection
    419         for (int i = 0; i < 5; ++i) {
    420             new RegisterFactoryThread("[" + i + "]", service, 0).start();
    421         }
    422         for (int i = 0; i < 5; ++i) {
    423             new UnregisterFactoryThread("[" + i + "]", service, 0).start();
    424         }
    425         runThreads();
    426         if (PRINTSTATS) System.out.println(service.stats());
    427     }
    428 
    429     @Test
    430     public void Test04_WitheringService() {
    431         ICUService service = new ICULocaleService();
    432         if (PRINTSTATS) service.stats();    // Enable the stats collection
    433 
    434         Collection fc = getFactoryCollection(50);
    435         registerFactories(service, fc);
    436 
    437         Factory[] factories = (Factory[])fc.toArray(new Factory[fc.size()]);
    438         Comparator comp = new Comparator() {
    439                 @Override
    440                 public int compare(Object lhs, Object rhs) {
    441                     return lhs.toString().compareTo(rhs.toString());
    442                 }
    443             };
    444         Arrays.sort(factories, comp);
    445 
    446         new GetThread("", service, 0).start();
    447         new UnregisterFactoryListThread("", service, 3, factories).start();
    448 
    449         runThreads(2000);
    450         if (PRINTSTATS) System.out.println(service.stats());
    451     }
    452 
    453     // "all hell breaks loose"
    454     // one register and one unregister thread, delay 500ms
    455     // two display threads with different locales, delay 500ms;
    456     // one visible id thread, delay 50ms
    457     // fifteen get threads, delay 0
    458     // run for ten seconds
    459     @Test
    460     public void Test05_ConcurrentEverything() {
    461         ICUService service = new ICULocaleService();
    462         if (PRINTSTATS) service.stats();    // Enable the stats collection
    463 
    464         new RegisterFactoryThread("", service, 500).start();
    465 
    466         for(int i = 0; i < 15; ++i) {
    467             new GetThread("[" + Integer.toString(i) + "]", service, 0).start();
    468         }
    469 
    470         new GetVisibleThread("",  service, 50).start();
    471 
    472         String[] localeNames = {
    473             "en", "de"
    474         };
    475         for(int i = 0; i < localeNames.length; ++i) {
    476             String locale = localeNames[i];
    477             new GetDisplayThread("[" + locale + "]",
    478                                  stableService(),
    479                                  500,
    480                                  new ULocale(locale)).start();
    481         }
    482 
    483         new UnregisterFactoryThread("", service, 500).start();
    484 
    485         // yoweee!!!
    486         runThreads(9500);
    487         if (PRINTSTATS) System.out.println(service.stats());
    488     }
    489 }
    490