blob: 0a99c8992d84402cc1e07c1377289fca4e651aa7 [file] [log] [blame]
Jacob Erlbeck0760a832013-09-16 11:20:28 +02001#!/usr/bin/env python
2
3# (C) 2013 by Jacob Erlbeck <jerlbeck@sysmocom.de>
Holger Hans Peter Freyther3adb7722014-03-04 17:16:58 +01004# (C) 2014 by Holger Hans Peter Freyther
Jacob Erlbeck0760a832013-09-16 11:20:28 +02005# based on vty_test_runner.py:
6# (C) 2013 by Katerina Barone-Adesi <kat.obsc@gmail.com>
7# (C) 2013 by Holger Hans Peter Freyther
8# based on bsc_control.py.
9
10# This program is free software: you can redistribute it and/or modify
11# it under the terms of the GNU General Public License as published by
12# the Free Software Foundation, either version 3 of the License, or
13# (at your option) any later version.
14
15# This program is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18# GNU General Public License for more details.
19
20# You should have received a copy of the GNU General Public License
21# along with this program. If not, see <http://www.gnu.org/licenses/>.
22
23import os
24import time
25import unittest
26import socket
27import sys
28import struct
29
30import osmopy.obscvty as obscvty
31import osmopy.osmoutil as osmoutil
32
Max310b7302017-05-02 16:10:07 +020033# add $top_srcdir/contrib to find ipa.py
34sys.path.append(os.path.join(sys.path[0], '..', 'contrib'))
35
36from ipa import Ctrl, IPA
37
Neels Hofmeyr476c4bb2017-02-24 17:55:11 +010038# to be able to find $top_srcdir/doc/...
39confpath = os.path.join(sys.path[0], '..')
Jacob Erlbeck0760a832013-09-16 11:20:28 +020040verbose = False
41
42class TestCtrlBase(unittest.TestCase):
43
44 def ctrl_command(self):
45 raise Exception("Needs to be implemented by a subclass")
46
47 def ctrl_app(self):
48 raise Exception("Needs to be implemented by a subclass")
49
50 def setUp(self):
51 osmo_ctrl_cmd = self.ctrl_command()[:]
52 config_index = osmo_ctrl_cmd.index('-c')
53 if config_index:
54 cfi = config_index + 1
55 osmo_ctrl_cmd[cfi] = os.path.join(confpath, osmo_ctrl_cmd[cfi])
56
57 try:
Jacob Erlbeck0760a832013-09-16 11:20:28 +020058 self.proc = osmoutil.popen_devnull(osmo_ctrl_cmd)
59 except OSError:
60 print >> sys.stderr, "Current directory: %s" % os.getcwd()
61 print >> sys.stderr, "Consider setting -b"
62 time.sleep(2)
63
64 appstring = self.ctrl_app()[2]
65 appport = self.ctrl_app()[0]
66 self.connect("127.0.0.1", appport)
67 self.next_id = 1000
68
69 def tearDown(self):
70 self.disconnect()
71 osmoutil.end_proc(self.proc)
72
Jacob Erlbeck0760a832013-09-16 11:20:28 +020073 def disconnect(self):
74 if not (self.sock is None):
75 self.sock.close()
76
77 def connect(self, host, port):
78 if verbose:
79 print "Connecting to host %s:%i" % (host, port)
80
Neels Hofmeyracc6e832017-02-27 02:01:37 +010081 retries = 30
82 while True:
83 try:
84 sck = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
85 sck.setblocking(1)
86 sck.connect((host, port))
87 except IOError:
88 retries -= 1
89 if retries <= 0:
90 raise
91 time.sleep(.1)
92 continue
93 break
Jacob Erlbeck0760a832013-09-16 11:20:28 +020094 self.sock = sck
95 return sck
96
97 def send(self, data):
98 if verbose:
99 print "Sending \"%s\"" %(data)
Max310b7302017-05-02 16:10:07 +0200100 data = Ctrl().add_header(data)
Jacob Erlbeck0760a832013-09-16 11:20:28 +0200101 return self.sock.send(data) == len(data)
102
103 def send_set(self, var, value, id):
104 setmsg = "SET %s %s %s" %(id, var, value)
105 return self.send(setmsg)
106
107 def send_get(self, var, id):
108 getmsg = "GET %s %s" %(id, var)
109 return self.send(getmsg)
110
111 def do_set(self, var, value):
112 id = self.next_id
113 self.next_id += 1
114 self.send_set(var, value, id)
115 return self.recv_msgs()[id]
116
117 def do_get(self, var):
118 id = self.next_id
119 self.next_id += 1
120 self.send_get(var, id)
121 return self.recv_msgs()[id]
122
123 def recv_msgs(self):
124 responses = {}
125 data = self.sock.recv(4096)
126 while (len(data)>0):
Max310b7302017-05-02 16:10:07 +0200127 (head, data) = IPA().split_combined(data)
128 answer = Ctrl().rem_header(head)
Jacob Erlbeck0760a832013-09-16 11:20:28 +0200129 if verbose:
130 print "Got message:", answer
131 (mtype, id, msg) = answer.split(None, 2)
132 id = int(id)
133 rsp = {'mtype': mtype, 'id': id}
134 if mtype == "ERROR":
135 rsp['error'] = msg
136 else:
Holger Hans Peter Freyther4ecc6872014-03-04 15:38:00 +0100137 split = msg.split(None, 1)
138 rsp['var'] = split[0]
139 if len(split) > 1:
140 rsp['value'] = split[1]
141 else:
142 rsp['value'] = None
Jacob Erlbeck0760a832013-09-16 11:20:28 +0200143 responses[id] = rsp
144
145 if verbose:
146 print "Decoded replies: ", responses
147
148 return responses
149
150
151class TestCtrlBSC(TestCtrlBase):
152
153 def tearDown(self):
154 TestCtrlBase.tearDown(self)
155 os.unlink("tmp_dummy_sock")
156
157 def ctrl_command(self):
158 return ["./src/osmo-bsc/osmo-bsc", "-r", "tmp_dummy_sock", "-c",
159 "doc/examples/osmo-bsc/osmo-bsc.cfg"]
160
161 def ctrl_app(self):
162 return (4249, "./src/osmo-bsc/osmo-bsc", "OsmoBSC", "bsc")
163
164 def testCtrlErrs(self):
165 r = self.do_get('invalid')
166 self.assertEquals(r['mtype'], 'ERROR')
167 self.assertEquals(r['error'], 'Command not found')
168
Jacob Erlbeck4f13d032013-09-16 11:20:29 +0200169 r = self.do_set('rf_locked', '999')
170 self.assertEquals(r['mtype'], 'ERROR')
171 self.assertEquals(r['error'], 'Value failed verification.')
172
Jacob Erlbeck0760a832013-09-16 11:20:28 +0200173 r = self.do_get('bts')
174 self.assertEquals(r['mtype'], 'ERROR')
175 self.assertEquals(r['error'], 'Error while parsing the index.')
176
177 r = self.do_get('bts.999')
178 self.assertEquals(r['mtype'], 'ERROR')
179 self.assertEquals(r['error'], 'Error while resolving object')
180
Holger Hans Peter Freyther054bc242014-11-10 11:41:03 +0100181 def testBtsLac(self):
182 r = self.do_get('bts.0.location-area-code')
183 self.assertEquals(r['mtype'], 'GET_REPLY')
184 self.assertEquals(r['var'], 'bts.0.location-area-code')
185 self.assertEquals(r['value'], '1')
186
187 r = self.do_set('bts.0.location-area-code', '23')
188 self.assertEquals(r['mtype'], 'SET_REPLY')
189 self.assertEquals(r['var'], 'bts.0.location-area-code')
190 self.assertEquals(r['value'], '23')
191
192 r = self.do_get('bts.0.location-area-code')
193 self.assertEquals(r['mtype'], 'GET_REPLY')
194 self.assertEquals(r['var'], 'bts.0.location-area-code')
195 self.assertEquals(r['value'], '23')
196
197 r = self.do_set('bts.0.location-area-code', '-1')
198 self.assertEquals(r['mtype'], 'ERROR')
199 self.assertEquals(r['error'], 'Input not within the range')
200
Holger Hans Peter Freyther8a641412014-11-21 10:54:42 +0100201 def testBtsCi(self):
202 r = self.do_get('bts.0.cell-identity')
203 self.assertEquals(r['mtype'], 'GET_REPLY')
204 self.assertEquals(r['var'], 'bts.0.cell-identity')
205 self.assertEquals(r['value'], '0')
206
207 r = self.do_set('bts.0.cell-identity', '23')
208 self.assertEquals(r['mtype'], 'SET_REPLY')
209 self.assertEquals(r['var'], 'bts.0.cell-identity')
210 self.assertEquals(r['value'], '23')
211
212 r = self.do_get('bts.0.cell-identity')
213 self.assertEquals(r['mtype'], 'GET_REPLY')
214 self.assertEquals(r['var'], 'bts.0.cell-identity')
215 self.assertEquals(r['value'], '23')
216
217 r = self.do_set('bts.0.cell-identity', '-1')
218 self.assertEquals(r['mtype'], 'ERROR')
219 self.assertEquals(r['error'], 'Input not within the range')
220
Holger Hans Peter Freythera49b2c02014-11-21 11:18:45 +0100221 def testBtsGenerateSystemInformation(self):
222 r = self.do_get('bts.0.send-new-system-informations')
223 self.assertEquals(r['mtype'], 'ERROR')
Maxf6e51702017-01-11 18:37:55 +0100224 self.assertEquals(r['error'], 'Write Only attribute')
Holger Hans Peter Freythera49b2c02014-11-21 11:18:45 +0100225
226 # No RSL links so it will fail
227 r = self.do_set('bts.0.send-new-system-informations', '1')
228 self.assertEquals(r['mtype'], 'ERROR')
229 self.assertEquals(r['error'], 'Failed to generate SI')
230
Holger Hans Peter Freyther5eebb7a2014-12-05 12:03:24 +0100231 def testBtsChannelLoad(self):
232 r = self.do_set('bts.0.channel-load', '1')
233 self.assertEquals(r['mtype'], 'ERROR')
Maxf6e51702017-01-11 18:37:55 +0100234 self.assertEquals(r['error'], 'Read Only attribute')
Holger Hans Peter Freyther5eebb7a2014-12-05 12:03:24 +0100235
236 # No RSL link so everything is 0
237 r = self.do_get('bts.0.channel-load')
238 self.assertEquals(r['mtype'], 'GET_REPLY')
Neels Hofmeyr17a6bab2016-07-23 16:14:06 +0200239 self.assertEquals(r['value'],
240 'CCCH+SDCCH4,0,0 TCH/F,0,0 TCH/H,0,0 SDCCH8,0,0'
241 + ' TCH/F_PDCH,0,0 CCCH+SDCCH4+CBCH,0,0'
242 + ' SDCCH8+CBCH,0,0 TCH/F_TCH/H_PDCH,0,0')
Holger Hans Peter Freyther5eebb7a2014-12-05 12:03:24 +0100243
Holger Hans Peter Freyther1f6cce72014-12-05 14:44:21 +0100244 def testBtsOmlConnectionState(self):
245 """Check OML state. It will not be connected"""
246 r = self.do_set('bts.0.oml-connection-state', '1')
247 self.assertEquals(r['mtype'], 'ERROR')
Maxf6e51702017-01-11 18:37:55 +0100248 self.assertEquals(r['error'], 'Read Only attribute')
Holger Hans Peter Freyther1f6cce72014-12-05 14:44:21 +0100249
250 # No RSL link so everything is 0
251 r = self.do_get('bts.0.oml-connection-state')
252 self.assertEquals(r['mtype'], 'GET_REPLY')
253 self.assertEquals(r['value'], 'disconnected')
254
Holger Hans Peter Freytherd092f482014-03-23 11:17:27 +0100255 def testTrxPowerRed(self):
256 r = self.do_get('bts.0.trx.0.max-power-reduction')
257 self.assertEquals(r['mtype'], 'GET_REPLY')
258 self.assertEquals(r['var'], 'bts.0.trx.0.max-power-reduction')
259 self.assertEquals(r['value'], '20')
260
261 r = self.do_set('bts.0.trx.0.max-power-reduction', '22')
262 self.assertEquals(r['mtype'], 'SET_REPLY')
263 self.assertEquals(r['var'], 'bts.0.trx.0.max-power-reduction')
264 self.assertEquals(r['value'], '22')
265
266 r = self.do_get('bts.0.trx.0.max-power-reduction')
267 self.assertEquals(r['mtype'], 'GET_REPLY')
268 self.assertEquals(r['var'], 'bts.0.trx.0.max-power-reduction')
269 self.assertEquals(r['value'], '22')
270
271 r = self.do_set('bts.0.trx.0.max-power-reduction', '1')
272 self.assertEquals(r['mtype'], 'ERROR')
273 self.assertEquals(r['error'], 'Value must be even')
274
Holger Hans Peter Freyther175a2402013-01-09 19:55:04 +0100275 def testTrxArfcn(self):
276 r = self.do_get('bts.0.trx.0.arfcn')
277 self.assertEquals(r['mtype'], 'GET_REPLY')
278 self.assertEquals(r['var'], 'bts.0.trx.0.arfcn')
279 self.assertEquals(r['value'], '871')
280
281 r = self.do_set('bts.0.trx.0.arfcn', '873')
282 self.assertEquals(r['mtype'], 'SET_REPLY')
283 self.assertEquals(r['var'], 'bts.0.trx.0.arfcn')
284 self.assertEquals(r['value'], '873')
285
286 r = self.do_get('bts.0.trx.0.arfcn')
287 self.assertEquals(r['mtype'], 'GET_REPLY')
288 self.assertEquals(r['var'], 'bts.0.trx.0.arfcn')
289 self.assertEquals(r['value'], '873')
290
291 r = self.do_set('bts.0.trx.0.arfcn', '2000')
292 self.assertEquals(r['mtype'], 'ERROR')
293 self.assertEquals(r['error'], 'Input not within the range')
294
Jacob Erlbeck0760a832013-09-16 11:20:28 +0200295 def testRfLock(self):
296 r = self.do_get('bts.0.rf_state')
297 self.assertEquals(r['mtype'], 'GET_REPLY')
298 self.assertEquals(r['var'], 'bts.0.rf_state')
299 self.assertEquals(r['value'], 'inoperational,unlocked,on')
300
301 r = self.do_set('rf_locked', '1')
302 self.assertEquals(r['mtype'], 'SET_REPLY')
303 self.assertEquals(r['var'], 'rf_locked')
304 self.assertEquals(r['value'], '1')
305
306 time.sleep(1.5)
307
308 r = self.do_get('bts.0.rf_state')
309 self.assertEquals(r['mtype'], 'GET_REPLY')
310 self.assertEquals(r['var'], 'bts.0.rf_state')
311 self.assertEquals(r['value'], 'inoperational,locked,off')
312
Holger Hans Peter Freyther66105fd2015-02-10 23:03:25 +0100313 r = self.do_get('rf_locked')
314 self.assertEquals(r['mtype'], 'GET_REPLY')
315 self.assertEquals(r['var'], 'rf_locked')
316 self.assertEquals(r['value'], 'state=off,policy=off')
317
Jacob Erlbeck0760a832013-09-16 11:20:28 +0200318 r = self.do_set('rf_locked', '0')
319 self.assertEquals(r['mtype'], 'SET_REPLY')
320 self.assertEquals(r['var'], 'rf_locked')
321 self.assertEquals(r['value'], '0')
322
323 time.sleep(1.5)
324
325 r = self.do_get('bts.0.rf_state')
326 self.assertEquals(r['mtype'], 'GET_REPLY')
327 self.assertEquals(r['var'], 'bts.0.rf_state')
328 self.assertEquals(r['value'], 'inoperational,unlocked,on')
329
Holger Hans Peter Freyther66105fd2015-02-10 23:03:25 +0100330 r = self.do_get('rf_locked')
331 self.assertEquals(r['mtype'], 'GET_REPLY')
332 self.assertEquals(r['var'], 'rf_locked')
333 self.assertEquals(r['value'], 'state=off,policy=on')
334
Jacob Erlbeckcc391b82013-10-01 13:26:42 +0200335 def testTimezone(self):
Neels Hofmeyr73983952016-05-10 13:29:33 +0200336 r = self.do_get('timezone')
Jacob Erlbeckcc391b82013-10-01 13:26:42 +0200337 self.assertEquals(r['mtype'], 'GET_REPLY')
Neels Hofmeyr73983952016-05-10 13:29:33 +0200338 self.assertEquals(r['var'], 'timezone')
Jacob Erlbeckcc391b82013-10-01 13:26:42 +0200339 self.assertEquals(r['value'], 'off')
340
Neels Hofmeyr73983952016-05-10 13:29:33 +0200341 r = self.do_set('timezone', '-2,15,2')
Jacob Erlbeckcc391b82013-10-01 13:26:42 +0200342 self.assertEquals(r['mtype'], 'SET_REPLY')
Neels Hofmeyr73983952016-05-10 13:29:33 +0200343 self.assertEquals(r['var'], 'timezone')
Jacob Erlbeckcc391b82013-10-01 13:26:42 +0200344 self.assertEquals(r['value'], '-2,15,2')
345
Neels Hofmeyr73983952016-05-10 13:29:33 +0200346 r = self.do_get('timezone')
Jacob Erlbeckcc391b82013-10-01 13:26:42 +0200347 self.assertEquals(r['mtype'], 'GET_REPLY')
Neels Hofmeyr73983952016-05-10 13:29:33 +0200348 self.assertEquals(r['var'], 'timezone')
Jacob Erlbeckcc391b82013-10-01 13:26:42 +0200349 self.assertEquals(r['value'], '-2,15,2')
350
351 # Test invalid input
Neels Hofmeyr73983952016-05-10 13:29:33 +0200352 r = self.do_set('timezone', '-2,15,2,5,6,7')
Jacob Erlbeckcc391b82013-10-01 13:26:42 +0200353 self.assertEquals(r['mtype'], 'SET_REPLY')
Neels Hofmeyr73983952016-05-10 13:29:33 +0200354 self.assertEquals(r['var'], 'timezone')
Jacob Erlbeckcc391b82013-10-01 13:26:42 +0200355 self.assertEquals(r['value'], '-2,15,2')
356
Neels Hofmeyr73983952016-05-10 13:29:33 +0200357 r = self.do_set('timezone', '-2,15')
Jacob Erlbeckcc391b82013-10-01 13:26:42 +0200358 self.assertEquals(r['mtype'], 'ERROR')
Neels Hofmeyr73983952016-05-10 13:29:33 +0200359 r = self.do_set('timezone', '-2')
Jacob Erlbeckcc391b82013-10-01 13:26:42 +0200360 self.assertEquals(r['mtype'], 'ERROR')
Neels Hofmeyr73983952016-05-10 13:29:33 +0200361 r = self.do_set('timezone', '1')
Jacob Erlbeckcc391b82013-10-01 13:26:42 +0200362
Neels Hofmeyr73983952016-05-10 13:29:33 +0200363 r = self.do_set('timezone', 'off')
Jacob Erlbeckcc391b82013-10-01 13:26:42 +0200364 self.assertEquals(r['mtype'], 'SET_REPLY')
Neels Hofmeyr73983952016-05-10 13:29:33 +0200365 self.assertEquals(r['var'], 'timezone')
Jacob Erlbeckcc391b82013-10-01 13:26:42 +0200366 self.assertEquals(r['value'], 'off')
367
Neels Hofmeyr73983952016-05-10 13:29:33 +0200368 r = self.do_get('timezone')
Jacob Erlbeckcc391b82013-10-01 13:26:42 +0200369 self.assertEquals(r['mtype'], 'GET_REPLY')
Neels Hofmeyr73983952016-05-10 13:29:33 +0200370 self.assertEquals(r['var'], 'timezone')
Jacob Erlbeckcc391b82013-10-01 13:26:42 +0200371 self.assertEquals(r['value'], 'off')
372
Holger Hans Peter Freythere9faa6f2014-04-24 10:30:05 +0200373 def testMcc(self):
374 r = self.do_set('mcc', '23')
375 r = self.do_get('mcc')
376 self.assertEquals(r['mtype'], 'GET_REPLY')
377 self.assertEquals(r['var'], 'mcc')
378 self.assertEquals(r['value'], '23')
379
380 r = self.do_set('mcc', '023')
381 r = self.do_get('mcc')
382 self.assertEquals(r['mtype'], 'GET_REPLY')
383 self.assertEquals(r['var'], 'mcc')
384 self.assertEquals(r['value'], '23')
385
386 def testMnc(self):
387 r = self.do_set('mnc', '9')
388 r = self.do_get('mnc')
389 self.assertEquals(r['mtype'], 'GET_REPLY')
390 self.assertEquals(r['var'], 'mnc')
391 self.assertEquals(r['value'], '9')
392
393 r = self.do_set('mnc', '09')
394 r = self.do_get('mnc')
395 self.assertEquals(r['mtype'], 'GET_REPLY')
396 self.assertEquals(r['var'], 'mnc')
397 self.assertEquals(r['value'], '9')
398
399
Holger Hans Peter Freyther3adb7722014-03-04 17:16:58 +0100400 def testMccMncApply(self):
401 # Test some invalid input
402 r = self.do_set('mcc-mnc-apply', 'WRONG')
403 self.assertEquals(r['mtype'], 'ERROR')
404
405 r = self.do_set('mcc-mnc-apply', '1,')
406 self.assertEquals(r['mtype'], 'ERROR')
407
408 r = self.do_set('mcc-mnc-apply', '200,3')
409 self.assertEquals(r['mtype'], 'SET_REPLY')
410 self.assertEquals(r['var'], 'mcc-mnc-apply')
411 self.assertEquals(r['value'], 'Tried to drop the BTS')
412
413 # Set it again
414 r = self.do_set('mcc-mnc-apply', '200,3')
415 self.assertEquals(r['mtype'], 'SET_REPLY')
416 self.assertEquals(r['var'], 'mcc-mnc-apply')
417 self.assertEquals(r['value'], 'Nothing changed')
418
419 # Change it
420 r = self.do_set('mcc-mnc-apply', '200,4')
421 self.assertEquals(r['mtype'], 'SET_REPLY')
422 self.assertEquals(r['var'], 'mcc-mnc-apply')
423 self.assertEquals(r['value'], 'Tried to drop the BTS')
424
425 # Change it
426 r = self.do_set('mcc-mnc-apply', '201,4')
427 self.assertEquals(r['mtype'], 'SET_REPLY')
428 self.assertEquals(r['var'], 'mcc-mnc-apply')
429 self.assertEquals(r['value'], 'Tried to drop the BTS')
430
431 # Verify
432 r = self.do_get('mnc')
433 self.assertEquals(r['mtype'], 'GET_REPLY')
434 self.assertEquals(r['var'], 'mnc')
435 self.assertEquals(r['value'], '4')
436
437 r = self.do_get('mcc')
438 self.assertEquals(r['mtype'], 'GET_REPLY')
439 self.assertEquals(r['var'], 'mcc')
440 self.assertEquals(r['value'], '201')
441
Holger Hans Peter Freythere9faa6f2014-04-24 10:30:05 +0200442 # Change it
443 r = self.do_set('mcc-mnc-apply', '202,03')
444 self.assertEquals(r['mtype'], 'SET_REPLY')
445 self.assertEquals(r['var'], 'mcc-mnc-apply')
446 self.assertEquals(r['value'], 'Tried to drop the BTS')
447
448 r = self.do_get('mnc')
449 self.assertEquals(r['mtype'], 'GET_REPLY')
450 self.assertEquals(r['var'], 'mnc')
451 self.assertEquals(r['value'], '3')
452
453 r = self.do_get('mcc')
454 self.assertEquals(r['mtype'], 'GET_REPLY')
455 self.assertEquals(r['var'], 'mcc')
456 self.assertEquals(r['value'], '202')
457
Holger Hans Peter Freyther9dbc3f82014-03-23 12:06:36 +0100458class TestCtrlNITB(TestCtrlBase):
459
460 def tearDown(self):
461 TestCtrlBase.tearDown(self)
462 os.unlink("test_hlr.sqlite3")
463
464 def ctrl_command(self):
465 return ["./src/osmo-nitb/osmo-nitb", "-c",
466 "doc/examples/osmo-nitb/nanobts/openbsc.cfg", "-l", "test_hlr.sqlite3"]
467
468 def ctrl_app(self):
469 return (4249, "./src/osmo-nitb/osmo-nitb", "OsmoBSC", "nitb")
470
Holger Hans Peter Freytherca415192015-02-10 21:55:37 +0100471 def testNumberOfBTS(self):
472 r = self.do_get('number-of-bts')
473 self.assertEquals(r['mtype'], 'GET_REPLY')
474 self.assertEquals(r['var'], 'number-of-bts')
475 self.assertEquals(r['value'], '1')
476
Holger Hans Peter Freyther9bcb1a52016-04-06 22:41:12 +0200477 def testSubscriberAddWithKi(self):
478 """Test that we can set the algorithm to none, xor, comp128v1"""
479
480 r = self.do_set('subscriber-modify-v1', '2620345,445566')
481 self.assertEquals(r['mtype'], 'SET_REPLY')
482 self.assertEquals(r['var'], 'subscriber-modify-v1')
483 self.assertEquals(r['value'], 'OK')
484
485 r = self.do_set('subscriber-modify-v1', '2620345,445566,none')
486 self.assertEquals(r['mtype'], 'SET_REPLY')
487 self.assertEquals(r['var'], 'subscriber-modify-v1')
488 self.assertEquals(r['value'], 'OK')
489
490 r = self.do_set('subscriber-modify-v1', '2620345,445566,xor')
491 self.assertEquals(r['mtype'], 'ERROR')
492 self.assertEquals(r['error'], 'Value failed verification.')
493
494 r = self.do_set('subscriber-modify-v1', '2620345,445566,comp128v1,00112233445566778899AABBCCDDEEFF')
495 self.assertEquals(r['mtype'], 'SET_REPLY')
496 self.assertEquals(r['var'], 'subscriber-modify-v1')
497 self.assertEquals(r['value'], 'OK')
498
499 r = self.do_set('subscriber-modify-v1', '2620345,445566,none')
500 self.assertEquals(r['mtype'], 'SET_REPLY')
501 self.assertEquals(r['var'], 'subscriber-modify-v1')
502 self.assertEquals(r['value'], 'OK')
503
Holger Hans Peter Freyther2d99eeb2014-03-23 14:01:08 +0100504 def testSubscriberAddRemove(self):
Holger Hans Peter Freyther9dbc3f82014-03-23 12:06:36 +0100505 r = self.do_set('subscriber-modify-v1', '2620345,445566')
506 self.assertEquals(r['mtype'], 'SET_REPLY')
507 self.assertEquals(r['var'], 'subscriber-modify-v1')
508 self.assertEquals(r['value'], 'OK')
509
510 r = self.do_set('subscriber-modify-v1', '2620345,445567')
511 self.assertEquals(r['mtype'], 'SET_REPLY')
512 self.assertEquals(r['var'], 'subscriber-modify-v1')
513 self.assertEquals(r['value'], 'OK')
514
515 # TODO. verify that the entry has been created and modified? Invoke
516 # the sqlite3 CLI or do it through the DB libraries?
517
Holger Hans Peter Freyther2d99eeb2014-03-23 14:01:08 +0100518 r = self.do_set('subscriber-delete-v1', '2620345')
519 self.assertEquals(r['mtype'], 'SET_REPLY')
520 self.assertEquals(r['value'], 'Removed')
521
522 r = self.do_set('subscriber-delete-v1', '2620345')
523 self.assertEquals(r['mtype'], 'ERROR')
524 self.assertEquals(r['error'], 'Failed to find subscriber')
525
Holger Hans Peter Freytherd883db02014-03-23 16:22:55 +0100526 def testSubscriberList(self):
527 # TODO. Add command to mark a subscriber as active
528 r = self.do_get('subscriber-list-active-v1')
529 self.assertEquals(r['mtype'], 'GET_REPLY')
530 self.assertEquals(r['var'], 'subscriber-list-active-v1')
531 self.assertEquals(r['value'], None)
532
Holger Hans Peter Freytherb1461152014-11-21 10:20:29 +0100533 def testApplyConfiguration(self):
534 r = self.do_get('bts.0.apply-configuration')
535 self.assertEquals(r['mtype'], 'ERROR')
Maxf6e51702017-01-11 18:37:55 +0100536 self.assertEquals(r['error'], 'Write Only attribute')
Holger Hans Peter Freytherb1461152014-11-21 10:20:29 +0100537
538 r = self.do_set('bts.0.apply-configuration', '1')
539 self.assertEquals(r['mtype'], 'SET_REPLY')
540 self.assertEquals(r['value'], 'Tried to drop the BTS')
541
Holger Hans Peter Freyther4e13a8f2015-01-31 22:16:00 +0100542 def testGprsMode(self):
543 r = self.do_get('bts.0.gprs-mode')
544 self.assertEquals(r['mtype'], 'GET_REPLY')
545 self.assertEquals(r['var'], 'bts.0.gprs-mode')
546 self.assertEquals(r['value'], 'none')
547
548 r = self.do_set('bts.0.gprs-mode', 'bla')
549 self.assertEquals(r['mtype'], 'ERROR')
550 self.assertEquals(r['error'], 'Mode is not known')
551
552 r = self.do_set('bts.0.gprs-mode', 'egprs')
553 self.assertEquals(r['mtype'], 'SET_REPLY')
554 self.assertEquals(r['value'], 'egprs')
555
556 r = self.do_get('bts.0.gprs-mode')
557 self.assertEquals(r['mtype'], 'GET_REPLY')
558 self.assertEquals(r['var'], 'bts.0.gprs-mode')
559 self.assertEquals(r['value'], 'egprs')
560
Holger Hans Peter Freyther4ecc6872014-03-04 15:38:00 +0100561class TestCtrlNAT(TestCtrlBase):
562
563 def ctrl_command(self):
564 return ["./src/osmo-bsc_nat/osmo-bsc_nat", "-c",
565 "doc/examples/osmo-bsc_nat/osmo-bsc_nat.cfg"]
566
567 def ctrl_app(self):
568 return (4250, "./src/osmo-bsc_nat/osmo-bsc_nat", "OsmoNAT", "nat")
569
570 def testAccessList(self):
571 r = self.do_get('net.0.bsc_cfg.0.access-list-name')
572 self.assertEquals(r['mtype'], 'GET_REPLY')
573 self.assertEquals(r['var'], 'net')
574 self.assertEquals(r['value'], None)
575
576 r = self.do_set('net.0.bsc_cfg.0.access-list-name', 'bla')
577 self.assertEquals(r['mtype'], 'SET_REPLY')
578 self.assertEquals(r['var'], 'net')
579 self.assertEquals(r['value'], 'bla')
580
581 r = self.do_get('net.0.bsc_cfg.0.access-list-name')
582 self.assertEquals(r['mtype'], 'GET_REPLY')
583 self.assertEquals(r['var'], 'net')
584 self.assertEquals(r['value'], 'bla')
585
586 r = self.do_set('net.0.bsc_cfg.0.no-access-list-name', '1')
587 self.assertEquals(r['mtype'], 'SET_REPLY')
588 self.assertEquals(r['var'], 'net')
589 self.assertEquals(r['value'], None)
590
Holger Hans Peter Freyther416c08f2014-12-09 19:13:00 +0100591 r = self.do_get('net.0.bsc_cfg.0.access-list-name')
592 self.assertEquals(r['mtype'], 'GET_REPLY')
Holger Hans Peter Freyther4ecc6872014-03-04 15:38:00 +0100593 self.assertEquals(r['var'], 'net')
594 self.assertEquals(r['value'], None)
Holger Hans Peter Freyther3adb7722014-03-04 17:16:58 +0100595
Holger Hans Peter Freytherab94ca12015-04-05 15:15:36 +0200596 def testAccessListManagement(self):
597 r = self.do_set("net.0.add.allow.access-list.404", "abc")
598 self.assertEquals(r['mtype'], 'ERROR')
599
600 r = self.do_set("net.0.add.allow.access-list.bla", "^234$")
601 self.assertEquals(r['mtype'], 'SET_REPLY')
602 self.assertEquals(r['var'], 'net.0.add.allow.access-list.bla')
603 self.assertEquals(r['value'], 'IMSI allow added to access list')
604
605 # TODO.. find a way to actually see if this rule has been
606 # added. e.g. by implementing a get for the list.
607
Holger Hans Peter Freythera2730302014-03-23 18:08:26 +0100608class TestCtrlSGSN(TestCtrlBase):
609 def ctrl_command(self):
610 return ["./src/gprs/osmo-sgsn", "-c",
611 "doc/examples/osmo-sgsn/osmo-sgsn.cfg"]
612
613 def ctrl_app(self):
614 return (4251, "./src/gprs/osmo-sgsn", "OsmoSGSN", "sgsn")
615
616 def testListSubscribers(self):
617 # TODO. Add command to mark a subscriber as active
618 r = self.do_get('subscriber-list-active-v1')
619 self.assertEquals(r['mtype'], 'GET_REPLY')
620 self.assertEquals(r['var'], 'subscriber-list-active-v1')
621 self.assertEquals(r['value'], None)
622
Jacob Erlbeck0760a832013-09-16 11:20:28 +0200623def add_bsc_test(suite, workdir):
624 if not os.path.isfile(os.path.join(workdir, "src/osmo-bsc/osmo-bsc")):
625 print("Skipping the BSC test")
626 return
627 test = unittest.TestLoader().loadTestsFromTestCase(TestCtrlBSC)
628 suite.addTest(test)
629
Holger Hans Peter Freyther9dbc3f82014-03-23 12:06:36 +0100630def add_nitb_test(suite, workdir):
631 test = unittest.TestLoader().loadTestsFromTestCase(TestCtrlNITB)
632 suite.addTest(test)
633
Holger Hans Peter Freyther4ecc6872014-03-04 15:38:00 +0100634def add_nat_test(suite, workdir):
635 if not os.path.isfile(os.path.join(workdir, "src/osmo-bsc_nat/osmo-bsc_nat")):
636 print("Skipping the NAT test")
637 return
638 test = unittest.TestLoader().loadTestsFromTestCase(TestCtrlNAT)
639 suite.addTest(test)
640
Holger Hans Peter Freythera2730302014-03-23 18:08:26 +0100641def add_sgsn_test(suite, workdir):
642 if not os.path.isfile(os.path.join(workdir, "src/gprs/osmo-sgsn")):
643 print("Skipping the SGSN test")
644 return
645 test = unittest.TestLoader().loadTestsFromTestCase(TestCtrlSGSN)
646 suite.addTest(test)
647
Jacob Erlbeck0760a832013-09-16 11:20:28 +0200648if __name__ == '__main__':
649 import argparse
650 import sys
651
652 workdir = '.'
653
654 parser = argparse.ArgumentParser()
655 parser.add_argument("-v", "--verbose", dest="verbose",
656 action="store_true", help="verbose mode")
657 parser.add_argument("-p", "--pythonconfpath", dest="p",
658 help="searchpath for config")
659 parser.add_argument("-w", "--workdir", dest="w",
660 help="Working directory")
661 args = parser.parse_args()
662
663 verbose_level = 1
664 if args.verbose:
665 verbose_level = 2
666 verbose = True
667
668 if args.w:
669 workdir = args.w
670
671 if args.p:
672 confpath = args.p
673
674 print "confpath %s, workdir %s" % (confpath, workdir)
675 os.chdir(workdir)
676 print "Running tests for specific control commands"
677 suite = unittest.TestSuite()
678 add_bsc_test(suite, workdir)
Holger Hans Peter Freyther9dbc3f82014-03-23 12:06:36 +0100679 add_nitb_test(suite, workdir)
Holger Hans Peter Freyther4ecc6872014-03-04 15:38:00 +0100680 add_nat_test(suite, workdir)
Holger Hans Peter Freythera2730302014-03-23 18:08:26 +0100681 add_sgsn_test(suite, workdir)
Jacob Erlbeck0760a832013-09-16 11:20:28 +0200682 res = unittest.TextTestRunner(verbosity=verbose_level).run(suite)
683 sys.exit(len(res.errors) + len(res.failures))