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