2 ==================================================================================
3 Copyright (c) 2019 AT&T Intellectual Property.
4 Copyright (c) 2019 Nokia
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
10 http://www.apache.org/licenses/LICENSE-2.0
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License for the specific language governing permissions and
16 limitations under the License.
19 This source code is part of the near-RT RIC (RAN Intelligent Controller)
20 platform project (RICP).
22 ==================================================================================
25 Mnemonic: httprestful_test.go
26 Abstract: HTTPRestful unit tests
35 xfmodel "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/models"
36 "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
37 "github.com/go-openapi/swag"
38 "github.com/spf13/viper"
44 "routing-manager/pkg/models"
45 "routing-manager/pkg/rpe"
46 "routing-manager/pkg/rtmgr"
47 "routing-manager/pkg/sbi"
48 "routing-manager/pkg/sdl"
49 "routing-manager/pkg/stub"
55 var BasicXAppLists = []byte(`[
57 "name":"xapp-01","status":"unknown","version":"1.2.3",
59 {"name":"xapp-01-instance-01","status":"pending","ip":"172.16.1.103","port":4555,
60 "txMessages":["ControlIndication"],
61 "rxMessages":["LoadIndication","Reset"]
63 {"name":"xapp-01-instance-02","status":"pending","ip":"10.244.1.12","port":4561,
64 "txMessages":["ControlIndication","SNStatusTransfer"],
65 "rxMessages":["LoadIndication","HandoverPreparation"]
71 var SubscriptionResp = []byte(`{"ID":"deadbeef1234567890", "Version":0, "EventType":"all"}`)
73 var E2TListResp = []byte(`[{"e2tAddress":"127.0.0.1:0","ranNames":["RanM0","RanN0"]},{"e2tAddress":"127.0.0.1:1","ranNames":["RanM1","RanN1"]},{"e2tAddress":"127.0.0.1:2","ranNames":["RanM2","RanN2"]},{"e2tAddress":"127.0.0.1:3","ranNames":["RanM3","RanN3"]}]`)
75 var SubscriptionList = []byte(`[{"SubscriptionId":11,"Meid":"Test-Gnb","Endpoint":["127.0.0.1:4056"]}]`)
77 var InvalidSubResp = []byte(`{"Version":0, "EventType":all}`)
79 type Consumer struct{}
82 func (m Consumer) Consume(params *xapp.RMRParams) (err error) {
83 xapp.Sdl.Store("myKey", params.Payload)
88 func TestMain(m *testing.M) {
89 go xapp.RunWithParams(Consumer{}, viper.GetBool("db.waitForSdl"))
90 time.Sleep(time.Duration(5) * time.Second)
95 func TestValidateXappCallbackData_1(t *testing.T) {
96 data := models.XappCallbackData{
97 XApps: *swag.String("[]"),
98 Version: *swag.Int64(1),
99 Event: *swag.String("someevent"),
100 ID: *swag.String("123456")}
102 err := validateXappCallbackData(&data)
104 t.Error("Invalid XApp callback data: " + err.Error())
108 func TestValidateXappCallbackDataInvalid(t *testing.T) {
109 data := models.XappCallbackData{}
110 err := validateXappCallbackData(&data)
114 func TestValidateXappSubscriptionsData(t *testing.T) {
116 rtmgr.RMRConnStatus = make(map[string]bool)
117 ep := make(map[string]*rtmgr.Endpoint)
118 ep["dummy"] = &rtmgr.Endpoint{Uuid: "10.0.0.1:0", Name: "E2TERM", XAppType: "app1", Ip: "", Port: 0, TxMessages: []string{"", ""}, RxMessages: []string{"", ""}, Socket: nil, IsReady: true, Keepalive: true}
120 data := models.XappSubscriptionData{
121 Address: swag.String("10.1.1.1"),
123 SubscriptionID: swag.Int32(123456)}
126 err = validateXappSubscriptionData(&data)
131 data1 := models.XappSubscriptionData{
132 Address: swag.String(""),
134 SubscriptionID: swag.Int32(123456)}
135 err = validateXappSubscriptionData(&data1)
138 data2 := models.E2tData{
139 E2TAddress: swag.String(""),
141 /*err = validateE2tData(&data2)*/
143 //e2tchannel := make(chan *models.E2tData, 10)
144 _ = CreateNewE2tHandleHandlerImpl(&data2)
145 //defer close(e2tchannel)
147 //test case for provideXappSubscriptionHandleImp
148 //datachannel := make(chan *models.XappSubscriptionData, 10)
149 sdlEngine, _ = sdl.GetSdl("file")
150 sbiEngine, _ = sbi.GetSbi("rmrpush")
151 rpeEngine, _ = rpe.GetRpe("rmrpush")
152 _ = ProvideXappSubscriptionHandleImpl(&data1)
153 //defer close(datachannel)
155 //test case for deleteXappSubscriptionHandleImpl
156 _ = DeleteXappSubscriptionHandleImpl(&data1)
158 data3 := models.XappSubscriptionData{
159 Address: swag.String("10.55.55.5"),
161 SubscriptionID: swag.Int32(123456)}
162 //test case for deleteXappSubscriptionHandleImpl
163 _ = DeleteXappSubscriptionHandleImpl(&data3)
164 data4 := models.XappSubscriptionData{
165 Address: swag.String("1.5.5.5"),
167 SubscriptionID: swag.Int32(1236)}
168 _ = DeleteXappSubscriptionHandleImpl(&data4)
172 func TestValidateE2tDataEmpty(t *testing.T) {
173 data := models.E2tData{
174 E2TAddress: swag.String(""),
176 err, _ := validateE2tData(&data)
180 func TestValidateE2tDataDNSLookUPfails(t *testing.T) {
181 rtmgr.RMRConnStatus = make(map[string]bool)
182 data := models.E2tData{
183 E2TAddress: swag.String("e2t.1com:1234"),
185 err, _ := validateE2tData(&data)
189 func TestValidateE2tDataInvalid(t *testing.T) {
190 rtmgr.RMRConnStatus = make(map[string]bool)
191 data := models.E2tData{
192 E2TAddress: swag.String("10.101.01.1"),
194 err, _ := validateE2tData(&data)
198 func TestValidateE2tDatavalid(t *testing.T) {
199 rtmgr.RMRConnStatus = make(map[string]bool)
200 data := models.E2tData{
201 E2TAddress: swag.String("10.101.01.1:8098"),
204 err, _ := validateE2tData(&data)
207 _ = CreateNewE2tHandleHandlerImpl(&data)
211 func TestValidateE2tDatavalidEndpointPresent(t *testing.T) {
212 rtmgr.RMRConnStatus = make(map[string]bool)
213 data := models.E2tData{
214 E2TAddress: swag.String("10.101.01.1:8098"),
217 // insert endpoint for testing purpose
218 uuid := "10.101.01.1:8098"
219 ep := &rtmgr.Endpoint{
224 err, _ := validateE2tData(&data)
227 // delete endpoint for at end of test case
228 delete(rtmgr.Eps, uuid)
232 func TestValidateDeleteE2tData(t *testing.T) {
234 rtmgr.RMRConnStatus = make(map[string]bool)
236 data := models.E2tDeleteData{
237 E2TAddress: swag.String(""),
240 err := validateDeleteE2tData(&data)
241 if err.Error() != "E2TAddress is empty!!!" {
246 data = models.E2tDeleteData{
247 E2TAddress: swag.String("10.101.01.1:8098"),
250 err = validateDeleteE2tData(&data)
256 //################ Create End Point dummy entry
257 uuid := "10.101.01.1:8098"
258 ep := &rtmgr.Endpoint{
262 //#####################
264 data = models.E2tDeleteData{
265 E2TAddress: swag.String("10.101.01.1:8098"),
266 RanAssocList: models.RanE2tMap{
267 {E2TAddress: swag.String("10.101.01.1:8098")},
271 err = validateDeleteE2tData(&data)
276 // delete endpoint for at end of test case
277 //################ Delete End Point dummy entry
278 delete(rtmgr.Eps, uuid)
279 //#####################
283 //################ Create End Point dummy entry
284 uuid = "10.101.01.1:9991"
285 ep = &rtmgr.Endpoint{
290 uuid = "10.101.01.1:9992"
291 ep = &rtmgr.Endpoint{
295 //#####################
297 data = models.E2tDeleteData{
298 E2TAddress: swag.String("10.101.01:8098"),
299 RanAssocList: models.RanE2tMap{
300 {E2TAddress: swag.String("10.101.01.1:9991")},
301 {E2TAddress: swag.String("10.101.01.1:9992")},
305 err = validateDeleteE2tData(&data)
309 //################ Delete End Point dummy entry
310 delete(rtmgr.Eps, "10.101.01.1:9991")
311 delete(rtmgr.Eps, "10.101.01.1:9992")
312 //#####################
316 data = models.E2tDeleteData{
317 E2TAddress: swag.String("10.101.01:8098"),
318 RanAssocList: models.RanE2tMap{
319 {E2TAddress: swag.String("10.101.01.19991")},
323 err = validateDeleteE2tData(&data)
324 if err.Error() != "E2T Delete - RanAssocList E2TAddress is not a proper format like ip:port, 10.101.01.19991" {
329 func TestValidateE2TAddressRANListData(t *testing.T) {
331 data := models.RanE2tMap{
333 E2TAddress: swag.String(""),
336 err := validateE2TAddressRANListData(data)
341 data = models.RanE2tMap{
343 E2TAddress: swag.String("10.101.01.1:8098"),
346 err = validateE2TAddressRANListData(data)
353 func TestAssociateRanToE2THandlerImpl(t *testing.T) {
355 data := models.RanE2tMap{
357 E2TAddress: swag.String("10.101.01.1:8098"),
360 err := AssociateRanToE2THandlerImpl(data)
365 //################ Create End Point dummy entry
366 uuid := "10.101.01.1:8098"
367 ep := &rtmgr.Endpoint{
371 //#####################
373 data = models.RanE2tMap{
375 E2TAddress: swag.String("10.101.01.1:8098"),
378 err = AssociateRanToE2THandlerImpl(data)
383 //################ Delete End Point dummy entry
384 delete(rtmgr.Eps, uuid)
385 //#####################
388 func TestDisassociateRanToE2THandlerImpl(t *testing.T) {
390 data := models.RanE2tMap{
392 E2TAddress: swag.String("10.101.01.1:8098"),
395 err := DisassociateRanToE2THandlerImpl(data)
399 //################ Create End Point dummy entry
400 uuid := "10.101.01.1:8098"
401 ep := &rtmgr.Endpoint{
405 //#####################
407 data = models.RanE2tMap{
409 E2TAddress: swag.String("10.101.01.1:8098"),
412 err = DisassociateRanToE2THandlerImpl(data)
417 //################ Delete End Point dummy entry
418 delete(rtmgr.Eps, uuid)
419 //#####################
422 func TestDeleteE2tHandleHandlerImpl(t *testing.T) {
424 data := models.E2tDeleteData{
425 E2TAddress: swag.String(""),
427 err := DeleteE2tHandleHandlerImpl(&data)
432 //################ Create End Point dummy entry
433 uuid := "10.101.01.1:8098"
434 ep := &rtmgr.Endpoint{
438 //#####################
440 data = models.E2tDeleteData{
441 E2TAddress: swag.String("10.101.01.1:8098"),
443 err = DeleteE2tHandleHandlerImpl(&data)
447 //################ Delete End Point dummy entry
448 delete(rtmgr.Eps, uuid)
449 //#####################
452 func TestSubscriptionExists(t *testing.T) {
454 data := models.XappSubscriptionData{
455 Address: swag.String("10.0.0.0"),
457 SubscriptionID: swag.Int32(1234)}
459 rtmgr.Subs = *stub.ValidSubscriptions
461 yes_no := subscriptionExists(&data)
462 yes_no = addSubscription(&rtmgr.Subs, &data)
463 yes_no = addSubscription(&rtmgr.Subs, &data)
464 yes_no = delSubscription(&rtmgr.Subs, &data)
465 yes_no = delSubscription(&rtmgr.Subs, &data)
469 func TestAddSubscriptions(t *testing.T) {
471 subdata := models.XappSubscriptionData{
472 Address: swag.String("10.0.0.0"),
474 SubscriptionID: swag.Int32(1234)}
476 rtmgr.Subs = *stub.ValidSubscriptions
477 yes_no := addSubscription(&rtmgr.Subs, &subdata)
481 func TestHttpInstance(t *testing.T) {
482 sdlEngine, _ := sdl.GetSdl("file")
483 rpeEngine, _ := rpe.GetRpe("rmrpush")
484 sbiEngine, _ := sbi.GetSbi("rmrpush")
485 httpinstance := NewHttpRestful()
486 err := httpinstance.Terminate()
488 fmt.Printf("sbiEngine = %v", sbiEngine)
490 createMockPlatformComponents()
491 //ts := createMockAppmgrWithData("127.0.0.1:3000", BasicXAppLists, nil)
495 err = httpinstance.Initialize(XMURL, "httpgetter", "rt.json", "config.json", E2MURL, sdlEngine, rpeEngine, &m)
498 func TestXappCallbackWithData(t *testing.T) {
499 data := models.XappCallbackData{
500 XApps: *swag.String("[]"),
501 Version: *swag.Int64(1),
502 Event: *swag.String("someevent"),
503 ID: *swag.String("123456")}
504 _, _ = recvXappCallbackData(&data)
507 func TestXappCallbackNodata(t *testing.T) {
508 //data := *models.XappCallbackData
509 _, _ = recvXappCallbackData(nil)
512 func TestE2TwithData(t *testing.T) {
513 data2 := models.E2tData{
514 E2TAddress: swag.String("1.2.3.4"),
515 RanNamelist: []string{"ran1", "ran2"},
517 _, _, _ = recvNewE2Tdata(&data2)
520 func TestE2TwithNoData(t *testing.T) {
521 _, _, _ = recvNewE2Tdata(nil)
524 func TestProvideXappSubscriptionHandleImpl(t *testing.T) {
526 data := models.XappSubscriptionData{
527 Address: swag.String("10.0.0.0"),
529 SubscriptionID: swag.Int32(1234)}
530 _ = ProvideXappSubscriptionHandleImpl(&data)
533 func createMockAppmgrWithData(url string, g []byte, p []byte, t []byte) *httptest.Server {
534 l, err := net.Listen("tcp", url)
536 fmt.Println("Failed to create listener: " + err.Error())
538 ts := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
539 if r.Method == "GET" && r.URL.String() == "/ric/v1/xapps" {
540 w.Header().Add("Content-Type", "application/json")
541 w.WriteHeader(http.StatusOK)
544 if r.Method == "POST" && r.URL.String() == "/ric/v1/subscriptions" {
545 w.Header().Add("Content-Type", "application/json")
546 w.WriteHeader(http.StatusCreated)
549 if r.Method == "GET" && r.URL.String() == "/ric/v1/e2t/list" {
550 w.Header().Add("Content-Type", "application/json")
551 w.WriteHeader(http.StatusOK)
561 func createMockSubmgrWithData(url string, t []byte) *httptest.Server {
562 l, err := net.Listen("tcp", url)
564 fmt.Println("Failed to create listener: " + err.Error())
566 ts := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
568 if r.Method == "GET" && r.URL.String() == "//ric/v1/subscriptions" {
569 w.Header().Add("Content-Type", "application/json")
570 w.WriteHeader(http.StatusOK)
580 func createMockPlatformComponents() {
581 var filename = "config.json"
582 file, _ := json.MarshalIndent(stub.ValidPlatformComponents, "", "")
583 filestr := string(file)
584 filestr = "{\"PlatformComponents\":" + filestr + "}"
585 file = []byte(filestr)
586 _ = ioutil.WriteFile(filename, file, 644)
589 func TestProvideXappHandleHandlerImpl(t *testing.T) {
590 data := models.XappCallbackData{
591 XApps: *swag.String("[]"),
592 Version: *swag.Int64(1),
593 Event: *swag.String("someevent"),
594 ID: *swag.String("123456")}
595 err := ProvideXappHandleHandlerImpl(&data)
597 //Empty XappCallbackdata
598 data1 := models.XappCallbackData{}
599 err = ProvideXappHandleHandlerImpl(&data1)
603 func TestValidateXappCallbackData(t *testing.T) {
604 data := models.XappCallbackData{
605 XApps: *swag.String("[]"),
606 Version: *swag.Int64(1),
607 Event: *swag.String("someevent"),
608 ID: *swag.String("123456")}
610 err := validateXappCallbackData(&data)
612 t.Error("Invalid XApp callback data: " + err.Error())
616 func TestValidateXappCallbackDataWithInvalidData(t *testing.T) {
617 data := models.XappCallbackData{
618 XApps: *swag.String("{}"),
619 Version: *swag.Int64(1),
620 Event: *swag.String("someevent"),
621 ID: *swag.String("123456")}
623 err := validateXappCallbackData(&data)
625 t.Error("Invalid XApp callback data: " + err.Error())
629 func TestHttpGetXAppsInvalidData(t *testing.T) {
630 _, err := httpGetXApps(XMURL)
632 t.Error("No XApp data received: " + err.Error())
636 func TestHttpGetXAppsWithValidData(t *testing.T) {
638 ts := createMockAppmgrWithData("127.0.0.1:3000", BasicXAppLists, nil, nil)
642 xapplist, err := httpGetXApps(XMURL)
644 t.Error("Error occured: " + err.Error())
646 if len(*xapplist) != expected {
647 t.Error("Invalid XApp data: got " + string(len(*xapplist)) + ", expected " + string(expected))
652 func TestRetrieveStartupDataTimeout(t *testing.T) {
653 sdlEngine, _ := sdl.GetSdl("file")
654 createMockPlatformComponents()
655 err := retrieveStartupData(XMURL, "httpgetter", "rt.json", "config.json", E2MURL, sdlEngine)
657 t.Error("Cannot retrieve startup data: " + err.Error())
660 os.Remove("config.json")
663 func TestRetrieveStartupData(t *testing.T) {
664 ts := createMockAppmgrWithData("127.0.0.1:3000", BasicXAppLists, SubscriptionResp, nil)
668 ts1 := createMockAppmgrWithData("127.0.0.1:8085", nil, nil, E2TListResp)
672 ts2 := createMockSubmgrWithData("127.0.0.1:8089", SubscriptionList)
676 sdlEngine, _ := sdl.GetSdl("file")
677 var httpRestful, _ = GetNbi("httpRESTful")
678 createMockPlatformComponents()
679 httpRestful.(*HttpRestful).RetrieveStartupData(XMURL, "httpgetter", "rt.json", "config.json", E2MURL, sdlEngine)
680 //err := retrieveStartupData(XMURL, "httpgetter", "rt.json", "config.json", sdlEngine)
682 t.Error("Cannot retrieve startup data: " + err.Error())
685 os.Remove("config.json")
688 func TestRetrieveStartupDataWithInvalidSubResp(t *testing.T) {
689 ts := createMockAppmgrWithData("127.0.0.1:3000", BasicXAppLists, InvalidSubResp, nil)
692 sdlEngine, _ := sdl.GetSdl("file")
693 var httpRestful, _ = GetNbi("httpRESTful")
694 createMockPlatformComponents()
695 err := httpRestful.(*HttpRestful).RetrieveStartupData(XMURL, "httpgetter", "rt.json", "config.json", E2MURL, sdlEngine)
697 t.Error("Cannot retrieve startup data: " + err.Error())
700 os.Remove("config.json")
703 func TestInvalidarguments(t *testing.T) {
704 _ = PostSubReq("\n", "nbifinterface")
705 _ = PostSubReq("xmurl", "\n")
708 func TestInitEngine(t *testing.T) {
712 func TestUpdateXappSubscription(t *testing.T) {
713 ep := make(map[string]*rtmgr.Endpoint)
714 ep["dummy"] = &rtmgr.Endpoint{Uuid: "10.0.0.1:0", Name: "E2TERM", XAppType: "app1", Ip: "10.1.1.1", Port: 1234, TxMessages: []string{"", ""}, RxMessages: []string{"", ""}, Socket: nil, IsReady: true, Keepalive: true}
719 xapp := models.XappElement{
720 Address: swag.String("10.1.1.1"),
724 var b models.XappList
726 _ = UpdateXappSubscriptionHandleImpl(&b, 10)
728 //Test case when subscriptions already exist
729 data := models.XappSubscriptionData{
730 Address: swag.String("10.0.0.0"),
732 SubscriptionID: swag.Int32(12345)}
734 rtmgr.Subs = *stub.ValidSubscriptions
736 subscriptionExists(&data)
737 addSubscription(&rtmgr.Subs, &data)
738 _ = UpdateXappSubscriptionHandleImpl(&b, 10)
742 func TestDumpDebugdata(t *testing.T) {
743 _, _ = DumpDebugData()
746 func TestManagerRequest(t *testing.T) {
747 var params xapp.RMRParams
748 var rmrmeid xapp.RMRMeid
749 sdlEngine, _ = sdl.GetSdl("file")
750 sbiEngine, _ = sbi.GetSbi("rmrpush")
751 rpeEngine, _ = rpe.GetRpe("rmrpush")
752 rmrmeid.RanName = "gnb1"
753 c := Control{make(chan *xapp.RMRParams)}
754 params.Payload = []byte{1, 2, 3, 4}
757 params.Meid = &rmrmeid
758 params.Src = "sender"
759 params.PayloadLen = 4
760 c.handleUpdateToRoutingManagerRequest(¶ms)
763 func TestRecievermr(t *testing.T) {
764 var params xapp.RMRParams
765 var rmrmeid xapp.RMRMeid
766 sdlEngine, _ = sdl.GetSdl("file")
767 sbiEngine, _ = sbi.GetSbi("rmrpush")
768 rpeEngine, _ = rpe.GetRpe("rmrpush")
769 rmrmeid.RanName = "gnb1"
771 params.Payload = []byte{1, 2, 3, 4}
773 params.Meid = &rmrmeid
774 params.Src = "sender"
775 params.PayloadLen = 4
777 c := Control{make(chan *xapp.RMRParams)}
778 params.Mtype = xapp.RICMessageTypes["RMRRM_REQ_TABLE"]
779 c.recievermr(¶ms)
780 params.Mtype = xapp.RICMessageTypes["RMRRM_TABLE_STATE"]
781 c.recievermr(¶ms)
783 c.recievermr(¶ms)
785 rtmgr.Rtmgr_ready = true
786 params.Mtype = xapp.RICMessageTypes["RMRRM_REQ_TABLE"]
787 c.recievermr(¶ms)
788 time.Sleep(time.Duration(5) * time.Second)
791 func TestAddDelRmr(t *testing.T) {
792 sdlEngine, _ = sdl.GetSdl("file")
793 sbiEngine, _ = sbi.GetSbi("rmrpush")
794 rpeEngine, _ = rpe.GetRpe("rmrpush")
795 var routelist models.Routelist
796 mtype := uint32(1234)
797 tendpoint := "goofle.com"
798 listofroutes := models.AddRmrRoute{SubscriptionID: 0, SenderEndPoint: "nokia.com", MessageType: &mtype, TargetEndPoint: &tendpoint}
799 listofroutes2 := models.AddRmrRoute{SubscriptionID: 1, SenderEndPoint: "", MessageType: &mtype, TargetEndPoint: &tendpoint}
800 listofroutes3 := models.AddRmrRoute{MessageType: &mtype, TargetEndPoint: &tendpoint}
801 Adddelrmrroute(routelist, false)
802 routelist = append(routelist, &listofroutes)
803 routelist = append(routelist, &listofroutes2)
804 routelist = append(routelist, &listofroutes3)
805 routelist = append(routelist, &listofroutes3)
806 Adddelrmrroute(routelist, true)
808 Adddelrmrroute(routelist, false)
811 func TestPopulateSubscription(t *testing.T) {
812 var sublist xfmodel.SubscriptionList
814 subdata := xfmodel.SubscriptionData{Endpoint: []string{"xapp1.com:3800"}, SubscriptionID: -1, Meid: ""}
815 subdata2 := xfmodel.SubscriptionData{Endpoint: []string{"xapp2.com:3800"}, SubscriptionID: 11, Meid: ""}
816 subdata3 := xfmodel.SubscriptionData{Endpoint: []string{"xapp3.com:3800"}, SubscriptionID: 221, Meid: ""}
817 sublist = append(sublist, &subdata)
818 sublist = append(sublist, &subdata2)
819 sublist = append(sublist, &subdata3)
821 PopulateSubscription(sublist)