More license header updates to appc-common files
[appc.git] / appc-common / src / test / java / org / onap / appc / pool / PoolTest.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP : APPC
4  * ================================================================================
5  * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Copyright (C) 2017 Amdocs
8  * =============================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  * 
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  * 
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  * 
21  * ============LICENSE_END=========================================================
22  */
23
24
25
26 package org.onap.appc.pool;
27
28 import static org.junit.Assert.assertEquals;
29 import static org.junit.Assert.assertFalse;
30 import static org.junit.Assert.assertNotNull;
31 import static org.junit.Assert.assertNull;
32 import static org.junit.Assert.assertTrue;
33
34 import java.io.IOException;
35 import java.lang.reflect.InvocationTargetException;
36 import java.lang.reflect.Method;
37 import java.lang.reflect.Proxy;
38
39 import org.junit.Before;
40 import org.junit.Test;
41 import org.onap.appc.pool.Allocator;
42 import org.onap.appc.pool.Destructor;
43 import org.onap.appc.pool.Pool;
44 import org.onap.appc.pool.PoolDrainedException;
45 import org.onap.appc.pool.PoolExtensionException;
46 import org.onap.appc.pool.PoolSpecificationException;
47 import org.onap.appc.pool.*;
48
49
50 public class PoolTest implements Allocator<Testable>, Destructor<Testable> {
51
52     private Pool<Testable> pool;
53     private static final int MIN = 10;
54     private static final int MAX = 100;
55     private int index = 0;
56     private int destroyCount = 0;
57
58     /**
59      * Set up the test by allocating a pool with MIN-MAX size (bounded pool)
60      *
61      * @throws PoolSpecificationException
62      *             If the minimum size is less than 0, or if the max size is non-zero and less than the min size.
63      */
64     @Before
65     public void setup() throws PoolSpecificationException {
66         pool = new Pool<>(MIN, MAX);
67         index = 0;
68         destroyCount = 0;
69     }
70
71     /**
72      * Test that trying to construct a pool with a bad minimum throws an exception
73      *
74      * @throws PoolSpecificationException
75      *             If the minimum size is less than 0, or if the max size is non-zero and less than the min size.
76      */
77     @Test(expected = PoolSpecificationException.class)
78     public void testInvalidMinSize() throws PoolSpecificationException {
79         pool = new Pool<>(-1, MAX);
80     }
81
82     /**
83      * Test that trying to construct a pool with a bad maximum throws an exception
84      *
85      * @throws PoolSpecificationException
86      *             If the minimum size is less than 0, or if the max size is non-zero and less than the min size.
87      */
88     @Test(expected = PoolSpecificationException.class)
89     public void testInvalidMaxSize() throws PoolSpecificationException {
90         pool = new Pool<>(MIN, -1);
91     }
92
93     /**
94      * Test creation of a pool where max is less than min fails
95      *
96      * @throws PoolSpecificationException
97      *             If the minimum size is less than 0, or if the max size is non-zero and less than the min size.
98      */
99     @Test(expected = PoolSpecificationException.class)
100     public void testInvalidSizeRange() throws PoolSpecificationException {
101         pool = new Pool<>(MAX, MIN);
102     }
103
104     /**
105      * Test state
106      */
107     @Test
108     public void testMinPool() {
109         assertEquals(MIN, pool.getMinPool());
110     }
111
112     /**
113      * Test state
114      */
115     @Test
116     public void testMaxPool() {
117         assertEquals(MAX, pool.getMaxPool());
118     }
119
120     /**
121      * Test state
122      */
123     @Test
124     public void testAllocator() {
125         assertNull(pool.getAllocator());
126         pool.setAllocator(this);
127         assertNotNull(pool.getAllocator());
128     }
129
130     /**
131      * Test state
132      */
133     @Test
134     public void testDestructor() {
135         assertNull(pool.getDestructor());
136         pool.setDestructor(this);
137         assertNotNull(pool.getDestructor());
138     }
139
140     /**
141      * Test that we can allocate and release elements and that the pool maintains them in MRU order
142      *
143      * @throws PoolExtensionException
144      *             If the pool cannot be extended
145      * @throws PoolDrainedException
146      *             If the caller is trying to reserve an element from a drained pool
147      */
148     @Test
149     public void testAllocateAndRelease() throws PoolExtensionException, PoolDrainedException {
150         pool.setAllocator(this);
151
152         assertFalse(pool.isDrained());
153
154         /*
155          * Allocate three elements
156          */
157         Testable value1 = pool.reserve();
158         assertNotNull(value1);
159         assertEquals(Integer.valueOf(MIN - 1), value1.getId());
160         assertEquals(1, pool.getAllocatedSize());
161         assertEquals(MIN - 1, pool.getFreeSize());
162         assertEquals(1, pool.getAllocatedSize());
163
164         Testable value2 = pool.reserve();
165         assertNotNull(value2);
166         assertEquals(Integer.valueOf(MIN - 2), value2.getId());
167         assertEquals(2, pool.getAllocatedSize());
168         assertEquals(MIN - 2, pool.getFreeSize());
169         assertEquals(2, pool.getAllocatedSize());
170
171         Testable value3 = pool.reserve();
172         assertNotNull(value3);
173         assertEquals(Integer.valueOf(MIN - 3), value3.getId());
174         assertEquals(3, pool.getAllocatedSize());
175         assertEquals(MIN - 3, pool.getFreeSize());
176         assertEquals(3, pool.getAllocatedSize());
177
178         /*
179          * Now, release them in the order obtained
180          */
181         pool.release(value1);
182         pool.release(value2);
183         pool.release(value3);
184
185         assertEquals(0, pool.getAllocatedSize());
186         assertEquals(MIN, pool.getFreeSize());
187
188         /*
189          * Now, allocate them again, but their values should be reversed (3, 2, 1) representing the most recently used
190          * to the least recently used.
191          */
192         value1 = pool.reserve();
193         assertNotNull(value1);
194         assertEquals(Integer.valueOf(MIN - 3), value1.getId());
195
196         value2 = pool.reserve();
197         assertNotNull(value2);
198         assertEquals(Integer.valueOf(MIN - 2), value2.getId());
199
200         value3 = pool.reserve();
201         assertNotNull(value3);
202         assertEquals(Integer.valueOf(MIN - 1), value3.getId());
203     }
204
205     /**
206      * Test that we can trim the pool to a desired size
207      *
208      * @throws PoolExtensionException
209      *             If the pool cannot be extended
210      * @throws NoSuchMethodException
211      *             if a matching method is not found.
212      * @throws SecurityException
213      *             if the request is denied.
214      * @throws IllegalAccessException
215      *             if this Method object is enforcing Java language access control and the underlying method is
216      *             inaccessible.
217      * @throws IllegalArgumentException
218      *             if the method is an instance method and the specified object argument is not an instance of the class
219      *             or interface declaring the underlying method (or of a subclass or implementor thereof); if the number
220      *             of actual and formal parameters differ; if an unwrapping conversion for primitive arguments fails; or
221      *             if, after possible unwrapping, a parameter value cannot be converted to the corresponding formal
222      *             parameter type by a method invocation conversion.
223      * @throws InvocationTargetException
224      *             if the underlying method throws an exception.
225      * @throws PoolDrainedException
226      *             If the caller is trying to reserve an element from a drained pool
227      */
228     @SuppressWarnings("nls")
229     @Test
230     public void testTrim() throws PoolExtensionException, NoSuchMethodException, SecurityException,
231         IllegalAccessException, IllegalArgumentException, InvocationTargetException, PoolDrainedException {
232         pool.setAllocator(this);
233         int SIZE = 50;
234         Proxy[] array = new Proxy[SIZE];
235
236         assertEquals(0, pool.getAllocatedSize());
237         for (int i = 0; i < SIZE; i++) {
238             array[i] = (Proxy) pool.reserve();
239         }
240         assertEquals(SIZE, pool.getAllocatedSize());
241
242         for (int i = 0; i < SIZE; i++) {
243             pool.release((Testable) array[i]);
244         }
245         assertEquals(0, pool.getAllocatedSize());
246
247         assertEquals(SIZE, pool.getFreeSize());
248
249         Method trimMethod = Pool.class.getDeclaredMethod("trim", new Class[] {
250             Integer.TYPE
251         });
252         trimMethod.setAccessible(true);
253         trimMethod.invoke(pool, new Object[] {
254             SIZE - MIN
255         });
256
257         assertEquals(MIN, pool.getFreeSize());
258     }
259
260     /**
261      * Test that we can drain a pool containing a mix of free and allocated elements
262      *
263      * @throws PoolExtensionException
264      *             If the pool cannot be extended
265      * @throws PoolDrainedException
266      *             If the caller is trying to reserve an element from a drained pool
267      */
268     @Test
269     public void testDrain() throws PoolExtensionException, PoolDrainedException {
270         int SIZE = 50;
271         int FREE = 20;
272         int ALLOC = SIZE - FREE;
273
274         Proxy[] array = new Proxy[SIZE];
275         pool.setAllocator(this);
276         pool.setDestructor(this);
277
278         assertFalse(pool.isDrained());
279
280         assertEquals(0, pool.getAllocatedSize());
281         for (int i = 0; i < SIZE; i++) {
282             array[i] = (Proxy) pool.reserve();
283         }
284         assertEquals(SIZE, pool.getAllocatedSize());
285
286         for (int i = 0; i < FREE; i++) {
287             pool.release((Testable) array[i]);
288         }
289         assertEquals(ALLOC, pool.getAllocatedSize());
290         assertEquals(FREE, pool.getFreeSize());
291
292         pool.drain();
293         assertEquals(0, pool.getFreeSize());
294         assertEquals(0, pool.getAllocatedSize());
295         assertTrue(pool.isDrained());
296
297         assertEquals(SIZE, destroyCount);
298     }
299
300     /**
301      * @see org.onap.appc.pool.Destructor#destroy(java.io.Closeable, org.onap.appc.pool.Pool)
302      */
303     @Override
304     public void destroy(Testable obj, Pool<Testable> pool) {
305         destroyCount++;
306         try {
307             obj.close();
308         } catch (IOException e) {
309             e.printStackTrace();
310         }
311     }
312
313     /**
314      * @see org.onap.appc.pool.Allocator#allocate(org.onap.appc.pool.Pool)
315      */
316     @Override
317     public Testable allocate(Pool<Testable> pool) {
318         Testable e = new Element(index++);
319
320         return e;
321     }
322 }