)
type RanLostConnectionHandler struct {
- ranReconnectionManager *managers.RanReconnectionManager
+ ranReconnectionManager managers.IRanReconnectionManager
}
-func NewRanLostConnectionHandler(ranReconnectionManager *managers.RanReconnectionManager) RanLostConnectionHandler {
+func NewRanLostConnectionHandler(ranReconnectionManager managers.IRanReconnectionManager) RanLostConnectionHandler {
return RanLostConnectionHandler{
ranReconnectionManager: ranReconnectionManager,
}
}
func (handler RanLostConnectionHandler) Handle(logger *logger.Logger, e2Sessions sessions.E2Sessions, request *models.NotificationRequest, messageChannel chan<- *models.NotificationResponse) {
- logger.Warnf("#ranLostConnectionHandler.Handle - Received lost connection (transaction id = %s): %s", request.TransactionId, request.Payload)
+ logger.Warnf("#RanLostConnectionHandler.Handle - RAN name: %s - Received lost connection notification", request.RanName)
err := handler.ranReconnectionManager.ReconnectRan(request.RanName)
if err != nil {
- logger.Errorf("#ranLostConnectionHandler.Handle - An error occurred while trying to reconnect RAN, %v", err)
+ logger.Errorf("#RanLostConnectionHandler.Handle - An error occurred while trying to reconnect RAN, %v", err)
return
}
}
//// See the License for the specific language governing permissions and
//// limitations under the License.
////
-//
package handlers
-//
-//import (
-// "e2mgr/logger"
-// "e2mgr/mocks"
-// "e2mgr/models"
-// "e2mgr/rNibWriter"
-// "e2mgr/rmrCgo"
-// "e2mgr/sessions"
-// "e2mgr/tests"
-// "fmt"
-// "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
-// "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
-// "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader"
-// "github.com/stretchr/testify/mock"
-// "testing"
-// "time"
-//)
-//
-///*
-// * Test an error response while in an x2 setup request session
-// */
-//func TestHandleInSession(t *testing.T){
-// log, err := logger.InitLogger(logger.InfoLevel)
-// if err!=nil{
-// t.Errorf("#sctp_errors_notification_handler_test.TestHandleInSession - failed to initialize logger, error: %s", err)
-// }
-//
-// readerMock :=&mocks.RnibReaderMock{}
-// rnibReaderProvider := func() reader.RNibReader {
-// return readerMock
-// }
-// writerMock := &mocks.RnibWriterMock{}
-// rnibWriterProvider := func() rNibWriter.RNibWriter {
-// return writerMock
-// }
-// h := NewRanLostConnectionHandler(rnibReaderProvider,rnibWriterProvider)
-//
-// e2Sessions := make(sessions.E2Sessions)
-// xaction := []byte(fmt.Sprintf("%32s", "1234"))
-// e2Sessions[string(xaction)] = sessions.E2SessionDetails{SessionStart: time.Now()}
-// payload := []byte("Error")
-// mBuf := rmrCgo.NewMBuf(tests.MessageType, len(payload),"RanName", &payload, &xaction)
-// notificationRequest := models.NotificationRequest{RanName: mBuf.Meid, Len: mBuf.Len, Payload: *mBuf.Payload,
-// StartTime: time.Now(), TransactionId: string(xaction)}
-// var messageChannel chan<- *models.NotificationResponse
-//
-// nb := &entities.NodebInfo{RanName:mBuf.Meid, ConnectionStatus:entities.ConnectionStatus_CONNECTED,}
-// var rnibErr common.IRNibError
-// readerMock.On("GetNodeb", mBuf.Meid).Return(nb, rnibErr)
-// updatedNb := &entities.NodebInfo{RanName:mBuf.Meid, ConnectionStatus:entities.ConnectionStatus_DISCONNECTED,}
-// writerMock.On("SaveNodeb", mock.Anything, updatedNb).Return(rnibErr)
-//
-// h.Handle(log,e2Sessions, ¬ificationRequest, messageChannel)
-//
-// if _, ok := e2Sessions[string(xaction)]; ok {
-// t.Errorf("want: no session entry, got: session entry for: %s", string(xaction) )
-// }
-//}
-//
-///*
-// * Test an error response triggered by the E2 Term
-// */
-//
-//func TestHandleNoSession(t *testing.T){
-// log, err := logger.InitLogger(logger.InfoLevel)
-// if err!=nil{
-// t.Errorf("#sctp_errors_notification_handler_test.TestHandleNoSession - failed to initialize logger, error: %s", err)
-// }
-//
-// readerMock :=&mocks.RnibReaderMock{}
-// rnibReaderProvider := func() reader.RNibReader {
-// return readerMock
-// }
-// writerMock := &mocks.RnibWriterMock{}
-// rnibWriterProvider := func() rNibWriter.RNibWriter {
-// return writerMock
-// }
-// h := NewRanLostConnectionHandler(rnibReaderProvider,rnibWriterProvider)
-//
-// e2Sessions := make(sessions.E2Sessions)
-// transactionId := "1234"
-// xaction := []byte(fmt.Sprintf("%32s", transactionId+"6"))
-// e2Sessions[transactionId] = sessions.E2SessionDetails{SessionStart: time.Now()}
-// payload := []byte("Error")
-// mBuf := rmrCgo.NewMBuf(tests.MessageType, len(payload),"RanName", &payload, &xaction)
-// notificationRequest := models.NotificationRequest{RanName: mBuf.Meid, Len: mBuf.Len, Payload: *mBuf.Payload, StartTime: time.Now(),
-// TransactionId: string(xaction)}
-// var messageChannel chan<- *models.NotificationResponse
-//
-// nb := &entities.NodebInfo{RanName:mBuf.Meid, ConnectionStatus:entities.ConnectionStatus_CONNECTED,}
-// var rnibErr common.IRNibError
-// readerMock.On("GetNodeb", mBuf.Meid).Return(nb, rnibErr)
-// updatedNb := &entities.NodebInfo{RanName:mBuf.Meid, ConnectionStatus:entities.ConnectionStatus_DISCONNECTED,}
-// writerMock.On("SaveNodeb", mock.Anything, updatedNb).Return(rnibErr)
-//
-// h.Handle(log,e2Sessions, ¬ificationRequest, messageChannel)
-//
-// if _, ok := e2Sessions[transactionId]; !ok {
-// t.Errorf("want: session entry for %s, got: no session entry", transactionId )
-// }
-//}
-///*
-// * Test an error response triggered by the E2 Term
-// */
-//func TestHandleUnsolicitedDisconnectionConnectedSuccess(t *testing.T){
-// log, err := logger.InitLogger(logger.DebugLevel)
-// if err!=nil{
-// t.Errorf("#sctp_errors_notification_handler_test.TestHandleNoSession - failed to initialize logger, error: %s", err)
-// }
-//
-// readerMock :=&mocks.RnibReaderMock{}
-// rnibReaderProvider := func() reader.RNibReader {
-// return readerMock
-// }
-// writerMock := &mocks.RnibWriterMock{}
-// rnibWriterProvider := func() rNibWriter.RNibWriter {
-// return writerMock
-// }
-// h := NewRanLostConnectionHandler(rnibReaderProvider,rnibWriterProvider)
-//
-// e2Sessions := make(sessions.E2Sessions)
-// transactionId := "1234"
-// xaction := []byte(fmt.Sprintf("%32s", transactionId+"6"))
-// e2Sessions[transactionId] = sessions.E2SessionDetails{SessionStart: time.Now()}
-// payload := []byte("Error")
-// mBuf := rmrCgo.NewMBuf(tests.MessageType, len(payload),"RanName", &payload, &xaction)
-// notificationRequest := models.NotificationRequest{RanName: mBuf.Meid, Len: mBuf.Len, Payload: *mBuf.Payload, StartTime: time.Now(),
-// TransactionId: string(xaction)}
-// var messageChannel chan<- *models.NotificationResponse
-//
-// nb := &entities.NodebInfo{RanName:mBuf.Meid, ConnectionStatus:entities.ConnectionStatus_CONNECTED,}
-// var rnibErr common.IRNibError
-// readerMock.On("GetNodeb", mBuf.Meid).Return(nb, rnibErr)
-// updatedNb := &entities.NodebInfo{RanName:mBuf.Meid, ConnectionStatus:entities.ConnectionStatus_DISCONNECTED,}
-// writerMock.On("SaveNodeb", mock.Anything, updatedNb).Return(rnibErr)
-//
-// h.Handle(log,e2Sessions, ¬ificationRequest, messageChannel)
-//}
+
+import (
+ "e2mgr/logger"
+ "e2mgr/mocks"
+ "e2mgr/models"
+ "e2mgr/sessions"
+ "github.com/pkg/errors"
+ "testing"
+)
+
+func TestLostConnectionHandlerSuccess(t *testing.T) {
+ logger, _ := logger.InitLogger(logger.InfoLevel)
+ ranName := "test"
+ notificationRequest := models.NotificationRequest{RanName: ranName}
+ ranReconnectionManagerMock := &mocks.RanReconnectionManagerMock{}
+ ranReconnectionManagerMock.On("ReconnectRan", ranName).Return(nil)
+ handler := NewRanLostConnectionHandler(ranReconnectionManagerMock)
+ handler.Handle(logger, make(sessions.E2Sessions), ¬ificationRequest, nil)
+ ranReconnectionManagerMock.AssertCalled(t, "ReconnectRan", ranName)
+}
+
+func TestLostConnectionHandlerFailure(t *testing.T) {
+ logger, _ := logger.InitLogger(logger.InfoLevel)
+ ranName := "test"
+ notificationRequest := models.NotificationRequest{RanName: ranName}
+ ranReconnectionManagerMock := &mocks.RanReconnectionManagerMock{}
+ ranReconnectionManagerMock.On("ReconnectRan", ranName).Return(errors.New("error"))
+ handler := NewRanLostConnectionHandler(ranReconnectionManagerMock)
+ handler.Handle(logger, make(sessions.E2Sessions), ¬ificationRequest, nil)
+ ranReconnectionManagerMock.AssertCalled(t, "ReconnectRan", ranName)
+}
+
//
//func TestHandleUnsolicitedDisconnectionNotConnectedSuccess(t *testing.T){
// log, err := logger.InitLogger(logger.DebugLevel)
rmrResponseChannel := make(chan *models.NotificationResponse, config.NotificationResponseBuffer)
rmrService := services.NewRmrService(rmrConfig, msgImpl, controllers.E2Sessions, rmrResponseChannel)
-
- var ranSetupManager = managers.NewRanSetupManager(logger, rmrService, reader.GetRNibReader, rNibWriter.GetRNibWriter)
- var ranReconnectionManager = managers.NewRanReconnectionManager(logger, config, reader.GetRNibReader, rNibWriter.GetRNibWriter, ranSetupManager)
+ var ranReconnectionManager = managers.NewRanReconnectionManager(logger, config, reader.GetRNibReader, rNibWriter.GetRNibWriter, rmrService)
var nManager = notificationmanager.NewNotificationManager(reader.GetRNibReader, rNibWriter.GetRNibWriter, ranReconnectionManager)
rmrServiceReceiver := receivers.NewRmrServiceReceiver(*rmrService, nManager)
+//
+// 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 managers
import (
"e2mgr/configuration"
"e2mgr/logger"
"e2mgr/rNibWriter"
+ "e2mgr/services"
"gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
"gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
"gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader"
)
+type IRanReconnectionManager interface {
+ ReconnectRan(inventoryName string) error
+}
+
type RanReconnectionManager struct {
logger *logger.Logger
config *configuration.Configuration
ranSetupManager *RanSetupManager
}
-func NewRanReconnectionManager(logger *logger.Logger, config *configuration.Configuration, rnibReaderProvider func() reader.RNibReader, rnibWriterProvider func() rNibWriter.RNibWriter, ranSetupManager *RanSetupManager) *RanReconnectionManager {
+func NewRanReconnectionManager(logger *logger.Logger, config *configuration.Configuration, rnibReaderProvider func() reader.RNibReader, rnibWriterProvider func() rNibWriter.RNibWriter, rmrService *services.RmrService) *RanReconnectionManager {
return &RanReconnectionManager{
logger: logger,
config: config,
rnibReaderProvider: rnibReaderProvider,
rnibWriterProvider: rnibWriterProvider,
- ranSetupManager: ranSetupManager,
+ ranSetupManager: NewRanSetupManager(logger,rmrService,rnibReaderProvider,rnibWriterProvider),
}
}
--- /dev/null
+//
+// 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 managers
+
+import (
+ "e2mgr/configuration"
+ "e2mgr/logger"
+ "e2mgr/mocks"
+ "e2mgr/models"
+ "e2mgr/rNibWriter"
+ "e2mgr/rmrCgo"
+ "e2mgr/services"
+ "e2mgr/sessions"
+ "e2mgr/tests"
+ "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
+ "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
+ "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader"
+ "github.com/pkg/errors"
+ "github.com/stretchr/testify/assert"
+ "testing"
+)
+
+func initRanLostConnectionTest(t *testing.T) (*logger.Logger, *mocks.RnibReaderMock, *mocks.RnibWriterMock, *RanReconnectionManager) {
+ logger, err := logger.InitLogger(logger.DebugLevel)
+ if err != nil {
+ t.Errorf("#... - failed to initialize logger, error: %s", err)
+ }
+
+ rmrService := getRmrService(&mocks.RmrMessengerMock{}, logger)
+
+ readerMock := &mocks.RnibReaderMock{}
+ rnibReaderProvider := func() reader.RNibReader {
+ return readerMock
+ }
+ writerMock := &mocks.RnibWriterMock{}
+ rnibWriterProvider := func() rNibWriter.RNibWriter {
+ return writerMock
+ }
+
+ ranReconnectionManager := NewRanReconnectionManager(logger, configuration.ParseConfiguration(), rnibReaderProvider, rnibWriterProvider, rmrService)
+ return logger, readerMock, writerMock, ranReconnectionManager
+}
+
+func TestLostConnectionFetchingNodebFailure(t *testing.T) {
+ _, readerMock, _, ranReconnectionManager := initRanLostConnectionTest(t)
+ ranName := "test"
+ var nodebInfo *entities.NodebInfo
+ readerMock.On("GetNodeb", ranName).Return(nodebInfo, common.NewInternalError(errors.New("Error")))
+ err := ranReconnectionManager.ReconnectRan(ranName)
+ assert.NotNil(t, err)
+}
+
+func TestLostConnectionUpdatingNodebForUnconnectableRanFailure(t *testing.T) {
+ _, readerMock, writerMock, ranReconnectionManager := initRanLostConnectionTest(t)
+ ranName := "test"
+ origNodebInfo := &entities.NodebInfo{RanName: ranName, GlobalNbId: &entities.GlobalNbId{PlmnId: "xxx", NbId: "yyy"}, ConnectionStatus: entities.ConnectionStatus_SHUTTING_DOWN}
+ var rnibErr common.IRNibError
+ readerMock.On("GetNodeb", ranName).Return(origNodebInfo, rnibErr)
+ updatedNodebInfo := *origNodebInfo
+ updatedNodebInfo.ConnectionStatus = entities.ConnectionStatus_SHUT_DOWN
+ writerMock.On("UpdateNodebInfo", &updatedNodebInfo).Return(common.NewInternalError(errors.New("Error")))
+ err := ranReconnectionManager.ReconnectRan(ranName)
+ assert.NotNil(t, err)
+}
+
+func TestLostConnectionOfConnectedRanWithMaxAttempts(t *testing.T) {
+ _, readerMock, writerMock, ranReconnectionManager := initRanLostConnectionTest(t)
+ ranName := "test"
+ origNodebInfo := &entities.NodebInfo{RanName: ranName, GlobalNbId: &entities.GlobalNbId{PlmnId: "xxx", NbId: "yyy"}, ConnectionStatus: entities.ConnectionStatus_CONNECTED, ConnectionAttempts: 20}
+ var rnibErr common.IRNibError
+ readerMock.On("GetNodeb", ranName).Return(origNodebInfo, rnibErr)
+ updatedNodebInfo := *origNodebInfo
+ updatedNodebInfo.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
+ writerMock.On("UpdateNodebInfo", &updatedNodebInfo).Return(rnibErr)
+ err := ranReconnectionManager.ReconnectRan(ranName)
+ assert.Nil(t, err)
+}
+
+func TestLostConnectionOfShutdownRan(t *testing.T) {
+ _, readerMock, _, ranReconnectionManager := initRanLostConnectionTest(t)
+ ranName := "test"
+ origNodebInfo := &entities.NodebInfo{RanName: ranName, GlobalNbId: &entities.GlobalNbId{PlmnId: "xxx", NbId: "yyy"}, ConnectionStatus: entities.ConnectionStatus_SHUT_DOWN}
+ var rnibErr common.IRNibError
+ readerMock.On("GetNodeb", ranName).Return(origNodebInfo, rnibErr)
+ err := ranReconnectionManager.ReconnectRan(ranName)
+ assert.Nil(t, err)
+}
+
+func TestLostConnectionOfShuttingdownRan(t *testing.T) {
+ _, readerMock, writerMock, ranReconnectionManager := initRanLostConnectionTest(t)
+ ranName := "test"
+ origNodebInfo := &entities.NodebInfo{RanName: ranName, GlobalNbId: &entities.GlobalNbId{PlmnId: "xxx", NbId: "yyy"}, ConnectionStatus: entities.ConnectionStatus_SHUTTING_DOWN}
+ var rnibErr common.IRNibError
+ readerMock.On("GetNodeb", ranName).Return(origNodebInfo, rnibErr)
+ updatedNodebInfo := *origNodebInfo
+ updatedNodebInfo.ConnectionStatus = entities.ConnectionStatus_SHUT_DOWN
+ writerMock.On("UpdateNodebInfo", &updatedNodebInfo).Return(rnibErr)
+ err := ranReconnectionManager.ReconnectRan(ranName)
+ assert.Nil(t, err)
+}
+
+// TODO: should extract to test_utils
+func getRmrService(rmrMessengerMock *mocks.RmrMessengerMock, log *logger.Logger) *services.RmrService {
+ rmrMessenger := rmrCgo.RmrMessenger(rmrMessengerMock)
+ messageChannel := make(chan *models.NotificationResponse)
+ rmrMessengerMock.On("Init", tests.GetPort(), tests.MaxMsgSize, tests.Flags, log).Return(&rmrMessenger)
+ return services.NewRmrService(services.NewRmrConfig(tests.Port, tests.MaxMsgSize, tests.Flags, log), rmrMessenger, make(sessions.E2Sessions), messageChannel)
+}
+//
+// 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 managers
import (
--- /dev/null
+// 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 mocks
+
+import (
+ "github.com/stretchr/testify/mock"
+)
+
+type RanReconnectionManagerMock struct {
+ mock.Mock
+}
+
+func (m *RanReconnectionManagerMock) ReconnectRan(inventoryName string) error {
+ args := m.Called(inventoryName)
+
+ return args.Error(0)
+}
return writerMock
}
- ranSetupManager := managers.NewRanSetupManager(logger, rmrService, rnibReaderProvider, rnibWriterProvider)
- ranReconnectionManager := managers.NewRanReconnectionManager(logger, configuration.ParseConfiguration(), rnibReaderProvider, rnibWriterProvider, ranSetupManager)
+ ranReconnectionManager := managers.NewRanReconnectionManager(logger, configuration.ParseConfiguration(), rnibReaderProvider, rnibWriterProvider, rmrService)
var testCases = []struct {
msgType int
return writerMock
}
- ranSetupManager := managers.NewRanSetupManager(logger, rmrService, rnibReaderProvider, rnibWriterProvider)
- ranReconnectionManager := managers.NewRanReconnectionManager(logger, configuration.ParseConfiguration(), rnibReaderProvider, rnibWriterProvider, ranSetupManager)
+ ranReconnectionManager := managers.NewRanReconnectionManager(logger, configuration.ParseConfiguration(), rnibReaderProvider, rnibWriterProvider, rmrService)
provider := NewNotificationHandlerProvider(rnibReaderProvider, rnibWriterProvider, ranReconnectionManager)
t.Run(fmt.Sprintf("%d", tc.msgType), func(t *testing.T) {
maxMsgSize: 4096
notificationResponseBuffer: 100
bigRedButtonTimeoutSec: 5
-maxConnectionAttempts: 20
+maxConnectionAttempts: 3
rmrService := getRmrService(rmrMessengerMock, logger)
- ranSetupManager := managers.NewRanSetupManager(logger, rmrService, rnibReaderProvider, rnibWriterProvider)
- ranReconnectionManager := managers.NewRanReconnectionManager(logger, configuration.ParseConfiguration(), rnibReaderProvider, rnibWriterProvider, ranSetupManager)
+ ranReconnectionManager := managers.NewRanReconnectionManager(logger, configuration.ParseConfiguration(), rnibReaderProvider, rnibWriterProvider, rmrService)
nManager := notificationmanager.NewNotificationManager(rnibReaderProvider, rnibWriterProvider, ranReconnectionManager)
return NewRmrServiceReceiver(*rmrService, nManager)