[RICPLT-1783] Add ValidateAndBuildRanLoadInformationKey | Fix dependencies | Reformat...
[ric-plt/nodeb-rnib.git] / common / rNibPool_test.go
1 //
2 // Copyright 2019 AT&T Intellectual Property
3 // Copyright 2019 Nokia
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //      http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16
17 package common
18
19 import (
20         "github.com/stretchr/testify/assert"
21         "sync"
22         "sync/atomic"
23         "testing"
24         "time"
25 )
26
27 var     max int32
28 var     counter int32
29 var poolGlob *Pool
30 type instance struct{}
31
32 func(instance) up(){
33         tmpc := atomic.AddInt32(&counter, 1)
34         swapped:= false
35         for !swapped {
36                 tmpm := atomic.LoadInt32(&max)
37                 if tmpc >tmpm {
38                         swapped = atomic.CompareAndSwapInt32(&max, tmpm, tmpc)
39                 } else {
40                         break
41                 }
42         }
43 }
44
45 func(instance) down(){
46         atomic.AddInt32(&counter, - 1)
47 }
48
49 func TestPoolMax(t *testing.T){
50         counter = 0
51         max = 0
52         validateMaxLimit(1, 1, t)
53         counter = 0
54         max = 0
55         validateMaxLimit(1, 2, t)
56         counter = 0
57         max = 0
58         validateMaxLimit(5, 10, t)
59 }
60
61 func validateMaxLimit(size int, iterations int, t *testing.T) {
62         poolGlob = NewPool(size, func() interface{} {
63                 inst := instance{}
64                 return inst
65         },
66                 func(obj interface{}) {
67                 },
68         )
69         group := sync.WaitGroup{}
70         for i := 0; i < iterations; i++ {
71                 go getPutInstance(group)
72         }
73         time.Sleep(time.Second)
74         group.Wait()
75         assert.Equal(t, int32(size), max)
76 }
77
78 func getPutInstance(group sync.WaitGroup) {
79         group.Add(1)
80         inst := poolGlob.Get().(instance)
81         inst.up()
82         time.Sleep(time.Millisecond*10)
83         inst.down()
84         poolGlob.Put(inst)
85         group.Done()
86 }
87
88 func TestNewPool(t *testing.T){
89         size := 5
90         pool := NewPool(size, func() interface{} {
91                 inst := instance{}
92                 return inst
93         },
94                 func(obj interface{}) {
95                 },
96         )
97         assert.NotNil(t, pool)
98         assert.NotNil(t, pool.New)
99         assert.NotNil(t, pool.Destroy)
100         assert.NotNil(t, pool.pool)
101         assert.Equal(t, cap(pool.pool), size, "the capacity of the pool should be " + string(size))
102 }
103
104 func TestGetCreated(t *testing.T) {
105         pool := NewPool(1, func() interface{} {
106                 inst := instance{}
107                 return inst
108         },
109                 func(obj interface{}) {
110                 },
111         )
112         pool.Get()
113         available, created := pool.Stats()
114         assert.Equal(t, 0, available, "number of available objects in the pool should be 0")
115         assert.Equal(t, 1, created, "number of created objects in the pool should be 1")
116         pool.Close()
117 }
118
119 func TestGetAndPut(t *testing.T) {
120         pool := NewPool(1, func() interface{} {
121                 inst := instance{}
122                 return inst
123         },
124                 func(obj interface{}) {
125                 },
126         )
127         pool.Put(pool.Get())
128         available, created := pool.Stats()
129         assert.Equal(t, 1, available, "number of available objects in the pool should be 1")
130         assert.Equal(t, 1, created, "number of created objects in the pool should be 1")
131         pool.Close()
132 }
133
134 func TestPutOutOfCapacity(t *testing.T) {
135         pool := NewPool(1, func() interface{} {
136                 inst := instance{}
137                 return inst
138         },
139                 func(obj interface{}) {
140                 },
141         )
142         pool.Put(pool.Get())
143         pool.Put(new(instance))
144         available, created := pool.Stats()
145         assert.Equal(t, 1, available, "number of available objects in the pool should be 1")
146         assert.Equal(t, 1, created, "number of created objects in the pool should be 1")
147         pool.Close()
148 }
149
150 func TestNotInitializedPut(t *testing.T) {
151         var poolEmpty Pool
152         poolEmpty.Put(new(instance))
153         available, created := poolEmpty.Stats()
154         assert.Equal(t, 0, available, "number of available objects in the pool should be 0")
155         assert.Equal(t, 0, created, "number of created objects in the pool should be 0")
156 }
157
158 func TestPutNilObject(t *testing.T) {
159         var poolEmpty Pool
160         poolEmpty.Put(nil)
161         available, created := poolEmpty.Stats()
162         assert.Equal(t, 0, available, "number of available objects in the pool should be 0")
163         assert.Equal(t, 0, created, "number of created objects in the pool should be 0")
164 }
165
166 func TestGet(t *testing.T) {
167         pool := NewPool(2, func() interface{} {
168                 inst := instance{}
169                 return inst
170         },
171                 func(obj interface{}) {
172                 },
173         )
174         i1 := pool.Get()
175         i2 := pool.Get()
176         available, created := pool.Stats()
177         assert.Equal(t, 0, available, "number of available objects in the pool should be 0")
178         assert.Equal(t, 2, created, "number of created objects in the pool should be 2")
179         pool.Put(i1)
180         pool.Put(i2)
181         pool.Put(new(instance))
182         available, created = pool.Stats()
183         assert.Equal(t, 2, available, "number of available objects in the pool should be 2")
184         assert.Equal(t, 2, created, "number of created objects in the pool should be 2")
185 }
186
187 func TestClose(t *testing.T) {
188         pool := NewPool(3, func() interface{} {
189                 inst := instance{}
190                 return inst
191         },
192                 func(obj interface{}) {
193                 },
194         )
195         i1 := pool.Get()
196         i2 := pool.Get()
197         i3 := pool.Get()
198         available, created := pool.Stats()
199         assert.Equal(t, 0, available, "number of available objects in the pool should be 0")
200         assert.Equal(t, 3, created, "number of created objects in the pool should be 3")
201         pool.Put(i1)
202         pool.Put(i2)
203         pool.Put(i3)
204         available, created = pool.Stats()
205         assert.Equal(t, 3, available, "number of available objects in the pool should be 3")
206         assert.Equal(t, 3, created, "number of created objects in the pool should be 3")
207         pool.Close()
208         i := pool.Get()
209         assert.Nil(t, i)
210         available, created = pool.Stats()
211         assert.Equal(t, 0, available, "number of available objects in the pool should be 0")
212         assert.Equal(t, 0, created, "number of created objects in the pool should be 0")
213 }
214
215 func TestPoolPutPanicsOnClosedChannel(t *testing.T){
216         pool := NewPool(1, func() interface{} {
217                 inst := instance{}
218                 return inst
219         },
220                 func(obj interface{}) {
221                 },
222         )
223         close(pool.pool)
224         assert.Panics(t, func(){pool.Put(instance{})})
225 }
226
227 func TestPoolClosePanicsOnClosedChannel(t *testing.T) {
228         pool := NewPool(1, func() interface{} {
229                 inst := instance{}
230                 return inst
231         },
232                 func(obj interface{}) {
233                 },
234         )
235         close(pool.pool)
236         assert.Panics(t, func(){pool.Close()})
237 }