Added Test Cases to improve subscription.go coverity coverage
[ric-plt/submgr.git] / pkg / control / subscription.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         "gerrit.o-ran-sc.org/r/ric-plt/e2ap/pkg/e2ap"
24         "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
25
26         //"reflect"
27         "sync"
28 )
29
30 //-----------------------------------------------------------------------------
31 //
32 //-----------------------------------------------------------------------------
33 type Subscription struct {
34         mutex            sync.Mutex                    // Lock
35         valid            bool                          // valid
36         registry         *Registry                     // Registry
37         ReqId            RequestId                     // ReqId (Requestor Id + Seq Nro a.k.a subsid)
38         Meid             *xapp.RMRMeid                 // Meid/ RanName
39         EpList           xapp.RmrEndpointList          // Endpoints
40         TransLock        sync.Mutex                    // Lock transactions, only one executed per time for subs
41         TheTrans         TransactionIf                 // Ongoing transaction
42         SubReqMsg        *e2ap.E2APSubscriptionRequest // Subscription information
43         SubRFMsg         interface{}                   // Subscription information
44         RetryFromXapp    bool                          // Retry form xApp for subscription that already exist
45         SubRespRcvd      bool                          // Subscription response received
46         DeleteFromDb     bool                          // Delete subscription form db
47         NoRespToXapp     bool                          // Send no response for subscription delete to xApp after restart
48         DoNotWaitSubResp bool                          // Test flag. Response is not waited for Subscription Request
49 }
50
51 func (s *Subscription) String() string {
52         meidstr := "N/A"
53         if s.Meid != nil {
54                 meidstr = s.Meid.String()
55         }
56         return "subs(" + s.ReqId.String() + "/" + meidstr + "/" + s.EpList.String() + ")"
57 }
58
59 func (s *Subscription) GetCachedResponse() (interface{}, bool) {
60         s.mutex.Lock()
61         defer s.mutex.Unlock()
62         return s.SubRFMsg, s.valid
63 }
64
65 func (s *Subscription) SetCachedResponse(subRFMsg interface{}, valid bool) (interface{}, bool) {
66         s.mutex.Lock()
67         defer s.mutex.Unlock()
68         s.SubRFMsg = subRFMsg
69         s.valid = valid
70         return s.SubRFMsg, s.valid
71 }
72
73 func (s *Subscription) GetReqId() *RequestId {
74         s.mutex.Lock()
75         defer s.mutex.Unlock()
76         return &s.ReqId
77 }
78
79 func (s *Subscription) GetMeid() *xapp.RMRMeid {
80         s.mutex.Lock()
81         defer s.mutex.Unlock()
82         return s.Meid
83 }
84
85 func (s *Subscription) GetTransaction() TransactionIf {
86         s.mutex.Lock()
87         defer s.mutex.Unlock()
88         return s.TheTrans
89 }
90
91 func (s *Subscription) WaitTransactionTurn(trans TransactionIf) {
92         s.TransLock.Lock()
93         s.mutex.Lock()
94         s.TheTrans = trans
95         s.mutex.Unlock()
96 }
97
98 func (s *Subscription) ReleaseTransactionTurn(trans TransactionIf) {
99         s.mutex.Lock()
100         if trans != nil && trans == s.TheTrans {
101                 s.TheTrans = nil
102         }
103         s.mutex.Unlock()
104         s.TransLock.Unlock()
105 }
106
107 func (s *Subscription) IsMergeable(trans *TransactionXapp, subReqMsg *e2ap.E2APSubscriptionRequest) bool {
108         s.mutex.Lock()
109         defer s.mutex.Unlock()
110
111         if s.valid == false {
112                 return false
113         }
114
115         if s.SubReqMsg == nil {
116                 return false
117         }
118
119         if s.Meid.RanName != trans.Meid.RanName {
120                 return false
121         }
122
123         // EventTrigger check
124         if s.SubReqMsg.EventTriggerDefinition.Data.Length != subReqMsg.EventTriggerDefinition.Data.Length {
125                 return false
126         }
127         for i := uint64(0); i < s.SubReqMsg.EventTriggerDefinition.Data.Length; i++ {
128                 if s.SubReqMsg.EventTriggerDefinition.Data.Data[i] != subReqMsg.EventTriggerDefinition.Data.Data[i] {
129                         return false
130                 }
131         }
132
133         // Actions check
134         if len(s.SubReqMsg.ActionSetups) != len(subReqMsg.ActionSetups) {
135                 return false
136         }
137
138         for _, acts := range s.SubReqMsg.ActionSetups {
139                 for _, actt := range subReqMsg.ActionSetups {
140                         if acts.ActionId != actt.ActionId {
141                                 return false
142                         }
143                         if acts.ActionType != actt.ActionType {
144                                 return false
145                         }
146
147                         if acts.ActionType != e2ap.E2AP_ActionTypeReport {
148                                 return false
149                         }
150
151                         if acts.RicActionDefinitionPresent != actt.RicActionDefinitionPresent {
152                                 return false
153                         }
154
155                         if acts.ActionDefinitionChoice.Data.Length != actt.ActionDefinitionChoice.Data.Length {
156                                 return false
157                         }
158                         for i := uint64(0); i < acts.ActionDefinitionChoice.Data.Length; i++ {
159                                 if acts.ActionDefinitionChoice.Data.Data[i] != actt.ActionDefinitionChoice.Data.Data[i] {
160                                         return false
161                                 }
162                         }
163                         //reflect.DeepEqual(acts.ActionDefinitionChoice, actt.ActionDefinitionChoice)
164
165                         if acts.SubsequentAction.Present != actt.SubsequentAction.Present ||
166                                 acts.SubsequentAction.Type != actt.SubsequentAction.Type ||
167                                 acts.SubsequentAction.TimetoWait != actt.SubsequentAction.TimetoWait {
168                                 return false
169                         }
170                 }
171         }
172
173         return true
174 }