var e2tMaxSubReqTryCount uint64 // Initial try + retry
var e2tMaxSubDelReqTryCount uint64 // Initial try + retry
var readSubsFromDb string
+var restDuplicateCtrl duplicateCtrl
type Control struct {
*xapp.RMRClient
return c
}
+ restDuplicateCtrl.Init()
+
// Read subscriptions from db
xapp.Logger.Info("Reading subscriptions from db")
subIds, register, err := c.ReadAllSubscriptionsFromSdl()
return nil, err
}
- go c.processSubscriptionRequests(restSubscription, &subReqList, p.ClientEndpoint, p.Meid, &restSubId)
+ err, duplicate, md5sum := restDuplicateCtrl.IsDuplicateToOngoingTransaction(restSubId, params)
+
+ if err != nil {
+ // We were unable to detect whether this request was duplicate or not, proceed
+ xapp.Logger.Info("%s - proceeding with the request", err.Error())
+ } else {
+ if duplicate {
+ if *p.SubscriptionDetails[0].ActionToBeSetupList[0].ActionType == "report" {
+ xapp.Logger.Info("Retransmission blocker dropped for report typer of request")
+ c.UpdateCounter(cRestSubRespToXapp)
+ return &subResp, nil
+ }
+ }
+ restSubscription.Md5sumOngoing = md5sum
+ }
+
+ go c.processSubscriptionRequests(restSubscription, &subReqList, p.ClientEndpoint, p.Meid, &restSubId, xAppRmrEndpoint)
c.UpdateCounter(cRestSubRespToXapp)
return &subResp, nil
}
+func (c *Control) sendUnsuccesfullResponseNotification(restSubId *string, restSubscription *RESTSubscription, xAppEventInstanceID int64, err error,
+ clientEndpoint *models.SubscriptionParamsClientEndpoint, trans *TransactionXapp) {
+
+ // Send notification to xApp that prosessing of a Subscription Request has failed.
+ e2EventInstanceID := (int64)(0)
+ errorCause := err.Error()
+ resp := &models.SubscriptionResponse{
+ SubscriptionID: restSubId,
+ SubscriptionInstances: []*models.SubscriptionInstance{
+ &models.SubscriptionInstance{E2EventInstanceID: &e2EventInstanceID,
+ ErrorCause: &errorCause,
+ XappEventInstanceID: &xAppEventInstanceID},
+ },
+ }
+ // Mark REST subscription request processed.
+ restSubscription.SetProcessed()
+ if trans != nil {
+ xapp.Logger.Info("Sending unsuccessful REST notification (cause %s) to endpoint=%v:%v, XappEventInstanceID=%v, E2EventInstanceID=%v, %s",
+ errorCause, clientEndpoint.Host, *clientEndpoint.HTTPPort, xAppEventInstanceID, e2EventInstanceID, idstring(nil, trans))
+ } else {
+ xapp.Logger.Info("Sending unsuccessful REST notification (cause %s) to endpoint=%v:%v, XappEventInstanceID=%v, E2EventInstanceID=%v",
+ errorCause, clientEndpoint.Host, *clientEndpoint.HTTPPort, xAppEventInstanceID, e2EventInstanceID)
+ }
+ xapp.Subscription.Notify(resp, *clientEndpoint)
+ c.UpdateCounter(cRestSubFailNotifToXapp)
+}
+
+func (c *Control) sendSuccesfullResponseNotification(restSubId *string, restSubscription *RESTSubscription, xAppEventInstanceID int64, e2EventInstanceID int64,
+ clientEndpoint *models.SubscriptionParamsClientEndpoint, trans *TransactionXapp) {
+
+ // Store successfully processed InstanceId for deletion
+ restSubscription.AddE2InstanceId((uint32)(e2EventInstanceID))
+ restSubscription.AddXappIdToE2Id(xAppEventInstanceID, e2EventInstanceID)
+
+ // Send notification to xApp that a Subscription Request has been processed.
+ resp := &models.SubscriptionResponse{
+ SubscriptionID: restSubId,
+ SubscriptionInstances: []*models.SubscriptionInstance{
+ &models.SubscriptionInstance{E2EventInstanceID: &e2EventInstanceID,
+ ErrorCause: nil,
+ XappEventInstanceID: &xAppEventInstanceID},
+ },
+ }
+ // Mark REST subscription request processesd.
+ restSubscription.SetProcessed()
+ xapp.Logger.Info("Sending successful REST notification to endpoint=%v:%v, XappEventInstanceID=%v, E2EventInstanceID=%v, %s",
+ clientEndpoint.Host, *clientEndpoint.HTTPPort, xAppEventInstanceID, e2EventInstanceID, idstring(nil, trans))
+ xapp.Subscription.Notify(resp, *clientEndpoint)
+ c.UpdateCounter(cRestSubNotifToXapp)
+}
+
//-------------------------------------------------------------------
//
//-------------------------------------------------------------------
func (c *Control) processSubscriptionRequests(restSubscription *RESTSubscription, subReqList *e2ap.SubscriptionRequestList,
- clientEndpoint *models.SubscriptionParamsClientEndpoint, meid *string, restSubId *string) {
+ clientEndpoint *models.SubscriptionParamsClientEndpoint, meid *string, restSubId *string, xAppRmrEndpoint string) {
xapp.Logger.Info("Subscription Request count=%v ", len(subReqList.E2APSubscriptionRequests))
- _, xAppRmrEndpoint, err := ConstructEndpointAddresses(*clientEndpoint)
- if err != nil {
- c.registry.DeleteRESTSubscription(restSubId)
- xapp.Logger.Error("XAPP-SubReq transaction not created, endpoint createtion failed for RESTSubId=%s, Meid=%s", *restSubId, *meid)
- return
- }
-
var xAppEventInstanceID int64
var e2EventInstanceID int64
- var errorCause string
+
+ defer restDuplicateCtrl.TransactionComplete(restSubscription.Md5sumOngoing)
+
for index := 0; index < len(subReqList.E2APSubscriptionRequests); index++ {
subReqMsg := subReqList.E2APSubscriptionRequests[index]
+ xAppEventInstanceID = (int64)(subReqMsg.RequestId.Id)
trans := c.tracker.NewXappTransaction(xapp.NewRmrEndpoint(xAppRmrEndpoint), *restSubId, subReqMsg.RequestId, &xapp.RMRMeid{RanName: *meid})
if trans == nil {
- c.registry.DeleteRESTSubscription(restSubId)
- xapp.Logger.Error("XAPP-SubReq transaction not created. RESTSubId=%s, EndPoint=%s, Meid=%s", *restSubId, xAppRmrEndpoint, *meid)
- return
+ // Send notification to xApp that prosessing of a Subscription Request has failed.
+ err := fmt.Errorf("Tracking failure")
+ c.sendUnsuccesfullResponseNotification(restSubId, restSubscription, xAppEventInstanceID, err, clientEndpoint, trans)
+ continue
}
- defer trans.Release()
- xAppEventInstanceID = (int64)(subReqMsg.RequestId.Id)
xapp.Logger.Info("Handle SubscriptionRequest index=%v, %s", index, idstring(nil, trans))
+
subRespMsg, err := c.handleSubscriptionRequest(trans, &subReqMsg, meid, restSubId)
if err != nil {
- // Send notification to xApp that prosessing of a Subscription Request has failed.
- e2EventInstanceID = (int64)(0)
- errorCause = err.Error()
- resp := &models.SubscriptionResponse{
- SubscriptionID: restSubId,
- SubscriptionInstances: []*models.SubscriptionInstance{
- &models.SubscriptionInstance{E2EventInstanceID: &e2EventInstanceID,
- ErrorCause: &errorCause,
- XappEventInstanceID: &xAppEventInstanceID},
- },
- }
- // Mark REST subscription request processed.
- restSubscription.SetProcessed()
- xapp.Logger.Info("Sending unsuccessful REST notification (cause %s) to endpoint=%v:%v, XappEventInstanceID=%v, E2EventInstanceID=%v, %s",
- errorCause, clientEndpoint.Host, *clientEndpoint.HTTPPort, xAppEventInstanceID, e2EventInstanceID, idstring(nil, trans))
- xapp.Subscription.Notify(resp, *clientEndpoint)
- c.UpdateCounter(cRestSubFailNotifToXapp)
+ c.sendUnsuccesfullResponseNotification(restSubId, restSubscription, xAppEventInstanceID, err, clientEndpoint, trans)
} else {
e2EventInstanceID = (int64)(subRespMsg.RequestId.InstanceId)
-
xapp.Logger.Info("SubscriptionRequest index=%v processed successfully. endpoint=%v:%v, XappEventInstanceID=%v, E2EventInstanceID=%v, %s",
index, clientEndpoint.Host, *clientEndpoint.HTTPPort, xAppEventInstanceID, e2EventInstanceID, idstring(nil, trans))
-
- // Store successfully processed InstanceId for deletion
- restSubscription.AddE2InstanceId(subRespMsg.RequestId.InstanceId)
- restSubscription.AddXappIdToE2Id(xAppEventInstanceID, e2EventInstanceID)
-
- // Send notification to xApp that a Subscription Request has been processed.
- resp := &models.SubscriptionResponse{
- SubscriptionID: restSubId,
- SubscriptionInstances: []*models.SubscriptionInstance{
- &models.SubscriptionInstance{E2EventInstanceID: &e2EventInstanceID,
- ErrorCause: nil,
- XappEventInstanceID: &xAppEventInstanceID},
- },
- }
- // Mark REST subscription request processesd.
- restSubscription.SetProcessed()
- xapp.Logger.Info("Sending successful REST notification to endpoint=%v:%v, XappEventInstanceID=%v, E2EventInstanceID=%v, %s",
- clientEndpoint.Host, *clientEndpoint.HTTPPort, xAppEventInstanceID, e2EventInstanceID, idstring(nil, trans))
- xapp.Subscription.Notify(resp, *clientEndpoint)
- c.UpdateCounter(cRestSubNotifToXapp)
-
+ c.sendSuccesfullResponseNotification(restSubId, restSubscription, xAppEventInstanceID, e2EventInstanceID, clientEndpoint, trans)
}
+ trans.Release()
}
}
--- /dev/null
+/*
+==================================================================================
+ Copyright (c) 2021 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 control
+
+import (
+ "bytes"
+ "crypto/md5"
+ "encoding/gob"
+ "encoding/hex"
+ "fmt"
+ "sync"
+ "time"
+
+ "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
+)
+
+type retransEntry struct {
+ restSubsId string
+ startTime time.Time
+}
+
+type duplicateCtrl struct {
+ mutex sync.Mutex
+ retransMap map[string]retransEntry
+ collCount int
+}
+
+func (d *duplicateCtrl) Init() {
+ d.retransMap = make(map[string]retransEntry)
+}
+
+func (d *duplicateCtrl) IsDuplicateToOngoingTransaction(restSubsId string, payload interface{}) (error, bool, string) {
+
+ var data bytes.Buffer
+ enc := gob.NewEncoder(&data)
+
+ if err := enc.Encode(payload); err != nil {
+ xapp.Logger.Error("Failed to encode %v\n", payload)
+ return err, false, ""
+ }
+
+ hash := md5.Sum(data.Bytes())
+
+ md5sum := hex.EncodeToString(hash[:])
+
+ d.mutex.Lock()
+ defer d.mutex.Unlock()
+
+ entry, present := d.retransMap[md5sum]
+
+ if present {
+ xapp.Logger.Info("Collision detected. REST subs ID %s has ongoing transaction with MD5SUM : %s started at %s\n", entry.restSubsId, md5sum, entry.startTime.Format(time.ANSIC))
+ d.collCount++
+ return nil, true, md5sum
+ }
+
+ entry = retransEntry{restSubsId: restSubsId, startTime: time.Now()}
+
+ xapp.Logger.Debug("Added Md5SUM %s for restSubsId %s at %s\n", md5sum, entry.restSubsId, entry.startTime)
+
+ d.retransMap[md5sum] = entry
+
+ return nil, false, md5sum
+}
+
+func (d *duplicateCtrl) TransactionComplete(md5sum string) error {
+
+ d.mutex.Lock()
+ defer d.mutex.Unlock()
+
+ entry, present := d.retransMap[md5sum]
+
+ if !present {
+ xapp.Logger.Error("MD5SUM : %s NOT found from table (%v)\n", md5sum, entry)
+ return fmt.Errorf("Retransmission entry not found for MD5SUM %s", md5sum)
+ }
+
+ xapp.Logger.Debug("Releasing transaction duplicate blocker for %s, MD5SUM : %s\n", entry.restSubsId, md5sum)
+
+ delete(d.retransMap, md5sum)
+
+ return nil
+}
--- /dev/null
+/*
+==================================================================================
+ Copyright (c) 2021 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 control
+
+import (
+ "fmt"
+ "testing"
+
+ "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/models"
+ "github.com/stretchr/testify/assert"
+)
+
+type testData struct {
+ Name *string
+ Data []byte
+ SomeVal *int64
+}
+
+func TestDefaultUseCase(t *testing.T) {
+
+ fmt.Println("##################### TestRetransmissionChecker #####################")
+
+ var retransCtrl duplicateCtrl
+ restSubdId := "898dfkjashntgkjasgho4"
+ var name string = "yolo"
+ var someVal int64 = 98765
+ data := testData{Name: &name, Data: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}, SomeVal: &someVal}
+
+ retransCtrl.Init()
+
+ _, duplicate, md5sum := retransCtrl.IsDuplicateToOngoingTransaction(restSubdId, data)
+
+ assert.Equal(t, 1, len(retransCtrl.retransMap))
+ assert.Equal(t, false, duplicate)
+
+ retransCtrl.TransactionComplete(md5sum)
+
+ assert.Equal(t, 0, len(retransCtrl.retransMap))
+}
+
+func TestDuplicate(t *testing.T) {
+
+ fmt.Println("##################### TestDuplicate #####################")
+
+ var retransCtrl duplicateCtrl
+ restSubdId := "898dfkjashntgkjasgho4"
+ var name string = "yolo"
+ var someVal int64 = 98765
+ data := testData{Name: &name, Data: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}, SomeVal: &someVal}
+
+ var name2 string = "yolo"
+ var someVal2 int64 = 98765
+
+ data2 := new(testData)
+ data2.Name = &name2
+ data2.SomeVal = &someVal2
+ datax := []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}
+ data2.Data = datax
+
+ retransCtrl.Init()
+
+ _, duplicate, md5sum := retransCtrl.IsDuplicateToOngoingTransaction(restSubdId, data)
+ assert.Equal(t, 1, len(retransCtrl.retransMap))
+ assert.Equal(t, false, duplicate)
+
+ _, duplicate, md5sum = retransCtrl.IsDuplicateToOngoingTransaction(restSubdId, data2)
+ assert.Equal(t, 1, len(retransCtrl.retransMap))
+ assert.Equal(t, true, duplicate)
+
+ retransCtrl.TransactionComplete(md5sum)
+
+ assert.Equal(t, 0, len(retransCtrl.retransMap))
+}
+
+func TestNoneDuplicate(t *testing.T) {
+
+ fmt.Println("##################### TestNoneDuplicate #####################")
+
+ var retransCtrl duplicateCtrl
+ restSubdId := "898dfkjashntgkjasgho4"
+ var name string = "yolo"
+ var someVal int64 = 98765
+ data := testData{Name: &name, Data: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}, SomeVal: &someVal}
+
+ var name2 string = "yolo"
+ var someVal2 int64 = 98765
+
+ data2 := new(testData)
+ data2.Name = &name2
+ data2.SomeVal = &someVal2
+ datax := []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 1} // One byte changed
+ data2.Data = datax
+
+ retransCtrl.Init()
+
+ _, duplicate, md5sum := retransCtrl.IsDuplicateToOngoingTransaction(restSubdId, data)
+ assert.Equal(t, 1, len(retransCtrl.retransMap))
+ assert.Equal(t, false, duplicate)
+
+ _, duplicate2, md5sum2 := retransCtrl.IsDuplicateToOngoingTransaction(restSubdId, data2)
+ assert.Equal(t, 2, len(retransCtrl.retransMap))
+ assert.Equal(t, false, duplicate2)
+
+ retransCtrl.TransactionComplete(md5sum)
+ retransCtrl.TransactionComplete(md5sum2)
+
+ assert.Equal(t, 0, len(retransCtrl.retransMap))
+}
+
+func TestEncodingError(t *testing.T) {
+
+ fmt.Println("##################### TestEncodingError #####################")
+
+ var retransCtrl duplicateCtrl
+ restSubdId := "898dfkjashntgkjasgho4"
+ var data interface{}
+
+ retransCtrl.Init()
+
+ err, duplicate, _ := retransCtrl.IsDuplicateToOngoingTransaction(restSubdId, data)
+ assert.NotEqual(t, err, nil)
+ assert.Equal(t, 0, len(retransCtrl.retransMap))
+ assert.Equal(t, false, duplicate)
+}
+
+func TestRemovalError(t *testing.T) {
+
+ fmt.Println("##################### TestRemovalError #####################")
+
+ var retransCtrl duplicateCtrl
+ restSubdId := "898dfkjashntgkjasgho4"
+ var data testData
+
+ retransCtrl.Init()
+
+ err, duplicate, md5sum := retransCtrl.IsDuplicateToOngoingTransaction(restSubdId, data)
+ assert.Equal(t, 1, len(retransCtrl.retransMap))
+ assert.Equal(t, false, duplicate)
+
+ err = retransCtrl.TransactionComplete(md5sum)
+ assert.Empty(t, err)
+
+ err = retransCtrl.TransactionComplete(md5sum)
+ assert.NotEmpty(t, err)
+}
+
+func TestXappRestReqDuplicate(t *testing.T) {
+
+ fmt.Println("##################### TestXappRestReqDuplicate #####################")
+
+ var retransCtrl duplicateCtrl
+
+ msg1 := new(models.SubscriptionParams)
+ msg2 := new(models.SubscriptionParams)
+
+ retransCtrl.Init()
+
+ _, duplicate, md5sum := retransCtrl.IsDuplicateToOngoingTransaction("foobar", msg1)
+ assert.Equal(t, 1, len(retransCtrl.retransMap))
+ assert.Equal(t, false, duplicate)
+
+ _, duplicate, md5sum = retransCtrl.IsDuplicateToOngoingTransaction("foobar", msg2)
+ assert.Equal(t, 1, len(retransCtrl.retransMap))
+ assert.Equal(t, true, duplicate)
+
+ retransCtrl.TransactionComplete(md5sum)
+
+ assert.Equal(t, 0, len(retransCtrl.retransMap))
+}
xAppIdToE2Id map[int64]int64
SubReqOngoing bool
SubDelReqOngoing bool
+ Md5sumOngoing string
}
func (r *RESTSubscription) AddE2InstanceId(instanceId uint32) {
func (r *RESTSubscription) SetProcessed() {
r.SubReqOngoing = false
+ r.Md5sumOngoing = ""
}
type Registry struct {
mainCtrl.c.registry.subIds = nil
// Initialize subIds slice and subscription map
mainCtrl.c.registry.Initialize()
+ restDuplicateCtrl.Init()
// Read subIds and subscriptions from database
subIds, register, err := mainCtrl.c.ReadAllSubscriptionsFromSdl()
if err != nil {
// SetPackerIf(e2ap_wrapper.NewAsn1E2APPacker())
SetPackerIf(e2ap_wrapper.NewUtAsn1E2APPacker())
+
+ restDuplicateCtrl.Init()
+
}
//-----------------------------------------------------------------------------
// | RESTSubReq2 | |
// | (retrans) | |
// |---------------->| |
-// | | |
-// | | SubReq2 |
-// | |------------->|
-// | RESTSubResp2 | |
+// | RESTSubResp(201)| |
// |<----------------| |
+// | | |
// | | SubResp1 |
// | |<-------------|
// | RESTNotif1 | |
// |<----------------| |
-// | | SubResp1 |
-// | |<-------------|
-// | RESTNotif2 | |
-// |<----------------| |
// | | |
// | [SUBS DELETE] |
// | | |
mainCtrl.CounterValuesToBeVeriefied(t, CountersToBeAdded{
Counter{cRestSubReqFromXapp, 2},
Counter{cRestSubRespToXapp, 2},
- Counter{cSubReqToE2, 2},
- Counter{cSubRespFromE2, 2},
- Counter{cRestSubNotifToXapp, 2},
- Counter{cRestSubDelReqFromXapp, 2},
- Counter{cSubDelReqToE2, 2},
- Counter{cSubDelRespFromE2, 2},
- Counter{cRestSubDelRespToXapp, 2},
+ Counter{cSubReqToE2, 1},
+ Counter{cSubRespFromE2, 1},
+ Counter{cRestSubNotifToXapp, 1},
+ Counter{cRestSubDelReqFromXapp, 1},
+ Counter{cSubDelReqToE2, 1},
+ Counter{cSubDelRespFromE2, 1},
+ Counter{cRestSubDelRespToXapp, 1},
})
// Retry/duplicate will get the same way as the first request. Submgr cannot detect duplicate RESTRequests
// Contianed duplicate messages from same xapp will not be merged. Here we use xappConn2 to simulate sending
waiter := rtmgrHttp.AllocNextSleep(10, true)
params := xappConn1.GetRESTSubsReqReportParams(subReqCount)
restSubId1 := xappConn1.SendRESTSubsReq(t, params)
- restSubId2 := xappConn2.SendRESTSubsReq(t, params)
+ xappConn2.SendRESTSubsReq(t, params)
waiter.WaitResult(t)
- xappConn1.WaitListedRestNotifications(t, []string{restSubId1, restSubId2})
+ xappConn1.WaitListedRestNotifications(t, []string{restSubId1})
// Depending one goroutine scheduling order, we cannot say for sure which xapp reaches e2term first. Thus
// the order is not significant he6re.
crereq, cremsg := e2termConn1.RecvSubsReq(t)
e2termConn1.SendSubsResp(t, crereq, cremsg)
- crereq, cremsg = e2termConn1.RecvSubsReq(t)
- e2termConn1.SendSubsResp(t, crereq, cremsg)
e2SubsIdA := <-xappConn1.ListedRESTNotifications
xapp.Logger.Info("TEST: 1.st XAPP notification received e2SubsId=%v", e2SubsIdA)
- e2SubsIdB := <-xappConn1.ListedRESTNotifications
- xapp.Logger.Info("TEST: 2.nd XAPP notification received e2SubsId=%v", e2SubsIdB)
// Del1
xappConn1.SendRESTSubsDelReq(t, &restSubId1)
delreq1, delmsg1 := e2termConn1.RecvSubsDelReq(t)
e2termConn1.SendSubsDelResp(t, delreq1, delmsg1)
- // Del2
- xappConn2.SendRESTSubsDelReq(t, &restSubId2)
- delreq2, delmsg2 := e2termConn1.RecvSubsDelReq(t)
- e2termConn1.SendSubsDelResp(t, delreq2, delmsg2)
-
- mainCtrl.wait_multi_subs_clean(t, []uint32{e2SubsIdA.E2SubsId, e2SubsIdB.E2SubsId}, 10)
-
- waitSubsCleanup(t, e2SubsIdB.E2SubsId, 10)
+ mainCtrl.wait_multi_subs_clean(t, []uint32{e2SubsIdA.E2SubsId}, 10)
mainCtrl.VerifyCounterValues(t)
}
// |<----------------| |
//
//-----------------------------------------------------------------------------
+
func TestRESTSubReqAndSubDelOkWithRestartInMiddle(t *testing.T) {
CaseBegin("TestRESTSubReqAndSubDelOkWithRestartInMiddle")
// | | | |
//
//-----------------------------------------------------------------------------
+
func TestRESTSubReqAndSubDelOkSameActionWithRestartsInMiddle(t *testing.T) {
CaseBegin("TestRESTSubReqAndSubDelOkSameActionWithRestartsInMiddle")
// |<----------------| |
//
//-----------------------------------------------------------------------------
+
func TestRESTReportSubReqAndSubDelOk(t *testing.T) {
CaseBegin("TestRESTReportSubReqAndSubDelOk")
subReqCount := 1
// | |<-------------|
//
//-----------------------------------------------------------------------------
+
func TestRESTUnpackSubscriptionResponseDecodeFail(t *testing.T) {
xapp.Logger.Info("TEST: TestRESTUnpackSubscriptionResponseDecodeFail")
subReqCount := 1
// | |<-------------|
//
//-----------------------------------------------------------------------------
+
func TestRESTUnpackSubscriptionResponseUnknownInstanceId(t *testing.T) {
xapp.Logger.Info("TEST: TestRESTUnpackSubscriptionResponseUnknownInstanceId")
subReqCount := 1