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.
17 ==================================================================================
26 "github.com/stretchr/testify/assert"
27 "github.com/stretchr/testify/mock"
36 "gerrit.o-ran-sc.org/r/ric-plt/appmgr/pkg/appmgr"
37 "gerrit.o-ran-sc.org/r/ric-plt/appmgr/pkg/models"
41 var resp models.SubscriptionResponse
42 var mockedSdl *SdlMock
43 var mockedSdl2 *SdlMock
46 func TestMain(m *testing.M) {
48 appmgr.Logger.SetLevel(0)
50 mockedSdl = new(SdlMock)
51 mockedSdl2 = new(SdlMock)
53 rh = createResthook(false, mockedSdl,mockedSdl2)
58 func TestAddSubscriptionSuccess(t *testing.T) {
59 var mockSdlRetOk error
60 subsReq := createSubscription(models.EventTypeCreated, int64(5), int64(10), "http://localhost:8087/xapps_hook")
62 mockedSdl.expectDbSet(t, subsReq, mockSdlRetOk)
63 resp := rh.AddSubscription(subsReq)
64 assert.Equal(t, resp.Version, int64(0))
65 assert.Equal(t, resp.EventType, models.EventTypeCreated)
68 func TestAddSubscriptionExists(t *testing.T) {
69 resp := rh.AddSubscription(createSubscription(models.EventTypeCreated, int64(5), int64(10), "http://localhost:8087/xapps_hook"))
70 assert.Equal(t, resp.Version, int64(0))
71 assert.Equal(t, resp.EventType, models.EventTypeCreated)
74 func TestDeletesubscriptionSuccess(t *testing.T) {
75 var mockSdlRetOk error
77 mockedSdl.On("Set", mock.Anything).Return(mockSdlRetOk)
78 resp := rh.AddSubscription(createSubscription(models.EventTypeDeleted, int64(5), int64(10), "http://localhost:8087/xapps_hook2"))
79 assert.Equal(t, resp.Version, int64(0))
80 assert.Equal(t, resp.EventType, models.EventTypeDeleted)
82 resp, ok := rh.DeleteSubscription(resp.ID)
83 assert.Equal(t, ok, true)
84 assert.Equal(t, resp.Version, int64(0))
85 assert.Equal(t, resp.EventType, models.EventTypeDeleted)
88 func TestDeletesubscriptionInvalid(t *testing.T) {
89 resp, ok := rh.DeleteSubscription("Non-existent-ID")
90 assert.Equal(t, ok, false)
91 assert.Equal(t, resp.Version, int64(0))
92 assert.Equal(t, resp.EventType, models.EventType(""))
95 func TestModifySubscriptionSuccess(t *testing.T) {
96 resp := rh.AddSubscription(createSubscription(models.EventTypeCreated, int64(5), int64(10), "http://localhost:8087/xapps_hook2"))
97 assert.Equal(t, resp.Version, int64(0))
98 assert.Equal(t, resp.EventType, models.EventTypeCreated)
100 resp, ok := rh.ModifySubscription(resp.ID, createSubscription(models.EventTypeModified, int64(5), int64(10), "http://localhost:8087/xapps_hook2"))
101 assert.Equal(t, ok, true)
102 assert.Equal(t, resp.Version, int64(0))
103 assert.Equal(t, resp.EventType, models.EventTypeModified)
106 func TestModifySubscriptionForNonExistingSubscription(t *testing.T) {
107 resp, ok := rh.ModifySubscription("Non-existent-ID", createSubscription(models.EventTypeModified, int64(5), int64(10), "http://localhost:8087/xapps_hook2"))
108 assert.Equal(t, ok, false)
109 assert.Equal(t, *resp, models.SubscriptionResponse{})
112 func TestDeleteSubscriptionForNonExistingSubscription(t *testing.T) {
113 resp, ok := rh.DeleteSubscription("Non-existent-ID")
114 assert.Equal(t, ok, false)
115 assert.Equal(t, resp.Version, int64(0))
116 assert.Equal(t, resp.EventType, models.EventType(""))
119 func TestGetAllSubscriptionSuccess(t *testing.T) {
120 flushExistingSubscriptions()
121 subscriptions := rh.GetAllSubscriptions()
122 assert.Equal(t, len(subscriptions), 0)
124 rh.AddSubscription(createSubscription(models.EventTypeCreated, int64(5), int64(10), "http://localhost:8087/xapps_hook"))
125 rh.AddSubscription(createSubscription(models.EventTypeModified, int64(5), int64(10), "http://localhost:8087/xapps_hook2"))
127 subscriptions = rh.GetAllSubscriptions()
128 assert.Equal(t, len(subscriptions), 2)
131 func TestGetSubscriptionByIdSuccess(t *testing.T) {
132 flushExistingSubscriptions()
134 sub1 := createSubscription(models.EventTypeCreated, int64(5), int64(10), "http://localhost:8087/xapps_hook")
135 sub2 := createSubscription(models.EventTypeModified, int64(5), int64(10), "http://localhost:8087/xapps_hook2")
136 r1 := rh.AddSubscription(sub1)
137 r2 := rh.AddSubscription(sub2)
139 resp1, ok := rh.GetSubscriptionById(r1.ID)
140 assert.Equal(t, ok, true)
141 assert.Equal(t, resp1.Data, sub1.Data)
143 resp2, ok := rh.GetSubscriptionById(r2.ID)
144 assert.Equal(t, ok, true)
145 assert.Equal(t, resp2.Data, sub2.Data)
148 func TestGetSubscriptionByIdForNonExistingSubscription(t *testing.T) {
149 resp, ok := rh.GetSubscriptionById("Non-existent-ID")
150 assert.Equal(t, ok, false)
151 assert.Equal(t, resp, models.Subscription{})
154 func TestNotifyClientsNoXapp(t *testing.T) {
155 rh.NotifyClients(models.AllDeployedXapps{}, models.EventTypeUndeployed)
158 func TestNotifySuccess(t *testing.T) {
159 flushExistingSubscriptions()
161 sub := createSubscription(models.EventTypeCreated, int64(5), int64(10), "http://localhost:8087/xapps_hook")
162 resp := rh.AddSubscription(sub)
164 xapp := getDummyXapp()
165 ts := createHTTPServer(t, "POST", "/xapps_hook", 8087, http.StatusOK, nil)
168 v, ok := rh.subscriptions.Get(resp.ID)
170 err := rh.notify(models.AllDeployedXapps{&xapp}, models.EventTypeUndeployed, v.(SubscriptionInfo), 1)
174 func TestNotifySuccessIfHttpErrorResponse(t *testing.T) {
175 flushExistingSubscriptions()
177 sub := createSubscription(models.EventTypeCreated, int64(5), int64(10), "http://localhost:8087/xapps_hook")
178 resp := rh.AddSubscription(sub)
180 xapp := getDummyXapp()
181 ts := createHTTPServer(t, "POST", "/xapps_hook", 8087, http.StatusInternalServerError, nil)
184 v, ok := rh.subscriptions.Get(resp.ID)
186 err := rh.notify(models.AllDeployedXapps{&xapp}, models.EventTypeUndeployed, v.(SubscriptionInfo), 1)
190 func TestNotifyReturnsErrorAfterRetriesIfNoHttpServer(t *testing.T) {
191 flushExistingSubscriptions()
193 sub := createSubscription(models.EventTypeCreated, int64(2), int64(1), "http://localhost:8087/xapps_hook")
194 resp := rh.AddSubscription(sub)
196 xapp := getDummyXapp()
198 v, ok := rh.subscriptions.Get(resp.ID)
200 err := rh.notify(models.AllDeployedXapps{&xapp}, models.EventTypeUndeployed, v.(SubscriptionInfo), 1)
201 assert.NotNil(t, err)
202 assert.Equal(t, 0, len(rh.subscriptions.Items()))
205 func TestRestoreSubscriptionsSuccess(t *testing.T) {
206 var mockSdlRetOk error
208 mSdl2 := new(SdlMock)
211 subsReq := createSubscription(models.EventTypeCreated, int64(5), int64(10), "http://localhost:8087/xapps_hook")
212 serializedSubsReq, err := json.Marshal(subsReq)
215 mockSdlGetRetVal := make(map[string]interface{})
216 //Cast data to string to act like a real SDL/Redis client
217 mockSdlGetRetVal[key] = string(serializedSubsReq)
218 mSdl.On("GetAll").Return([]string{key}, mockSdlRetOk).Twice()
219 mSdl.On("Get", []string{key}).Return(mockSdlGetRetVal, mockSdlRetOk).Once()
220 restHook := createResthook(true, mSdl,mSdl2)
222 val, found := restHook.subscriptions.Get(key)
223 assert.True(t, found)
224 assert.Equal(t, subsReq, val.(SubscriptionInfo).req)
227 func TestRestoreSubscriptionsFailsIfSdlGetAllFails(t *testing.T) {
228 var mockSdlRetStatus error
230 mSdl2 := new(SdlMock)
232 mGetAllCall := mSdl.On("GetAll")
233 mGetAllCall.RunFn = func(args mock.Arguments) {
235 mockSdlRetStatus = errors.New("some SDL error")
238 mGetAllCall.ReturnArguments = mock.Arguments{[]string{}, mockSdlRetStatus}
241 restHook := createResthook(true, mSdl,mSdl2)
242 assert.Equal(t, 0, len(restHook.subscriptions.Items()))
245 func TestRestoreSubscriptionsFailsIfSdlGetFails(t *testing.T) {
246 var mockSdlRetOk error
248 mSdl2 := new(SdlMock)
249 mockSdlRetNok := errors.New("some SDL error")
251 subsReq := createSubscription(models.EventTypeCreated, int64(5), int64(10), "http://localhost:8087/xapps_hook")
252 serializedSubsReq, err := json.Marshal(subsReq)
255 mockSdlGetRetVal := make(map[string]interface{})
256 mockSdlGetRetVal[key] = serializedSubsReq
258 mSdl.On("GetAll").Return([]string{key}, mockSdlRetOk).Twice()
259 mSdl.On("Get", []string{key}).Return(mockSdlGetRetVal, mockSdlRetNok).Once()
261 restHook := createResthook(true, mSdl,mSdl2)
262 assert.Equal(t, 0, len(restHook.subscriptions.Items()))
265 func TestTeardown(t *testing.T) {
266 var mockSdlRetOk error
267 mockedSdl.On("RemoveAll").Return(mockSdlRetOk).Once()
269 rh.FlushSubscriptions()
272 func TestUpdateAppDataFail1(t *testing.T) {
273 var reg models.RegisterRequest
274 var tEndpoint string = "10.104.237.59"
275 reg.HTTPEndpoint = &tEndpoint
276 rh.UpdateAppData(reg, false)
279 func TestUpdateAppDataFail2(t *testing.T) {
280 var mockSdlRetOk error
281 var params models.RegisterRequest
284 mSdl2 := new(SdlMock)
285 mockSdlRetNok := errors.New("some SDL error")
286 var tEndpoint1 string = "10.104.237.59:8087"
287 params.HTTPEndpoint = &tEndpoint1
288 serializedSubsReq2, err := json.Marshal(params)
290 t.Logf("error in marshal .. %v", err)
293 subsReq := createSubscription(models.EventTypeCreated, int64(5), int64(10), "http://localhost:8087/xapps_hook")
294 serializedSubsReq, err := json.Marshal(subsReq)
299 mockSdlGetRetVal := make(map[string]interface{})
300 mockSdlGetRetVal[key] = serializedSubsReq
302 mockSdlGetRetVal2 := make(map[string]interface{})
303 mockSdlGetRetVal2[value] = serializedSubsReq2
304 mSdl.On("GetAll").Return([]string{key}, mockSdlRetOk).Twice()
305 mSdl.On("Get", []string{key}).Return(mockSdlGetRetVal, mockSdlRetNok).Once()
306 mSdl2.On("Get", []string{value}).Return(mockSdlGetRetVal2, mockSdlRetOk).Once()
308 restHook := createResthook(false, mSdl,mSdl2)
310 mSdl2.On("Get", []string{value}).Return(mockSdlGetRetVal2, mockSdlRetOk).Once()
312 ret := restHook.GetAppsInSDL()
318 func TestGetAppsInSDLFail3(t *testing.T) {
319 var mockSdlRetOk error
320 var params models.RegisterRequest
323 mSdl2 := new(SdlMock)
324 mockSdlRetNok := errors.New("some SDL error")
326 serializedSubsReq1, err := json.Marshal(params)
328 t.Logf("error in marshal .. %v", err)
331 subsReq := createSubscription(models.EventTypeCreated, int64(5), int64(10), "http://localhost:8087/xapps_hook")
332 serializedSubsReq, err := json.Marshal(subsReq)
337 mockSdlGetRetVal := make(map[string]interface{})
338 mockSdlGetRetVal[key] = serializedSubsReq
340 mockSdlGetRetVal1 := make(map[string]interface{})
341 mockSdlGetRetVal1[key] = serializedSubsReq1
343 mSdl.On("GetAll").Return([]string{key}, mockSdlRetOk).Twice()
344 mSdl.On("Get", []string{key}).Return(mockSdlGetRetVal, mockSdlRetNok).Once()
345 mSdl2.On("Get", []string{value}).Return(mockSdlGetRetVal1, mockSdlRetOk).Once()
347 restHook := createResthook(false, mSdl,mSdl2)
349 mSdl2.On("Get", []string{value}).Return(mockSdlGetRetVal1, mockSdlRetOk).Once()
350 ret2 := restHook.GetAppsInSDL()
352 t.Logf("SDL Returning: %s \n",*ret2)
358 func TestUpdateAppDataSucc(t *testing.T) {
359 var mockSdlRetOk error
360 var params models.RegisterRequest
363 mSdl2 := new(SdlMock)
364 mockSdlRetNok := errors.New("some SDL error")
366 var tEndpoint1 string = "10.104.237.59:8087"
367 params.HTTPEndpoint = &tEndpoint1
368 serializedSubsReq1, err := json.Marshal(params)
370 t.Logf("error in marshal .. %v", err)
372 subsReq := createSubscription(models.EventTypeCreated, int64(5), int64(10), "http://localhost:8087/xapps_hook")
373 serializedSubsReq, err := json.Marshal(subsReq)
378 mockSdlGetRetVal := make(map[string]interface{})
379 mockSdlGetRetVal[key] = serializedSubsReq
381 mockSdlGetRetVal1 := make(map[string]interface{})
382 mockSdlGetRetVal1[key] = serializedSubsReq1
384 mSdl.On("GetAll").Return([]string{key}, mockSdlRetOk).Twice()
385 mSdl.On("Get", []string{key}).Return(mockSdlGetRetVal, mockSdlRetNok).Once()
386 mSdl2.On("Get", []string{value}).Return(mockSdlGetRetVal1, mockSdlRetOk).Once()
388 restHook := createResthook(false, mSdl,mSdl2)
390 mSdl2.On("Get", []string{value}).Return(mockSdlGetRetVal1, mockSdlRetOk).Once()
391 mSdl2.On("Set", mock.Anything).Return(mockSdlRetOk)
392 restHook.UpdateAppData(params, true)
395 func TestUpdateAppDataSucc1(t *testing.T) {
396 var mockSdlRetOk error
397 var params models.RegisterRequest
400 mSdl2 := new(SdlMock)
401 mockSdlRetNok := errors.New("some SDL error")
403 var tEndpoint1 string = "10.104.237.59:8087"
404 params.HTTPEndpoint = &tEndpoint1
405 appsindb := []string{ "10.104.237.59:8088 " , " ", " "," 10.104.237.59:8087"}
406 serializedSubsReq1, err := json.Marshal(appsindb)
408 t.Logf("error in marshal .. %v", err)
410 subsReq := createSubscription(models.EventTypeCreated, int64(5), int64(10), "http://localhost:8087/xapps_hook")
411 serializedSubsReq, err := json.Marshal(subsReq)
416 mockSdlGetRetVal := make(map[string]interface{})
417 mockSdlGetRetVal[key] = serializedSubsReq
419 mockSdlGetRetVal1 := make(map[string]interface{})
420 mockSdlGetRetVal1[value] = serializedSubsReq1
422 mSdl.On("GetAll").Return([]string{key}, mockSdlRetOk).Twice()
423 mSdl.On("Get", []string{key}).Return(mockSdlGetRetVal, mockSdlRetNok).Once()
424 mSdl2.On("Get", []string{value}).Return(mockSdlGetRetVal1, mockSdlRetOk).Once()
426 restHook := createResthook(false, mSdl,mSdl2)
428 mSdl2.On("Get", []string{value}).Return(mockSdlGetRetVal1, mockSdlRetOk).Once()
429 mSdl2.On("Set", []string{value}).Return(mockSdlRetOk).Twice()
431 mSdl2.On("Remove").Return(mockSdlRetOk)
432 mSdl2.On("Set", mock.Anything).Return(mockSdlRetOk)
433 restHook.UpdateAppData(params, true)
437 func TestUpdateAppDataSucc2(t *testing.T) {
438 var mockSdlRetOk error
439 var params models.RegisterRequest
442 mSdl2 := new(SdlMock)
443 mockSdlRetNok := errors.New("some SDL error")
445 var tEndpoint1 string = "10.104.237.59:8087"
446 params.Config = "/temp/config.yaml"
447 params.HTTPEndpoint = &tEndpoint1
448 serializedSubsReq1, err := json.Marshal(tEndpoint1)
450 t.Logf("error in marshal .. %v", err)
452 subsReq := createSubscription(models.EventTypeCreated, int64(5), int64(10), "http://localhost:8087/xapps_hook")
453 serializedSubsReq, err := json.Marshal(subsReq)
458 mockSdlGetRetVal := make(map[string]interface{})
459 mockSdlGetRetVal[key] = serializedSubsReq
461 mockSdlGetRetVal1 := make(map[string]interface{})
462 mockSdlGetRetVal1[value] = serializedSubsReq1
464 mSdl.On("GetAll").Return([]string{key}, mockSdlRetOk).Twice()
465 mSdl.On("Get", []string{key}).Return(mockSdlGetRetVal, mockSdlRetNok).Once()
466 mSdl2.On("Get", []string{value}).Return(mockSdlGetRetVal1, mockSdlRetOk).Once()
468 restHook := createResthook(false, mSdl,mSdl2)
470 mSdl2.On("Get", []string{value}).Return(mockSdlGetRetVal1, mockSdlRetOk).Once()
471 mSdl2.On("Set", []string{value}).Return(mockSdlRetOk).Twice()
473 mSdl2.On("Remove").Return(mockSdlRetOk)
474 mSdl2.On("Set", mock.Anything).Return(mockSdlRetOk)
475 restHook.UpdateAppData(params, true)
477 func createSubscription(et models.EventType, maxRetries, retryTimer int64, targetUrl string) models.SubscriptionRequest {
478 return models.SubscriptionRequest{&models.SubscriptionData{et, &maxRetries, &retryTimer, &targetUrl}}
481 func getDummyXapp() models.Xapp {
482 return generateXapp("dummy-xapp", "deployed", "1.0", "dummy-xapp-8984fc9fd-bkcbp", "running", "service-ricxapp-dummy-xapp-rmr.ricxapp", "4560")
485 func generateXapp(name, status, ver, iname, istatus, ip, port string) (x models.Xapp) {
489 p, _ := strconv.Atoi(port)
490 var msgs appmgr.RtmData
492 instance := &models.XappInstance{
497 TxMessages: msgs.TxMessages,
498 RxMessages: msgs.RxMessages,
500 x.Instances = append(x.Instances, instance)
504 func flushExistingSubscriptions() {
505 var mockSdlRetOk error
506 mockedSdl.On("RemoveAll").Return(mockSdlRetOk).Once()
507 rh.FlushSubscriptions()
510 func createHTTPServer(t *testing.T, method, url string, port, status int, respData interface{}) *httptest.Server {
511 l, err := net.Listen("tcp", fmt.Sprintf("localhost:%d", port))
513 t.Error("Failed to create listener: " + err.Error())
515 ts := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
516 assert.Equal(t, r.Method, method)
517 assert.Equal(t, r.URL.String(), url)
518 w.Header().Add("Content-Type", "application/json")
519 w.WriteHeader(status)
520 b, _ := json.Marshal(respData)
527 time.Sleep(time.Duration(1 * time.Second))
531 func (m *SdlMock) expectDbSet(t *testing.T, subsReq models.SubscriptionRequest, mockRet error) {
532 serializedSubReq, _ := json.Marshal(subsReq)
533 m.On("Set", mock.Anything).Run(
534 func(args mock.Arguments) {
535 sdlKVs := args.Get(0).([]interface{})
536 assert.Equal(t, 2, len(sdlKVs))
537 //Validate that subscription request is set to SDL
538 assert.Equal(t, serializedSubReq, sdlKVs[1])
539 }).Return(mockRet).Once()
542 func TestPublishSubscription(t *testing.T) {
543 sub := createSubscription(models.EventTypeCreated, int64(2), int64(1), "http://localhost:8087/xapps_hook")
544 resp := rh.AddSubscription(sub)
546 xapp := getDummyXapp()
548 v, ok := rh.subscriptions.Get(resp.ID)
551 t.Logf("value : %+v",v)
553 rh.PublishSubscription(xapp,models.EventTypeUndeployed)
556 type SdlMock struct {
560 func (m *SdlMock) Set(pairs ...interface{}) error {
565 func (m *SdlMock) Get(keys []string) (map[string]interface{}, error) {
567 return a.Get(0).(map[string]interface{}), a.Error(1)
570 func (m *SdlMock) GetAll() ([]string, error) {
572 return a.Get(0).([]string), a.Error(1)
575 func (m *SdlMock) RemoveAll() error {
580 func (m *SdlMock) Remove(keys []string) error {