1 4 package com.tc.object.bytecode.hook.impl; 5 6 import com.tc.exception.ImplementMe; 7 import com.tc.object.ObjectID; 8 import com.tc.object.TCClass; 9 import com.tc.object.TCObject; 10 import com.tc.object.dna.api.DNA; 11 import com.tc.object.dna.api.DNAException; 12 import com.tc.object.dna.api.DNAWriter; 13 import com.tc.util.concurrent.ThreadUtil; 14 15 import gnu.trove.TLinkable; 16 17 import java.util.ArrayList ; 18 import java.util.IdentityHashMap ; 19 import java.util.List ; 20 import java.util.Map ; 21 import java.util.Random ; 22 23 import junit.framework.TestCase; 24 25 public class ArrayManagerTest extends TestCase { 26 27 private final Map registerdPairs = new IdentityHashMap (); 28 private static final List errors = new ArrayList (); 29 private Object [] arrays; 30 31 protected void setUp() throws Exception { 32 for (int i = 0; i < 100; i++) { 33 TCObject tco = new FakeTCObject(); 34 Object array = new Object [] {}; 35 registerdPairs.put(array, tco); ArrayManager.register(array, tco); 37 } 38 39 arrays = registerdPairs.keySet().toArray(); 40 } 41 42 protected void tearDown() throws Exception { 43 super.tearDown(); 44 45 synchronized (errors) { 46 if (errors.size() > 0) { 47 errors.clear(); 48 fail(); 49 } 50 } 51 } 52 53 static void addError(Throwable t) { 54 t.printStackTrace(); 55 synchronized (errors) { 56 errors.add(t); 57 } 58 } 59 60 public void testCache() { 61 Random r = new Random (); 62 for (int i = 0; i < 100000; i++) { 63 Object array = arrays[r.nextInt(arrays.length)]; 64 TCObject expected = (TCObject) registerdPairs.get(array); 65 assertEquals(expected, ArrayManager.getObject(array)); 66 } 67 } 68 69 public void testReplaceCachedNegative() { 70 List refs = new ArrayList (); 71 for (int i = 0; i < 50000; i++) { 72 Object array = new Object [] {}; 73 refs.add(array); 74 assertNull(ArrayManager.getObject(array)); 75 TCObject tco = new FakeTCObject(); 76 ArrayManager.register(array, tco); 77 assertEquals(tco, ArrayManager.getObject(array)); 78 assertEquals(tco, ArrayManager.getObject(array)); } 80 } 81 82 public void testThreadsNoGC() throws Exception { 83 testThreads(false); 84 } 85 86 public void testThreads() throws Exception { 87 testThreads(true); 88 } 89 90 private void testThreads(boolean withGC) throws Exception { 91 AddNew addNew = new AddNew(); 92 Thread adder = new Thread (addNew, "Adder"); 93 94 Query[] query = new Query[2]; 95 for (int i = 0; i < query.length; i++) { 96 query[i] = new Query(arrays, registerdPairs, withGC); 97 } 98 Thread [] queries = new Thread [query.length]; 99 for (int i = 0; i < queries.length; i++) { 100 queries[i] = new Thread (query[i]); 101 queries[i].setName("Query #" + i); 102 queries[i].start(); 103 } 104 105 adder.start(); 106 107 ThreadUtil.reallySleep(30000); 108 109 addNew.stop(); 110 adder.join(); 111 112 for (int i = 0; i < queries.length; i++) { 113 query[i].stop(); 114 } 115 for (int i = 0; i < queries.length; i++) { 116 queries[i].join(); 117 } 118 119 } 120 121 private static abstract class Base implements Runnable { 122 private volatile boolean stop = false; 123 private int count = 0; 124 125 public void run() { 126 try { 127 while (!stop) { 128 work(); 129 count++; 130 } 131 } catch (Throwable t) { 132 addError(t); 133 } finally { 134 System.err.println(Thread.currentThread().getName() + " made " + count + " loops"); 135 } 136 } 137 138 void stop() { 139 stop = true; 140 } 141 142 abstract void work() throws Throwable ; 143 } 144 145 private static class Query extends Base { 146 private final Random r = new Random (); 147 private final Map pairs; 148 private final Object [] arrays; 149 private final boolean withGC; 150 151 Query(Object [] arrays, Map pairs, boolean withGC) { 152 this.arrays = arrays; 153 this.pairs = pairs; 154 this.withGC = withGC; 155 } 156 157 void work() throws Throwable { 158 if (r.nextBoolean()) { 159 Object array = arrays[r.nextInt(arrays.length)]; 160 TCObject expect = (TCObject) pairs.get(array); 161 if (expect != ArrayManager.getObject(array)) { throw new AssertionError ("wrong mapping returned"); } 162 } else { 163 if (ArrayManager.getObject(new Object [] {}) != null) { throw new AssertionError ( 164 "found object for brand new array"); } 165 } 166 167 if (withGC && (System.currentTimeMillis() % 255) == 0) { 168 System.out.println(Thread.currentThread().getName() + " doing GC"); 169 System.gc(); 170 } 171 172 } 173 } 174 175 private class AddNew extends Base { 176 void work() { 177 Object newArray = new Object [] {}; 178 ArrayManager.getObject(newArray); 179 ArrayManager.register(newArray, new FakeTCObject()); 180 181 for (int i = 0; i < 10; i++) { 182 if (hashCode() == System.currentTimeMillis()) { 184 System.out.println("BONK -- This is harmless ;-)"); 185 } 186 } 187 188 } 189 } 190 191 private static class FakeTCObject implements TCObject { 192 193 public boolean autoLockingDisabled() { 194 throw new ImplementMe(); 195 } 196 197 public void booleanFieldChanged(String classname, String fieldname, boolean newValue, int index) { 198 throw new ImplementMe(); 199 } 200 201 public void byteFieldChanged(String classname, String fieldname, byte newValue, int index) { 202 throw new ImplementMe(); 203 } 204 205 public void charFieldChanged(String classname, String fieldname, char newValue, int index) { 206 throw new ImplementMe(); 207 } 208 209 public void clearReference(String fieldName) { 210 throw new ImplementMe(); 211 } 212 213 public int clearReferences(int toClear) { 214 throw new ImplementMe(); 215 } 216 217 public void dehydrate(DNAWriter writer) throws DNAException { 218 throw new ImplementMe(); 219 } 220 221 public void disableAutoLocking() { 222 throw new ImplementMe(); 223 } 224 225 public void doubleFieldChanged(String classname, String fieldname, double newValue, int index) { 226 throw new ImplementMe(); 227 } 228 229 public void floatFieldChanged(String classname, String fieldname, float newValue, int index) { 230 throw new ImplementMe(); 231 } 232 233 public boolean getAndResetNew() { 234 throw new ImplementMe(); 235 } 236 237 public String getFieldNameByOffset(long fieldOffset) { 238 throw new ImplementMe(); 239 } 240 241 public TLinkable getNext() { 242 throw new ImplementMe(); 243 } 244 245 public ObjectID getObjectID() { 246 throw new ImplementMe(); 247 } 248 249 public Object getPeerObject() { 250 throw new ImplementMe(); 251 } 252 253 public TLinkable getPrevious() { 254 throw new ImplementMe(); 255 } 256 257 public Object getResolveLock() { 258 throw new ImplementMe(); 259 } 260 261 public TCClass getTCClass() { 262 throw new ImplementMe(); 263 } 264 265 public long getVersion() { 266 throw new ImplementMe(); 267 } 268 269 public void hydrate(DNA from, boolean force) throws DNAException { 270 throw new ImplementMe(); 271 } 272 273 public void intFieldChanged(String classname, String fieldname, int newValue, int index) { 274 throw new ImplementMe(); 275 } 276 277 public boolean isNew() { 278 throw new ImplementMe(); 279 } 280 281 public boolean isShared() { 282 throw new ImplementMe(); 283 } 284 285 public void logicalInvoke(int method, String methodSignature, Object [] params) { 286 throw new ImplementMe(); 287 } 288 289 public void longFieldChanged(String classname, String fieldname, long newValue, int index) { 290 throw new ImplementMe(); 291 } 292 293 public void objectFieldChanged(String classname, String fieldname, Object newValue, int index) { 294 throw new ImplementMe(); 295 } 296 297 public void objectFieldChangedByOffset(String classname, long fieldOffset, Object newValue, int index) { 298 throw new ImplementMe(); 299 } 300 301 public void resolveAllReferences() { 302 throw new ImplementMe(); 303 } 304 305 public void resolveArrayReference(int index) { 306 throw new ImplementMe(); 307 } 308 309 public void resolveReference(String fieldName) { 310 throw new ImplementMe(); 311 } 312 313 public void setIsNew() { 314 throw new ImplementMe(); 315 } 316 317 public void setNext(TLinkable link) { 318 throw new ImplementMe(); 319 } 320 321 public void setPrevious(TLinkable link) { 322 throw new ImplementMe(); 323 } 324 325 public void setReference(String fieldName, ObjectID id) { 326 throw new ImplementMe(); 327 } 328 329 public void setValue(String fieldName, Object obj) { 330 throw new ImplementMe(); 331 } 332 333 public void setVersion(long version) { 334 throw new ImplementMe(); 335 } 336 337 public void shortFieldChanged(String classname, String fieldname, short newValue, int index) { 338 throw new ImplementMe(); 339 } 340 341 public boolean canEvict() { 342 throw new ImplementMe(); 343 } 344 345 public void clearAccessed() { 346 throw new ImplementMe(); 347 } 348 349 public void markAccessed() { 350 throw new ImplementMe(); 351 } 352 353 public boolean recentlyAccessed() { 354 throw new ImplementMe(); 355 } 356 357 public void objectArrayChanged(int startPos, Object [] array, int length) { 358 throw new ImplementMe(); 359 } 360 361 public void primitiveArrayChanged(int startPos, Object array, int length) { 362 throw new ImplementMe(); 363 } 364 365 public int accessCount(int factor) { 366 throw new ImplementMe(); 367 } 368 369 public void literalValueChanged(Object newValue, Object oldValue) { 370 throw new ImplementMe(); 371 } 372 373 public void setLiteralValue(Object newValue) { 374 throw new ImplementMe(); 375 } 376 377 public ArrayIndexOutOfBoundsException checkArrayIndex(int index) { 378 throw new ImplementMe(); 379 } 380 381 } 382 383 } 384 | Popular Tags |