1 22 package org.jboss.test.marathon.test; 23 24 import java.rmi.RemoteException ; 25 import java.rmi.ServerException ; 26 import java.util.Collection ; 27 import java.util.Iterator ; 28 import java.util.List ; 29 import java.util.Random ; 30 31 import javax.ejb.CreateException ; 32 import javax.ejb.FinderException ; 33 import javax.naming.Context ; 34 import javax.naming.InitialContext ; 35 import javax.naming.NamingException ; 36 import javax.transaction.TransactionRolledbackException ; 37 38 import org.jboss.test.banknew.interfaces.AccountData; 39 import org.jboss.test.banknew.interfaces.AccountSession; 40 import org.jboss.test.banknew.interfaces.AccountSessionHome; 41 import org.jboss.test.banknew.interfaces.BankData; 42 import org.jboss.test.banknew.interfaces.BankSession; 43 import org.jboss.test.banknew.interfaces.BankSessionHome; 44 import org.jboss.test.banknew.interfaces.Constants; 45 import org.jboss.test.banknew.interfaces.CustomerData; 46 import org.jboss.test.banknew.interfaces.CustomerSession; 47 import org.jboss.test.banknew.interfaces.CustomerSessionHome; 48 import org.jboss.test.banknew.interfaces.TellerSession; 49 import org.jboss.test.banknew.interfaces.TellerSessionHome; 50 51 import junit.framework.Test; 52 import junit.framework.TestCase; 53 import junit.framework.TestSuite; 54 55 import org.jboss.util.deadlock.ApplicationDeadlockException; 56 import org.jboss.test.JBossTestCase; 57 58 import org.jboss.logging.Logger; 59 60 69 public class BankMarathonTestCase 70 extends JBossTestCase 71 { 72 74 public static final int DEFAULT_DURATION = Constants.ONE_DAY; 76 private static final int INITIAL_NUMBER_OF_CUSTOMERS = 100; 78 80 private volatile int mCount; 81 private volatile Exception mException; 82 private volatile boolean mExit = false; 83 84 private Context mContext; 85 private BankSession mBankSession = null; 86 public int mCustomerCount = INITIAL_NUMBER_OF_CUSTOMERS; 87 88 90 public static Test suite() throws Exception { 91 return getDeploySetup( BankMarathonTestCase.class, "banknew.jar" ); 92 } 93 94 public BankMarathonTestCase( String pName ) { 96 super( pName ); 97 log.debug( "create test case with name: " + pName ); 98 } 99 100 102 105 public void testEnvironment() 106 throws Exception 107 { 108 log.debug( "testEnvironment(), start" ); 110 111 BankSessionHome lBankHome = (BankSessionHome) mContext.lookup( BankSessionHome.JNDI_NAME ); 112 CustomerSessionHome lCustomerHome = (CustomerSessionHome) mContext.lookup( CustomerSessionHome.JNDI_NAME ); 113 AccountSessionHome lAccountHome = (AccountSessionHome) mContext.lookup( AccountSessionHome.JNDI_NAME ); 114 TellerSessionHome lTellerHome = (TellerSessionHome) mContext.lookup( TellerSessionHome.JNDI_NAME ); 115 116 BankSession lBank = lBankHome.create(); 118 CustomerSession lCustomer = lCustomerHome.create(); 119 AccountSession lAccount = lAccountHome.create(); 120 TellerSession lTeller = lTellerHome.create(); 121 122 BankData lBankData = lBank.createBank( "Andy's TestBank", "12345 XMass Avenue, New JBoss, GA" ); 124 125 CustomerData lCustomerData = lTeller.createCustomer( lBankData.getId(), "One", 100 ); 128 CustomerData lCustomerData2 = lTeller.getCustomer( lCustomerData.getId() ); 129 Collection lCustomers = lTeller.getCustomers( lBankData.getId() ); 130 131 AccountData lAccountData = lTeller.createAccount( lCustomerData.getId(), Constants.SAVING, 150 ); 132 AccountData lAccountData2 = lTeller.getAccount( lCustomerData.getId(), Constants.SAVING ); 133 AccountData lAccountData3 = lTeller.getAccount( lAccountData.getId() ); 134 AccountData lAccountData4 = lTeller.getAccount( lCustomerData.getId(), Constants.CHECKING ); 135 Collection lAccounts = lTeller.getAccounts( lCustomerData.getId() ); 136 137 lTeller.deposit( lAccountData4.getId(), 75 ); 138 lTeller.withdraw( lAccountData3.getId(), 63 ); 139 lTeller.transfer( lAccountData4.getId(), lAccountData3.getId(), 52 ); 140 141 lTeller.removeAccount( lAccountData4.getId() ); 142 lTeller.removeAccount( lAccountData.getId() ); 143 lTeller.removeCustomer( lCustomerData.getId() ); 144 145 lBank.removeBank( lBankData.getId() ); 146 log.debug( "testEnvironment() ends" ); 147 } 148 149 170 public void testMarathon() 171 throws Exception 172 { 173 log.debug( "testMarathon(), start" ); 174 setUp(); 176 setupBank(); 178 179 mCount = getThreadCount(); 180 mExit = false; 181 log.debug( "testMarathon(), start marathon, " + getThreadCount() + " threads" ); 182 183 long lStart = System.currentTimeMillis(); 184 185 for( int i = 0; i < getThreadCount(); i++ ) { 186 Thread.sleep( 100 ); 187 log.debug( "testMarathon(), create new thread #: " + i ); 188 new Thread ( 189 new RegularTeller( i ) 190 ).start(); 191 if( mException != null ) { 192 break; 194 } 195 } 196 197 int lMinutes = (int) ( getDuration() / ( Constants.ONE_MINUTE ) ) + 201 ( getDuration() % ( Constants.ONE_MINUTE ) == 0 ? 0 : 1 ); log.debug( "Test runs for: " + lMinutes + " minutes" ); 203 for( int i = 0; i < lMinutes; i++ ) { 207 log.debug( "Sleep for one minute" ); 208 Thread.sleep( Constants.ONE_MINUTE ); 209 log.debug( "------------------------------------------------------------------------" ); 210 log.debug( "Awake after a sleep for one minute ( " + ( lMinutes - i ) + " minutes left" ); 211 log.debug( "------------------------------------------------------------------------" ); 212 if( mException != null || mCount == 0 ) { 213 break; 215 } 216 } 217 mExit = true; while( mCount > 0 ) { log.debug( "testMarathon(), thread count: " + mCount + ", release lock" ); 220 Thread.sleep( Constants.ONE_SECOND ); } 222 223 long lEnd = System.currentTimeMillis(); 224 225 log.info( "testMarathon(), time balance" ); 226 log.info( 227 "testMarathon(), total time test was running: " + 228 ( ( lEnd - lStart ) / Constants.ONE_MINUTE ) + " minutes." 229 ); 230 231 log.debug( "testMarathon(), ends" ); 232 if( mException != null ) { 233 throw mException; 235 } 236 } 237 238 protected void setUp() 239 throws Exception 240 { 241 log.debug( "setUp(), start" ); 242 mContext = new InitialContext (); 243 244 log.info("Remove accounts and customers"); 245 BankSessionHome lBankHome = (BankSessionHome) mContext.lookup( BankSessionHome.JNDI_NAME ); 246 CustomerSessionHome lCustomerHome = (CustomerSessionHome) mContext.lookup( CustomerSessionHome.JNDI_NAME ); 247 AccountSessionHome lAccountHome = (AccountSessionHome) mContext.lookup( AccountSessionHome.JNDI_NAME ); 248 BankSession lBankSession = lBankHome.create(); 249 Collection lBanks = lBankSession.getBanks(); 250 Iterator i = lBanks.iterator(); 251 while( i.hasNext() ) { 252 BankData lBank = (BankData) i.next(); 253 CustomerSession lCustomerSession = lCustomerHome.create(); 255 Collection lCustomers = lCustomerSession.getCustomers( lBank.getId() ); 256 Iterator j = lCustomers.iterator(); 257 while( j.hasNext() ) { 258 CustomerData lCustomer = (CustomerData) j.next(); 259 AccountSession lAccountSession = lAccountHome.create(); 261 Collection lAccounts = lAccountSession.getAccounts( lCustomer.getId() ); 262 Iterator k = lAccounts.iterator(); 263 while( k.hasNext() ) { 264 AccountData lAccount = (AccountData) k.next(); 265 lAccountSession.removeAccount( lAccount.getId() ); 266 } 267 lCustomerSession.removeCustomer( lCustomer.getId() ); 268 } 269 lBankSession.removeBank( lBank.getId() ); 270 } 271 log.debug( "setUp() ends" ); 272 } 273 274 protected int getDuration() { 275 return Integer.getInteger( 276 "jbosstest.duration", 277 DEFAULT_DURATION 278 ).intValue(); 279 } 280 281 public void setupBank() 282 throws Exception 283 { 284 log.debug( "setupBank(), create bank" ); 286 BankData lBank = getBankSession().createBank( "Andy's TestBank", "12345 XMass Avenue, New JBoss, GA" ); 287 for( int i = 0; i < INITIAL_NUMBER_OF_CUSTOMERS; i++ ) { 288 log.debug( "setupBank(), create customer #: " + i ); 289 CustomerData lCustomer = getCustomerSession().createCustomer( lBank.getId(), "test", 100 ); 290 } 291 } 292 293 private BankSession getBankSession() 294 throws CreateException , RemoteException , NamingException 295 { 296 if( mBankSession == null ) { 297 mBankSession = ( (BankSessionHome) mContext.lookup( BankSessionHome.JNDI_NAME ) ).create(); 298 } 299 return mBankSession; 300 } 301 302 private CustomerSession getCustomerSession() 303 throws CreateException , RemoteException , NamingException 304 { 305 return ( (CustomerSessionHome) mContext.lookup( CustomerSessionHome.JNDI_NAME ) ).create(); 306 } 307 308 private AccountSession getAccountSession() 309 throws CreateException , RemoteException , NamingException 310 { 311 return ( (AccountSessionHome) mContext.lookup( AccountSessionHome.JNDI_NAME ) ).create(); 312 } 313 314 class RegularTeller 315 implements Runnable 316 { 317 private int mId = 0; 318 private Logger mLog = null; 319 320 public RegularTeller( int pId ) { 321 mId = pId; 322 mLog = Logger.getLogger( this.getClass().getName() ); 323 } 324 325 public void run() { 326 int mAccountCount = 0; 327 Random lRandom = new Random (); 328 mLog.debug( "run(), id: " + mId + ", exit: " + mExit ); 329 330 try { 331 Thread.sleep( lRandom.nextInt( 2 * Constants.ONE_MINUTE ) ); 334 Collection lBanks = getBankSession().getBanks(); 336 BankData lBank = (BankData) lBanks.iterator().next(); 337 mLog.debug( "run(), tread id: " + mId + ", got bank: " + lBank ); 338 while( !mExit && mException == null ) { 340 CustomerData lCustomer = null; 341 mLog.debug( "run(), tread id: " + mId + ", create or find customer" ); 342 if( lRandom.nextInt( 100 ) < 10 ) { 343 mLog.debug( "run(), thread id: " + mId + ", create new customer" ); 344 lCustomer = getCustomerSession().createCustomer( lBank.getId(), "test", 100 ); 345 mCustomerCount++; 346 mLog.debug( "run(), thread id: " + mId + ", new customer: " + lCustomer ); 347 } else { 348 int i = 0; 349 while( lCustomer == null ) { 350 i++; 351 try { 352 int lCustomerId = lRandom.nextInt( mCustomerCount ); 353 mLog.debug( "run(), thread id: " + mId + ", look up customer, id: " + lCustomerId ); 354 lCustomer = getBankSession().getCustomer( "" + lCustomerId ); 355 mLog.debug( "run(), thread id: " + mId + ", found customer: " + lCustomer ); 356 } 357 catch( FinderException fe ) { 358 if( i > 100 ) { 359 throw fe; 360 } 361 } 362 } 363 } 364 mLog.debug( "run(), tread id: " + mId + ", create or find account" ); 365 List lAccounts = (List ) getCustomerSession().getAccounts( lCustomer.getId() ); 367 AccountData lAccount = null; 368 if( lRandom.nextInt( 100 ) < 5 ) { 369 try { 370 lAccount = getCustomerSession().createAccount( 371 lCustomer.getId(), lRandom.nextInt( 3 ), 123 372 ); 373 mLog.debug( "run(), thread id: " + mId + ", created account: " + lAccount ); 374 } 375 catch( CreateException ce ) { 376 } 377 } 378 if( lAccount == null ) { 379 lAccount = (AccountData) lAccounts.get( lRandom.nextInt( lAccounts.size() ) ); 380 mLog.debug( "run(), thread id: " + mId + ", got account: " + lAccount ); 381 } 382 if( lAccount == null ) { 383 throw new RuntimeException ( "Could not find an account" ); 384 } 385 int lLoops = lRandom.nextInt( 10 ); 387 for( int i = 0; i < lLoops; i++ ) { 388 int lSelection = lRandom.nextInt( 4 ); 389 mLog.debug( "run(), thread: " + mId + ", business selection : " + lSelection ); 390 switch( lSelection ) { 391 case 0: 392 if( lAccount.getBalance() > 50 ) { 394 getAccountSession().withdraw( lAccount.getId(), lRandom.nextInt( 50 ) ); 395 } 396 break; 397 case 1: 398 if( lAccounts.size() > 1 && lAccount.getBalance() > 50 ) { 399 AccountData lOtherAccount = null; 400 while( true ) { 401 lOtherAccount = (AccountData) lAccounts.get( lRandom.nextInt( lAccounts.size() ) ); 402 if( lOtherAccount.getType() != lAccount.getType() ) { 403 break; 405 } 406 } 407 while( true ) { 408 try { 409 getAccountSession().transfer( lAccount.getId(), lOtherAccount.getId(), lRandom.nextInt( 50 ) ); 410 break; 411 } 412 catch( ServerException se ) { 413 checkServerException( se ); 414 } 415 } 416 } 417 break; 418 case 2: 419 if( lAccount.getBalance() > 50 ) { 420 List lCustomers = (List ) getBankSession().getCustomers( lBank.getId() ); 421 if( lCustomers.size() > 1 ) { 422 CustomerData lOtherCustomer = null; 423 while( true ) { 424 lOtherCustomer = (CustomerData) lCustomers.get( lRandom.nextInt( lCustomers.size() ) ); 425 if( !lOtherCustomer.getId().equals( lCustomer.getId() ) ) { 426 break; 427 } 428 } 429 List lAccounts2 = (List ) getAccountSession().getAccounts( lOtherCustomer.getId() ); 430 if( lAccounts2.size() > 0 ) { 431 AccountData lOtherAccount = (AccountData) lAccounts2.get( lRandom.nextInt( lAccounts2.size() ) ); 432 while( true ) { 433 try { 434 getAccountSession().transfer( lAccount.getId(), lOtherAccount.getId(), lRandom.nextInt( 50 ) ); 435 break; 436 } 437 catch( ServerException se ) { 438 checkServerException( se ); 439 } 440 } 441 } 442 } 443 } 444 break; 445 case 3: 446 getAccountSession().deposit( lAccount.getId(), lRandom.nextInt( 100 ) ); 447 break; 448 } 449 mLog.debug( "run(), thread: " + mId + ", end business iteration, exit: " + mExit ); 450 if( mException != null || mExit ) { 452 break; 453 } 454 Thread.sleep( lRandom.nextInt( 2 * Constants.ONE_MINUTE ) ); 456 if( mException != null || mExit ) { 458 break; 459 } 460 } 461 } 462 } 463 catch( Exception e ) { 464 mLog.error( "run(), got exception", e ); 465 if( mException == null ) { 467 mException = e; 468 mExit = true; 470 } 471 } 472 473 mCount--; 474 mLog.debug( "run(), thread exists, only " + mCount + " active threads left" ); 475 } 476 477 private void checkServerException( ServerException pException ) 478 throws ServerException 479 { 480 Throwable lThrowable = pException.detail; 481 if( lThrowable instanceof ApplicationDeadlockException ) { 482 mLog.debug( "Found ADE in ServerException: " + pException ); 483 return; 484 } else 485 if( lThrowable instanceof TransactionRolledbackException ) { 486 TransactionRolledbackException lTRE = (TransactionRolledbackException ) lThrowable; 487 if( lTRE.detail instanceof ApplicationDeadlockException ) { 488 mLog.debug( "Found ADE in TransactionRolledbackException: " + lTRE ); 489 return; 490 } else 491 if( lTRE.detail instanceof TransactionRolledbackException ) { 492 TransactionRolledbackException lTRE2 = (TransactionRolledbackException ) lTRE.detail; 493 if( lTRE2.detail instanceof ApplicationDeadlockException ) { 494 mLog.debug( "Found ADE in 2. TransactionRolledbackException: " + lTRE2 ); 495 return; 496 } 497 } 498 } 499 throw pException; 500 } 501 502 } 503 } 504 | Popular Tags |