2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
24 package org.openecomp.appc.pool;
26 import static org.junit.Assert.assertEquals;
27 import static org.junit.Assert.assertFalse;
28 import static org.junit.Assert.assertNotNull;
29 import static org.junit.Assert.assertNull;
30 import static org.junit.Assert.assertTrue;
32 import java.io.IOException;
33 import java.lang.reflect.InvocationTargetException;
34 import java.lang.reflect.Method;
35 import java.lang.reflect.Proxy;
37 import org.junit.Before;
38 import org.junit.Test;
39 import org.openecomp.appc.pool.Allocator;
40 import org.openecomp.appc.pool.Destructor;
41 import org.openecomp.appc.pool.Pool;
42 import org.openecomp.appc.pool.PoolDrainedException;
43 import org.openecomp.appc.pool.PoolExtensionException;
44 import org.openecomp.appc.pool.PoolSpecificationException;
45 import org.openecomp.appc.pool.*;
48 public class PoolTest implements Allocator<Testable>, Destructor<Testable> {
50 private Pool<Testable> pool;
51 private static final int MIN = 10;
52 private static final int MAX = 100;
53 private int index = 0;
54 private int destroyCount = 0;
57 * Set up the test by allocating a pool with MIN-MAX size (bounded pool)
59 * @throws PoolSpecificationException
60 * If the minimum size is less than 0, or if the max size is non-zero and less than the min size.
63 public void setup() throws PoolSpecificationException {
64 pool = new Pool<>(MIN, MAX);
70 * Test that trying to construct a pool with a bad minimum throws an exception
72 * @throws PoolSpecificationException
73 * If the minimum size is less than 0, or if the max size is non-zero and less than the min size.
75 @Test(expected = PoolSpecificationException.class)
76 public void testInvalidMinSize() throws PoolSpecificationException {
77 pool = new Pool<>(-1, MAX);
81 * Test that trying to construct a pool with a bad maximum throws an exception
83 * @throws PoolSpecificationException
84 * If the minimum size is less than 0, or if the max size is non-zero and less than the min size.
86 @Test(expected = PoolSpecificationException.class)
87 public void testInvalidMaxSize() throws PoolSpecificationException {
88 pool = new Pool<>(MIN, -1);
92 * Test creation of a pool where max is less than min fails
94 * @throws PoolSpecificationException
95 * If the minimum size is less than 0, or if the max size is non-zero and less than the min size.
97 @Test(expected = PoolSpecificationException.class)
98 public void testInvalidSizeRange() throws PoolSpecificationException {
99 pool = new Pool<>(MAX, MIN);
106 public void testMinPool() {
107 assertEquals(MIN, pool.getMinPool());
114 public void testMaxPool() {
115 assertEquals(MAX, pool.getMaxPool());
122 public void testAllocator() {
123 assertNull(pool.getAllocator());
124 pool.setAllocator(this);
125 assertNotNull(pool.getAllocator());
132 public void testDestructor() {
133 assertNull(pool.getDestructor());
134 pool.setDestructor(this);
135 assertNotNull(pool.getDestructor());
139 * Test that we can allocate and release elements and that the pool maintains them in MRU order
141 * @throws PoolExtensionException
142 * If the pool cannot be extended
143 * @throws PoolDrainedException
144 * If the caller is trying to reserve an element from a drained pool
147 public void testAllocateAndRelease() throws PoolExtensionException, PoolDrainedException {
148 pool.setAllocator(this);
150 assertFalse(pool.isDrained());
153 * Allocate three elements
155 Testable value1 = pool.reserve();
156 assertNotNull(value1);
157 assertEquals(Integer.valueOf(MIN - 1), value1.getId());
158 assertEquals(1, pool.getAllocatedSize());
159 assertEquals(MIN - 1, pool.getFreeSize());
160 assertEquals(1, pool.getAllocatedSize());
162 Testable value2 = pool.reserve();
163 assertNotNull(value2);
164 assertEquals(Integer.valueOf(MIN - 2), value2.getId());
165 assertEquals(2, pool.getAllocatedSize());
166 assertEquals(MIN - 2, pool.getFreeSize());
167 assertEquals(2, pool.getAllocatedSize());
169 Testable value3 = pool.reserve();
170 assertNotNull(value3);
171 assertEquals(Integer.valueOf(MIN - 3), value3.getId());
172 assertEquals(3, pool.getAllocatedSize());
173 assertEquals(MIN - 3, pool.getFreeSize());
174 assertEquals(3, pool.getAllocatedSize());
177 * Now, release them in the order obtained
179 pool.release(value1);
180 pool.release(value2);
181 pool.release(value3);
183 assertEquals(0, pool.getAllocatedSize());
184 assertEquals(MIN, pool.getFreeSize());
187 * Now, allocate them again, but their values should be reversed (3, 2, 1) representing the most recently used
188 * to the least recently used.
190 value1 = pool.reserve();
191 assertNotNull(value1);
192 assertEquals(Integer.valueOf(MIN - 3), value1.getId());
194 value2 = pool.reserve();
195 assertNotNull(value2);
196 assertEquals(Integer.valueOf(MIN - 2), value2.getId());
198 value3 = pool.reserve();
199 assertNotNull(value3);
200 assertEquals(Integer.valueOf(MIN - 1), value3.getId());
204 * Test that we can trim the pool to a desired size
206 * @throws PoolExtensionException
207 * If the pool cannot be extended
208 * @throws NoSuchMethodException
209 * if a matching method is not found.
210 * @throws SecurityException
211 * if the request is denied.
212 * @throws IllegalAccessException
213 * if this Method object is enforcing Java language access control and the underlying method is
215 * @throws IllegalArgumentException
216 * if the method is an instance method and the specified object argument is not an instance of the class
217 * or interface declaring the underlying method (or of a subclass or implementor thereof); if the number
218 * of actual and formal parameters differ; if an unwrapping conversion for primitive arguments fails; or
219 * if, after possible unwrapping, a parameter value cannot be converted to the corresponding formal
220 * parameter type by a method invocation conversion.
221 * @throws InvocationTargetException
222 * if the underlying method throws an exception.
223 * @throws PoolDrainedException
224 * If the caller is trying to reserve an element from a drained pool
226 @SuppressWarnings("nls")
228 public void testTrim() throws PoolExtensionException, NoSuchMethodException, SecurityException,
229 IllegalAccessException, IllegalArgumentException, InvocationTargetException, PoolDrainedException {
230 pool.setAllocator(this);
232 Proxy[] array = new Proxy[SIZE];
234 assertEquals(0, pool.getAllocatedSize());
235 for (int i = 0; i < SIZE; i++) {
236 array[i] = (Proxy) pool.reserve();
238 assertEquals(SIZE, pool.getAllocatedSize());
240 for (int i = 0; i < SIZE; i++) {
241 pool.release((Testable) array[i]);
243 assertEquals(0, pool.getAllocatedSize());
245 assertEquals(SIZE, pool.getFreeSize());
247 Method trimMethod = Pool.class.getDeclaredMethod("trim", new Class[] {
250 trimMethod.setAccessible(true);
251 trimMethod.invoke(pool, new Object[] {
255 assertEquals(MIN, pool.getFreeSize());
259 * Test that we can drain a pool containing a mix of free and allocated elements
261 * @throws PoolExtensionException
262 * If the pool cannot be extended
263 * @throws PoolDrainedException
264 * If the caller is trying to reserve an element from a drained pool
267 public void testDrain() throws PoolExtensionException, PoolDrainedException {
270 int ALLOC = SIZE - FREE;
272 Proxy[] array = new Proxy[SIZE];
273 pool.setAllocator(this);
274 pool.setDestructor(this);
276 assertFalse(pool.isDrained());
278 assertEquals(0, pool.getAllocatedSize());
279 for (int i = 0; i < SIZE; i++) {
280 array[i] = (Proxy) pool.reserve();
282 assertEquals(SIZE, pool.getAllocatedSize());
284 for (int i = 0; i < FREE; i++) {
285 pool.release((Testable) array[i]);
287 assertEquals(ALLOC, pool.getAllocatedSize());
288 assertEquals(FREE, pool.getFreeSize());
291 assertEquals(0, pool.getFreeSize());
292 assertEquals(0, pool.getAllocatedSize());
293 assertTrue(pool.isDrained());
295 assertEquals(SIZE, destroyCount);
299 * @see org.openecomp.appc.pool.Destructor#destroy(java.io.Closeable, org.openecomp.appc.pool.Pool)
302 public void destroy(Testable obj, Pool<Testable> pool) {
306 } catch (IOException e) {
312 * @see org.openecomp.appc.pool.Allocator#allocate(org.openecomp.appc.pool.Pool)
315 public Testable allocate(Pool<Testable> pool) {
316 Testable e = new Element(index++);