1   /*
2    * Copyright 1999-2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.apache.commons.pool.impl;
18  
19  import junit.framework.TestCase;
20  import junit.framework.TestSuite;
21  
22  import org.apache.commons.pool.PoolableObjectFactory;
23  
24  import java.util.Arrays;
25  import java.util.HashMap;
26  
27  /***
28   * @author Dirk Verbeeck
29   * @version $Revision: 155430 $ $Date: 2005-02-26 08:13:28 -0500 (Sat, 26 Feb 2005) $
30   */
31  public class TestSoftRefOutOfMemory extends TestCase {
32      private SoftReferenceObjectPool pool;
33  
34      public TestSoftRefOutOfMemory(String testName) {
35          super(testName);
36      }
37  
38      public static TestSuite suite() {
39          return new TestSuite(TestSoftRefOutOfMemory.class);
40      }
41  
42      public void tearDown() throws Exception {
43          if (pool != null) {
44              pool.close();
45              pool = null;
46          }
47          System.gc();
48      }
49  
50      public void testOutOfMemory() throws Exception {
51          pool = new SoftReferenceObjectPool(new SmallPoolableObjectFactory());
52  
53          Object obj = pool.borrowObject();
54          assertEquals("1", obj);
55          pool.returnObject(obj);
56          obj = null;
57          
58          assertEquals(1, pool.getNumIdle());
59  
60          try {
61              HashMap map = new HashMap();
62  
63              for (int i = 0; i < 1000000; i++) {
64                  map.put(new Integer(i), new String("Fred Flintstone" + i));
65              }
66          } catch (OutOfMemoryError ex) {
67              
68          }
69          obj = pool.borrowObject();
70          assertEquals("2", obj);
71          pool.returnObject(obj);
72          obj = null;
73              
74          assertEquals(1, pool.getNumIdle());
75      }
76  
77      public void testOutOfMemory1000() throws Exception {
78          pool = new SoftReferenceObjectPool(new SmallPoolableObjectFactory());
79  
80          for (int i = 0 ; i < 1000 ; i++) {
81              pool.addObject();
82          }
83  
84          Object obj = pool.borrowObject();
85          assertEquals("1000", obj);
86          pool.returnObject(obj);
87          obj = null;
88          
89          assertEquals(1000, pool.getNumIdle());
90  
91          try {
92              HashMap map = new HashMap();
93  
94              for (int i = 0; i < 1000000; i++) {
95                  map.put(new Integer(i), new String("Fred Flintstone" + i));
96              }
97          }
98          catch (OutOfMemoryError ex) { }
99          
100         obj = pool.borrowObject();
101         assertEquals("1001", obj);
102         pool.returnObject(obj);
103         obj = null;
104             
105         assertEquals(1, pool.getNumIdle());
106     }
107 
108     public void testOutOfMemoryLarge() throws Exception {
109         pool = new SoftReferenceObjectPool(new LargePoolableObjectFactory(1000000));
110 
111         Object obj = pool.borrowObject();
112         assertTrue(((String)obj).startsWith("1."));
113         pool.returnObject(obj);
114         obj = null;
115         
116         assertEquals(1, pool.getNumIdle());
117 
118         try {
119             HashMap map = new HashMap();
120 
121             for (int i = 0; i < 1000000; i++) {
122                 map.put(new Integer(i), new String("Fred Flintstone" + i));
123             }
124         }
125         catch (OutOfMemoryError ex) { }
126         
127         obj = pool.borrowObject();
128         assertTrue(((String)obj).startsWith("2."));
129         pool.returnObject(obj);
130         obj = null;
131             
132         assertEquals(1, pool.getNumIdle());
133     }
134 
135     public void testOutOfMemoryKeepMap() throws Exception {
136         pool = new SoftReferenceObjectPool(new LargePoolableObjectFactory(1000000));
137 
138         Object obj = pool.borrowObject();
139         assertTrue(((String)obj).startsWith("1."));
140         pool.returnObject(obj);
141         obj = null;
142         
143         assertEquals(1, pool.getNumIdle());
144 
145         // allocate map outside try/catch block
146         HashMap map = new HashMap();
147         try {
148             for (int i = 0; i < 1000000; i++) {
149                 map.put(new Integer(i), new String("Fred Flintstone" + i));
150             }
151         }
152         catch (OutOfMemoryError ex) { }
153 
154         try {
155             obj = pool.borrowObject();
156             fail("Expected out of memory");
157         }
158         catch (OutOfMemoryError ex) { }
159     }
160 
161 
162     public static class SmallPoolableObjectFactory implements PoolableObjectFactory {
163         private int counter = 0;
164         
165         public Object makeObject() {
166             counter++;
167             return String.valueOf(counter);
168         }
169         public boolean validateObject(Object obj) {
170             return true;
171         }
172         public void activateObject(Object obj) { }
173         public void passivateObject(Object obj) { }
174         public void destroyObject(Object obj) { }
175     }
176 
177     public static class LargePoolableObjectFactory implements PoolableObjectFactory {
178         private String buffer;
179         private int counter = 0;
180         
181         public LargePoolableObjectFactory(int size) {
182             char[] data = new char[size];
183             Arrays.fill(data, '.');
184             buffer = new String(data);
185         }
186         
187         public Object makeObject() {
188             counter++;
189             return String.valueOf(counter) + buffer;
190         }
191         public boolean validateObject(Object obj) {
192             return true;
193         }
194         public void activateObject(Object obj) { }
195         public void passivateObject(Object obj) { }
196         public void destroyObject(Object obj) { }
197     }
198 }