001    package org.cocome.tradingsystem.systests.scenarios;
002    
003    import java.util.ArrayList;
004    import java.util.List;
005    import java.util.Random;
006    
007    import junit.framework.TestCase;
008    
009    import org.cocome.tradingsystem.systests.TestManager;
010    import org.cocome.tradingsystem.systests.interfaces.IBank;
011    import org.cocome.tradingsystem.systests.interfaces.ICashDesk;
012    import org.cocome.tradingsystem.systests.interfaces.IEnterprise;
013    import org.cocome.tradingsystem.systests.interfaces.IStorePC;
014    import org.cocome.tradingsystem.systests.interfaces.ITestDriver;
015    import org.cocome.tradingsystem.systests.util.GeneratedProduct;
016    import org.cocome.tradingsystem.systests.util.GeneratedStockItem;
017    import org.cocome.tradingsystem.systests.util.ProductGenerator;
018    import org.cocome.tradingsystem.systests.util.StockGenerator;
019    
020    /**
021     * This is the base class for all test scenarios. It prepares the system for
022     * testing and provides helper methods to simplify test setup and testing.
023     * 
024     * @author Benjamin Hummel
025     * @author Christian Pfaller
026     * @author $Author: hummel $
027     * @version $Rev: 64 $
028     * @levd.rating GREEN: 64
029     */
030    public abstract class TestScenarioBase extends TestCase {
031    
032            /** Random number generator used to generate seeds for other RNGs. */
033            protected final Random seedRng = new Random(42);
034    
035            /** The test driver used for this test. */
036            protected ITestDriver testDriver;
037    
038            /** The (globally unique) enterprise used. */
039            protected IEnterprise enterprise;
040    
041            /** Generator used for adding new products. */
042            protected ProductGenerator productGenerator;
043    
044            /** The list of stores. */
045            protected List<StoreWrapper> stores;
046    
047            /** The bank */
048            protected IBank bank;
049    
050            /** {@inheritDoc} */
051            @Override
052            protected void setUp() throws Exception {
053                    super.setUp();
054                    testDriver = TestManager.getInstance().createTestDriver();
055                    enterprise = testDriver.initializeSystem();
056    
057                    productGenerator = new ProductGenerator(seedRng.nextLong(), enterprise);
058                    stores = new ArrayList<StoreWrapper>();
059                    bank = testDriver.getBank();
060            }
061    
062            /**
063             * Copy the setup information from another scenario. This is used to
064             * initialize this class without actually creating new objects which is
065             * useful for concurrent testing where this is only the base for some tests.
066             */
067            protected void copySetup(TestScenarioBase otherBase) {
068                    this.testDriver = otherBase.testDriver;
069                    this.enterprise = otherBase.enterprise;
070                    this.productGenerator = otherBase.productGenerator;
071                    this.stores = otherBase.stores;
072                    this.bank = otherBase.bank;
073            }
074    
075            /**
076             * Creates a new store with the given number of cash lines and a generated
077             * stock.
078             */
079            protected StoreWrapper createStore(int numCashLines) throws Exception {
080                    StoreWrapper wrapper = new StoreWrapper(testDriver.createStore());
081                    wrapper.getStockGenerator().generateAll();
082                    for (int i = 0; i < numCashLines; ++i) {
083                            wrapper.createCashDesk();
084                    }
085    
086                    stores.add(wrapper);
087                    return wrapper;
088            }
089    
090            /** {@inheritDoc} */
091            @Override
092            protected void tearDown() throws Exception {
093                    testDriver.shutdownSystem();
094                    super.tearDown();
095            }
096    
097            /** Class holding a store and some management information. */
098            protected class StoreWrapper {
099    
100                    private final Random rng;
101    
102                    /** The store PC for the store. */
103                    private final IStorePC storePC;
104    
105                    /** The stock generator used for generator stock items. */
106                    private final StockGenerator stockGenerator;
107    
108                    /** The list of cash desks for this store. */
109                    private final List<ICashDesk> cashDesks = new ArrayList<ICashDesk>();
110    
111                    /**
112                     * Creates a new instance.
113                     * 
114                     * @param storePC
115                     *            the store PC for the store.
116                     */
117                    public StoreWrapper(IStorePC storePC) {
118                            this.rng = new Random();
119                            this.storePC = storePC;
120                            this.stockGenerator = new StockGenerator(seedRng.nextLong(),
121                                            storePC, productGenerator);
122                    }
123    
124                    /** Creates a new cash line for this store. */
125                    public void createCashDesk() throws Exception {
126                            cashDesks.add(testDriver.createCashDesk(storePC));
127                    }
128    
129                    /** Returns the number of cash desks for this store. */
130                    public int getNumberOfCashDesks() {
131                            return cashDesks.size();
132                    }
133    
134                    /** Returns the cash desk of the given index. */
135                    public ICashDesk getCashDesk(int i) {
136                            return cashDesks.get(i);
137                    }
138    
139                    /** Returns the stock generator used for generator stock items. */
140                    public StockGenerator getStockGenerator() {
141                            return stockGenerator;
142                    }
143    
144                    /** Returns the store PC for the store. */
145                    public IStorePC getStorePC() {
146                            return storePC;
147                    }
148    
149                    /** Returns a product which is ready for sale (amount in stock > 0) */
150                    public GeneratedProduct getProductReadyForSale() {
151                            List<GeneratedProduct> productsForSale = new ArrayList<GeneratedProduct>();
152                            for (int i = 0; i < getStockGenerator().getNumberOfStockItems(); i++) {
153                                    GeneratedStockItem stockItem = getStockGenerator()
154                                                    .getGeneratedStockItem(i);
155                                    GeneratedProduct product = stockItem.getProduct();
156                                    if (stockItem.getAmount() > 0
157                                                    && !productsForSale.contains(product)) {
158                                            productsForSale.add(product);
159                                    }
160                            }
161                            return productsForSale.get(rng.nextInt(productsForSale.size()));
162                    }
163    
164                    /** Returns a product which is low on stock (amount <= minAmount) */
165                    public GeneratedStockItem getItemLowOnStock() {
166                            List<GeneratedStockItem> itemsForSale = new ArrayList<GeneratedStockItem>();
167                            for (int i = 0; i < getStockGenerator().getNumberOfStockItems(); i++) {
168                                    GeneratedStockItem stockItem = getStockGenerator()
169                                                    .getGeneratedStockItem(i);
170                                    if (stockItem.getAmount() <= stockItem.getMinAmount()) {
171                                            itemsForSale.add(stockItem);
172                                    }
173                            }
174                            return itemsForSale.get(rng.nextInt(itemsForSale.size()));
175                    }
176    
177            }
178    
179    }