blob: b91107c4127d8e6b1fc4a39ee8275981993b5a8a [file] [log] [blame]
/*
* Copyright 2020-present Open Networking Foundation
*
* 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 ponresourcemanager
import (
"context"
"encoding/json"
"errors"
"github.com/opencord/voltha-lib-go/v3/pkg/db"
"github.com/opencord/voltha-lib-go/v3/pkg/db/kvstore"
"github.com/opencord/voltha-lib-go/v3/pkg/log"
"github.com/stretchr/testify/assert"
"strings"
"testing"
"time"
)
const (
GEM_POOL_PATH = "gemport_id_pool"
RESERVED_GEM_PORT_ID = uint32(5)
)
// MockKVClient mocks the AdapterProxy interface.
type MockResKVClient struct {
resourceMap map[string]interface{}
}
func newMockKvClient() *MockResKVClient {
var mockResKVClient MockResKVClient
mockResKVClient.resourceMap = make(map[string]interface{})
return &mockResKVClient
}
// List function implemented for KVClient.
func (kvclient *MockResKVClient) List(ctx context.Context, key string) (map[string]*kvstore.KVPair, error) {
return nil, errors.New("key didn't find")
}
// Get mock function implementation for KVClient
func (kvclient *MockResKVClient) Get(ctx context.Context, key string) (*kvstore.KVPair, error) {
logger.Debugw("Get of MockKVClient called", log.Fields{"key": key})
if key != "" {
if strings.Contains(key, RESERVED_GEMPORT_IDS_PATH) {
logger.Debug("Getting Key:", RESERVED_GEMPORT_IDS_PATH)
reservedGemPorts := []uint32{RESERVED_GEM_PORT_ID}
str, _ := json.Marshal(reservedGemPorts)
return kvstore.NewKVPair(key, str, "mock", 3000, 1), nil
}
if strings.Contains(key, GEM_POOL_PATH) {
logger.Debug("Getting Key:", GEM_POOL_PATH)
resource := kvclient.resourceMap[key]
return kvstore.NewKVPair(key, resource, "mock", 3000, 1), nil
}
maps := make(map[string]*kvstore.KVPair)
maps[key] = &kvstore.KVPair{Key: key}
return maps[key], nil
}
return nil, errors.New("key didn't find")
}
// Put mock function implementation for KVClient
func (kvclient *MockResKVClient) Put(ctx context.Context, key string, value interface{}) error {
if key != "" {
if strings.Contains(key, GEMPORT_ID_POOL_PATH) && value != nil {
kvclient.resourceMap[key] = value
}
return nil
}
return errors.New("key didn't find")
}
// Delete mock function implementation for KVClient
func (kvclient *MockResKVClient) Delete(ctx context.Context, key string) error {
return nil
}
// Reserve mock function implementation for KVClient
func (kvclient *MockResKVClient) Reserve(ctx context.Context, key string, value interface{}, ttl time.Duration) (interface{}, error) {
return nil, errors.New("key didn't find")
}
// ReleaseReservation mock function implementation for KVClient
func (kvclient *MockResKVClient) ReleaseReservation(ctx context.Context, key string) error {
return nil
}
// ReleaseAllReservations mock function implementation for KVClient
func (kvclient *MockResKVClient) ReleaseAllReservations(ctx context.Context) error {
return nil
}
// RenewReservation mock function implementation for KVClient
func (kvclient *MockResKVClient) RenewReservation(ctx context.Context, key string) error {
return nil
}
// Watch mock function implementation for KVClient
func (kvclient *MockResKVClient) Watch(ctx context.Context, key string, withPrefix bool) chan *kvstore.Event {
return nil
}
// AcquireLock mock function implementation for KVClient
func (kvclient *MockResKVClient) AcquireLock(ctx context.Context, lockName string, timeout time.Duration) error {
return nil
}
// ReleaseLock mock function implementation for KVClient
func (kvclient *MockResKVClient) ReleaseLock(lockName string) error {
return nil
}
// IsConnectionUp mock function implementation for KVClient
func (kvclient *MockResKVClient) IsConnectionUp(ctx context.Context) bool { // timeout in second
return true
}
// CloseWatch mock function implementation for KVClient
func (kvclient *MockResKVClient) CloseWatch(key string, ch chan *kvstore.Event) {
}
// Close mock function implementation for KVClient
func (kvclient *MockResKVClient) Close() {
}
func TestExcludeReservedGemPortIdFromThePool(t *testing.T) {
PONRMgr, err := NewPONResourceManager("gpon", "onu", "olt1",
"etcd", "1:1")
if err != nil {
return
}
PONRMgr.KVStore = &db.Backend{
Client: newMockKvClient(),
}
PONRMgr.KVStoreForConfig = &db.Backend{
Client: newMockKvClient(),
}
// create a pool in the range of [1,16]
// and exclude id 5 from this pool
StartIndex := uint32(1)
EndIndex := uint32(16)
ctx := context.Background()
reservedGemPortIds, defined := PONRMgr.getReservedGemPortIdsFromKVStore(ctx)
if !defined {
return
}
FormatResult, err := PONRMgr.FormatResource(1, StartIndex, EndIndex, reservedGemPortIds)
if err != nil {
t.Error("Failed to format resource", err)
return
}
// Add resource as json in kv store.
err = PONRMgr.KVStore.Put(ctx, GEMPORT_ID_POOL_PATH, FormatResult)
if err != nil {
t.Error("Error in posting data to kv store", GEMPORT_ID_POOL_PATH)
return
}
for i := StartIndex; i <= (EndIndex - uint32(len(reservedGemPortIds))); i++ {
// get gem port id pool from the kv store
resource, err := PONRMgr.GetResource(context.Background(), GEMPORT_ID_POOL_PATH)
if err != nil {
t.Error("Failed to get resource from gem port id pool", err)
return
}
// get a gem port id from the pool
nextID, err := PONRMgr.GenerateNextID(resource)
if err != nil {
t.Error("Failed to get gem port id from the pool", err)
return
}
//given gem port id should not equal to the reserved gem port id
assert.NotEqual(t, nextID, RESERVED_GEM_PORT_ID)
// put updated gem port id pool into the kv store
err = PONRMgr.UpdateResource(context.Background(), GEMPORT_ID_POOL_PATH, resource)
if err != nil {
t.Error("Failed to put updated gem port id pool into the kv store", err)
return
}
}
}