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