blob: a11548823d2380b03350462650c00938b604506e [file] [log] [blame]
Jacob Erlbeck5741e1f2013-09-16 11:20:28 +02001#!/usr/bin/env python
2
3# (C) 2013 by Jacob Erlbeck <jerlbeck@sysmocom.de>
Holger Hans Peter Freythereab2a3f2014-03-04 17:16:58 +01004# (C) 2014 by Holger Hans Peter Freyther
Jacob Erlbeck5741e1f2013-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 Erlbeck5741e1f2013-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
89 sck = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
90 sck.setblocking(1)
91 sck.connect((host, port))
92 self.sock = sck
93 return sck
94
95 def send(self, data):
96 if verbose:
97 print "Sending \"%s\"" %(data)
98 data = self.prefix_ipa_ctrl_header(data)
99 return self.sock.send(data) == len(data)
100
101 def send_set(self, var, value, id):
102 setmsg = "SET %s %s %s" %(id, var, value)
103 return self.send(setmsg)
104
105 def send_get(self, var, id):
106 getmsg = "GET %s %s" %(id, var)
107 return self.send(getmsg)
108
109 def do_set(self, var, value):
110 id = self.next_id
111 self.next_id += 1
112 self.send_set(var, value, id)
113 return self.recv_msgs()[id]
114
115 def do_get(self, var):
116 id = self.next_id
117 self.next_id += 1
118 self.send_get(var, id)
119 return self.recv_msgs()[id]
120
121 def recv_msgs(self):
122 responses = {}
123 data = self.sock.recv(4096)
124 while (len(data)>0):
125 (answer, data) = self.remove_ipa_ctrl_header(data)
126 if verbose:
127 print "Got message:", answer
128 (mtype, id, msg) = answer.split(None, 2)
129 id = int(id)
130 rsp = {'mtype': mtype, 'id': id}
131 if mtype == "ERROR":
132 rsp['error'] = msg
133 else:
Holger Hans Peter Freyther842137a2014-03-04 15:38:00 +0100134 split = msg.split(None, 1)
135 rsp['var'] = split[0]
136 if len(split) > 1:
137 rsp['value'] = split[1]
138 else:
139 rsp['value'] = None
Jacob Erlbeck5741e1f2013-09-16 11:20:28 +0200140 responses[id] = rsp
141
142 if verbose:
143 print "Decoded replies: ", responses
144
145 return responses
146
147
148class TestCtrlBSC(TestCtrlBase):
149
150 def tearDown(self):
151 TestCtrlBase.tearDown(self)
152 os.unlink("tmp_dummy_sock")
153
154 def ctrl_command(self):
155 return ["./src/osmo-bsc/osmo-bsc", "-r", "tmp_dummy_sock", "-c",
156 "doc/examples/osmo-bsc/osmo-bsc.cfg"]
157
158 def ctrl_app(self):
159 return (4249, "./src/osmo-bsc/osmo-bsc", "OsmoBSC", "bsc")
160
161 def testCtrlErrs(self):
162 r = self.do_get('invalid')
163 self.assertEquals(r['mtype'], 'ERROR')
164 self.assertEquals(r['error'], 'Command not found')
165
Jacob Erlbeck21f6d152013-09-16 11:20:29 +0200166 r = self.do_set('rf_locked', '999')
167 self.assertEquals(r['mtype'], 'ERROR')
168 self.assertEquals(r['error'], 'Value failed verification.')
169
Jacob Erlbeck5741e1f2013-09-16 11:20:28 +0200170 r = self.do_get('bts')
171 self.assertEquals(r['mtype'], 'ERROR')
172 self.assertEquals(r['error'], 'Error while parsing the index.')
173
174 r = self.do_get('bts.999')
175 self.assertEquals(r['mtype'], 'ERROR')
176 self.assertEquals(r['error'], 'Error while resolving object')
177
Holger Hans Peter Freytherba8679d2014-11-10 11:41:03 +0100178 def testBtsLac(self):
179 r = self.do_get('bts.0.location-area-code')
180 self.assertEquals(r['mtype'], 'GET_REPLY')
181 self.assertEquals(r['var'], 'bts.0.location-area-code')
182 self.assertEquals(r['value'], '1')
183
184 r = self.do_set('bts.0.location-area-code', '23')
185 self.assertEquals(r['mtype'], 'SET_REPLY')
186 self.assertEquals(r['var'], 'bts.0.location-area-code')
187 self.assertEquals(r['value'], '23')
188
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'], '23')
193
194 r = self.do_set('bts.0.location-area-code', '-1')
195 self.assertEquals(r['mtype'], 'ERROR')
196 self.assertEquals(r['error'], 'Input not within the range')
197
Holger Hans Peter Freyther982bb292014-11-21 10:54:42 +0100198 def testBtsCi(self):
199 r = self.do_get('bts.0.cell-identity')
200 self.assertEquals(r['mtype'], 'GET_REPLY')
201 self.assertEquals(r['var'], 'bts.0.cell-identity')
202 self.assertEquals(r['value'], '0')
203
204 r = self.do_set('bts.0.cell-identity', '23')
205 self.assertEquals(r['mtype'], 'SET_REPLY')
206 self.assertEquals(r['var'], 'bts.0.cell-identity')
207 self.assertEquals(r['value'], '23')
208
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'], '23')
213
214 r = self.do_set('bts.0.cell-identity', '-1')
215 self.assertEquals(r['mtype'], 'ERROR')
216 self.assertEquals(r['error'], 'Input not within the range')
217
Holger Hans Peter Freytherd0284c82014-11-21 11:18:45 +0100218 def testBtsGenerateSystemInformation(self):
219 r = self.do_get('bts.0.send-new-system-informations')
220 self.assertEquals(r['mtype'], 'ERROR')
Max78a58032017-01-11 18:37:55 +0100221 self.assertEquals(r['error'], 'Write Only attribute')
Holger Hans Peter Freytherd0284c82014-11-21 11:18:45 +0100222
223 # No RSL links so it will fail
224 r = self.do_set('bts.0.send-new-system-informations', '1')
225 self.assertEquals(r['mtype'], 'ERROR')
226 self.assertEquals(r['error'], 'Failed to generate SI')
227
Holger Hans Peter Freyther9fe98462014-12-05 12:03:24 +0100228 def testBtsChannelLoad(self):
229 r = self.do_set('bts.0.channel-load', '1')
230 self.assertEquals(r['mtype'], 'ERROR')
Max78a58032017-01-11 18:37:55 +0100231 self.assertEquals(r['error'], 'Read Only attribute')
Holger Hans Peter Freyther9fe98462014-12-05 12:03:24 +0100232
233 # No RSL link so everything is 0
234 r = self.do_get('bts.0.channel-load')
235 self.assertEquals(r['mtype'], 'GET_REPLY')
Neels Hofmeyr266e7e02016-07-23 16:14:06 +0200236 self.assertEquals(r['value'],
237 'CCCH+SDCCH4,0,0 TCH/F,0,0 TCH/H,0,0 SDCCH8,0,0'
238 + ' TCH/F_PDCH,0,0 CCCH+SDCCH4+CBCH,0,0'
239 + ' SDCCH8+CBCH,0,0 TCH/F_TCH/H_PDCH,0,0')
Holger Hans Peter Freyther9fe98462014-12-05 12:03:24 +0100240
Holger Hans Peter Freyther0c47d9e2014-12-05 14:44:21 +0100241 def testBtsOmlConnectionState(self):
242 """Check OML state. It will not be connected"""
243 r = self.do_set('bts.0.oml-connection-state', '1')
244 self.assertEquals(r['mtype'], 'ERROR')
Max78a58032017-01-11 18:37:55 +0100245 self.assertEquals(r['error'], 'Read Only attribute')
Holger Hans Peter Freyther0c47d9e2014-12-05 14:44:21 +0100246
247 # No RSL link so everything is 0
248 r = self.do_get('bts.0.oml-connection-state')
249 self.assertEquals(r['mtype'], 'GET_REPLY')
250 self.assertEquals(r['value'], 'disconnected')
251
Holger Hans Peter Freyther2de46892014-03-23 11:17:27 +0100252 def testTrxPowerRed(self):
253 r = self.do_get('bts.0.trx.0.max-power-reduction')
254 self.assertEquals(r['mtype'], 'GET_REPLY')
255 self.assertEquals(r['var'], 'bts.0.trx.0.max-power-reduction')
256 self.assertEquals(r['value'], '20')
257
258 r = self.do_set('bts.0.trx.0.max-power-reduction', '22')
259 self.assertEquals(r['mtype'], 'SET_REPLY')
260 self.assertEquals(r['var'], 'bts.0.trx.0.max-power-reduction')
261 self.assertEquals(r['value'], '22')
262
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'], '22')
267
268 r = self.do_set('bts.0.trx.0.max-power-reduction', '1')
269 self.assertEquals(r['mtype'], 'ERROR')
270 self.assertEquals(r['error'], 'Value must be even')
271
Holger Hans Peter Freytherb96705b2013-01-09 19:55:04 +0100272 def testTrxArfcn(self):
273 r = self.do_get('bts.0.trx.0.arfcn')
274 self.assertEquals(r['mtype'], 'GET_REPLY')
275 self.assertEquals(r['var'], 'bts.0.trx.0.arfcn')
276 self.assertEquals(r['value'], '871')
277
278 r = self.do_set('bts.0.trx.0.arfcn', '873')
279 self.assertEquals(r['mtype'], 'SET_REPLY')
280 self.assertEquals(r['var'], 'bts.0.trx.0.arfcn')
281 self.assertEquals(r['value'], '873')
282
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'], '873')
287
288 r = self.do_set('bts.0.trx.0.arfcn', '2000')
289 self.assertEquals(r['mtype'], 'ERROR')
290 self.assertEquals(r['error'], 'Input not within the range')
291
Jacob Erlbeck5741e1f2013-09-16 11:20:28 +0200292 def testRfLock(self):
293 r = self.do_get('bts.0.rf_state')
294 self.assertEquals(r['mtype'], 'GET_REPLY')
295 self.assertEquals(r['var'], 'bts.0.rf_state')
296 self.assertEquals(r['value'], 'inoperational,unlocked,on')
297
298 r = self.do_set('rf_locked', '1')
299 self.assertEquals(r['mtype'], 'SET_REPLY')
300 self.assertEquals(r['var'], 'rf_locked')
301 self.assertEquals(r['value'], '1')
302
303 time.sleep(1.5)
304
305 r = self.do_get('bts.0.rf_state')
306 self.assertEquals(r['mtype'], 'GET_REPLY')
307 self.assertEquals(r['var'], 'bts.0.rf_state')
308 self.assertEquals(r['value'], 'inoperational,locked,off')
309
Holger Hans Peter Freytherd476a802015-02-10 23:03:25 +0100310 r = self.do_get('rf_locked')
311 self.assertEquals(r['mtype'], 'GET_REPLY')
312 self.assertEquals(r['var'], 'rf_locked')
313 self.assertEquals(r['value'], 'state=off,policy=off')
314
Jacob Erlbeck5741e1f2013-09-16 11:20:28 +0200315 r = self.do_set('rf_locked', '0')
316 self.assertEquals(r['mtype'], 'SET_REPLY')
317 self.assertEquals(r['var'], 'rf_locked')
318 self.assertEquals(r['value'], '0')
319
320 time.sleep(1.5)
321
322 r = self.do_get('bts.0.rf_state')
323 self.assertEquals(r['mtype'], 'GET_REPLY')
324 self.assertEquals(r['var'], 'bts.0.rf_state')
325 self.assertEquals(r['value'], 'inoperational,unlocked,on')
326
Holger Hans Peter Freytherd476a802015-02-10 23:03:25 +0100327 r = self.do_get('rf_locked')
328 self.assertEquals(r['mtype'], 'GET_REPLY')
329 self.assertEquals(r['var'], 'rf_locked')
330 self.assertEquals(r['value'], 'state=off,policy=on')
331
Jacob Erlbeck64e143a2013-10-01 13:26:42 +0200332 def testTimezone(self):
Neels Hofmeyr21edaef2016-05-10 13:29:33 +0200333 r = self.do_get('timezone')
Jacob Erlbeck64e143a2013-10-01 13:26:42 +0200334 self.assertEquals(r['mtype'], 'GET_REPLY')
Neels Hofmeyr21edaef2016-05-10 13:29:33 +0200335 self.assertEquals(r['var'], 'timezone')
Jacob Erlbeck64e143a2013-10-01 13:26:42 +0200336 self.assertEquals(r['value'], 'off')
337
Neels Hofmeyr21edaef2016-05-10 13:29:33 +0200338 r = self.do_set('timezone', '-2,15,2')
Jacob Erlbeck64e143a2013-10-01 13:26:42 +0200339 self.assertEquals(r['mtype'], 'SET_REPLY')
Neels Hofmeyr21edaef2016-05-10 13:29:33 +0200340 self.assertEquals(r['var'], 'timezone')
Jacob Erlbeck64e143a2013-10-01 13:26:42 +0200341 self.assertEquals(r['value'], '-2,15,2')
342
Neels Hofmeyr21edaef2016-05-10 13:29:33 +0200343 r = self.do_get('timezone')
Jacob Erlbeck64e143a2013-10-01 13:26:42 +0200344 self.assertEquals(r['mtype'], 'GET_REPLY')
Neels Hofmeyr21edaef2016-05-10 13:29:33 +0200345 self.assertEquals(r['var'], 'timezone')
Jacob Erlbeck64e143a2013-10-01 13:26:42 +0200346 self.assertEquals(r['value'], '-2,15,2')
347
348 # Test invalid input
Neels Hofmeyr21edaef2016-05-10 13:29:33 +0200349 r = self.do_set('timezone', '-2,15,2,5,6,7')
Jacob Erlbeck64e143a2013-10-01 13:26:42 +0200350 self.assertEquals(r['mtype'], 'SET_REPLY')
Neels Hofmeyr21edaef2016-05-10 13:29:33 +0200351 self.assertEquals(r['var'], 'timezone')
Jacob Erlbeck64e143a2013-10-01 13:26:42 +0200352 self.assertEquals(r['value'], '-2,15,2')
353
Neels Hofmeyr21edaef2016-05-10 13:29:33 +0200354 r = self.do_set('timezone', '-2,15')
Jacob Erlbeck64e143a2013-10-01 13:26:42 +0200355 self.assertEquals(r['mtype'], 'ERROR')
Neels Hofmeyr21edaef2016-05-10 13:29:33 +0200356 r = self.do_set('timezone', '-2')
Jacob Erlbeck64e143a2013-10-01 13:26:42 +0200357 self.assertEquals(r['mtype'], 'ERROR')
Neels Hofmeyr21edaef2016-05-10 13:29:33 +0200358 r = self.do_set('timezone', '1')
Jacob Erlbeck64e143a2013-10-01 13:26:42 +0200359
Neels Hofmeyr21edaef2016-05-10 13:29:33 +0200360 r = self.do_set('timezone', 'off')
Jacob Erlbeck64e143a2013-10-01 13:26:42 +0200361 self.assertEquals(r['mtype'], 'SET_REPLY')
Neels Hofmeyr21edaef2016-05-10 13:29:33 +0200362 self.assertEquals(r['var'], 'timezone')
Jacob Erlbeck64e143a2013-10-01 13:26:42 +0200363 self.assertEquals(r['value'], 'off')
364
Neels Hofmeyr21edaef2016-05-10 13:29:33 +0200365 r = self.do_get('timezone')
Jacob Erlbeck64e143a2013-10-01 13:26:42 +0200366 self.assertEquals(r['mtype'], 'GET_REPLY')
Neels Hofmeyr21edaef2016-05-10 13:29:33 +0200367 self.assertEquals(r['var'], 'timezone')
Jacob Erlbeck64e143a2013-10-01 13:26:42 +0200368 self.assertEquals(r['value'], 'off')
369
Holger Hans Peter Freytherf9fe3232014-04-24 10:30:05 +0200370 def testMcc(self):
371 r = self.do_set('mcc', '23')
372 r = self.do_get('mcc')
373 self.assertEquals(r['mtype'], 'GET_REPLY')
374 self.assertEquals(r['var'], 'mcc')
375 self.assertEquals(r['value'], '23')
376
377 r = self.do_set('mcc', '023')
378 r = self.do_get('mcc')
379 self.assertEquals(r['mtype'], 'GET_REPLY')
380 self.assertEquals(r['var'], 'mcc')
381 self.assertEquals(r['value'], '23')
382
383 def testMnc(self):
384 r = self.do_set('mnc', '9')
385 r = self.do_get('mnc')
386 self.assertEquals(r['mtype'], 'GET_REPLY')
387 self.assertEquals(r['var'], 'mnc')
388 self.assertEquals(r['value'], '9')
389
390 r = self.do_set('mnc', '09')
391 r = self.do_get('mnc')
392 self.assertEquals(r['mtype'], 'GET_REPLY')
393 self.assertEquals(r['var'], 'mnc')
394 self.assertEquals(r['value'], '9')
395
396
Holger Hans Peter Freythereab2a3f2014-03-04 17:16:58 +0100397 def testMccMncApply(self):
398 # Test some invalid input
399 r = self.do_set('mcc-mnc-apply', 'WRONG')
400 self.assertEquals(r['mtype'], 'ERROR')
401
402 r = self.do_set('mcc-mnc-apply', '1,')
403 self.assertEquals(r['mtype'], 'ERROR')
404
405 r = self.do_set('mcc-mnc-apply', '200,3')
406 self.assertEquals(r['mtype'], 'SET_REPLY')
407 self.assertEquals(r['var'], 'mcc-mnc-apply')
408 self.assertEquals(r['value'], 'Tried to drop the BTS')
409
410 # Set it again
411 r = self.do_set('mcc-mnc-apply', '200,3')
412 self.assertEquals(r['mtype'], 'SET_REPLY')
413 self.assertEquals(r['var'], 'mcc-mnc-apply')
414 self.assertEquals(r['value'], 'Nothing changed')
415
416 # Change it
417 r = self.do_set('mcc-mnc-apply', '200,4')
418 self.assertEquals(r['mtype'], 'SET_REPLY')
419 self.assertEquals(r['var'], 'mcc-mnc-apply')
420 self.assertEquals(r['value'], 'Tried to drop the BTS')
421
422 # Change it
423 r = self.do_set('mcc-mnc-apply', '201,4')
424 self.assertEquals(r['mtype'], 'SET_REPLY')
425 self.assertEquals(r['var'], 'mcc-mnc-apply')
426 self.assertEquals(r['value'], 'Tried to drop the BTS')
427
428 # Verify
429 r = self.do_get('mnc')
430 self.assertEquals(r['mtype'], 'GET_REPLY')
431 self.assertEquals(r['var'], 'mnc')
432 self.assertEquals(r['value'], '4')
433
434 r = self.do_get('mcc')
435 self.assertEquals(r['mtype'], 'GET_REPLY')
436 self.assertEquals(r['var'], 'mcc')
437 self.assertEquals(r['value'], '201')
438
Holger Hans Peter Freytherf9fe3232014-04-24 10:30:05 +0200439 # Change it
440 r = self.do_set('mcc-mnc-apply', '202,03')
441 self.assertEquals(r['mtype'], 'SET_REPLY')
442 self.assertEquals(r['var'], 'mcc-mnc-apply')
443 self.assertEquals(r['value'], 'Tried to drop the BTS')
444
445 r = self.do_get('mnc')
446 self.assertEquals(r['mtype'], 'GET_REPLY')
447 self.assertEquals(r['var'], 'mnc')
448 self.assertEquals(r['value'], '3')
449
450 r = self.do_get('mcc')
451 self.assertEquals(r['mtype'], 'GET_REPLY')
452 self.assertEquals(r['var'], 'mcc')
453 self.assertEquals(r['value'], '202')
454
Holger Hans Peter Freytherfba03162014-03-23 12:06:36 +0100455class TestCtrlNITB(TestCtrlBase):
456
457 def tearDown(self):
458 TestCtrlBase.tearDown(self)
459 os.unlink("test_hlr.sqlite3")
460
461 def ctrl_command(self):
462 return ["./src/osmo-nitb/osmo-nitb", "-c",
463 "doc/examples/osmo-nitb/nanobts/openbsc.cfg", "-l", "test_hlr.sqlite3"]
464
465 def ctrl_app(self):
466 return (4249, "./src/osmo-nitb/osmo-nitb", "OsmoBSC", "nitb")
467
Holger Hans Peter Freytherbbd8ea12015-02-10 21:55:37 +0100468 def testNumberOfBTS(self):
469 r = self.do_get('number-of-bts')
470 self.assertEquals(r['mtype'], 'GET_REPLY')
471 self.assertEquals(r['var'], 'number-of-bts')
472 self.assertEquals(r['value'], '1')
473
Holger Hans Peter Freyther7bd1b702016-04-06 22:41:12 +0200474 def testSubscriberAddWithKi(self):
475 """Test that we can set the algorithm to none, xor, comp128v1"""
476
477 r = self.do_set('subscriber-modify-v1', '2620345,445566')
478 self.assertEquals(r['mtype'], 'SET_REPLY')
479 self.assertEquals(r['var'], 'subscriber-modify-v1')
480 self.assertEquals(r['value'], 'OK')
481
482 r = self.do_set('subscriber-modify-v1', '2620345,445566,none')
483 self.assertEquals(r['mtype'], 'SET_REPLY')
484 self.assertEquals(r['var'], 'subscriber-modify-v1')
485 self.assertEquals(r['value'], 'OK')
486
487 r = self.do_set('subscriber-modify-v1', '2620345,445566,xor')
488 self.assertEquals(r['mtype'], 'ERROR')
489 self.assertEquals(r['error'], 'Value failed verification.')
490
491 r = self.do_set('subscriber-modify-v1', '2620345,445566,comp128v1,00112233445566778899AABBCCDDEEFF')
492 self.assertEquals(r['mtype'], 'SET_REPLY')
493 self.assertEquals(r['var'], 'subscriber-modify-v1')
494 self.assertEquals(r['value'], 'OK')
495
496 r = self.do_set('subscriber-modify-v1', '2620345,445566,none')
497 self.assertEquals(r['mtype'], 'SET_REPLY')
498 self.assertEquals(r['var'], 'subscriber-modify-v1')
499 self.assertEquals(r['value'], 'OK')
500
Holger Hans Peter Freytherc652a5d2014-03-23 14:01:08 +0100501 def testSubscriberAddRemove(self):
Holger Hans Peter Freytherfba03162014-03-23 12:06:36 +0100502 r = self.do_set('subscriber-modify-v1', '2620345,445566')
503 self.assertEquals(r['mtype'], 'SET_REPLY')
504 self.assertEquals(r['var'], 'subscriber-modify-v1')
505 self.assertEquals(r['value'], 'OK')
506
507 r = self.do_set('subscriber-modify-v1', '2620345,445567')
508 self.assertEquals(r['mtype'], 'SET_REPLY')
509 self.assertEquals(r['var'], 'subscriber-modify-v1')
510 self.assertEquals(r['value'], 'OK')
511
512 # TODO. verify that the entry has been created and modified? Invoke
513 # the sqlite3 CLI or do it through the DB libraries?
514
Holger Hans Peter Freytherc652a5d2014-03-23 14:01:08 +0100515 r = self.do_set('subscriber-delete-v1', '2620345')
516 self.assertEquals(r['mtype'], 'SET_REPLY')
517 self.assertEquals(r['value'], 'Removed')
518
519 r = self.do_set('subscriber-delete-v1', '2620345')
520 self.assertEquals(r['mtype'], 'ERROR')
521 self.assertEquals(r['error'], 'Failed to find subscriber')
522
Holger Hans Peter Freytherd41b7b72014-03-23 16:22:55 +0100523 def testSubscriberList(self):
524 # TODO. Add command to mark a subscriber as active
525 r = self.do_get('subscriber-list-active-v1')
526 self.assertEquals(r['mtype'], 'GET_REPLY')
527 self.assertEquals(r['var'], 'subscriber-list-active-v1')
528 self.assertEquals(r['value'], None)
529
Holger Hans Peter Freyther87b35d52014-11-21 10:20:29 +0100530 def testApplyConfiguration(self):
531 r = self.do_get('bts.0.apply-configuration')
532 self.assertEquals(r['mtype'], 'ERROR')
Max78a58032017-01-11 18:37:55 +0100533 self.assertEquals(r['error'], 'Write Only attribute')
Holger Hans Peter Freyther87b35d52014-11-21 10:20:29 +0100534
535 r = self.do_set('bts.0.apply-configuration', '1')
536 self.assertEquals(r['mtype'], 'SET_REPLY')
537 self.assertEquals(r['value'], 'Tried to drop the BTS')
538
Holger Hans Peter Freyther611f7752015-01-31 22:16:00 +0100539 def testGprsMode(self):
540 r = self.do_get('bts.0.gprs-mode')
541 self.assertEquals(r['mtype'], 'GET_REPLY')
542 self.assertEquals(r['var'], 'bts.0.gprs-mode')
543 self.assertEquals(r['value'], 'none')
544
545 r = self.do_set('bts.0.gprs-mode', 'bla')
546 self.assertEquals(r['mtype'], 'ERROR')
547 self.assertEquals(r['error'], 'Mode is not known')
548
549 r = self.do_set('bts.0.gprs-mode', 'egprs')
550 self.assertEquals(r['mtype'], 'SET_REPLY')
551 self.assertEquals(r['value'], 'egprs')
552
553 r = self.do_get('bts.0.gprs-mode')
554 self.assertEquals(r['mtype'], 'GET_REPLY')
555 self.assertEquals(r['var'], 'bts.0.gprs-mode')
556 self.assertEquals(r['value'], 'egprs')
557
Holger Hans Peter Freyther842137a2014-03-04 15:38:00 +0100558class TestCtrlNAT(TestCtrlBase):
559
560 def ctrl_command(self):
561 return ["./src/osmo-bsc_nat/osmo-bsc_nat", "-c",
562 "doc/examples/osmo-bsc_nat/osmo-bsc_nat.cfg"]
563
564 def ctrl_app(self):
565 return (4250, "./src/osmo-bsc_nat/osmo-bsc_nat", "OsmoNAT", "nat")
566
567 def testAccessList(self):
568 r = self.do_get('net.0.bsc_cfg.0.access-list-name')
569 self.assertEquals(r['mtype'], 'GET_REPLY')
570 self.assertEquals(r['var'], 'net')
571 self.assertEquals(r['value'], None)
572
573 r = self.do_set('net.0.bsc_cfg.0.access-list-name', 'bla')
574 self.assertEquals(r['mtype'], 'SET_REPLY')
575 self.assertEquals(r['var'], 'net')
576 self.assertEquals(r['value'], 'bla')
577
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'], 'bla')
582
583 r = self.do_set('net.0.bsc_cfg.0.no-access-list-name', '1')
584 self.assertEquals(r['mtype'], 'SET_REPLY')
585 self.assertEquals(r['var'], 'net')
586 self.assertEquals(r['value'], None)
587
Holger Hans Peter Freyther56ec6a72014-12-09 19:13:00 +0100588 r = self.do_get('net.0.bsc_cfg.0.access-list-name')
589 self.assertEquals(r['mtype'], 'GET_REPLY')
Holger Hans Peter Freyther842137a2014-03-04 15:38:00 +0100590 self.assertEquals(r['var'], 'net')
591 self.assertEquals(r['value'], None)
Holger Hans Peter Freythereab2a3f2014-03-04 17:16:58 +0100592
Holger Hans Peter Freyther5bb90f52015-04-05 15:15:36 +0200593 def testAccessListManagement(self):
594 r = self.do_set("net.0.add.allow.access-list.404", "abc")
595 self.assertEquals(r['mtype'], 'ERROR')
596
597 r = self.do_set("net.0.add.allow.access-list.bla", "^234$")
598 self.assertEquals(r['mtype'], 'SET_REPLY')
599 self.assertEquals(r['var'], 'net.0.add.allow.access-list.bla')
600 self.assertEquals(r['value'], 'IMSI allow added to access list')
601
602 # TODO.. find a way to actually see if this rule has been
603 # added. e.g. by implementing a get for the list.
604
Holger Hans Peter Freythere8e5ef22014-03-23 18:08:26 +0100605class TestCtrlSGSN(TestCtrlBase):
606 def ctrl_command(self):
607 return ["./src/gprs/osmo-sgsn", "-c",
608 "doc/examples/osmo-sgsn/osmo-sgsn.cfg"]
609
610 def ctrl_app(self):
611 return (4251, "./src/gprs/osmo-sgsn", "OsmoSGSN", "sgsn")
612
613 def testListSubscribers(self):
614 # TODO. Add command to mark a subscriber as active
615 r = self.do_get('subscriber-list-active-v1')
616 self.assertEquals(r['mtype'], 'GET_REPLY')
617 self.assertEquals(r['var'], 'subscriber-list-active-v1')
618 self.assertEquals(r['value'], None)
619
Jacob Erlbeck5741e1f2013-09-16 11:20:28 +0200620def add_bsc_test(suite, workdir):
621 if not os.path.isfile(os.path.join(workdir, "src/osmo-bsc/osmo-bsc")):
622 print("Skipping the BSC test")
623 return
624 test = unittest.TestLoader().loadTestsFromTestCase(TestCtrlBSC)
625 suite.addTest(test)
626
Holger Hans Peter Freytherfba03162014-03-23 12:06:36 +0100627def add_nitb_test(suite, workdir):
628 test = unittest.TestLoader().loadTestsFromTestCase(TestCtrlNITB)
629 suite.addTest(test)
630
Holger Hans Peter Freyther842137a2014-03-04 15:38:00 +0100631def add_nat_test(suite, workdir):
632 if not os.path.isfile(os.path.join(workdir, "src/osmo-bsc_nat/osmo-bsc_nat")):
633 print("Skipping the NAT test")
634 return
635 test = unittest.TestLoader().loadTestsFromTestCase(TestCtrlNAT)
636 suite.addTest(test)
637
Holger Hans Peter Freythere8e5ef22014-03-23 18:08:26 +0100638def add_sgsn_test(suite, workdir):
639 if not os.path.isfile(os.path.join(workdir, "src/gprs/osmo-sgsn")):
640 print("Skipping the SGSN test")
641 return
642 test = unittest.TestLoader().loadTestsFromTestCase(TestCtrlSGSN)
643 suite.addTest(test)
644
Jacob Erlbeck5741e1f2013-09-16 11:20:28 +0200645if __name__ == '__main__':
646 import argparse
647 import sys
648
649 workdir = '.'
650
651 parser = argparse.ArgumentParser()
652 parser.add_argument("-v", "--verbose", dest="verbose",
653 action="store_true", help="verbose mode")
654 parser.add_argument("-p", "--pythonconfpath", dest="p",
655 help="searchpath for config")
656 parser.add_argument("-w", "--workdir", dest="w",
657 help="Working directory")
658 args = parser.parse_args()
659
660 verbose_level = 1
661 if args.verbose:
662 verbose_level = 2
663 verbose = True
664
665 if args.w:
666 workdir = args.w
667
668 if args.p:
669 confpath = args.p
670
671 print "confpath %s, workdir %s" % (confpath, workdir)
672 os.chdir(workdir)
673 print "Running tests for specific control commands"
674 suite = unittest.TestSuite()
675 add_bsc_test(suite, workdir)
Holger Hans Peter Freytherfba03162014-03-23 12:06:36 +0100676 add_nitb_test(suite, workdir)
Holger Hans Peter Freyther842137a2014-03-04 15:38:00 +0100677 add_nat_test(suite, workdir)
Holger Hans Peter Freythere8e5ef22014-03-23 18:08:26 +0100678 add_sgsn_test(suite, workdir)
Jacob Erlbeck5741e1f2013-09-16 11:20:28 +0200679 res = unittest.TextTestRunner(verbosity=verbose_level).run(suite)
680 sys.exit(len(res.errors) + len(res.failures))