blob: 5030e8b1b925e5626677a4a4aa0c9629b2dc96b3 [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
33confpath = '.'
34verbose = False
35
36class TestCtrlBase(unittest.TestCase):
37
38 def ctrl_command(self):
39 raise Exception("Needs to be implemented by a subclass")
40
41 def ctrl_app(self):
42 raise Exception("Needs to be implemented by a subclass")
43
44 def setUp(self):
45 osmo_ctrl_cmd = self.ctrl_command()[:]
46 config_index = osmo_ctrl_cmd.index('-c')
47 if config_index:
48 cfi = config_index + 1
49 osmo_ctrl_cmd[cfi] = os.path.join(confpath, osmo_ctrl_cmd[cfi])
50
51 try:
Jacob Erlbeck0760a832013-09-16 11:20:28 +020052 self.proc = osmoutil.popen_devnull(osmo_ctrl_cmd)
53 except OSError:
54 print >> sys.stderr, "Current directory: %s" % os.getcwd()
55 print >> sys.stderr, "Consider setting -b"
56 time.sleep(2)
57
58 appstring = self.ctrl_app()[2]
59 appport = self.ctrl_app()[0]
60 self.connect("127.0.0.1", appport)
61 self.next_id = 1000
62
63 def tearDown(self):
64 self.disconnect()
65 osmoutil.end_proc(self.proc)
66
67 def prefix_ipa_ctrl_header(self, data):
68 return struct.pack(">HBB", len(data)+1, 0xee, 0) + data
69
70 def remove_ipa_ctrl_header(self, data):
71 if (len(data) < 4):
72 raise BaseException("Answer too short!")
73 (plen, ipa_proto, osmo_proto) = struct.unpack(">HBB", data[:4])
74 if (plen + 3 > len(data)):
75 print "Warning: Wrong payload length (expected %i, got %i)" % (plen, len(data) - 3)
76 if (ipa_proto != 0xee or osmo_proto != 0):
77 raise BaseException("Wrong protocol in answer!")
78
79 return data[4:plen+3], data[plen+3:]
80
81 def disconnect(self):
82 if not (self.sock is None):
83 self.sock.close()
84
85 def connect(self, host, port):
86 if verbose:
87 print "Connecting to host %s:%i" % (host, port)
88
Neels Hofmeyracc6e832017-02-27 02:01:37 +010089 retries = 30
90 while True:
91 try:
92 sck = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
93 sck.setblocking(1)
94 sck.connect((host, port))
95 except IOError:
96 retries -= 1
97 if retries <= 0:
98 raise
99 time.sleep(.1)
100 continue
101 break
Jacob Erlbeck0760a832013-09-16 11:20:28 +0200102 self.sock = sck
103 return sck
104
105 def send(self, data):
106 if verbose:
107 print "Sending \"%s\"" %(data)
108 data = self.prefix_ipa_ctrl_header(data)
109 return self.sock.send(data) == len(data)
110
111 def send_set(self, var, value, id):
112 setmsg = "SET %s %s %s" %(id, var, value)
113 return self.send(setmsg)
114
115 def send_get(self, var, id):
116 getmsg = "GET %s %s" %(id, var)
117 return self.send(getmsg)
118
119 def do_set(self, var, value):
120 id = self.next_id
121 self.next_id += 1
122 self.send_set(var, value, id)
123 return self.recv_msgs()[id]
124
125 def do_get(self, var):
126 id = self.next_id
127 self.next_id += 1
128 self.send_get(var, id)
129 return self.recv_msgs()[id]
130
131 def recv_msgs(self):
132 responses = {}
133 data = self.sock.recv(4096)
134 while (len(data)>0):
135 (answer, data) = self.remove_ipa_ctrl_header(data)
136 if verbose:
137 print "Got message:", answer
138 (mtype, id, msg) = answer.split(None, 2)
139 id = int(id)
140 rsp = {'mtype': mtype, 'id': id}
141 if mtype == "ERROR":
142 rsp['error'] = msg
143 else:
Holger Hans Peter Freyther4ecc6872014-03-04 15:38:00 +0100144 split = msg.split(None, 1)
145 rsp['var'] = split[0]
146 if len(split) > 1:
147 rsp['value'] = split[1]
148 else:
149 rsp['value'] = None
Jacob Erlbeck0760a832013-09-16 11:20:28 +0200150 responses[id] = rsp
151
152 if verbose:
153 print "Decoded replies: ", responses
154
155 return responses
156
157
158class TestCtrlBSC(TestCtrlBase):
159
160 def tearDown(self):
161 TestCtrlBase.tearDown(self)
162 os.unlink("tmp_dummy_sock")
163
164 def ctrl_command(self):
165 return ["./src/osmo-bsc/osmo-bsc", "-r", "tmp_dummy_sock", "-c",
166 "doc/examples/osmo-bsc/osmo-bsc.cfg"]
167
168 def ctrl_app(self):
169 return (4249, "./src/osmo-bsc/osmo-bsc", "OsmoBSC", "bsc")
170
171 def testCtrlErrs(self):
172 r = self.do_get('invalid')
173 self.assertEquals(r['mtype'], 'ERROR')
174 self.assertEquals(r['error'], 'Command not found')
175
Jacob Erlbeck4f13d032013-09-16 11:20:29 +0200176 r = self.do_set('rf_locked', '999')
177 self.assertEquals(r['mtype'], 'ERROR')
178 self.assertEquals(r['error'], 'Value failed verification.')
179
Jacob Erlbeck0760a832013-09-16 11:20:28 +0200180 r = self.do_get('bts')
181 self.assertEquals(r['mtype'], 'ERROR')
182 self.assertEquals(r['error'], 'Error while parsing the index.')
183
184 r = self.do_get('bts.999')
185 self.assertEquals(r['mtype'], 'ERROR')
186 self.assertEquals(r['error'], 'Error while resolving object')
187
Holger Hans Peter Freyther054bc242014-11-10 11:41:03 +0100188 def testBtsLac(self):
189 r = self.do_get('bts.0.location-area-code')
190 self.assertEquals(r['mtype'], 'GET_REPLY')
191 self.assertEquals(r['var'], 'bts.0.location-area-code')
192 self.assertEquals(r['value'], '1')
193
194 r = self.do_set('bts.0.location-area-code', '23')
195 self.assertEquals(r['mtype'], 'SET_REPLY')
196 self.assertEquals(r['var'], 'bts.0.location-area-code')
197 self.assertEquals(r['value'], '23')
198
199 r = self.do_get('bts.0.location-area-code')
200 self.assertEquals(r['mtype'], 'GET_REPLY')
201 self.assertEquals(r['var'], 'bts.0.location-area-code')
202 self.assertEquals(r['value'], '23')
203
204 r = self.do_set('bts.0.location-area-code', '-1')
205 self.assertEquals(r['mtype'], 'ERROR')
206 self.assertEquals(r['error'], 'Input not within the range')
207
Holger Hans Peter Freyther8a641412014-11-21 10:54:42 +0100208 def testBtsCi(self):
209 r = self.do_get('bts.0.cell-identity')
210 self.assertEquals(r['mtype'], 'GET_REPLY')
211 self.assertEquals(r['var'], 'bts.0.cell-identity')
212 self.assertEquals(r['value'], '0')
213
214 r = self.do_set('bts.0.cell-identity', '23')
215 self.assertEquals(r['mtype'], 'SET_REPLY')
216 self.assertEquals(r['var'], 'bts.0.cell-identity')
217 self.assertEquals(r['value'], '23')
218
219 r = self.do_get('bts.0.cell-identity')
220 self.assertEquals(r['mtype'], 'GET_REPLY')
221 self.assertEquals(r['var'], 'bts.0.cell-identity')
222 self.assertEquals(r['value'], '23')
223
224 r = self.do_set('bts.0.cell-identity', '-1')
225 self.assertEquals(r['mtype'], 'ERROR')
226 self.assertEquals(r['error'], 'Input not within the range')
227
Holger Hans Peter Freythera49b2c02014-11-21 11:18:45 +0100228 def testBtsGenerateSystemInformation(self):
229 r = self.do_get('bts.0.send-new-system-informations')
230 self.assertEquals(r['mtype'], 'ERROR')
Maxf6e51702017-01-11 18:37:55 +0100231 self.assertEquals(r['error'], 'Write Only attribute')
Holger Hans Peter Freythera49b2c02014-11-21 11:18:45 +0100232
233 # No RSL links so it will fail
234 r = self.do_set('bts.0.send-new-system-informations', '1')
235 self.assertEquals(r['mtype'], 'ERROR')
236 self.assertEquals(r['error'], 'Failed to generate SI')
237
Holger Hans Peter Freyther5eebb7a2014-12-05 12:03:24 +0100238 def testBtsChannelLoad(self):
239 r = self.do_set('bts.0.channel-load', '1')
240 self.assertEquals(r['mtype'], 'ERROR')
Maxf6e51702017-01-11 18:37:55 +0100241 self.assertEquals(r['error'], 'Read Only attribute')
Holger Hans Peter Freyther5eebb7a2014-12-05 12:03:24 +0100242
243 # No RSL link so everything is 0
244 r = self.do_get('bts.0.channel-load')
245 self.assertEquals(r['mtype'], 'GET_REPLY')
Neels Hofmeyr17a6bab2016-07-23 16:14:06 +0200246 self.assertEquals(r['value'],
247 'CCCH+SDCCH4,0,0 TCH/F,0,0 TCH/H,0,0 SDCCH8,0,0'
248 + ' TCH/F_PDCH,0,0 CCCH+SDCCH4+CBCH,0,0'
249 + ' SDCCH8+CBCH,0,0 TCH/F_TCH/H_PDCH,0,0')
Holger Hans Peter Freyther5eebb7a2014-12-05 12:03:24 +0100250
Holger Hans Peter Freyther1f6cce72014-12-05 14:44:21 +0100251 def testBtsOmlConnectionState(self):
252 """Check OML state. It will not be connected"""
253 r = self.do_set('bts.0.oml-connection-state', '1')
254 self.assertEquals(r['mtype'], 'ERROR')
Maxf6e51702017-01-11 18:37:55 +0100255 self.assertEquals(r['error'], 'Read Only attribute')
Holger Hans Peter Freyther1f6cce72014-12-05 14:44:21 +0100256
257 # No RSL link so everything is 0
258 r = self.do_get('bts.0.oml-connection-state')
259 self.assertEquals(r['mtype'], 'GET_REPLY')
260 self.assertEquals(r['value'], 'disconnected')
261
Holger Hans Peter Freytherd092f482014-03-23 11:17:27 +0100262 def testTrxPowerRed(self):
263 r = self.do_get('bts.0.trx.0.max-power-reduction')
264 self.assertEquals(r['mtype'], 'GET_REPLY')
265 self.assertEquals(r['var'], 'bts.0.trx.0.max-power-reduction')
266 self.assertEquals(r['value'], '20')
267
268 r = self.do_set('bts.0.trx.0.max-power-reduction', '22')
269 self.assertEquals(r['mtype'], 'SET_REPLY')
270 self.assertEquals(r['var'], 'bts.0.trx.0.max-power-reduction')
271 self.assertEquals(r['value'], '22')
272
273 r = self.do_get('bts.0.trx.0.max-power-reduction')
274 self.assertEquals(r['mtype'], 'GET_REPLY')
275 self.assertEquals(r['var'], 'bts.0.trx.0.max-power-reduction')
276 self.assertEquals(r['value'], '22')
277
278 r = self.do_set('bts.0.trx.0.max-power-reduction', '1')
279 self.assertEquals(r['mtype'], 'ERROR')
280 self.assertEquals(r['error'], 'Value must be even')
281
Holger Hans Peter Freyther175a2402013-01-09 19:55:04 +0100282 def testTrxArfcn(self):
283 r = self.do_get('bts.0.trx.0.arfcn')
284 self.assertEquals(r['mtype'], 'GET_REPLY')
285 self.assertEquals(r['var'], 'bts.0.trx.0.arfcn')
286 self.assertEquals(r['value'], '871')
287
288 r = self.do_set('bts.0.trx.0.arfcn', '873')
289 self.assertEquals(r['mtype'], 'SET_REPLY')
290 self.assertEquals(r['var'], 'bts.0.trx.0.arfcn')
291 self.assertEquals(r['value'], '873')
292
293 r = self.do_get('bts.0.trx.0.arfcn')
294 self.assertEquals(r['mtype'], 'GET_REPLY')
295 self.assertEquals(r['var'], 'bts.0.trx.0.arfcn')
296 self.assertEquals(r['value'], '873')
297
298 r = self.do_set('bts.0.trx.0.arfcn', '2000')
299 self.assertEquals(r['mtype'], 'ERROR')
300 self.assertEquals(r['error'], 'Input not within the range')
301
Jacob Erlbeck0760a832013-09-16 11:20:28 +0200302 def testRfLock(self):
303 r = self.do_get('bts.0.rf_state')
304 self.assertEquals(r['mtype'], 'GET_REPLY')
305 self.assertEquals(r['var'], 'bts.0.rf_state')
306 self.assertEquals(r['value'], 'inoperational,unlocked,on')
307
308 r = self.do_set('rf_locked', '1')
309 self.assertEquals(r['mtype'], 'SET_REPLY')
310 self.assertEquals(r['var'], 'rf_locked')
311 self.assertEquals(r['value'], '1')
312
313 time.sleep(1.5)
314
315 r = self.do_get('bts.0.rf_state')
316 self.assertEquals(r['mtype'], 'GET_REPLY')
317 self.assertEquals(r['var'], 'bts.0.rf_state')
318 self.assertEquals(r['value'], 'inoperational,locked,off')
319
Holger Hans Peter Freyther66105fd2015-02-10 23:03:25 +0100320 r = self.do_get('rf_locked')
321 self.assertEquals(r['mtype'], 'GET_REPLY')
322 self.assertEquals(r['var'], 'rf_locked')
323 self.assertEquals(r['value'], 'state=off,policy=off')
324
Jacob Erlbeck0760a832013-09-16 11:20:28 +0200325 r = self.do_set('rf_locked', '0')
326 self.assertEquals(r['mtype'], 'SET_REPLY')
327 self.assertEquals(r['var'], 'rf_locked')
328 self.assertEquals(r['value'], '0')
329
330 time.sleep(1.5)
331
332 r = self.do_get('bts.0.rf_state')
333 self.assertEquals(r['mtype'], 'GET_REPLY')
334 self.assertEquals(r['var'], 'bts.0.rf_state')
335 self.assertEquals(r['value'], 'inoperational,unlocked,on')
336
Holger Hans Peter Freyther66105fd2015-02-10 23:03:25 +0100337 r = self.do_get('rf_locked')
338 self.assertEquals(r['mtype'], 'GET_REPLY')
339 self.assertEquals(r['var'], 'rf_locked')
340 self.assertEquals(r['value'], 'state=off,policy=on')
341
Jacob Erlbeckcc391b82013-10-01 13:26:42 +0200342 def testTimezone(self):
Neels Hofmeyr73983952016-05-10 13:29:33 +0200343 r = self.do_get('timezone')
Jacob Erlbeckcc391b82013-10-01 13:26:42 +0200344 self.assertEquals(r['mtype'], 'GET_REPLY')
Neels Hofmeyr73983952016-05-10 13:29:33 +0200345 self.assertEquals(r['var'], 'timezone')
Jacob Erlbeckcc391b82013-10-01 13:26:42 +0200346 self.assertEquals(r['value'], 'off')
347
Neels Hofmeyr73983952016-05-10 13:29:33 +0200348 r = self.do_set('timezone', '-2,15,2')
Jacob Erlbeckcc391b82013-10-01 13:26:42 +0200349 self.assertEquals(r['mtype'], 'SET_REPLY')
Neels Hofmeyr73983952016-05-10 13:29:33 +0200350 self.assertEquals(r['var'], 'timezone')
Jacob Erlbeckcc391b82013-10-01 13:26:42 +0200351 self.assertEquals(r['value'], '-2,15,2')
352
Neels Hofmeyr73983952016-05-10 13:29:33 +0200353 r = self.do_get('timezone')
Jacob Erlbeckcc391b82013-10-01 13:26:42 +0200354 self.assertEquals(r['mtype'], 'GET_REPLY')
Neels Hofmeyr73983952016-05-10 13:29:33 +0200355 self.assertEquals(r['var'], 'timezone')
Jacob Erlbeckcc391b82013-10-01 13:26:42 +0200356 self.assertEquals(r['value'], '-2,15,2')
357
358 # Test invalid input
Neels Hofmeyr73983952016-05-10 13:29:33 +0200359 r = self.do_set('timezone', '-2,15,2,5,6,7')
Jacob Erlbeckcc391b82013-10-01 13:26:42 +0200360 self.assertEquals(r['mtype'], 'SET_REPLY')
Neels Hofmeyr73983952016-05-10 13:29:33 +0200361 self.assertEquals(r['var'], 'timezone')
Jacob Erlbeckcc391b82013-10-01 13:26:42 +0200362 self.assertEquals(r['value'], '-2,15,2')
363
Neels Hofmeyr73983952016-05-10 13:29:33 +0200364 r = self.do_set('timezone', '-2,15')
Jacob Erlbeckcc391b82013-10-01 13:26:42 +0200365 self.assertEquals(r['mtype'], 'ERROR')
Neels Hofmeyr73983952016-05-10 13:29:33 +0200366 r = self.do_set('timezone', '-2')
Jacob Erlbeckcc391b82013-10-01 13:26:42 +0200367 self.assertEquals(r['mtype'], 'ERROR')
Neels Hofmeyr73983952016-05-10 13:29:33 +0200368 r = self.do_set('timezone', '1')
Jacob Erlbeckcc391b82013-10-01 13:26:42 +0200369
Neels Hofmeyr73983952016-05-10 13:29:33 +0200370 r = self.do_set('timezone', 'off')
Jacob Erlbeckcc391b82013-10-01 13:26:42 +0200371 self.assertEquals(r['mtype'], 'SET_REPLY')
Neels Hofmeyr73983952016-05-10 13:29:33 +0200372 self.assertEquals(r['var'], 'timezone')
Jacob Erlbeckcc391b82013-10-01 13:26:42 +0200373 self.assertEquals(r['value'], 'off')
374
Neels Hofmeyr73983952016-05-10 13:29:33 +0200375 r = self.do_get('timezone')
Jacob Erlbeckcc391b82013-10-01 13:26:42 +0200376 self.assertEquals(r['mtype'], 'GET_REPLY')
Neels Hofmeyr73983952016-05-10 13:29:33 +0200377 self.assertEquals(r['var'], 'timezone')
Jacob Erlbeckcc391b82013-10-01 13:26:42 +0200378 self.assertEquals(r['value'], 'off')
379
Holger Hans Peter Freythere9faa6f2014-04-24 10:30:05 +0200380 def testMcc(self):
381 r = self.do_set('mcc', '23')
382 r = self.do_get('mcc')
383 self.assertEquals(r['mtype'], 'GET_REPLY')
384 self.assertEquals(r['var'], 'mcc')
385 self.assertEquals(r['value'], '23')
386
387 r = self.do_set('mcc', '023')
388 r = self.do_get('mcc')
389 self.assertEquals(r['mtype'], 'GET_REPLY')
390 self.assertEquals(r['var'], 'mcc')
391 self.assertEquals(r['value'], '23')
392
393 def testMnc(self):
394 r = self.do_set('mnc', '9')
395 r = self.do_get('mnc')
396 self.assertEquals(r['mtype'], 'GET_REPLY')
397 self.assertEquals(r['var'], 'mnc')
398 self.assertEquals(r['value'], '9')
399
400 r = self.do_set('mnc', '09')
401 r = self.do_get('mnc')
402 self.assertEquals(r['mtype'], 'GET_REPLY')
403 self.assertEquals(r['var'], 'mnc')
404 self.assertEquals(r['value'], '9')
405
406
Holger Hans Peter Freyther3adb7722014-03-04 17:16:58 +0100407 def testMccMncApply(self):
408 # Test some invalid input
409 r = self.do_set('mcc-mnc-apply', 'WRONG')
410 self.assertEquals(r['mtype'], 'ERROR')
411
412 r = self.do_set('mcc-mnc-apply', '1,')
413 self.assertEquals(r['mtype'], 'ERROR')
414
415 r = self.do_set('mcc-mnc-apply', '200,3')
416 self.assertEquals(r['mtype'], 'SET_REPLY')
417 self.assertEquals(r['var'], 'mcc-mnc-apply')
418 self.assertEquals(r['value'], 'Tried to drop the BTS')
419
420 # Set it again
421 r = self.do_set('mcc-mnc-apply', '200,3')
422 self.assertEquals(r['mtype'], 'SET_REPLY')
423 self.assertEquals(r['var'], 'mcc-mnc-apply')
424 self.assertEquals(r['value'], 'Nothing changed')
425
426 # Change it
427 r = self.do_set('mcc-mnc-apply', '200,4')
428 self.assertEquals(r['mtype'], 'SET_REPLY')
429 self.assertEquals(r['var'], 'mcc-mnc-apply')
430 self.assertEquals(r['value'], 'Tried to drop the BTS')
431
432 # Change it
433 r = self.do_set('mcc-mnc-apply', '201,4')
434 self.assertEquals(r['mtype'], 'SET_REPLY')
435 self.assertEquals(r['var'], 'mcc-mnc-apply')
436 self.assertEquals(r['value'], 'Tried to drop the BTS')
437
438 # Verify
439 r = self.do_get('mnc')
440 self.assertEquals(r['mtype'], 'GET_REPLY')
441 self.assertEquals(r['var'], 'mnc')
442 self.assertEquals(r['value'], '4')
443
444 r = self.do_get('mcc')
445 self.assertEquals(r['mtype'], 'GET_REPLY')
446 self.assertEquals(r['var'], 'mcc')
447 self.assertEquals(r['value'], '201')
448
Holger Hans Peter Freythere9faa6f2014-04-24 10:30:05 +0200449 # Change it
450 r = self.do_set('mcc-mnc-apply', '202,03')
451 self.assertEquals(r['mtype'], 'SET_REPLY')
452 self.assertEquals(r['var'], 'mcc-mnc-apply')
453 self.assertEquals(r['value'], 'Tried to drop the BTS')
454
455 r = self.do_get('mnc')
456 self.assertEquals(r['mtype'], 'GET_REPLY')
457 self.assertEquals(r['var'], 'mnc')
458 self.assertEquals(r['value'], '3')
459
460 r = self.do_get('mcc')
461 self.assertEquals(r['mtype'], 'GET_REPLY')
462 self.assertEquals(r['var'], 'mcc')
463 self.assertEquals(r['value'], '202')
464
Holger Hans Peter Freyther9dbc3f82014-03-23 12:06:36 +0100465class TestCtrlNITB(TestCtrlBase):
466
467 def tearDown(self):
468 TestCtrlBase.tearDown(self)
469 os.unlink("test_hlr.sqlite3")
470
471 def ctrl_command(self):
472 return ["./src/osmo-nitb/osmo-nitb", "-c",
473 "doc/examples/osmo-nitb/nanobts/openbsc.cfg", "-l", "test_hlr.sqlite3"]
474
475 def ctrl_app(self):
476 return (4249, "./src/osmo-nitb/osmo-nitb", "OsmoBSC", "nitb")
477
Holger Hans Peter Freytherca415192015-02-10 21:55:37 +0100478 def testNumberOfBTS(self):
479 r = self.do_get('number-of-bts')
480 self.assertEquals(r['mtype'], 'GET_REPLY')
481 self.assertEquals(r['var'], 'number-of-bts')
482 self.assertEquals(r['value'], '1')
483
Holger Hans Peter Freyther9bcb1a52016-04-06 22:41:12 +0200484 def testSubscriberAddWithKi(self):
485 """Test that we can set the algorithm to none, xor, comp128v1"""
486
487 r = self.do_set('subscriber-modify-v1', '2620345,445566')
488 self.assertEquals(r['mtype'], 'SET_REPLY')
489 self.assertEquals(r['var'], 'subscriber-modify-v1')
490 self.assertEquals(r['value'], 'OK')
491
492 r = self.do_set('subscriber-modify-v1', '2620345,445566,none')
493 self.assertEquals(r['mtype'], 'SET_REPLY')
494 self.assertEquals(r['var'], 'subscriber-modify-v1')
495 self.assertEquals(r['value'], 'OK')
496
497 r = self.do_set('subscriber-modify-v1', '2620345,445566,xor')
498 self.assertEquals(r['mtype'], 'ERROR')
499 self.assertEquals(r['error'], 'Value failed verification.')
500
501 r = self.do_set('subscriber-modify-v1', '2620345,445566,comp128v1,00112233445566778899AABBCCDDEEFF')
502 self.assertEquals(r['mtype'], 'SET_REPLY')
503 self.assertEquals(r['var'], 'subscriber-modify-v1')
504 self.assertEquals(r['value'], 'OK')
505
506 r = self.do_set('subscriber-modify-v1', '2620345,445566,none')
507 self.assertEquals(r['mtype'], 'SET_REPLY')
508 self.assertEquals(r['var'], 'subscriber-modify-v1')
509 self.assertEquals(r['value'], 'OK')
510
Holger Hans Peter Freyther2d99eeb2014-03-23 14:01:08 +0100511 def testSubscriberAddRemove(self):
Holger Hans Peter Freyther9dbc3f82014-03-23 12:06:36 +0100512 r = self.do_set('subscriber-modify-v1', '2620345,445566')
513 self.assertEquals(r['mtype'], 'SET_REPLY')
514 self.assertEquals(r['var'], 'subscriber-modify-v1')
515 self.assertEquals(r['value'], 'OK')
516
517 r = self.do_set('subscriber-modify-v1', '2620345,445567')
518 self.assertEquals(r['mtype'], 'SET_REPLY')
519 self.assertEquals(r['var'], 'subscriber-modify-v1')
520 self.assertEquals(r['value'], 'OK')
521
522 # TODO. verify that the entry has been created and modified? Invoke
523 # the sqlite3 CLI or do it through the DB libraries?
524
Holger Hans Peter Freyther2d99eeb2014-03-23 14:01:08 +0100525 r = self.do_set('subscriber-delete-v1', '2620345')
526 self.assertEquals(r['mtype'], 'SET_REPLY')
527 self.assertEquals(r['value'], 'Removed')
528
529 r = self.do_set('subscriber-delete-v1', '2620345')
530 self.assertEquals(r['mtype'], 'ERROR')
531 self.assertEquals(r['error'], 'Failed to find subscriber')
532
Holger Hans Peter Freytherd883db02014-03-23 16:22:55 +0100533 def testSubscriberList(self):
534 # TODO. Add command to mark a subscriber as active
535 r = self.do_get('subscriber-list-active-v1')
536 self.assertEquals(r['mtype'], 'GET_REPLY')
537 self.assertEquals(r['var'], 'subscriber-list-active-v1')
538 self.assertEquals(r['value'], None)
539
Holger Hans Peter Freytherb1461152014-11-21 10:20:29 +0100540 def testApplyConfiguration(self):
541 r = self.do_get('bts.0.apply-configuration')
542 self.assertEquals(r['mtype'], 'ERROR')
Maxf6e51702017-01-11 18:37:55 +0100543 self.assertEquals(r['error'], 'Write Only attribute')
Holger Hans Peter Freytherb1461152014-11-21 10:20:29 +0100544
545 r = self.do_set('bts.0.apply-configuration', '1')
546 self.assertEquals(r['mtype'], 'SET_REPLY')
547 self.assertEquals(r['value'], 'Tried to drop the BTS')
548
Holger Hans Peter Freyther4e13a8f2015-01-31 22:16:00 +0100549 def testGprsMode(self):
550 r = self.do_get('bts.0.gprs-mode')
551 self.assertEquals(r['mtype'], 'GET_REPLY')
552 self.assertEquals(r['var'], 'bts.0.gprs-mode')
553 self.assertEquals(r['value'], 'none')
554
555 r = self.do_set('bts.0.gprs-mode', 'bla')
556 self.assertEquals(r['mtype'], 'ERROR')
557 self.assertEquals(r['error'], 'Mode is not known')
558
559 r = self.do_set('bts.0.gprs-mode', 'egprs')
560 self.assertEquals(r['mtype'], 'SET_REPLY')
561 self.assertEquals(r['value'], 'egprs')
562
563 r = self.do_get('bts.0.gprs-mode')
564 self.assertEquals(r['mtype'], 'GET_REPLY')
565 self.assertEquals(r['var'], 'bts.0.gprs-mode')
566 self.assertEquals(r['value'], 'egprs')
567
Holger Hans Peter Freyther4ecc6872014-03-04 15:38:00 +0100568class TestCtrlNAT(TestCtrlBase):
569
570 def ctrl_command(self):
571 return ["./src/osmo-bsc_nat/osmo-bsc_nat", "-c",
572 "doc/examples/osmo-bsc_nat/osmo-bsc_nat.cfg"]
573
574 def ctrl_app(self):
575 return (4250, "./src/osmo-bsc_nat/osmo-bsc_nat", "OsmoNAT", "nat")
576
577 def testAccessList(self):
578 r = self.do_get('net.0.bsc_cfg.0.access-list-name')
579 self.assertEquals(r['mtype'], 'GET_REPLY')
580 self.assertEquals(r['var'], 'net')
581 self.assertEquals(r['value'], None)
582
583 r = self.do_set('net.0.bsc_cfg.0.access-list-name', 'bla')
584 self.assertEquals(r['mtype'], 'SET_REPLY')
585 self.assertEquals(r['var'], 'net')
586 self.assertEquals(r['value'], 'bla')
587
588 r = self.do_get('net.0.bsc_cfg.0.access-list-name')
589 self.assertEquals(r['mtype'], 'GET_REPLY')
590 self.assertEquals(r['var'], 'net')
591 self.assertEquals(r['value'], 'bla')
592
593 r = self.do_set('net.0.bsc_cfg.0.no-access-list-name', '1')
594 self.assertEquals(r['mtype'], 'SET_REPLY')
595 self.assertEquals(r['var'], 'net')
596 self.assertEquals(r['value'], None)
597
Holger Hans Peter Freyther416c08f2014-12-09 19:13:00 +0100598 r = self.do_get('net.0.bsc_cfg.0.access-list-name')
599 self.assertEquals(r['mtype'], 'GET_REPLY')
Holger Hans Peter Freyther4ecc6872014-03-04 15:38:00 +0100600 self.assertEquals(r['var'], 'net')
601 self.assertEquals(r['value'], None)
Holger Hans Peter Freyther3adb7722014-03-04 17:16:58 +0100602
Holger Hans Peter Freytherab94ca12015-04-05 15:15:36 +0200603 def testAccessListManagement(self):
604 r = self.do_set("net.0.add.allow.access-list.404", "abc")
605 self.assertEquals(r['mtype'], 'ERROR')
606
607 r = self.do_set("net.0.add.allow.access-list.bla", "^234$")
608 self.assertEquals(r['mtype'], 'SET_REPLY')
609 self.assertEquals(r['var'], 'net.0.add.allow.access-list.bla')
610 self.assertEquals(r['value'], 'IMSI allow added to access list')
611
612 # TODO.. find a way to actually see if this rule has been
613 # added. e.g. by implementing a get for the list.
614
Holger Hans Peter Freythera2730302014-03-23 18:08:26 +0100615class TestCtrlSGSN(TestCtrlBase):
616 def ctrl_command(self):
617 return ["./src/gprs/osmo-sgsn", "-c",
618 "doc/examples/osmo-sgsn/osmo-sgsn.cfg"]
619
620 def ctrl_app(self):
621 return (4251, "./src/gprs/osmo-sgsn", "OsmoSGSN", "sgsn")
622
623 def testListSubscribers(self):
624 # TODO. Add command to mark a subscriber as active
625 r = self.do_get('subscriber-list-active-v1')
626 self.assertEquals(r['mtype'], 'GET_REPLY')
627 self.assertEquals(r['var'], 'subscriber-list-active-v1')
628 self.assertEquals(r['value'], None)
629
Jacob Erlbeck0760a832013-09-16 11:20:28 +0200630def add_bsc_test(suite, workdir):
631 if not os.path.isfile(os.path.join(workdir, "src/osmo-bsc/osmo-bsc")):
632 print("Skipping the BSC test")
633 return
634 test = unittest.TestLoader().loadTestsFromTestCase(TestCtrlBSC)
635 suite.addTest(test)
636
Holger Hans Peter Freyther9dbc3f82014-03-23 12:06:36 +0100637def add_nitb_test(suite, workdir):
638 test = unittest.TestLoader().loadTestsFromTestCase(TestCtrlNITB)
639 suite.addTest(test)
640
Holger Hans Peter Freyther4ecc6872014-03-04 15:38:00 +0100641def add_nat_test(suite, workdir):
642 if not os.path.isfile(os.path.join(workdir, "src/osmo-bsc_nat/osmo-bsc_nat")):
643 print("Skipping the NAT test")
644 return
645 test = unittest.TestLoader().loadTestsFromTestCase(TestCtrlNAT)
646 suite.addTest(test)
647
Holger Hans Peter Freythera2730302014-03-23 18:08:26 +0100648def add_sgsn_test(suite, workdir):
649 if not os.path.isfile(os.path.join(workdir, "src/gprs/osmo-sgsn")):
650 print("Skipping the SGSN test")
651 return
652 test = unittest.TestLoader().loadTestsFromTestCase(TestCtrlSGSN)
653 suite.addTest(test)
654
Jacob Erlbeck0760a832013-09-16 11:20:28 +0200655if __name__ == '__main__':
656 import argparse
657 import sys
658
659 workdir = '.'
660
661 parser = argparse.ArgumentParser()
662 parser.add_argument("-v", "--verbose", dest="verbose",
663 action="store_true", help="verbose mode")
664 parser.add_argument("-p", "--pythonconfpath", dest="p",
665 help="searchpath for config")
666 parser.add_argument("-w", "--workdir", dest="w",
667 help="Working directory")
668 args = parser.parse_args()
669
670 verbose_level = 1
671 if args.verbose:
672 verbose_level = 2
673 verbose = True
674
675 if args.w:
676 workdir = args.w
677
678 if args.p:
679 confpath = args.p
680
681 print "confpath %s, workdir %s" % (confpath, workdir)
682 os.chdir(workdir)
683 print "Running tests for specific control commands"
684 suite = unittest.TestSuite()
685 add_bsc_test(suite, workdir)
Holger Hans Peter Freyther9dbc3f82014-03-23 12:06:36 +0100686 add_nitb_test(suite, workdir)
Holger Hans Peter Freyther4ecc6872014-03-04 15:38:00 +0100687 add_nat_test(suite, workdir)
Holger Hans Peter Freythera2730302014-03-23 18:08:26 +0100688 add_sgsn_test(suite, workdir)
Jacob Erlbeck0760a832013-09-16 11:20:28 +0200689 res = unittest.TextTestRunner(verbosity=verbose_level).run(suite)
690 sys.exit(len(res.errors) + len(res.failures))