From d87a48993ea97a5fd89db260804f44cf56b844ee Mon Sep 17 00:00:00 2001 From: ns019t Date: Wed, 14 Aug 2019 12:30:43 +0300 Subject: [PATCH] [1704] - Reset Response Handler, UT Change-Id: I6198b9698c9d6ab5c6f5c732062f62fba9b420b5 Signed-off-by: ns019t --- E2Manager/handlers/x2_reset_response_handler.go | 64 ++++++++++ .../handlers/x2_reset_response_handler_test.go | 130 +++++++++++++++++++++ .../providers/notification_handler_provider.go | 1 + E2Manager/rmrCgo/rmrCgoTypes.go | 1 + E2Manager/tests/payloadProvider.go | 80 +++++++++++++ 5 files changed, 276 insertions(+) create mode 100644 E2Manager/handlers/x2_reset_response_handler.go create mode 100644 E2Manager/handlers/x2_reset_response_handler_test.go create mode 100644 E2Manager/tests/payloadProvider.go diff --git a/E2Manager/handlers/x2_reset_response_handler.go b/E2Manager/handlers/x2_reset_response_handler.go new file mode 100644 index 0000000..e64c0ce --- /dev/null +++ b/E2Manager/handlers/x2_reset_response_handler.go @@ -0,0 +1,64 @@ +// +// 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 handlers + +// #cgo CFLAGS: -I../asn1codec/inc/ -I../asn1codec/e2ap_engine/ +// #cgo LDFLAGS: -L ../asn1codec/lib/ -L../asn1codec/e2ap_engine/ -le2ap_codec -lasncodec +// #include +import "C" +import ( + "e2mgr/logger" + "e2mgr/models" + "e2mgr/sessions" + "fmt" + "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader" +) + +type X2ResetResponseHandler struct{ + rnibReaderProvider func() reader.RNibReader +} + +func NewX2ResetResponseHandler(rnibReaderProvider func() reader.RNibReader) X2ResetResponseHandler { + return X2ResetResponseHandler{ + rnibReaderProvider: rnibReaderProvider, + } +} + +func (src X2ResetResponseHandler) Handle(logger *logger.Logger, e2Sessions sessions.E2Sessions, + request *models.NotificationRequest, messageChannel chan<- *models.NotificationResponse) { + + logger.Debugf("#x2ResetResponseHandler.Handle - transactionId %s: received reset response. Payload: %s", request.TransactionId, request.Payload) + + if nb, rNibErr := src.rnibReaderProvider().GetNodeb(request.RanName); rNibErr != nil { + logger.Errorf("#x2ResetResponseHandler.Handle - transactionId %s: failed to retrieve nb entity. RanName: %s. Error: %s", request.TransactionId, request.RanName, rNibErr.Error()) + } else { + logger.Debugf("#x2ResetResponseHandler.Handle - transactionId %s: nb entity retrieved. RanName %s, ConnectionStatus %s", request.TransactionId, nb.RanName, nb.ConnectionStatus) + refinedMessage, err := unpackX2apPduAndRefine(logger, MaxAsn1CodecAllocationBufferSize /*allocation buffer*/, request.Len, request.Payload, MaxAsn1CodecMessageBufferSize /*message buffer*/) + if err != nil { + logger.Errorf("#x2ResetResponseHandler.Handle - transactionId %s: failed to unpack reset response message. RanName %s, Payload: %s", request.TransactionId , request.RanName, request.Payload) + } else { + logger.Infof("#x2ResetResponseHandler.Handle - transactionId %s: reset response message payload unpacked. RanName %s, Message: %s", request.TransactionId , request.RanName, refinedMessage.pduPrint) + } + } + e2session, ok := e2Sessions[request.TransactionId] + if ok { + printHandlingSetupResponseElapsedTimeInMs(logger, fmt.Sprintf("#x2ResetResponseHandler.Handle- Summary: Total roundtrip elapsed time for transactionId %s", request.TransactionId), e2session.SessionStart) + delete(e2Sessions, request.TransactionId) + } + +} \ No newline at end of file diff --git a/E2Manager/handlers/x2_reset_response_handler_test.go b/E2Manager/handlers/x2_reset_response_handler_test.go new file mode 100644 index 0000000..1ea8384 --- /dev/null +++ b/E2Manager/handlers/x2_reset_response_handler_test.go @@ -0,0 +1,130 @@ +// +// 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 handlers + +import ( + "e2mgr/logger" + "e2mgr/mocks" + "e2mgr/models" + "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/pkg/errors" + "testing" + "time" +) + +func TestX2ResetResponseSuccess(t *testing.T) { + payload, err := tests.BuildPackedX2ResetResponse() + if err != nil { + t.Errorf("#x2_reset_response_handler_test.TestX2resetResponse - failed to build and pack X2ResetResponse. Error %x", err) + } + log, err := logger.InitLogger(logger.DebugLevel) + 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 + } + + h := NewX2ResetResponseHandler(rnibReaderProvider) + e2Sessions := make(sessions.E2Sessions) + xaction := []byte(fmt.Sprintf("%32s", "1234")) + e2Sessions[string(xaction)] = sessions.E2SessionDetails{SessionStart: time.Now()} + 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_SETUP_FAILED,} + var rnibErr common.IRNibError + readerMock.On("GetNodeb", mBuf.Meid).Return(nb, 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) ) + } +} + +func TestX2ResetResponseReaderFailure(t *testing.T) { + var payload []byte + log, err := logger.InitLogger(logger.DebugLevel) + if err!=nil{ + t.Errorf("#sctp_errors_notification_handler_test.TestX2ResetResponseReaderFailure - failed to initialize logger, error: %s", err) + } + readerMock :=&mocks.RnibReaderMock{} + rnibReaderProvider := func() reader.RNibReader { + return readerMock + } + + h := NewX2ResetResponseHandler(rnibReaderProvider) + e2Sessions := make(sessions.E2Sessions) + xaction := []byte(fmt.Sprintf("%32s", "1234")) + e2Sessions[string(xaction)] = sessions.E2SessionDetails{SessionStart: time.Now()} + 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 + + var nb *entities.NodebInfo + rnibErr := common.NewResourceNotFoundError(errors.New("nodeb not found")) + readerMock.On("GetNodeb", mBuf.Meid).Return(nb, 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) ) + } +} + +func TestX2ResetResponseUnpackFailure(t *testing.T) { + payload := []byte("not valid payload") + log, err := logger.InitLogger(logger.DebugLevel) + if err!=nil{ + t.Errorf("#sctp_errors_notification_handler_test.TestX2ResetResponseUnpackFailure - failed to initialize logger, error: %s", err) + } + readerMock :=&mocks.RnibReaderMock{} + rnibReaderProvider := func() reader.RNibReader { + return readerMock + } + + h := NewX2ResetResponseHandler(rnibReaderProvider) + e2Sessions := make(sessions.E2Sessions) + xaction := []byte(fmt.Sprintf("%32s", "1234")) + e2Sessions[string(xaction)] = sessions.E2SessionDetails{SessionStart: time.Now()} + 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_SETUP_FAILED,} + var rnibErr common.IRNibError + readerMock.On("GetNodeb", mBuf.Meid).Return(nb, 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) ) + } +} diff --git a/E2Manager/providers/notification_handler_provider.go b/E2Manager/providers/notification_handler_provider.go index 3a101db..534a598 100644 --- a/E2Manager/providers/notification_handler_provider.go +++ b/E2Manager/providers/notification_handler_provider.go @@ -50,6 +50,7 @@ func initNotificationHandlersMap(rnibReaderProvider func() reader.RNibReader, rn rmrCgo.RIC_ENB_LOAD_INFORMATION: handlers.RicEnbLoadInformationNotificationHandler{}, rmrCgo.RIC_ENB_CONF_UPDATE: handlers.X2EnbConfigurationUpdateHandler{}, rmrCgo.RIC_ENDC_CONF_UPDATE: handlers.EndcConfigurationUpdateHandler{}, + rmrCgo.RIC_X2_RESET_RESP: handlers.NewX2ResetResponseHandler(rnibReaderProvider), } } diff --git a/E2Manager/rmrCgo/rmrCgoTypes.go b/E2Manager/rmrCgo/rmrCgoTypes.go index cc92dca..a284c95 100644 --- a/E2Manager/rmrCgo/rmrCgoTypes.go +++ b/E2Manager/rmrCgo/rmrCgoTypes.go @@ -64,6 +64,7 @@ const ( RIC_ENDC_CONF_UPDATE_ACK = C.RIC_ENDC_CONF_UPDATE_ACK RIC_ENDC_CONF_UPDATE_FAILURE = C.RIC_ENDC_CONF_UPDATE_FAILURE RIC_SCTP_CLEAR_ALL = C.RIC_SCTP_CLEAR_ALL + RIC_X2_RESET_RESP = C.RIC_X2_RESET_RESP ) const ( diff --git a/E2Manager/tests/payloadProvider.go b/E2Manager/tests/payloadProvider.go new file mode 100644 index 0000000..e4a6ae4 --- /dev/null +++ b/E2Manager/tests/payloadProvider.go @@ -0,0 +1,80 @@ +// +// 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 tests + +// #cgo CFLAGS: -I../asn1codec/inc/ -I../asn1codec/e2ap_engine/ +// #cgo LDFLAGS: -L ../asn1codec/lib/ -L../asn1codec/e2ap_engine/ -le2ap_codec -lasncodec +// #include +// #include +// +// bool +// build_pack_x2_reset_response(size_t* packed_buf_size, unsigned char* packed_buf, size_t err_buf_size, char* err_buf){ +// bool rc = true; +// E2AP_PDU_t *pdu = calloc(1, sizeof(E2AP_PDU_t)); +// SuccessfulOutcome_t *successfulOutcome = calloc(1, sizeof(SuccessfulOutcome_t)); +// ResetResponse_t *resetResponse; +// ResetResponse_IEs_t *resetResponse_IEs = calloc(1, sizeof(ResetResponse_IEs_t)); +// +// assert(pdu != 0); +// assert(successfulOutcome != 0); +// assert(resetResponse_IEs != 0); +// +// pdu->present = E2AP_PDU_PR_successfulOutcome; +// pdu->choice.successfulOutcome = successfulOutcome; +// +// successfulOutcome->procedureCode = ProcedureCode_id_reset; +// successfulOutcome->criticality = Criticality_reject; +// successfulOutcome->value.present = SuccessfulOutcome__value_PR_ResetResponse; +// resetResponse = &successfulOutcome->value.choice.ResetResponse; +// +// CriticalityDiagnostics_IE_List_t *critList = calloc(1, sizeof(CriticalityDiagnostics_IE_List_t)); +// assert(critList != 0); +// resetResponse_IEs->id = ProtocolIE_ID_id_CriticalityDiagnostics; +// resetResponse_IEs->criticality = Criticality_ignore; +// resetResponse_IEs->value.present = ResetResponse_IEs__value_PR_CriticalityDiagnostics; +// ASN_SEQUENCE_ADD(resetResponse_IEs->value.choice.CriticalityDiagnostics.iEsCriticalityDiagnostics,critList); +// +// CriticalityDiagnostics_IE_List__Member *member= calloc(1, sizeof(CriticalityDiagnostics_IE_List__Member)); +// assert(member != 0); +// ASN_SEQUENCE_ADD(critList ,member); +// +// ASN_SEQUENCE_ADD(&resetResponse->protocolIEs, resetResponse_IEs); +// +// rc = per_pack_pdu(pdu, packed_buf_size, packed_buf,err_buf_size, err_buf); +// +// ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, pdu); +// return rc; +// } +import "C" +import ( + "errors" + "fmt" + "unsafe" +) +const PackedBufferSize = 4096 + +func BuildPackedX2ResetResponse()([]byte, error){ + payloadSize := C.ulong(PackedBufferSize) + packedBuffer := [PackedBufferSize]C.uchar{} + errorBuffer := [PackedBufferSize]C.char{} + res := bool(C.build_pack_x2_reset_response(&payloadSize, &packedBuffer[0], PackedBufferSize, &errorBuffer[0])) + if !res { + return nil, errors.New(fmt.Sprintf("packing error: %s", C.GoString(&errorBuffer[0]))) + } + return C.GoBytes(unsafe.Pointer(&packedBuffer), C.int(payloadSize)), nil +} -- 2.16.6