001: /*
002: * Copyright 1999-2004 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.apache.commons.pool.impl;
018:
019: import java.util.BitSet;
020: import java.util.NoSuchElementException;
021: import java.util.List;
022: import java.util.ArrayList;
023: import java.util.Arrays;
024:
025: import junit.framework.Test;
026: import junit.framework.TestSuite;
027:
028: import org.apache.commons.pool.ObjectPool;
029: import org.apache.commons.pool.PoolableObjectFactory;
030: import org.apache.commons.pool.TestObjectPool;
031:
032: /**
033: * @author Rodney Waldhoff
034: * @author Dirk Verbeeck
035: * @version $Revision: 383290 $ $Date: 2006-03-05 02:00:15 -0500 (Sun, 05 Mar 2006) $
036: */
037: public class TestStackObjectPool extends TestObjectPool {
038: public TestStackObjectPool(String testName) {
039: super (testName);
040: }
041:
042: public static Test suite() {
043: return new TestSuite(TestStackObjectPool.class);
044: }
045:
046: protected ObjectPool makeEmptyPool(int mincap) {
047: return new StackObjectPool(new SimpleFactory());
048: }
049:
050: protected Object getNthObject(int n) {
051: return String.valueOf(n);
052: }
053:
054: public void testIdleCap() throws Exception {
055: ObjectPool pool = makeEmptyPool(8);
056: Object[] active = new Object[100];
057: for (int i = 0; i < 100; i++) {
058: active[i] = pool.borrowObject();
059: }
060: assertEquals(100, pool.getNumActive());
061: assertEquals(0, pool.getNumIdle());
062: for (int i = 0; i < 100; i++) {
063: pool.returnObject(active[i]);
064: assertEquals(99 - i, pool.getNumActive());
065: assertEquals((i < 8 ? i + 1 : 8), pool.getNumIdle());
066: }
067: }
068:
069: public void testPoolWithNullFactory() throws Exception {
070: ObjectPool pool = new StackObjectPool(10);
071: for (int i = 0; i < 10; i++) {
072: pool.returnObject(new Integer(i));
073: }
074: for (int j = 0; j < 3; j++) {
075: Integer[] borrowed = new Integer[10];
076: BitSet found = new BitSet();
077: for (int i = 0; i < 10; i++) {
078: borrowed[i] = (Integer) (pool.borrowObject());
079: assertNotNull(borrowed);
080: assertTrue(!found.get(borrowed[i].intValue()));
081: found.set(borrowed[i].intValue());
082: }
083: for (int i = 0; i < 10; i++) {
084: pool.returnObject(borrowed[i]);
085: }
086: }
087: pool.invalidateObject(pool.borrowObject());
088: pool.invalidateObject(pool.borrowObject());
089: pool.clear();
090: }
091:
092: public void testBorrowFromEmptyPoolWithNullFactory()
093: throws Exception {
094: ObjectPool pool = new StackObjectPool();
095: try {
096: pool.borrowObject();
097: fail("Expected NoSuchElementException");
098: } catch (NoSuchElementException e) {
099: // expected
100: }
101: }
102:
103: public void testSetFactory() throws Exception {
104: ObjectPool pool = new StackObjectPool();
105: try {
106: pool.borrowObject();
107: fail("Expected NoSuchElementException");
108: } catch (NoSuchElementException e) {
109: // expected
110: }
111: pool.setFactory(new SimpleFactory());
112: Object obj = pool.borrowObject();
113: assertNotNull(obj);
114: pool.returnObject(obj);
115: }
116:
117: public void testCantResetFactoryWithActiveObjects()
118: throws Exception {
119: ObjectPool pool = new StackObjectPool();
120: pool.setFactory(new SimpleFactory());
121: Object obj = pool.borrowObject();
122: assertNotNull(obj);
123:
124: try {
125: pool.setFactory(new SimpleFactory());
126: fail("Expected IllegalStateException");
127: } catch (IllegalStateException e) {
128: // expected
129: }
130: }
131:
132: public void testCanResetFactoryWithoutActiveObjects()
133: throws Exception {
134: ObjectPool pool = new StackObjectPool();
135: {
136: pool.setFactory(new SimpleFactory());
137: Object obj = pool.borrowObject();
138: assertNotNull(obj);
139: pool.returnObject(obj);
140: }
141: {
142: pool.setFactory(new SimpleFactory());
143: Object obj = pool.borrowObject();
144: assertNotNull(obj);
145: pool.returnObject(obj);
146: }
147: }
148:
149: public void testBorrowWithSometimesInvalidObjects()
150: throws Exception {
151: ObjectPool pool = new StackObjectPool(20);
152: pool.setFactory(new PoolableObjectFactory() {
153: // factory makes Integer objects
154: int counter = 0;
155:
156: public Object makeObject() {
157: return new Integer(counter++);
158: }
159:
160: public void destroyObject(Object obj) {
161: }
162:
163: public boolean validateObject(Object obj) {
164: // only odd objects are valid
165: if (obj instanceof Integer) {
166: return ((((Integer) obj).intValue() % 2) == 1);
167: } else {
168: return false;
169: }
170: }
171:
172: public void activateObject(Object obj) {
173: }
174:
175: public void passivateObject(Object obj) {
176: if (obj instanceof Integer) {
177: if ((((Integer) obj).intValue() % 3) == 0) {
178: throw new RuntimeException("Couldn't passivate");
179: }
180: } else {
181: throw new RuntimeException("Couldn't passivate");
182: }
183: }
184: });
185:
186: Object[] obj = new Object[10];
187: for (int i = 0; i < 10; i++) {
188: obj[i] = pool.borrowObject();
189: assertEquals("Each time we borrow, get one more active.",
190: i + 1, pool.getNumActive());
191:
192: }
193: for (int i = 0; i < 10; i++) {
194: pool.returnObject(obj[i]);
195: assertEquals("Each time we borrow, get one less active.",
196: 9 - i, pool.getNumActive());
197: }
198: assertEquals(7, pool.getNumIdle());
199: }
200:
201: public void testBorrowReturnWithSometimesInvalidObjects()
202: throws Exception {
203: ObjectPool pool = new StackObjectPool(20);
204:
205: class TestingPoolableObjectFactory implements
206: PoolableObjectFactory {
207: // factory makes Integer objects
208: int counter = 0;
209: boolean reject = false;
210:
211: public Object makeObject() {
212: return new Integer(counter++);
213: }
214:
215: public void destroyObject(Object obj) {
216: }
217:
218: public boolean validateObject(Object obj) {
219: if (reject) {
220: // only odd objects are valid
221: if (obj instanceof Integer) {
222: return ((((Integer) obj).intValue() % 2) == 1);
223: } else {
224: return false;
225: }
226: } else {
227: return true;
228: }
229:
230: }
231:
232: public void activateObject(Object obj) {
233: }
234:
235: public void passivateObject(Object obj) {
236: if (obj instanceof Integer) {
237: if ((((Integer) obj).intValue() % 3) == 0) {
238: throw new RuntimeException("Couldn't passivate");
239: }
240: } else {
241: throw new RuntimeException("Couldn't passivate");
242: }
243: }
244: }
245: ;
246:
247: TestingPoolableObjectFactory factory = new TestingPoolableObjectFactory();
248:
249: pool.setFactory(factory);
250:
251: Object[] obj = new Object[10];
252: for (int i = 0; i < 10; i++) {
253: obj[i] = pool.borrowObject();
254: assertEquals("Each time we borrow, get one more active.",
255: i + 1, pool.getNumActive());
256:
257: }
258:
259: // now reject even numbers
260: factory.reject = true;
261:
262: for (int i = 0; i < 10; i++) {
263: pool.returnObject(obj[i]);
264: assertEquals("Each time we borrow, get one less active.",
265: 9 - i, pool.getNumActive());
266: }
267: assertEquals(3, pool.getNumIdle());
268: }
269:
270: public void testVariousConstructors() throws Exception {
271: {
272: StackObjectPool pool = new StackObjectPool();
273: assertNotNull(pool);
274: }
275: {
276: StackObjectPool pool = new StackObjectPool(10);
277: assertNotNull(pool);
278: }
279: {
280: StackObjectPool pool = new StackObjectPool(10, 5);
281: assertNotNull(pool);
282: }
283: {
284: StackObjectPool pool = new StackObjectPool(null);
285: assertNotNull(pool);
286: }
287: {
288: StackObjectPool pool = new StackObjectPool(null, 10);
289: assertNotNull(pool);
290: }
291: {
292: StackObjectPool pool = new StackObjectPool(null, 10, 5);
293: assertNotNull(pool);
294: }
295: }
296:
297: private final List destroyed = new ArrayList();
298:
299: public void testReturnObjectDiscardOrder() throws Exception {
300: // setup
301: // We need a factory that tracks what was discarded.
302: PoolableObjectFactory pof = new PoolableObjectFactory() {
303: int i = 0;
304:
305: public Object makeObject() throws Exception {
306: return new Integer(i++);
307: }
308:
309: public void destroyObject(Object obj) throws Exception {
310: destroyed.add(obj);
311: }
312:
313: public boolean validateObject(Object obj) {
314: return obj instanceof Integer;
315: }
316:
317: public void activateObject(Object obj) throws Exception {
318: }
319:
320: public void passivateObject(Object obj) throws Exception {
321: }
322: };
323: ObjectPool pool = new StackObjectPool(pof, 3);
324:
325: // borrow more objects than the pool can hold
326: Integer i0 = (Integer) pool.borrowObject();
327: Integer i1 = (Integer) pool.borrowObject();
328: Integer i2 = (Integer) pool.borrowObject();
329: Integer i3 = (Integer) pool.borrowObject();
330:
331: // tests
332: // return as many as the pool will hold.
333: pool.returnObject(i0);
334: pool.returnObject(i1);
335: pool.returnObject(i2);
336:
337: // the pool should now be full.
338: assertEquals(
339: "No returned objects should have been destroyed yet.",
340: 0, destroyed.size());
341:
342: // cause the pool to discard a returned object.
343: pool.returnObject(i3);
344: assertEquals("One object should have been destroyed.", 1,
345: destroyed.size());
346:
347: // check to see what object was destroyed
348: Integer d = (Integer) destroyed.get(0);
349: assertEquals(
350: "Destoryed objects should have the stalest object.",
351: i0, d);
352: }
353:
354: private List testFactorySequenceStates = new ArrayList(5);
355:
356: public void testFactorySequence() throws Exception {
357: // setup
358: // We need a factory that tracks method call sequence.
359: PoolableObjectFactory pof = new PoolableObjectFactory() {
360: public Object makeObject() throws Exception {
361: testFactorySequenceStates.add("makeObject");
362: return new Object();
363: }
364:
365: public void activateObject(Object obj) throws Exception {
366: testFactorySequenceStates.add("activateObject");
367: }
368:
369: public boolean validateObject(Object obj) {
370: testFactorySequenceStates.add("validateObject");
371: return true;
372: }
373:
374: public void passivateObject(Object obj) throws Exception {
375: testFactorySequenceStates.add("passivateObject");
376: }
377:
378: public void destroyObject(Object obj) throws Exception {
379: testFactorySequenceStates.add("destroyObject");
380: }
381: };
382:
383: ObjectPool pool = new StackObjectPool(pof, 1);
384:
385: // check the order in which the factory is called during borrow
386: testFactorySequenceStates.clear();
387: Object o = pool.borrowObject();
388: List desiredSequence = Arrays.asList(new String[] {
389: "makeObject", "activateObject", "validateObject" });
390: assertEquals("Wrong sequence", desiredSequence,
391: testFactorySequenceStates);
392:
393: // check the order in which the factory is called when returning an object
394: testFactorySequenceStates.clear();
395: pool.returnObject(o);
396: desiredSequence = Arrays.asList(new String[] {
397: "validateObject", "passivateObject" });
398: assertEquals("Wrong sequence", desiredSequence,
399: testFactorySequenceStates);
400:
401: // check the order in which the factory is called during borrow again
402: testFactorySequenceStates.clear();
403: o = pool.borrowObject();
404: desiredSequence = Arrays.asList(new String[] {
405: "activateObject", "validateObject" });
406: assertEquals("Wrong sequence", desiredSequence,
407: testFactorySequenceStates);
408:
409: // check the order in which the factory is called when invalidating an object
410: testFactorySequenceStates.clear();
411: pool.invalidateObject(o);
412: desiredSequence = Arrays
413: .asList(new String[] { "destroyObject" });
414: assertEquals("Wrong sequence", desiredSequence,
415: testFactorySequenceStates);
416: }
417:
418: static class SimpleFactory implements PoolableObjectFactory {
419: int counter = 0;
420:
421: public Object makeObject() {
422: return String.valueOf(counter++);
423: }
424:
425: public void destroyObject(Object obj) {
426: }
427:
428: public boolean validateObject(Object obj) {
429: return true;
430: }
431:
432: public void activateObject(Object obj) {
433: }
434:
435: public void passivateObject(Object obj) {
436: }
437: }
438:
439: protected boolean isLifo() {
440: return true;
441: }
442:
443: protected boolean isFifo() {
444: return false;
445: }
446: }
|