1 5 package com.tctest; 6 7 import org.apache.xmlbeans.XmlObject; 8 9 import com.tc.cluster.Cluster; 10 import com.tc.config.schema.NewCommonL2Config; 11 import com.tc.config.schema.NewSystemConfig; 12 import com.tc.config.schema.dynamic.BooleanConfigItem; 13 import com.tc.config.schema.dynamic.ConfigItem; 14 import com.tc.config.schema.dynamic.ConfigItemListener; 15 import com.tc.config.schema.dynamic.IntConfigItem; 16 import com.tc.config.schema.setup.ConfigurationSetupException; 17 import com.tc.config.schema.setup.L1TVSConfigurationSetupManager; 18 import com.tc.config.schema.setup.L2TVSConfigurationSetupManager; 19 import com.tc.config.schema.setup.TestTVSConfigurationSetupManagerFactory; 20 import com.tc.lang.StartupHelper; 21 import com.tc.lang.TCThreadGroup; 22 import com.tc.lang.ThrowableHandler; 23 import com.tc.lang.StartupHelper.StartupAction; 24 import com.tc.logging.TCLogging; 25 import com.tc.net.protocol.transport.NullConnectionPolicy; 26 import com.tc.object.BaseDSOTestCase; 27 import com.tc.object.DistributedObjectClient; 28 import com.tc.object.bytecode.MockClassProvider; 29 import com.tc.object.bytecode.NullManager; 30 import com.tc.object.bytecode.hook.impl.PreparedComponentsFromL2Connection; 31 import com.tc.object.config.DSOClientConfigHelper; 32 import com.tc.object.config.StandardDSOClientConfigHelper; 33 import com.tc.object.config.schema.NewDSOApplicationConfig; 34 import com.tc.object.config.schema.NewL2DSOConfig; 35 import com.tc.object.lockmanager.api.LockID; 36 import com.tc.object.lockmanager.api.LockLevel; 37 import com.tc.object.lockmanager.api.ThreadID; 38 import com.tc.object.lockmanager.impl.ClientLockManagerImpl; 39 import com.tc.objectserver.impl.DistributedObjectServer; 40 import com.tc.objectserver.lockmanager.api.DeadlockChain; 41 import com.tc.objectserver.lockmanager.api.DeadlockResults; 42 import com.tc.objectserver.managedobject.ManagedObjectStateFactory; 43 import com.tc.server.NullTCServerInfo; 44 import com.tc.util.concurrent.SetOnceFlag; 45 import com.tc.util.concurrent.ThreadUtil; 46 47 import java.io.InputStream ; 48 import java.util.ArrayList ; 49 import java.util.List ; 50 51 public class LockManagerSystemTest extends BaseDSOTestCase { 52 53 private static final boolean slow = true; 56 57 private DistributedObjectServer server; 58 private DistributedObjectClient client; 59 private ClientLockManagerImpl lockManager; 60 private TCThreadGroup group = new TCThreadGroup(new ThrowableHandler(TCLogging 61 .getLogger(DistributedObjectServer.class))); 62 63 static { 64 70 System.setProperty("org.terracotta.server.disableJmxConnector", "true"); 71 } 72 73 private class StartAction implements StartupAction { 74 private final L2TVSConfigurationSetupManager l2Manager; 75 76 StartAction(L2TVSConfigurationSetupManager l2manager) { 77 this.l2Manager = l2manager; 78 } 79 80 public void execute() throws Throwable { 81 server = new DistributedObjectServer(new ConfigOverride(l2Manager), 82 group, new NullConnectionPolicy(), 83 new NullTCServerInfo()); 84 server.start(); 85 } 86 } 87 88 public void setUp() throws Exception { 89 TestTVSConfigurationSetupManagerFactory factory = createDistributedConfigFactory(); 90 91 ManagedObjectStateFactory.disableSingleton(true); 92 L2TVSConfigurationSetupManager l2Manager = factory.createL2TVSConfigurationSetupManager(null); 93 94 new StartupHelper(group, new StartAction(l2Manager)).startUp(); 95 96 makeClientUsePort(server.getListenPort()); 97 98 L1TVSConfigurationSetupManager manager = super.createL1ConfigManager(); 99 DSOClientConfigHelper configHelper = new StandardDSOClientConfigHelper(manager); 100 101 PreparedComponentsFromL2Connection components = new PreparedComponentsFromL2Connection(manager); 102 103 client = new DistributedObjectClient(configHelper, new TCThreadGroup(new ThrowableHandler(TCLogging 104 .getLogger(DistributedObjectClient.class))), new MockClassProvider(), components, NullManager.getInstance(), new Cluster()); 105 client.start(); 106 107 lockManager = (ClientLockManagerImpl) client.getLockManager(); 108 } 109 110 protected void tearDown() { 111 if (client != null) { 112 client.stop(); 113 } 114 115 if (server != null) { 116 server.stop(); 117 } 118 } 119 120 public void testUpgradeDeadlock() throws Exception { 121 final LockID l1 = new LockID("1"); 122 123 final ThreadID tid1 = new ThreadID(1); 124 final ThreadID tid2 = new ThreadID(2); 125 126 lockManager.lock(l1, tid1, LockLevel.READ); 127 lockManager.lock(l1, tid2, LockLevel.READ); 128 129 Thread t1 = new Thread () { 130 public void run() { 131 LockManagerSystemTest.this.lockManager.lock(l1, tid1, LockLevel.WRITE); 132 } 133 }; 134 135 Thread t2 = new Thread () { 136 public void run() { 137 LockManagerSystemTest.this.lockManager.lock(l1, tid2, LockLevel.WRITE); 138 } 139 }; 140 141 t1.start(); 142 t2.start(); 143 144 t1.join(2000); 145 t2.join(2000); 146 147 assertTrue(t1.isAlive()); 148 assertTrue(t2.isAlive()); 149 150 final List deadlocks = new ArrayList (); 152 DeadlockResults results = new DeadlockResults() { 153 public void foundDeadlock(DeadlockChain chain) { 154 deadlocks.add(chain); 155 } 156 }; 157 158 server.getContext().getLockManager().scanForDeadlocks(results); 159 160 assertEquals(1, deadlocks.size()); 161 DeadlockChain chain = (DeadlockChain) deadlocks.remove(0); 162 163 ThreadID id1 = chain.getWaiter().getClientThreadID(); 164 LockID lid1 = chain.getWaitingOn(); 165 chain = chain.getNextLink(); 166 ThreadID id2 = chain.getWaiter().getClientThreadID(); 167 LockID lid2 = chain.getWaitingOn(); 168 169 assertEquals(id1, chain.getNextLink().getWaiter().getClientThreadID()); 170 171 assertEquals(lid1, l1); 172 assertEquals(lid2, l1); 173 assertEquals(lid1, lid2); 174 175 if (id1.equals(tid1)) { 176 assertEquals(id2, tid2); 177 } else { 178 assertEquals(id1, tid2); 179 } 180 181 } 182 183 private static void sleep(long amount) { 184 amount *= (slow ? 300 : 50); 185 ThreadUtil.reallySleep(amount); 186 } 187 188 public void testUpgrade() throws Exception { 189 final LockID l1 = new LockID("1"); 190 191 final ThreadID tid1 = new ThreadID(1); 192 final ThreadID tid2 = new ThreadID(2); 193 final ThreadID tid3 = new ThreadID(3); 194 195 final SetOnceFlag flag = new SetOnceFlag(); 196 lockManager.lock(l1, tid1, LockLevel.READ); 197 lockManager.lock(l1, tid2, LockLevel.READ); 198 lockManager.lock(l1, tid3, LockLevel.READ); 199 200 Thread t = new Thread () { 201 public void run() { 202 LockManagerSystemTest.this.lockManager.lock(l1, tid1, LockLevel.WRITE); 203 flag.set(); 204 } 205 }; 206 t.start(); 207 208 sleep(5); 209 assertFalse(flag.isSet()); 210 211 lockManager.unlock(l1, tid2); 212 sleep(5); 213 assertFalse(flag.isSet()); 214 215 lockManager.unlock(l1, tid3); 216 sleep(5); 217 assertTrue(flag.isSet()); 218 219 t.join(); 220 221 Thread secondReader = new Thread () { 222 public void run() { 223 System.out.println("Read requested !"); 224 LockManagerSystemTest.this.lockManager.lock(l1, tid2, LockLevel.READ); 225 System.out.println("Got Read !"); 226 } 227 }; 228 secondReader.start(); 229 230 Thread secondWriter = new Thread () { 231 public void run() { 232 System.out.println("Write requested !"); 233 LockManagerSystemTest.this.lockManager.lock(l1, tid3, LockLevel.WRITE); 234 System.out.println("Got Write !"); 235 } 236 }; 237 secondWriter.start(); 238 239 sleep(5); 240 lockManager.unlock(l1, tid1); 241 sleep(5); 242 secondReader.join(5000); 243 assertFalse(secondReader.isAlive()); 244 assertTrue(secondWriter.isAlive()); 245 246 lockManager.unlock(l1, tid1); 247 sleep(5); 248 assertTrue(secondWriter.isAlive()); 249 lockManager.unlock(l1, tid2); 250 secondWriter.join(60000); 251 assertFalse(secondWriter.isAlive()); 252 } 253 254 public void testBasic() throws Exception { 255 final LockID l1 = new LockID("1"); 256 final LockID l3 = new LockID("3"); 257 258 final ThreadID tid1 = new ThreadID(1); 259 final ThreadID tid2 = new ThreadID(2); 260 final ThreadID tid3 = new ThreadID(3); 261 final ThreadID tid4 = new ThreadID(4); 262 263 System.out.println("Asked for first lock"); 265 lockManager.lock(l1, tid1, LockLevel.WRITE); 266 267 System.out.println("Got first lock"); 268 269 lockManager.lock(l1, tid1, LockLevel.WRITE); 271 System.out.println("Got first lock again"); 272 273 final boolean[] done = new boolean[2]; 274 275 Thread t = new Thread () { 278 public void run() { 279 System.out.println("Asked for second lock"); 280 lockManager.lock(l1, tid2, LockLevel.WRITE); 281 System.out.println("Got second lock"); 282 done[0] = true; 283 } 284 }; 285 286 t.start(); 287 sleep(5); 288 assertFalse(done[0]); 289 lockManager.unlock(l1, tid1); 290 lockManager.unlock(l1, tid1); sleep(5); 292 assertTrue(done[0]); 294 lockManager.lock(l3, tid1, LockLevel.READ); 296 lockManager.lock(l3, tid2, LockLevel.READ); 297 lockManager.lock(l3, tid3, LockLevel.READ); 298 done[0] = false; 299 t = new Thread () { 300 public void run() { 301 System.out.println("Asking for write lock"); 302 lockManager.lock(l3, tid4, LockLevel.WRITE); 303 System.out.println("Got write lock"); 304 done[0] = true; 305 } 306 }; 307 t.start(); 308 sleep(5); 309 assertFalse(done[0]); 310 311 lockManager.unlock(l3, tid1); 312 sleep(5); 313 assertFalse(done[0]); 314 315 lockManager.unlock(l3, tid2); 316 sleep(5); 317 assertFalse(done[0]); 318 319 lockManager.unlock(l3, tid3); 320 sleep(5); 321 assertTrue(done[0]); 322 323 done[0] = false; 324 t = new Thread () { 325 public void run() { 326 System.out.println("Asking for read lock"); 327 lockManager.lock(l3, tid1, LockLevel.READ); 328 System.out.println("Got read lock"); 329 done[0] = true; 330 } 331 }; 332 t.start(); 333 334 done[1] = false; 335 t = new Thread () { 336 public void run() { 337 System.out.println("Asking for read lock"); 338 lockManager.lock(l3, tid2, LockLevel.READ); 339 System.out.println("Got read lock"); 340 done[1] = true; 341 } 342 }; 343 344 t.start(); 345 sleep(5); 346 assertFalse(done[0]); 347 assertFalse(done[1]); 348 lockManager.unlock(l3, tid4); 349 sleep(5); 350 assertTrue(done[0]); 351 assertTrue(done[1]); 352 lockManager.unlock(l3, tid1); 353 lockManager.unlock(l3, tid2); 354 } 355 356 private static class ConfigOverride implements L2TVSConfigurationSetupManager { 357 358 private final L2TVSConfigurationSetupManager realConfig; 359 360 ConfigOverride(L2TVSConfigurationSetupManager realConfig) { 361 this.realConfig = realConfig; 362 } 363 364 public String [] allCurrentlyKnownServers() { 365 return realConfig.allCurrentlyKnownServers(); 366 } 367 368 public String [] applicationNames() { 369 return realConfig.applicationNames(); 370 } 371 372 public NewCommonL2Config commonl2Config() { 373 return realConfig.commonl2Config(); 374 } 375 376 public NewCommonL2Config commonL2ConfigFor(String name) throws ConfigurationSetupException { 377 return realConfig.commonL2ConfigFor(name); 378 } 379 380 public String describeSources() { 381 return realConfig.describeSources(); 382 } 383 384 public NewDSOApplicationConfig dsoApplicationConfigFor(String applicationName) { 385 return realConfig.dsoApplicationConfigFor(applicationName); 386 } 387 388 public NewL2DSOConfig dsoL2Config() { 389 return new L2ConfigOverride(realConfig.dsoL2Config()); 390 } 391 392 public NewL2DSOConfig dsoL2ConfigFor(String name) throws ConfigurationSetupException { 393 return realConfig.dsoL2ConfigFor(name); 394 } 395 396 public InputStream rawConfigFile() { 397 return realConfig.rawConfigFile(); 398 } 399 400 public NewSystemConfig systemConfig() { 401 return realConfig.systemConfig(); 402 } 403 404 private static class L2ConfigOverride implements NewL2DSOConfig { 405 406 private final NewL2DSOConfig config; 407 408 public L2ConfigOverride(NewL2DSOConfig config) { 409 this.config = config; 410 } 411 412 public void changesInItemForbidden(ConfigItem item) { 413 config.changesInItemForbidden(item); 414 } 415 416 public void changesInItemIgnored(ConfigItem item) { 417 config.changesInItemIgnored(item); 418 } 419 420 public IntConfigItem clientReconnectWindow() { 421 return config.clientReconnectWindow(); 422 } 423 424 public BooleanConfigItem garbageCollectionEnabled() { 425 return config.garbageCollectionEnabled(); 426 } 427 428 public IntConfigItem garbageCollectionInterval() { 429 return config.garbageCollectionInterval(); 430 } 431 432 public BooleanConfigItem garbageCollectionVerbose() { 433 return config.garbageCollectionVerbose(); 434 } 435 436 public IntConfigItem listenPort() { 437 return new IntConfigItem() { 438 public int getInt() { 439 return 0; 440 } 441 442 public void addListener(ConfigItemListener changeListener) { 443 } 445 446 public Object getObject() { 447 return new Integer (0); 448 } 449 450 public void removeListener(ConfigItemListener changeListener) { 451 } 453 }; 454 } 455 456 public ConfigItem persistenceMode() { 457 return config.persistenceMode(); 458 } 459 460 public XmlObject getBean() { 461 return config.getBean(); 462 } 463 464 } 465 466 } 467 468 } 469
| Popular Tags
|