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 */ 10package android.icu.dev.test.util; 11 12import java.text.Collator; 13import java.util.ArrayList; 14import java.util.Arrays; 15import java.util.Collection; 16import java.util.Comparator; 17import java.util.HashSet; 18import java.util.Iterator; 19import java.util.List; 20import java.util.Locale; 21import java.util.Map; 22import java.util.Map.Entry; 23import java.util.MissingResourceException; 24import java.util.Random; 25import java.util.Set; 26import java.util.SortedMap; 27 28import org.junit.Test; 29 30import android.icu.dev.test.TestFmwk; 31import android.icu.dev.test.TestLog; 32import android.icu.impl.ICULocaleService; 33import android.icu.impl.ICUService; 34import android.icu.impl.ICUService.Factory; 35import android.icu.impl.ICUService.SimpleFactory; 36import android.icu.util.ULocale; 37 38public 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