import (
"e2mgr/logger"
"e2mgr/services"
+ "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"
"sync"
}
func (m *E2TInstancesManager) AddE2TInstance(e2tAddress string) error {
+
+ if len(e2tAddress) == 0 {
+ m.logger.Errorf("#AddE2TInstance - Empty E2T address received")
+ return fmt.Errorf("empty E2T address")
+ }
+
e2tInstance := entities.NewE2TInstance(e2tAddress)
err := m.rnibDataService.SaveE2TInstance(e2tInstance)
--- /dev/null
+package managers
+
+import (
+ "e2mgr/configuration"
+ "e2mgr/logger"
+ "e2mgr/mocks"
+ "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"
+ "github.com/pkg/errors"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/mock"
+ "testing"
+)
+
+const E2TAddress = "10.0.2.15"
+
+func initE2TInstancesManagerTest(t *testing.T) (*mocks.RnibReaderMock, *mocks.RnibWriterMock, *E2TInstancesManager) {
+ logger, err := logger.InitLogger(logger.DebugLevel)
+ if err != nil {
+ t.Errorf("#... - failed to initialize logger, error: %s", err)
+ }
+ config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3}
+
+ readerMock := &mocks.RnibReaderMock{}
+ writerMock := &mocks.RnibWriterMock{}
+ rnibDataService := services.NewRnibDataService(logger, config, readerMock, writerMock)
+ e2tInstancesManager := NewE2TInstancesManager(rnibDataService, logger)
+ return readerMock, writerMock, e2tInstancesManager
+}
+
+func TestAddNewE2TInstanceEmptyAddress(t *testing.T) {
+ _, rnibWriterMock, e2tInstancesManager := initE2TInstancesManagerTest(t)
+ err := e2tInstancesManager.AddE2TInstance("")
+ assert.NotNil(t, err)
+ rnibWriterMock.AssertNotCalled(t, "SaveE2TInstance")
+}
+
+func TestAddNewE2TInstanceSaveE2TInstanceFailure(t *testing.T) {
+ rnibReaderMock, rnibWriterMock, e2tInstancesManager := initE2TInstancesManagerTest(t)
+ rnibWriterMock.On("SaveE2TInstance", mock.Anything).Return(common.NewInternalError(errors.New("Error")))
+ err := e2tInstancesManager.AddE2TInstance(E2TAddress)
+ assert.NotNil(t, err)
+ rnibReaderMock.AssertNotCalled(t, "GetE2TInfoList")
+}
+
+func TestAddNewE2TInstanceGetE2TInfoListInternalFailure(t *testing.T) {
+ rnibReaderMock, rnibWriterMock, e2tInstancesManager := initE2TInstancesManagerTest(t)
+ rnibWriterMock.On("SaveE2TInstance", mock.Anything).Return(nil)
+ e2tInfoList := []*entities.E2TInstanceInfo{}
+ rnibReaderMock.On("GetE2TInfoList").Return(e2tInfoList, common.NewInternalError(errors.New("Error")))
+ err := e2tInstancesManager.AddE2TInstance(E2TAddress)
+ assert.NotNil(t, err)
+ rnibReaderMock.AssertNotCalled(t, "SaveE2TInfoList")
+}
+
+func TestAddNewE2TInstanceNoE2TInfoList(t *testing.T) {
+ rnibReaderMock, rnibWriterMock, e2tInstancesManager := initE2TInstancesManagerTest(t)
+ rnibWriterMock.On("SaveE2TInstance", mock.Anything).Return(nil)
+ e2tInfoList := []*entities.E2TInstanceInfo{}
+ rnibReaderMock.On("GetE2TInfoList").Return(e2tInfoList, common.NewResourceNotFoundError(""))
+ e2tInfoList = append(e2tInfoList, &entities.E2TInstanceInfo{Address: E2TAddress})
+ rnibWriterMock.On("SaveE2TInfoList", e2tInfoList).Return(nil)
+ err := e2tInstancesManager.AddE2TInstance(E2TAddress)
+ assert.Nil(t, err)
+ rnibWriterMock.AssertCalled(t, "SaveE2TInfoList", e2tInfoList)
+}
+
+func TestAddNewE2TInstanceEmptyE2TInfoList(t *testing.T) {
+ rnibReaderMock, rnibWriterMock, e2tInstancesManager := initE2TInstancesManagerTest(t)
+ rnibWriterMock.On("SaveE2TInstance", mock.Anything).Return(nil)
+ e2tInfoList := []*entities.E2TInstanceInfo{}
+ rnibReaderMock.On("GetE2TInfoList").Return(e2tInfoList, nil)
+ e2tInfoList = append(e2tInfoList, &entities.E2TInstanceInfo{Address: E2TAddress})
+ rnibWriterMock.On("SaveE2TInfoList", e2tInfoList).Return(nil)
+ err := e2tInstancesManager.AddE2TInstance(E2TAddress)
+ assert.Nil(t, err)
+ rnibWriterMock.AssertCalled(t, "SaveE2TInfoList", e2tInfoList)
+}
+
+func TestAddNewE2TInstanceSaveE2TInfoListFailure(t *testing.T) {
+ rnibReaderMock, rnibWriterMock, e2tInstancesManager := initE2TInstancesManagerTest(t)
+ rnibWriterMock.On("SaveE2TInstance", mock.Anything).Return(nil)
+ e2tInfoList := []*entities.E2TInstanceInfo{}
+ rnibReaderMock.On("GetE2TInfoList").Return(e2tInfoList, nil)
+ e2tInfoList = append(e2tInfoList, &entities.E2TInstanceInfo{Address: E2TAddress})
+ rnibWriterMock.On("SaveE2TInfoList", e2tInfoList).Return(common.NewResourceNotFoundError(""))
+ err := e2tInstancesManager.AddE2TInstance(E2TAddress)
+ assert.NotNil(t, err)
+}
m.logger.Infof("#RanReconnectionManager.ReconnectRan - RAN name: %s - RAN's connection status: %s, RAN's connection attempts: %d", nodebInfo.RanName, nodebInfo.ConnectionStatus, nodebInfo.ConnectionAttempts)
if !m.canReconnectRan(nodebInfo) {
- err := m.setConnectionStatusOfUnconnectableRan(nodebInfo)
+ e2tAddress := nodebInfo.AssociatedE2TInstanceAddress
+ err := m.updateUnconnectableRan(nodebInfo)
if err != nil {
return err
}
if m.isRanExceededConnectionAttempts(nodebInfo) {
- return m.e2tInstancesManager.DeassociateRan(nodebInfo.RanName, nodebInfo.AssociatedE2TInstanceAddress)
+ return m.e2tInstancesManager.DeassociateRan(nodebInfo.RanName, e2tAddress)
}
return nil
int(nodebInfo.GetConnectionAttempts()) < m.config.MaxConnectionAttempts
}
-func (m *RanReconnectionManager) updateNodebInfoStatus(nodebInfo *entities.NodebInfo, connectionStatus entities.ConnectionStatus) error {
- if nodebInfo.ConnectionStatus == connectionStatus {
- return nil
- }
+func (m *RanReconnectionManager) updateNodebInfo(nodebInfo *entities.NodebInfo, connectionStatus entities.ConnectionStatus, resetE2tAddress bool) error {
nodebInfo.ConnectionStatus = connectionStatus;
+
+ if resetE2tAddress {
+ nodebInfo.AssociatedE2TInstanceAddress = ""
+ }
+
err := m.rnibDataService.UpdateNodebInfo(nodebInfo)
if err != nil {
- m.logger.Errorf("#RanReconnectionManager.updateNodebInfoStatus - RAN name: %s - Failed updating RAN's connection status to %s in rNib. Error: %v", nodebInfo.RanName, connectionStatus, err)
+ m.logger.Errorf("#RanReconnectionManager.updateNodebInfo - RAN name: %s - Failed updating RAN's connection status to %s in rNib. Error: %v", nodebInfo.RanName, connectionStatus, err)
return err
}
- m.logger.Infof("#RanReconnectionManager.updateNodebInfoStatus - RAN name: %s - Successfully updated rNib. RAN's current connection status: %s", nodebInfo.RanName, nodebInfo.ConnectionStatus)
+ m.logger.Infof("#RanReconnectionManager.updateNodebInfo - RAN name: %s - Successfully updated rNib. RAN's current connection status: %s", nodebInfo.RanName, nodebInfo.ConnectionStatus)
return nil
}
-func (m *RanReconnectionManager) setConnectionStatusOfUnconnectableRan(nodebInfo *entities.NodebInfo) error {
+func (m *RanReconnectionManager) updateUnconnectableRan(nodebInfo *entities.NodebInfo) error {
connectionStatus := nodebInfo.GetConnectionStatus()
if connectionStatus == entities.ConnectionStatus_SHUT_DOWN {
- m.logger.Warnf("#RanReconnectionManager.ReconnectRan - RAN name: %s - Cannot reconnect RAN. Reason: connection status is SHUT_DOWN", nodebInfo.RanName)
+ m.logger.Warnf("#RanReconnectionManager.updateUnconnectableRan - RAN name: %s - Cannot reconnect RAN. Reason: connection status is SHUT_DOWN", nodebInfo.RanName)
return nil
}
if connectionStatus == entities.ConnectionStatus_SHUTTING_DOWN {
- m.logger.Warnf("#RanReconnectionManager.ReconnectRan - RAN name: %s - Cannot reconnect RAN. Reason: connection status is SHUTTING_DOWN", nodebInfo.RanName)
- return m.updateNodebInfoStatus(nodebInfo, entities.ConnectionStatus_SHUT_DOWN)
+ m.logger.Warnf("#RanReconnectionManager.updateUnconnectableRan - RAN name: %s - Cannot reconnect RAN. Reason: connection status is SHUTTING_DOWN", nodebInfo.RanName)
+ return m.updateNodebInfo(nodebInfo, entities.ConnectionStatus_SHUT_DOWN, false)
}
if m.isRanExceededConnectionAttempts(nodebInfo) {
- m.logger.Warnf("#RanReconnectionManager.ReconnectRan - RAN name: %s - Cannot reconnect RAN. Reason: RAN's connection attempts exceeded the limit (%d)", nodebInfo.RanName, m.config.MaxConnectionAttempts)
- return m.updateNodebInfoStatus(nodebInfo, entities.ConnectionStatus_DISCONNECTED)
+ m.logger.Warnf("#RanReconnectionManager.updateUnconnectableRan - RAN name: %s - Cannot reconnect RAN. Reason: RAN's connection attempts exceeded the limit (%d)", nodebInfo.RanName, m.config.MaxConnectionAttempts)
+ return m.updateNodebInfo(nodebInfo, entities.ConnectionStatus_DISCONNECTED, true)
}
return nil
readerMock.On("GetNodeb", ranName).Return(origNodebInfo, rnibErr)
updatedNodebInfo := *origNodebInfo
updatedNodebInfo.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
+ updatedNodebInfo.AssociatedE2TInstanceAddress = ""
writerMock.On("UpdateNodebInfo", &updatedNodebInfo).Return(rnibErr)
e2tInstancesManagerMock.On("DeassociateRan", ranName, e2tAddress).Return(nil)
err := ranReconnectionManager.ReconnectRan(ranName)
readerMock.On("GetNodeb", ranName).Return(origNodebInfo, rnibErr)
updatedNodebInfo := *origNodebInfo
updatedNodebInfo.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
+ updatedNodebInfo.AssociatedE2TInstanceAddress = ""
writerMock.On("UpdateNodebInfo", &updatedNodebInfo).Return(rnibErr)
e2tInstancesManagerMock.On("DeassociateRan", ranName, e2tAddress).Return(common.NewInternalError(errors.New("Error")))
err := ranReconnectionManager.ReconnectRan(ranName)
writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 1)
}
-func TestUnnecessaryUpdateNodebInfoStatus(t *testing.T) {
- _, _, _, _, ranReconnectionManager, _ := initRanLostConnectionTest(t)
- nodebInfo := &entities.NodebInfo{RanName: "ranName", GlobalNbId: &entities.GlobalNbId{PlmnId: "xxx", NbId: "yyy"}, ConnectionStatus: entities.ConnectionStatus_CONNECTED}
- err := ranReconnectionManager.updateNodebInfoStatus(nodebInfo, entities.ConnectionStatus_CONNECTED)
- assert.Nil(t, err)
-}
-
func TestNoSetConnectionStatus(t *testing.T) {
_, _, _, _, ranReconnectionManager, _ := initRanLostConnectionTest(t)
nodebInfo := &entities.NodebInfo{RanName: "ranName", GlobalNbId: &entities.GlobalNbId{PlmnId: "xxx", NbId: "yyy"}, ConnectionStatus: entities.ConnectionStatus_CONNECTED}
- err := ranReconnectionManager.setConnectionStatusOfUnconnectableRan(nodebInfo)
+ err := ranReconnectionManager.updateUnconnectableRan(nodebInfo)
assert.Nil(t, err)
}
[
{
- "id": "RIC_X2_SETUP_REQ",
- "action": "send",
+ "id": "X2_SETUP_REQUEST",
"rmrMessageType": "10060",
"transactionId": "e2e$",
"payloadHeader": "$ranIp|$ranPort|$ranName|#packedPayload|",
"packedPayload": "0006002a000002001500080013302300fffff000140017000001f700133023fffff0000000133023000000000001"
},
{
- "id": "RIC_ENDC_SETUP_REQ",
- "action": "send",
- "rmrMessageType": "10360",
- "transactionId": "e2e$",
- "payloadHeader": "$ranIp|$ranPort|$ranName|#packedPayload|",
- "packedPayload": ""
- },
- {
- "id": "RIC_ENDC_SETUP_RESPONSE",
- "rmrMessageType": "10361",
- "packedPayload": ""
- },
- {
- "id": "RIC_ENB_CONF_UPDATE_ACK_positive",
- "sendRmrMessageType": "10081",
- "transactionId": "e2e$",
- "packedPayload": "2025000a00000100f70003000000"
+ "id": "X2_SETUP_RESPONSE",
+ "rmrMessageType": "10061",
+ "packedPayload": "2006002a000002001500080002f82900007ab000140017000000630002f8290007ab00102002f829000001000133"
},
{
- "id": "RIC_SUBSCRIPTION_REQ",
+ "id": "RIC_SUBSCRIPTION_REQUEST",
"rmrMessageType": "12010",
"transactionId": "e2e$",
"packedPayload": "00c9002b000003ea7e0005004eec0182ea6300020001ea810015000a0011121300212224264000ea6b000420000000"
"packedPayload": "40c9001f000003ea7e00050000010001ea6300020000ea6e000908ea6f400400014100"
},
{
- "id": "RIC_SUBSCRIPTION_DELETE_REQ",
+ "id": "RIC_SUBSCRIPTION_DELETE_REQUEST",
"rmrMessageType": "12020",
"transactionId": "e2e$",
"packedPayload": "00ca0012000002ea7e0005004eec0182ea6300020001"
"transactionId": "e2e$",
"packedPayload": "20ca0012000002ea7e0005004eec0182ea6300020001"
},
- {
- "id": "RIC_X2_SETUP_RESPONSE",
- "rmrMessageType": "10061",
- "packedPayload": "2006002a000002001500080002f82900007ab000140017000000630002f8290007ab00102002f829000001000133"
- },
{
"id": "RIC_INDICATION",
"rmrMessageType": "12050"