32ea09f8627d288ad1cc30e55e3de52255a7663b
[ric-plt/submgr.git] / pkg / control / main_test.go
1 /*
2 ==================================================================================
3   Copyright (c) 2019 AT&T Intellectual Property.
4   Copyright (c) 2019 Nokia
5
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
9
10        http://www.apache.org/licenses/LICENSE-2.0
11
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 ==================================================================================
18 */
19
20 package control
21
22 import (
23         "encoding/json"
24         "fmt"
25         "gerrit.o-ran-sc.org/r/ric-plt/submgr/pkg/rtmgr_models"
26         "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
27         "io/ioutil"
28         "net/http"
29         "os"
30         "strconv"
31         "strings"
32         "testing"
33         "time"
34 )
35
36 //-----------------------------------------------------------------------------
37 //
38 //-----------------------------------------------------------------------------
39 type testingControl struct {
40         desc     string
41         syncChan chan struct{}
42 }
43
44 func (tc *testingControl) ReadyCB(data interface{}) {
45         xapp.Logger.Info("testingControl(%s) ReadyCB", tc.desc)
46         tc.syncChan <- struct{}{}
47         return
48 }
49
50 func (tc *testingControl) WaitCB() {
51         <-tc.syncChan
52 }
53
54 func initTestingControl(desc string, rtfile string, port string) testingControl {
55         tc := testingControl{}
56         os.Setenv("RMR_SEED_RT", rtfile)
57         os.Setenv("RMR_SRC_ID", "localhost:"+port)
58         xapp.Logger.Info("Using rt file %s", os.Getenv("RMR_SEED_RT"))
59         xapp.Logger.Info("Using src id  %s", os.Getenv("RMR_SRC_ID"))
60         tc.desc = strings.ToUpper(desc)
61         tc.syncChan = make(chan struct{})
62         return tc
63 }
64
65 //-----------------------------------------------------------------------------
66 //
67 //-----------------------------------------------------------------------------
68 type testingRmrControl struct {
69         testingControl
70         rmrClientTest *xapp.RMRClient
71         active        bool
72 }
73
74 func (tc *testingRmrControl) RmrSend(params *RMRParams) (err error) {
75         //
76         //NOTE: Do this way until xapp-frame sending is improved
77         //
78         xapp.Logger.Info("(%s) RmrSend %s", tc.desc, params.String())
79         status := false
80         i := 1
81         for ; i <= 10 && status == false; i++ {
82                 status = tc.rmrClientTest.SendMsg(params.RMRParams)
83                 if status == false {
84                         xapp.Logger.Info("(%s) RmrSend failed. Retry count %v, %s", tc.desc, i, params.String())
85                         time.Sleep(500 * time.Millisecond)
86                 }
87         }
88         if status == false {
89                 err = fmt.Errorf("(%s) RmrSend failed. Retry count %v, %s", tc.desc, i, params.String())
90                 xapp.Rmr.Free(params.Mbuf)
91         }
92         return
93 }
94
95 func initTestingRmrControl(desc string, rtfile string, port string, stat string, consumer xapp.MessageConsumer) testingRmrControl {
96         tc := testingRmrControl{}
97         tc.active = false
98         tc.testingControl = initTestingControl(desc, rtfile, port)
99         tc.rmrClientTest = xapp.NewRMRClientWithParams("tcp:"+port, 4096, 1, stat)
100         tc.rmrClientTest.SetReadyCB(tc.ReadyCB, nil)
101         go tc.rmrClientTest.Start(consumer)
102         tc.WaitCB()
103         return tc
104 }
105
106 //-----------------------------------------------------------------------------
107 //
108 //-----------------------------------------------------------------------------
109 type testingMessageChannel struct {
110         rmrConChan chan *RMRParams
111 }
112
113 func initTestingMessageChannel() testingMessageChannel {
114         mc := testingMessageChannel{}
115         mc.rmrConChan = make(chan *RMRParams)
116         return mc
117 }
118
119 //-----------------------------------------------------------------------------
120 //
121 //-----------------------------------------------------------------------------
122 type xappTransaction struct {
123         tc   *testingXappControl
124         xid  string
125         meid *xapp.RMRMeid
126 }
127
128 type testingXappControl struct {
129         testingRmrControl
130         testingMessageChannel
131         xid_seq uint64
132 }
133
134 func (tc *testingXappControl) newXid() string {
135         var xid string
136         xid = tc.desc + "_XID_" + strconv.FormatUint(uint64(tc.xid_seq), 10)
137         tc.xid_seq++
138         return xid
139 }
140
141 func (tc *testingXappControl) newXappTransaction(xid *string, ranname string) *xappTransaction {
142         trans := &xappTransaction{}
143         trans.tc = tc
144         if xid == nil {
145                 trans.xid = tc.newXid()
146         } else {
147                 trans.xid = *xid
148         }
149         trans.meid = &xapp.RMRMeid{RanName: ranname}
150         return trans
151 }
152
153 func (tc *testingXappControl) Consume(params *xapp.RMRParams) (err error) {
154         xapp.Rmr.Free(params.Mbuf)
155         params.Mbuf = nil
156         msg := &RMRParams{params}
157
158         if params.Mtype == 55555 {
159                 xapp.Logger.Info("(%s) Testing message ignore %s", tc.desc, msg.String())
160                 tc.active = true
161                 return
162         }
163
164         if strings.Contains(msg.Xid, tc.desc) {
165                 xapp.Logger.Info("(%s) Consume %s", tc.desc, msg.String())
166                 tc.rmrConChan <- msg
167         } else {
168                 xapp.Logger.Info("(%s) Ignore %s", tc.desc, msg.String())
169         }
170         return
171 }
172
173 func createNewXappControl(desc string, rtfile string, port string, stat string) *testingXappControl {
174         xappCtrl := &testingXappControl{}
175         xappCtrl.testingRmrControl = initTestingRmrControl(desc, rtfile, port, stat, xappCtrl)
176         xappCtrl.testingMessageChannel = initTestingMessageChannel()
177         xappCtrl.xid_seq = 1
178         return xappCtrl
179 }
180
181 //-----------------------------------------------------------------------------
182 //
183 //-----------------------------------------------------------------------------
184 type testingE2termControl struct {
185         testingRmrControl
186         testingMessageChannel
187 }
188
189 func (tc *testingE2termControl) Consume(params *xapp.RMRParams) (err error) {
190         xapp.Rmr.Free(params.Mbuf)
191         params.Mbuf = nil
192         msg := &RMRParams{params}
193
194         if params.Mtype == 55555 {
195                 xapp.Logger.Info("(%s) Testing message ignore %s", tc.desc, msg.String())
196                 tc.active = true
197                 return
198         }
199
200         xapp.Logger.Info("(%s) Consume %s", tc.desc, msg.String())
201         tc.rmrConChan <- msg
202         return
203 }
204
205 func createNewE2termControl(desc string, rtfile string, port string, stat string) *testingE2termControl {
206         e2termCtrl := &testingE2termControl{}
207         e2termCtrl.testingRmrControl = initTestingRmrControl(desc, rtfile, port, stat, e2termCtrl)
208         e2termCtrl.testingMessageChannel = initTestingMessageChannel()
209         return e2termCtrl
210 }
211
212 //-----------------------------------------------------------------------------
213 //
214 //-----------------------------------------------------------------------------
215 type testingMainControl struct {
216         testingControl
217         c *Control
218 }
219
220 func createNewMainControl(desc string, rtfile string, port string) *testingMainControl {
221         mainCtrl = &testingMainControl{}
222         mainCtrl.testingControl = initTestingControl(desc, rtfile, port)
223         mainCtrl.c = NewControl()
224         xapp.SetReadyCB(mainCtrl.ReadyCB, nil)
225         go xapp.RunWithParams(mainCtrl.c, false)
226         mainCtrl.WaitCB()
227         return mainCtrl
228 }
229
230 //-----------------------------------------------------------------------------
231 //
232 //-----------------------------------------------------------------------------
233
234 func testError(t *testing.T, pattern string, args ...interface{}) {
235         xapp.Logger.Error(fmt.Sprintf(pattern, args...))
236         t.Errorf(fmt.Sprintf(pattern, args...))
237 }
238
239 func testLog(t *testing.T, pattern string, args ...interface{}) {
240         xapp.Logger.Info(fmt.Sprintf(pattern, args...))
241         t.Logf(fmt.Sprintf(pattern, args...))
242 }
243
244 func testCreateTmpFile(str string) (string, error) {
245         file, err := ioutil.TempFile("/tmp", "*.rt")
246         if err != nil {
247                 return "", err
248         }
249         _, err = file.WriteString(str)
250         if err != nil {
251                 file.Close()
252                 return "", err
253         }
254         return file.Name(), nil
255 }
256
257 //-----------------------------------------------------------------------------
258 //
259 //-----------------------------------------------------------------------------
260
261 var xappConn1 *testingXappControl
262 var xappConn2 *testingXappControl
263 var e2termConn *testingE2termControl
264 var mainCtrl *testingMainControl
265
266 func TestMain(m *testing.M) {
267         xapp.Logger.Info("TestMain start")
268
269         //---------------------------------
270         //
271         //---------------------------------
272         http_handler := func(w http.ResponseWriter, r *http.Request) {
273                 var req rtmgr_models.XappSubscriptionData
274                 err := json.NewDecoder(r.Body).Decode(&req)
275                 if err != nil {
276                         xapp.Logger.Error("%s", err.Error())
277                 }
278                 xapp.Logger.Info("(http handler) handling Address=%s Port=%d SubscriptionID=%d", *req.Address, *req.Port, *req.SubscriptionID)
279
280                 w.WriteHeader(200)
281         }
282
283         go func() {
284                 http.HandleFunc("/", http_handler)
285                 http.ListenAndServe("localhost:8989", nil)
286         }()
287
288         //---------------------------------
289         //
290         //---------------------------------
291
292         //
293         //Cfg creation won't work like this as xapp-frame reads it during init.
294         //
295         /*
296             cfgstr:=`{
297               "local": {
298                   "host": ":8080"
299               },
300               "logger": {
301                   "level": 4
302               },
303               "rmr": {
304                  "protPort": "tcp:14560",
305                  "maxSize": 4096,
306                  "numWorkers": 1,
307                  "txMessages": ["RIC_SUB_REQ", "RIC_SUB_DEL_REQ"],
308                  "rxMessages": ["RIC_SUB_RESP", "RIC_SUB_FAILURE", "RIC_SUB_DEL_RESP", "RIC_SUB_DEL_FAILURE", "RIC_INDICATION"]
309               },
310               "db": {
311                   "host": "localhost",
312                   "port": 6379,
313                   "namespaces": ["sdl", "rnib"]
314               },
315                  "rtmgr" : {
316                    "HostAddr" : "localhost",
317                    "port" : "8989",
318                    "baseUrl" : "/"
319                  }
320            `
321
322            cfgfilename,_ := testCreateTmpFile(cfgstr)
323            defer os.Remove(cfgfilename)
324            os.Setenv("CFG_FILE", cfgfilename)
325         */
326         xapp.Logger.Info("Using cfg file %s", os.Getenv("CFG_FILE"))
327
328         //---------------------------------
329         // Static routetable for rmr
330         //
331         // NOTE: Routing table is configured so, that responses
332         //       are duplicated to xapp1 and xapp2 instances.
333         //       If XID is not matching xapp stub will just
334         //       drop message. (Messages 12011, 12012, 12021, 12022)
335         //
336         // 14560 submgr
337         // 15560 e2term stub
338         // 13560 xapp1 stub
339         // 13660 xapp2 stub
340         //
341         //---------------------------------
342
343         allrt := `newrt|start
344 mse|12010|-1|localhost:14560
345 mse|12010,localhost:14560|-1|localhost:15560
346 mse|12011,localhost:15560|-1|localhost:14560
347 mse|12012,localhost:15560|-1|localhost:14560
348 mse|12011,localhost:14560|-1|localhost:13660;localhost:13560
349 mse|12012,localhost:14560|-1|localhost:13660;localhost:13560
350 mse|12020|-1|localhost:14560
351 mse|12020,localhost:14560|-1|localhost:15560
352 mse|12021,localhost:15560|-1|localhost:14560
353 mse|12022,localhost:15560|-1|localhost:14560
354 mse|12021,localhost:14560|-1|localhost:13660;localhost:13560
355 mse|12022,localhost:14560|-1|localhost:13660;localhost:13560
356 mse|55555|-1|localhost:13660;localhost:13560,localhost:15560
357 newrt|end
358 `
359
360         //---------------------------------
361         //
362         //---------------------------------
363         xapp.Logger.Info("### submgr main run ###")
364
365         subsrt := allrt
366         /*
367                 subsrt := `newrt|start
368            mse|12010|-1|localhost:14560
369            mse|12010,localhost:14560|-1|localhost:15560
370            mse|12011,localhost:15560|-1|localhost:14560
371            mse|12011|-1|localhost:13560;localhost:13660
372            mse|12012,localhost:15560|-1|localhost:14560
373            mse|12012|-1|localhost:13560;localhost:13660
374            mse|12020|-1|localhost:14560
375            mse|12020,localhost:14560|-1|localhost:15560
376            mse|12021,localhost:15560|-1|localhost:14560
377            mse|12021|-1|localhost:13560;localhost:13660
378            mse|12022,localhost:15560|-1|localhost:14560
379            mse|12022|-1|localhost:13560;localhost:13660
380            newrt|end
381            `
382         */
383
384         subrtfilename, _ := testCreateTmpFile(subsrt)
385         defer os.Remove(subrtfilename)
386         mainCtrl = createNewMainControl("main", subrtfilename, "14560")
387
388         //---------------------------------
389         //
390         //---------------------------------
391         xapp.Logger.Info("### xapp1 rmr run ###")
392
393         xapprt1 := allrt
394         /*
395                 xapprt1 := `newrt|start
396            mse|12010|-1|localhost:14560
397            mse|12011|-1|localhost:13560
398            mse|12012|-1|localhost:13560
399            mse|12020|-1|localhost:14560
400            mse|12021|-1|localhost:13560
401            mse|12022|-1|localhost:13560
402            newrt|end
403            `
404         */
405
406         xapprtfilename1, _ := testCreateTmpFile(xapprt1)
407         defer os.Remove(xapprtfilename1)
408         xappConn1 = createNewXappControl("xappstub1", xapprtfilename1, "13560", "RMRXAPP1STUB")
409
410         //---------------------------------
411         //
412         //---------------------------------
413
414         xapp.Logger.Info("### xapp2 rmr run ###")
415
416         xapprt2 := allrt
417         /*
418                 xapprt2 := `newrt|start
419            mse|12010|-1|localhost:14560
420            mse|12011|-1|localhost:13660
421            mse|12012|-1|localhost:13660
422            mse|12020|-1|localhost:14560
423            mse|12021|-1|localhost:13660
424            mse|12022|-1|localhost:13660
425            newrt|end
426            `
427         */
428
429         xapprtfilename2, _ := testCreateTmpFile(xapprt2)
430         defer os.Remove(xapprtfilename2)
431         xappConn2 = createNewXappControl("xappstub2", xapprtfilename2, "13660", "RMRXAPP2STUB")
432
433         //---------------------------------
434         //
435         //---------------------------------
436         xapp.Logger.Info("### e2term rmr run ###")
437
438         e2termrt := allrt
439         /*
440                 e2termrt := `newrt|start
441            mse|12010|-1|localhost:15560
442            mse|12011|-1|localhost:14560
443            mse|12012|-1|localhost:14560
444            mse|12020|-1|localhost:15560
445            mse|12021|-1|localhost:14560
446            mse|12022|-1|localhost:14560
447            newrt|end
448            `
449         */
450
451         e2termrtfilename, _ := testCreateTmpFile(e2termrt)
452         defer os.Remove(e2termrtfilename)
453         e2termConn = createNewE2termControl("e2termstub", e2termrtfilename, "15560", "RMRE2TERMSTUB")
454
455         //---------------------------------
456         // Testing message sending
457         //---------------------------------
458         var dummyBuf []byte = make([]byte, 100)
459
460         params := &RMRParams{&xapp.RMRParams{}}
461         params.Mtype = 55555
462         params.SubId = -1
463         params.Payload = dummyBuf
464         params.PayloadLen = 100
465         params.Meid = &xapp.RMRMeid{RanName: "NONEXISTINGRAN"}
466         params.Xid = "THISISTESTFORSTUBS"
467         params.Mbuf = nil
468
469         status := false
470         i := 1
471         for ; i <= 10 && status == false; i++ {
472                 xapp.Rmr.Send(params.RMRParams, false)
473                 if e2termConn.active == true && xappConn1.active == true && xappConn2.active == true {
474                         status = true
475                         break
476                 } else {
477                         xapp.Logger.Info("Sleep 0.5 secs and try routes again")
478                         time.Sleep(500 * time.Millisecond)
479                 }
480         }
481
482         if status == false {
483                 xapp.Logger.Error("Could not initialize routes")
484                 os.Exit(1)
485         }
486
487         //---------------------------------
488         //
489         //---------------------------------
490         code := m.Run()
491         os.Exit(code)
492 }