blob: 0b0168eaaab618920080757229b9f9107ec7a75f [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
14# pylint: disable=protected-access
15from devices.device_utils import EnodebDeviceName
16from tests.test_utils.enb_acs_builder import (
17 EnodebAcsStateMachineBuilder,
18)
19from tests.test_utils.enodeb_handler import EnodebHandlerTestCase
20from tests.test_utils.tr069_msg_builder import Tr069MessageBuilder
21from tr069 import models
22
23
24class BaicellsQAFBHandlerTests(EnodebHandlerTestCase):
25 def test_manual_reboot(self) -> None:
26 """
27 Test a scenario where a Magma user goes through the enodebd CLI to
28 reboot the Baicells eNodeB.
29
30 This checks the scenario where the command is not sent in the middle
31 of a TR-069 provisioning session.
32 """
33 acs_state_machine = \
34 EnodebAcsStateMachineBuilder \
35 .build_acs_state_machine(EnodebDeviceName.BAICELLS_QAFB)
36
37 # User uses the CLI tool to get eNodeB to reboot
38 acs_state_machine.reboot_asap()
39
40 # And now the Inform message arrives from the eNodeB
41 inform_msg = \
42 Tr069MessageBuilder.get_qafb_inform(
43 '48BF74',
44 'BaiBS_QAFBv123',
45 '1202000181186TB0006',
46 ['2 PERIODIC'],
47 )
48 resp = acs_state_machine.handle_tr069_message(inform_msg)
49 self.assertTrue(
50 isinstance(resp, models.InformResponse),
51 'In reboot sequence, state machine should still '
52 'respond to an Inform with InformResponse.',
53 )
54 req = models.DummyInput()
55 resp = acs_state_machine.handle_tr069_message(req)
56 self.assertTrue(
57 isinstance(resp, models.Reboot),
58 'In reboot sequence, state machine should send a '
59 'Reboot message.',
60 )
61 req = Tr069MessageBuilder.get_reboot_response()
62 resp = acs_state_machine.handle_tr069_message(req)
63 self.assertTrue(
64 isinstance(resp, models.DummyInput),
65 'State machine should end TR-069 session after '
66 'receiving a RebootResponse',
67 )
68
69 def test_manual_reboot_during_provisioning(self) -> None:
70 """
71 Test a scenario where a Magma user goes through the enodebd CLI to
72 reboot the Baicells eNodeB.
73
74 This checks the scenario where the command is sent in the middle
75 of a TR-069 provisioning session.
76 """
77 acs_state_machine = \
78 EnodebAcsStateMachineBuilder \
79 .build_acs_state_machine(EnodebDeviceName.BAICELLS_QAFB)
80
81 # Send an Inform message, wait for an InformResponse
82 inform_msg = \
83 Tr069MessageBuilder.get_qafb_inform(
84 '48BF74',
85 'BaiBS_QAFBv123',
86 '1202000181186TB0006',
87 ['2 PERIODIC'],
88 )
89 resp = acs_state_machine.handle_tr069_message(inform_msg)
90 self.assertTrue(
91 isinstance(resp, models.InformResponse),
92 'Should respond with an InformResponse',
93 )
94
95 # Send an empty http request to kick off the rest of provisioning
96 req = models.DummyInput()
97 resp = acs_state_machine.handle_tr069_message(req)
98
99 # Expect a request for an optional parameter, three times
100 self.assertTrue(
101 isinstance(resp, models.GetParameterValues),
102 'State machine should be requesting param values',
103 )
104 req = Tr069MessageBuilder.get_fault()
105
106 # User uses the CLI tool to get eNodeB to reboot
107 acs_state_machine.reboot_asap()
108
109 resp = acs_state_machine.handle_tr069_message(req)
110 self.assertTrue(
111 isinstance(resp, models.Reboot),
112 'In reboot sequence, state machine should send a '
113 'Reboot message.',
114 )
115 req = Tr069MessageBuilder.get_reboot_response()
116 resp = acs_state_machine.handle_tr069_message(req)
117 self.assertTrue(
118 isinstance(resp, models.DummyInput),
119 'State machine should end TR-069 session after '
120 'receiving a RebootResponse',
121 )
122
123 def test_provision(self) -> None:
124 acs_state_machine = \
125 EnodebAcsStateMachineBuilder \
126 .build_acs_state_machine(EnodebDeviceName.BAICELLS_QAFB)
127
128 # Send an Inform message, wait for an InformResponse
129 inform_msg = \
130 Tr069MessageBuilder.get_qafb_inform(
131 '48BF74',
132 'BaiBS_QAFBv123',
133 '1202000181186TB0006',
134 ['2 PERIODIC'],
135 )
136 resp = acs_state_machine.handle_tr069_message(inform_msg)
137 self.assertTrue(
138 isinstance(resp, models.InformResponse),
139 'Should respond with an InformResponse',
140 )
141
142 # Send an empty http request to kick off the rest of provisioning
143 req = models.DummyInput()
144 resp = acs_state_machine.handle_tr069_message(req)
145
146 # Expect a request for read-only params
147 self.assertTrue(
148 isinstance(resp, models.GetParameterValues),
149 'State machine should be requesting param values',
150 )
151 req = Tr069MessageBuilder.get_qafb_read_only_param_values_response()
152
153 # Send back some typical values
154 # And then SM should request regular parameter values
155 resp = acs_state_machine.handle_tr069_message(req)
156 self.assertTrue(
157 isinstance(resp, models.GetParameterValues),
158 'State machine should be requesting param values',
159 )
160
161 # Send back typical values for the regular parameters
162 req = Tr069MessageBuilder.\
163 get_qafb_regular_param_values_response(
164 admin_state=False,
165 earfcndl=39150,
166 )
167 resp = acs_state_machine.handle_tr069_message(req)
168
169 # SM will be requesting object parameter values
170 self.assertTrue(
171 isinstance(resp, models.GetParameterValues),
172 'State machine should be requesting object param vals',
173 )
174
175 # Send back some typical values for object parameters
176 req = Tr069MessageBuilder.get_qafb_object_param_values_response()
177 resp = acs_state_machine.handle_tr069_message(req)
178
179 self.assertTrue(
180 isinstance(resp, models.AddObject),
181 'State machine should be adding objects',
182 )
183
184 def test_get_rpc_methods_cold(self) -> None:
185 """
186 Test the scenario where:
187 - enodeB just booted
188 - enodeB is cold and has no state of ACS RPCMethods
189 - Simulate the enodeB performing the initial Inform and
190 the call for the GetRPCMethods, and the subsequent Empty
191 response for provisioning
192 finishing on the Baicells eNodeB
193
194 Verifies that the ACS will continue into provisioning
195 """
196 acs_state_machine = \
197 EnodebAcsStateMachineBuilder\
198 .build_acs_state_machine(EnodebDeviceName.BAICELLS_QAFB)
199
200 # Send an Inform message, wait for an InformResponse
201 inform_msg = \
202 Tr069MessageBuilder.get_inform(
203 '48BF74',
204 'BaiBS_QAFBv123',
205 '120200002618AGP0003',
206 ['1 BOOT'],
207 )
208 resp = acs_state_machine.handle_tr069_message(inform_msg)
209 self.assertTrue(
210 isinstance(resp, models.InformResponse),
211 'Should respond with an InformResponse',
212 )
213
214 # Send GetRPCMethods
215 req = models.GetRPCMethods()
216 resp = acs_state_machine.handle_tr069_message(req)
217 self.assertTrue(
218 isinstance(resp, models.GetRPCMethodsResponse),
219 'State machine should be sending RPC methods',
220 )
221
222 # Send an empty http request to kick off the rest of provisioning
223 req = models.DummyInput()
224 resp = acs_state_machine.handle_tr069_message(req)
225
226 # Expect a request for an optional parameter
227 self.assertTrue(
228 isinstance(resp, models.GetParameterValues),
229 'State machine should be requesting param values',
230 )