blob: 561007db3c2d86503c1d291310c522fca5ad5a9b [file] [log] [blame]
Wei-Yu Chen49950b92021-11-08 19:19:18 +08001"""
2Copyright 2020 The Magma Authors.
3
4This source code is licensed under the BSD-style license found in the
5LICENSE file in the root directory of this source tree.
6
7Unless required by applicable law or agreed to in writing, software
8distributed under the License is distributed on an "AS IS" BASIS,
9WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10See the License for the specific language governing permissions and
11limitations under the License.
12"""
13
14from typing import Dict
15from unittest import TestCase
16from unittest.mock import patch
17
18from common.service import MagmaService
19from data_models.data_model import DataModel
20from devices.device_utils import EnodebDeviceName
21from exceptions import Tr069Error
22from state_machines.enb_acs_impl import BasicEnodebAcsStateMachine
23from state_machines.enb_acs_states import (
24 AcsMsgAndTransition,
25 AcsReadMsgResult,
26 EnodebAcsState,
27 WaitEmptyMessageState,
28 WaitInformState,
29 WaitSetParameterValuesState,
30)
31from tests.test_utils.enb_acs_builder import (
32 EnodebAcsStateMachineBuilder,
33)
34from tr069 import models
35
36
37class DummyDataModel(DataModel):
38 @classmethod
39 def get_parameter(cls, param_name):
40 return None
41
42 @classmethod
43 def _get_magma_transforms(cls):
44 return {}
45
46 @classmethod
47 def _get_enb_transforms(cls):
48 return {}
49
50 @classmethod
51 def get_load_parameters(cls):
52 return []
53
54 @classmethod
55 def get_num_plmns(cls) -> int:
56 return 1
57
58 @classmethod
59 def get_parameter_names(cls):
60 return []
61
62 @classmethod
63 def get_numbered_param_names(cls):
64 return {}
65
66
67class DummyHandler(BasicEnodebAcsStateMachine):
68
69 def __init__(
70 self,
71 service: MagmaService,
72 ) -> None:
73 self._state_map = {}
74 super().__init__(service=service, use_param_key=False)
75
76 def are_invasive_changes_applied(self) -> bool:
77 return False
78
79 def _init_state_map(self) -> None:
80 self._state_map = {
81 'wait_inform': WaitInformState(
82 self,
83 when_done='wait_empty',
84 when_boot='wait_rem',
85 ),
86 }
87
88 @property
89 def state_map(self) -> Dict[str, EnodebAcsState]:
90 return self._state_map
91
92 @property
93 def disconnected_state_name(self) -> str:
94 return 'wait_inform'
95
96 @property
97 def unexpected_fault_state_name(self) -> str:
98 """ State to handle unexpected Fault messages """
99 return ''
100
101 @property
102 def device_name(self) -> EnodebDeviceName:
103 return "dummy"
104
105 @property
106 def config_postprocessor(self):
107 pass
108
109 def reboot_asap(self) -> None:
110 """
111 Send a request to reboot the eNodeB ASAP
112 """
113 pass
114
115 def is_enodeb_connected(self) -> bool:
116 return True
117
118 @property
119 def data_model_class(self):
120 return DummyDataModel
121
122
123class EnodebStatusTests(TestCase):
124
125 def _get_acs(self):
126 """ Get a dummy ACS statemachine for tests"""
127 service = EnodebAcsStateMachineBuilder.build_magma_service()
128 return DummyHandler(service)
129
130 @patch(
131 'magma.enodebd.state_machines.enb_acs_states'
132 '.get_param_values_to_set',
133 )
134 @patch(
135 'magma.enodebd.state_machines.enb_acs_states.get_obj_param_values_to_set',
136 )
137 def test_wait_set_parameter_values_state(
138 self, mock_get_obj_param,
139 mock_get_param,
140 ):
141 """ Test SetParameter return values"""
142 mock_get_param.return_value = {}
143 mock_get_obj_param.return_value = {}
144 test_message_0 = models.SetParameterValuesResponse()
145 test_message_0.Status = 0
146 test_message_1 = models.SetParameterValuesResponse()
147 test_message_1.Status = 1
148 # TC-1: return value is 0. No fault
149 acs_state = WaitSetParameterValuesState(
150 self._get_acs(), 'done',
151 'invasive',
152 )
153
154 rc = acs_state.read_msg(test_message_0)
155 self.assertEqual(type(rc), AcsReadMsgResult)
156
157 # It raises exception if we return 1
158 self.assertRaises(
159 Tr069Error,
160 acs_state.read_msg, test_message_1,
161 )
162
163 # It passes if we return 1 and pass the non zero flag
164 acs_state = WaitSetParameterValuesState(
165 self._get_acs(), 'done',
166 'invasive',
167 status_non_zero_allowed=True,
168 )
169 rc = acs_state.read_msg(test_message_1)
170 self.assertEqual(type(rc), AcsReadMsgResult)
171 rc = acs_state.read_msg(test_message_0)
172 self.assertEqual(type(rc), AcsReadMsgResult)
173
174 @patch(
175 'magma.enodebd.state_machines.enb_acs_states.get_optional_param_to_check',
176 )
177 def test_wait_empty_message_state(
178 self,
179 mock_param_to_check,
180 ):
181 test_message_1 = models.DummyInput()
182 test_message_2 = models.SetParameterValuesResponse()
183 mock_param_to_check.return_value = True
184
185 # test 1: No missing_param_transition
186 # ensure we go to done state even when there are
187 # optional params to check
188 acs_state = WaitEmptyMessageState(
189 self._get_acs(),
190 when_done='done',
191 )
192 rc = acs_state.read_msg(test_message_1)
193 self.assertEqual(type(rc), AcsReadMsgResult)
194 self.assertEqual(rc.next_state, 'done')
195 self.assertEqual(rc.msg_handled, True)
196
197 # test 2: No unknown_param_transition
198 # ensure we go to missing state when there are
199 # optional params to check and missing state is specified
200 acs_state = WaitEmptyMessageState(
201 self._get_acs(),
202 when_done='done',
203 when_missing='missing',
204 )
205 rc = acs_state.read_msg(test_message_1)
206 self.assertEqual(type(rc), AcsReadMsgResult)
207 self.assertEqual(rc.next_state, 'missing')
208 self.assertEqual(rc.msg_handled, True)
209
210 # test 3: Negative test case send a message that is not empty
211 # ensure we return msg_handled is False
212 acs_state = WaitEmptyMessageState(
213 self._get_acs(),
214 when_done='done',
215 when_missing='missing',
216 )
217 rc = acs_state.read_msg(test_message_2)
218 self.assertEqual(type(rc), AcsReadMsgResult)
219 self.assertEqual(rc.next_state, None)
220 self.assertEqual(rc.msg_handled, False)
221
222 # test 4: Test get_msg
223 rc = acs_state.get_msg(test_message_1)
224 self.assertEqual(type(rc), AcsMsgAndTransition)
225 self.assertEqual(type(rc.msg), models.DummyInput)
226 self.assertEqual(rc.next_state, None)