Improve Pool
[aaf/authz.git] / cadi / core / src / test / java / org / onap / aaf / cadi / util / test / JU_Pool.java
1 /*******************************************************************************
2  * * org.onap.aaf
3  * * ===========================================================================
4  * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
5  * * ===========================================================================
6  * * Licensed under the Apache License, Version 2.0 (the "License");
7  * * you may not use this file except in compliance with the License.
8  * * You may obtain a copy of the License at
9  * *
10  *  *      http://www.apache.org/licenses/LICENSE-2.0
11  * *
12  *  * Unless required by applicable law or agreed to in writing, software
13  * * distributed under the License is distributed on an "AS IS" BASIS,
14  * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * * See the License for the specific language governing permissions and
16  * * limitations under the License.
17  * * ============LICENSE_END====================================================
18  * *
19  * *
20  ******************************************************************************/
21
22 package org.onap.aaf.cadi.util.test;
23
24 import static org.junit.Assert.*;
25
26 import java.util.ArrayList;
27 import java.util.List;
28
29 import static org.hamcrest.CoreMatchers.*;
30 import org.junit.*;
31 import org.onap.aaf.cadi.CadiException;
32 import org.onap.aaf.cadi.util.Log;
33 import org.onap.aaf.cadi.util.Pool;
34 import org.onap.aaf.cadi.util.Pool.*;
35
36 public class JU_Pool {
37
38     private class IntegerCreator implements Creator<Integer> {
39         private int current = 0;
40
41         @Override
42         public Integer create() {
43             return current++;
44         }
45
46         @Override
47         public void destroy(Integer t) {
48             t = 0;
49         }
50
51         @Override
52         public boolean isValid(Integer t) {
53             return (t & 0x1) == 0;
54         }
55
56         @Override
57         public void reuse(Integer t) {
58         }
59     }
60
61     // Used for CustomLogger Testing
62     private StringBuilder sb = new StringBuilder();
63
64     private class CustomLogger implements Log {
65         @Override
66         public void log(Log.Type type, Object... o) {
67             for (Object item : o) {
68                 sb.append(item.toString());
69             }
70         }
71     }
72
73     /**
74          * Enter variable amount in this order 
75          * 
76          *   count, used, max_range, max_objects
77          * @param intPool
78          * @param ints
79          */
80         private void check(Pool<Integer> intPool, int ... ints) {
81                 String rpt = intPool.toString();
82                 // Fallthrough on purpose, to process only the ints entered, but in the right order.
83                 switch(ints.length) {
84                         case 4:
85                         assertTrue(rpt.contains(String.format("max_objects(%d)", ints[3])));
86                         case 3:
87                         assertTrue(rpt.contains(String.format("max_range(%d)", ints[2])));
88                         case 2:
89                         assertTrue(rpt.contains(String.format("used(%d)", ints[1])));
90                         case 1:
91                                 assertTrue(rpt.contains(String.format("count(%d)", ints[0])));
92                 }
93         }
94
95         @Test
96     public void settings() throws CadiException {
97         Pool<Integer> intPool = new Pool<Integer>(new IntegerCreator());
98         check(intPool,0,0,Pool.MAX_RANGE,Pool.MAX_OBJECTS);
99
100         // Check MaxObjects, min is 0
101         intPool.setMaxObjects(-10);
102         check(intPool,0,0,Pool.MAX_RANGE,0);
103
104         intPool.setMaxObjects(10);
105         check(intPool,0,0,Pool.MAX_RANGE,10);
106
107         // Check MaxRange, min is 0
108         intPool.setMaxRange(-10);
109         check(intPool,0,0,0,10);
110
111         intPool.setMaxRange(2);
112         check(intPool,0,0,2,10);
113
114         // Validate Priming
115         intPool.prime(3);
116         check(intPool,3,3,2,10);
117         
118         // Drain 
119         intPool.drain();
120         check(intPool,0,0,2,10);
121     }
122     
123     @Test
124     public void range() throws CadiException {
125         Pool<Integer> intPool = new Pool<Integer>(new IntegerCreator());
126         intPool.setMaxRange(2); 
127         check(intPool,0,0,2);
128         
129         // Prime
130         intPool.prime(3);
131         check(intPool,3,3,2);
132         
133         // Using 3 leaves count (in Pool) and Used (by System) 3
134         List<Pooled<Integer>> using = new ArrayList<>();
135         for(int i=0;i<3;++i) {
136                 using.add(intPool.get());
137         }
138         check(intPool,0,3,2);
139
140         // Using 3 more creates more Objects, and uses immediately
141         for(int i=0;i<3;++i) {
142                 using.add(intPool.get());
143         }
144         check(intPool,0,6,2);
145         
146         // Clean out all Objects in possession, but there are 6 Objects not returned yet.
147         intPool.drain();
148         check(intPool,0,6,2);
149         
150         // Returning Objects 
151         for(Pooled<Integer> i : using)  {
152                 i.done();
153         }
154         
155         // Since Range is 2, keep only 2, and destroy the rest
156         check(intPool,2,2,2);
157
158         // Shutdown (helpful for stopping Services) involves turning off range
159         intPool.setMaxRange(0).drain();
160         check(intPool,0,0,0);
161     }
162     
163     @Test
164         public void tooManyObjects() throws CadiException {
165         /*
166          * It should be noted that "tooManyObjects" isn't enforced by the Pool, because Objects are not 
167          * tracked (other than used) once they leave the pool.  
168          * 
169          * It is information that using entities, like Thread Pools, can use to limit creations of expensive objects
170          */
171                 Pool<Integer> intPool = new Pool<Integer>(new IntegerCreator());
172                 intPool.setMaxObjects(10).setMaxRange(2);
173                 check(intPool,0,0,2,10);
174
175                 assertFalse(intPool.tooManyObjects());
176
177                 // Obtain up to maxium Objects
178                 List<Pooled<Integer>> using = new ArrayList<>();
179                 for(int i=0;i<10;++i) {
180                         using.add(intPool.get());
181                 }
182                 
183                 check(intPool,0,10,2,10);
184                 assertFalse(intPool.tooManyObjects());
185                 
186                 using.add(intPool.get());
187                 check(intPool,0,11,2,10);
188                 assertTrue(intPool.tooManyObjects());
189                 
190         // Returning Objects 
191         for(Pooled<Integer> i : using)  {
192                 i.done();
193         }
194         
195         // Returning Objects puts Pool back in range
196                 check(intPool,2,2,2,10);
197                 assertFalse(intPool.tooManyObjects());
198
199         }
200
201         @Test
202     public void bulkTest() throws CadiException {
203         Pool<Integer> intPool = new Pool<Integer>(new IntegerCreator());
204
205         intPool.prime(10);
206         // Remove all of the invalid items (in this case, odd numbers)
207         assertFalse(intPool.validate());
208
209         // Make sure we got them all
210         assertTrue(intPool.validate());
211
212         // Get an item from the pool
213         Pooled<Integer> gotten = intPool.get();
214         assertThat(gotten.content, is(0));
215
216         // finalize that item, then check the next one to make sure we actually purged
217         // the odd numbers
218         gotten = intPool.get();
219         assertThat(gotten.content, is(2));
220
221         intPool.drain();
222
223     }
224
225     @Test
226     public void loggingTest() {
227         Pool<Integer> intPool = new Pool<Integer>(new IntegerCreator());
228
229         // Log to Log.NULL for coverage
230         intPool.log(Log.Type.info,"Test log output");
231
232         intPool.setLogger(new CustomLogger());
233         intPool.log(Log.Type.info,"Test log output");
234
235         assertThat(sb.toString(), is("Test log output"));
236     }
237
238 }