upload nodeb rnib reader version 1.0.5
[ric-plt/nodeb-rnib.git] / common / rNibPool_test.go
diff --git a/common/rNibPool_test.go b/common/rNibPool_test.go
new file mode 100644 (file)
index 0000000..e7eb662
--- /dev/null
@@ -0,0 +1,237 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package common
+
+import (
+       "github.com/stretchr/testify/assert"
+       "sync"
+       "sync/atomic"
+       "testing"
+       "time"
+)
+
+var    max int32
+var    counter int32
+var poolGlob *Pool
+type instance struct{}
+
+func(instance) up(){
+       tmpc := atomic.AddInt32(&counter, 1)
+       swapped:= false
+       for !swapped {
+               tmpm := atomic.LoadInt32(&max)
+               if tmpc >tmpm {
+                       swapped = atomic.CompareAndSwapInt32(&max, tmpm, tmpc)
+               } else {
+                       break
+               }
+       }
+}
+
+func(instance) down(){
+       atomic.AddInt32(&counter, - 1)
+}
+
+func TestPoolMax(t *testing.T){
+       counter = 0
+       max = 0
+       validateMaxLimit(1, 1, t)
+       counter = 0
+       max = 0
+       validateMaxLimit(1, 2, t)
+       counter = 0
+       max = 0
+       validateMaxLimit(5, 10, t)
+}
+
+func validateMaxLimit(size int, iterations int, t *testing.T) {
+       poolGlob = NewPool(size, func() interface{} {
+               inst := instance{}
+               return inst
+       },
+               func(obj interface{}) {
+               },
+       )
+       group := sync.WaitGroup{}
+       for i := 0; i < iterations; i++ {
+               go getPutInstance(group)
+       }
+       time.Sleep(time.Second)
+       group.Wait()
+       assert.Equal(t, int32(size), max)
+}
+
+func getPutInstance(group sync.WaitGroup) {
+       group.Add(1)
+       inst := poolGlob.Get().(instance)
+       inst.up()
+       time.Sleep(time.Millisecond*10)
+       inst.down()
+       poolGlob.Put(inst)
+       group.Done()
+}
+
+func TestNewPool(t *testing.T){
+       size := 5
+       pool := NewPool(size, func() interface{} {
+               inst := instance{}
+               return inst
+       },
+               func(obj interface{}) {
+               },
+       )
+       assert.NotNil(t, pool)
+       assert.NotNil(t, pool.New)
+       assert.NotNil(t, pool.Destroy)
+       assert.NotNil(t, pool.pool)
+       assert.Equal(t, cap(pool.pool), size, "the capacity of the pool should be " + string(size))
+}
+
+func TestGetCreated(t *testing.T) {
+       pool := NewPool(1, func() interface{} {
+               inst := instance{}
+               return inst
+       },
+               func(obj interface{}) {
+               },
+       )
+       pool.Get()
+       available, created := pool.Stats()
+       assert.Equal(t, 0, available, "number of available objects in the pool should be 0")
+       assert.Equal(t, 1, created, "number of created objects in the pool should be 1")
+       pool.Close()
+}
+
+func TestGetAndPut(t *testing.T) {
+       pool := NewPool(1, func() interface{} {
+               inst := instance{}
+               return inst
+       },
+               func(obj interface{}) {
+               },
+       )
+       pool.Put(pool.Get())
+       available, created := pool.Stats()
+       assert.Equal(t, 1, available, "number of available objects in the pool should be 1")
+       assert.Equal(t, 1, created, "number of created objects in the pool should be 1")
+       pool.Close()
+}
+
+func TestPutOutOfCapacity(t *testing.T) {
+       pool := NewPool(1, func() interface{} {
+               inst := instance{}
+               return inst
+       },
+               func(obj interface{}) {
+               },
+       )
+       pool.Put(pool.Get())
+       pool.Put(new(instance))
+       available, created := pool.Stats()
+       assert.Equal(t, 1, available, "number of available objects in the pool should be 1")
+       assert.Equal(t, 1, created, "number of created objects in the pool should be 1")
+       pool.Close()
+}
+
+func TestNotInitializedPut(t *testing.T) {
+       var poolEmpty Pool
+       poolEmpty.Put(new(instance))
+       available, created := poolEmpty.Stats()
+       assert.Equal(t, 0, available, "number of available objects in the pool should be 0")
+       assert.Equal(t, 0, created, "number of created objects in the pool should be 0")
+}
+
+func TestPutNilObject(t *testing.T) {
+       var poolEmpty Pool
+       poolEmpty.Put(nil)
+       available, created := poolEmpty.Stats()
+       assert.Equal(t, 0, available, "number of available objects in the pool should be 0")
+       assert.Equal(t, 0, created, "number of created objects in the pool should be 0")
+}
+
+func TestGet(t *testing.T) {
+       pool := NewPool(2, func() interface{} {
+               inst := instance{}
+               return inst
+       },
+               func(obj interface{}) {
+               },
+       )
+       i1 := pool.Get()
+       i2 := pool.Get()
+       available, created := pool.Stats()
+       assert.Equal(t, 0, available, "number of available objects in the pool should be 0")
+       assert.Equal(t, 2, created, "number of created objects in the pool should be 2")
+       pool.Put(i1)
+       pool.Put(i2)
+       pool.Put(new(instance))
+       available, created = pool.Stats()
+       assert.Equal(t, 2, available, "number of available objects in the pool should be 2")
+       assert.Equal(t, 2, created, "number of created objects in the pool should be 2")
+}
+
+func TestClose(t *testing.T) {
+       pool := NewPool(3, func() interface{} {
+               inst := instance{}
+               return inst
+       },
+               func(obj interface{}) {
+               },
+       )
+       i1 := pool.Get()
+       i2 := pool.Get()
+       i3 := pool.Get()
+       available, created := pool.Stats()
+       assert.Equal(t, 0, available, "number of available objects in the pool should be 0")
+       assert.Equal(t, 3, created, "number of created objects in the pool should be 3")
+       pool.Put(i1)
+       pool.Put(i2)
+       pool.Put(i3)
+       available, created = pool.Stats()
+       assert.Equal(t, 3, available, "number of available objects in the pool should be 3")
+       assert.Equal(t, 3, created, "number of created objects in the pool should be 3")
+       pool.Close()
+       i := pool.Get()
+       assert.Nil(t, i)
+       available, created = pool.Stats()
+       assert.Equal(t, 0, available, "number of available objects in the pool should be 0")
+       assert.Equal(t, 0, created, "number of created objects in the pool should be 0")
+}
+
+func TestPoolPutPanicsOnClosedChannel(t *testing.T){
+       pool := NewPool(1, func() interface{} {
+               inst := instance{}
+               return inst
+       },
+               func(obj interface{}) {
+               },
+       )
+       close(pool.pool)
+       assert.Panics(t, func(){pool.Put(instance{})})
+}
+
+func TestPoolClosePanicsOnClosedChannel(t *testing.T) {
+       pool := NewPool(1, func() interface{} {
+               inst := instance{}
+               return inst
+       },
+               func(obj interface{}) {
+               },
+       )
+       close(pool.pool)
+       assert.Panics(t, func(){pool.Close()})
+}