blob: 9be8d03ccce9d1cc0da85e8b7481241dc0d45431 [file] [log] [blame]
Holger Hans Peter Freythereb0acb62013-06-24 15:47:34 +02001#!/usr/bin/env python
2
3# (C) 2013 by Katerina Barone-Adesi <kat.obsc@gmail.com>
4# (C) 2013 by Holger Hans Peter Freyther
5# This program is free software: you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation, either version 3 of the License, or
8# (at your option) any later version.
9
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU General Public License for more details.
14
15# You should have received a copy of the GNU General Public License
16# along with this program. If not, see <http://www.gnu.org/licenses/>.
17
Max3e676892016-11-16 14:55:21 +010018import os, sys
Holger Hans Peter Freythereb0acb62013-06-24 15:47:34 +020019import time
20import unittest
Jacob Erlbeck6cb2ccc2013-08-14 11:10:34 +020021import socket
Neels Hofmeyrbcfee2a2017-02-03 16:09:17 +010022import subprocess
Holger Hans Peter Freythereb0acb62013-06-24 15:47:34 +020023
24import osmopy.obscvty as obscvty
25import osmopy.osmoutil as osmoutil
26
Neels Hofmeyr476c4bb2017-02-24 17:55:11 +010027# add $top_srcdir/contrib to find ipa.py
28sys.path.append(os.path.join(sys.path[0], '..', 'contrib'))
29
Max3e676892016-11-16 14:55:21 +010030from ipa import IPA
31
Neels Hofmeyr476c4bb2017-02-24 17:55:11 +010032# to be able to find $top_srcdir/doc/...
33confpath = os.path.join(sys.path[0], '..')
Holger Hans Peter Freythereb0acb62013-06-24 15:47:34 +020034
35class TestVTYBase(unittest.TestCase):
36
Neels Hofmeyr2188a772016-05-20 21:59:55 +020037 def checkForEndAndExit(self):
38 res = self.vty.command("list")
39 #print ('looking for "exit"\n')
40 self.assert_(res.find(' exit\r') > 0)
41 #print 'found "exit"\nlooking for "end"\n'
42 self.assert_(res.find(' end\r') > 0)
43 #print 'found "end"\n'
44
Holger Hans Peter Freythereb0acb62013-06-24 15:47:34 +020045 def vty_command(self):
46 raise Exception("Needs to be implemented by a subclass")
47
48 def vty_app(self):
49 raise Exception("Needs to be implemented by a subclass")
50
51 def setUp(self):
52 osmo_vty_cmd = self.vty_command()[:]
53 config_index = osmo_vty_cmd.index('-c')
54 if config_index:
55 cfi = config_index + 1
56 osmo_vty_cmd[cfi] = os.path.join(confpath, osmo_vty_cmd[cfi])
57
58 try:
Holger Hans Peter Freythereb0acb62013-06-24 15:47:34 +020059 self.proc = osmoutil.popen_devnull(osmo_vty_cmd)
60 except OSError:
61 print >> sys.stderr, "Current directory: %s" % os.getcwd()
62 print >> sys.stderr, "Consider setting -b"
Holger Hans Peter Freythereb0acb62013-06-24 15:47:34 +020063
64 appstring = self.vty_app()[2]
65 appport = self.vty_app()[0]
66 self.vty = obscvty.VTYInteract(appstring, "127.0.0.1", appport)
67
68 def tearDown(self):
Neels Hofmeyr40a91b32017-02-24 17:54:22 +010069 if self.vty:
70 self.vty._close_socket()
Holger Hans Peter Freythereb0acb62013-06-24 15:47:34 +020071 self.vty = None
72 osmoutil.end_proc(self.proc)
73
Jacob Erlbeck96903c42013-09-02 13:17:14 +020074
Neels Hofmeyree6cfdc2017-07-13 02:03:50 +020075class TestVTYGbproxy(TestVTYBase):
Jacob Erlbeck6d233712013-10-23 11:24:15 +020076
77 def vty_command(self):
78 return ["./src/gprs/osmo-gbproxy", "-c",
79 "doc/examples/osmo-gbproxy/osmo-gbproxy.cfg"]
80
81 def vty_app(self):
82 return (4246, "./src/gprs/osmo-gbproxy", "OsmoGbProxy", "bsc")
83
84 def testVtyTree(self):
85 self.vty.enable()
86 self.assertTrue(self.vty.verify('configure terminal', ['']))
87 self.assertEquals(self.vty.node(), 'config')
Jacob Erlbeck6e919db2013-10-29 09:30:31 +010088 self.checkForEndAndExit()
Jacob Erlbeck6d233712013-10-23 11:24:15 +020089 self.assertTrue(self.vty.verify('ns', ['']))
90 self.assertEquals(self.vty.node(), 'config-ns')
91 self.checkForEndAndExit()
92 self.assertTrue(self.vty.verify('exit', ['']))
93 self.assertEquals(self.vty.node(), 'config')
94 self.assertTrue(self.vty.verify('gbproxy', ['']))
95 self.assertEquals(self.vty.node(), 'config-gbproxy')
96 self.checkForEndAndExit()
97 self.assertTrue(self.vty.verify('exit', ['']))
98 self.assertEquals(self.vty.node(), 'config')
99
100 def testVtyShow(self):
101 res = self.vty.command("show ns")
102 self.assert_(res.find('Encapsulation NS-UDP-IP') >= 0)
103
104 res = self.vty.command("show gbproxy stats")
105 self.assert_(res.find('GBProxy Global Statistics') >= 0)
106
Jacob Erlbeck4211d792013-10-24 12:48:23 +0200107 def testVtyDeletePeer(self):
108 self.vty.enable()
109 self.assertTrue(self.vty.verify('delete-gbproxy-peer 9999 bvci 7777', ['BVC not found']))
110 res = self.vty.command("delete-gbproxy-peer 9999 all dry-run")
111 self.assert_(res.find('Not Deleted 0 BVC') >= 0)
112 self.assert_(res.find('Not Deleted 0 NS-VC') >= 0)
113 res = self.vty.command("delete-gbproxy-peer 9999 only-bvc dry-run")
114 self.assert_(res.find('Not Deleted 0 BVC') >= 0)
115 self.assert_(res.find('Not Deleted 0 NS-VC') < 0)
116 res = self.vty.command("delete-gbproxy-peer 9999 only-nsvc dry-run")
117 self.assert_(res.find('Not Deleted 0 BVC') < 0)
118 self.assert_(res.find('Not Deleted 0 NS-VC') >= 0)
119 res = self.vty.command("delete-gbproxy-peer 9999 all")
120 self.assert_(res.find('Deleted 0 BVC') >= 0)
121 self.assert_(res.find('Deleted 0 NS-VC') >= 0)
122
Neels Hofmeyree6cfdc2017-07-13 02:03:50 +0200123class TestVTYSGSN(TestVTYBase):
Jacob Erlbeck144b8b12014-11-04 11:15:01 +0100124
125 def vty_command(self):
126 return ["./src/gprs/osmo-sgsn", "-c",
Daniel Willmannc01bc002017-05-11 17:50:04 +0200127 "doc/examples/osmo-sgsn/osmo-sgsn-accept-all.cfg"]
Jacob Erlbeck144b8b12014-11-04 11:15:01 +0100128
129 def vty_app(self):
130 return (4245, "./src/gprs/osmo-sgsn", "OsmoSGSN", "sgsn")
131
132 def testVtyTree(self):
133 self.vty.enable()
134 self.assertTrue(self.vty.verify('configure terminal', ['']))
135 self.assertEquals(self.vty.node(), 'config')
136 self.checkForEndAndExit()
137 self.assertTrue(self.vty.verify('ns', ['']))
138 self.assertEquals(self.vty.node(), 'config-ns')
139 self.checkForEndAndExit()
140 self.assertTrue(self.vty.verify('exit', ['']))
141 self.assertEquals(self.vty.node(), 'config')
142 self.assertTrue(self.vty.verify('sgsn', ['']))
143 self.assertEquals(self.vty.node(), 'config-sgsn')
144 self.checkForEndAndExit()
145 self.assertTrue(self.vty.verify('exit', ['']))
146 self.assertEquals(self.vty.node(), 'config')
147
148 def testVtyShow(self):
149 res = self.vty.command("show ns")
150 self.assert_(res.find('Encapsulation NS-UDP-IP') >= 0)
151 self.assertTrue(self.vty.verify('show bssgp', ['']))
152 self.assertTrue(self.vty.verify('show bssgp stats', ['']))
153 # TODO: uncomment when the command does not segfault anymore
154 # self.assertTrue(self.vty.verify('show bssgp nsei 123', ['']))
155 # self.assertTrue(self.vty.verify('show bssgp nsei 123 stats', ['']))
156
157 self.assertTrue(self.vty.verify('show sgsn', ['']))
158 self.assertTrue(self.vty.verify('show mm-context all', ['']))
159 self.assertTrue(self.vty.verify('show mm-context imsi 000001234567', ['No MM context for IMSI 000001234567']))
160 self.assertTrue(self.vty.verify('show pdp-context all', ['']))
161
162 res = self.vty.command("show sndcp")
163 self.assert_(res.find('State of SNDCP Entities') >= 0)
164
165 res = self.vty.command("show llc")
166 self.assert_(res.find('State of LLC Entities') >= 0)
167
Jacob Erlbeck106f5472014-11-04 10:08:37 +0100168 def testVtyAuth(self):
169 self.vty.enable()
170 self.assertTrue(self.vty.verify('configure terminal', ['']))
171 self.assertEquals(self.vty.node(), 'config')
172 self.assertTrue(self.vty.verify('sgsn', ['']))
173 self.assertEquals(self.vty.node(), 'config-sgsn')
174 self.assertTrue(self.vty.verify('auth-policy accept-all', ['']))
175 res = self.vty.command("show running-config")
176 self.assert_(res.find('auth-policy accept-all') > 0)
177 self.assertTrue(self.vty.verify('auth-policy acl-only', ['']))
178 res = self.vty.command("show running-config")
179 self.assert_(res.find('auth-policy acl-only') > 0)
180 self.assertTrue(self.vty.verify('auth-policy closed', ['']))
181 res = self.vty.command("show running-config")
182 self.assert_(res.find('auth-policy closed') > 0)
Max176b62a2016-07-04 11:09:07 +0200183 self.assertTrue(self.vty.verify('gsup remote-ip 127.0.0.4', ['']))
184 self.assertTrue(self.vty.verify('gsup remote-port 2222', ['']))
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +0100185 self.assertTrue(self.vty.verify('auth-policy remote', ['']))
186 res = self.vty.command("show running-config")
187 self.assert_(res.find('auth-policy remote') > 0)
Jacob Erlbeck106f5472014-11-04 10:08:37 +0100188
Jacob Erlbeck207f4a52014-11-11 14:01:48 +0100189 def testVtySubscriber(self):
190 self.vty.enable()
191 res = self.vty.command('show subscriber cache')
192 self.assert_(res.find('1234567890') < 0)
Jacob Erlbeckd9193432015-01-19 14:11:46 +0100193 self.assertTrue(self.vty.verify('update-subscriber imsi 1234567890 create', ['']))
194 res = self.vty.command('show subscriber cache')
195 self.assert_(res.find('1234567890') >= 0)
196 self.assert_(res.find('Authorized: 0') >= 0)
197 self.assertTrue(self.vty.verify('update-subscriber imsi 1234567890 update-location-result ok', ['']))
Jacob Erlbeck207f4a52014-11-11 14:01:48 +0100198 res = self.vty.command('show subscriber cache')
199 self.assert_(res.find('1234567890') >= 0)
200 self.assert_(res.find('Authorized: 1') >= 0)
Jacob Erlbeck8000e0e2015-01-27 14:56:40 +0100201 self.assertTrue(self.vty.verify('update-subscriber imsi 1234567890 cancel update-procedure', ['']))
Jacob Erlbeck207f4a52014-11-11 14:01:48 +0100202 res = self.vty.command('show subscriber cache')
Jacob Erlbecke988ae42015-01-27 12:41:19 +0100203 self.assert_(res.find('1234567890') >= 0)
204 self.assertTrue(self.vty.verify('update-subscriber imsi 1234567890 destroy', ['']))
205 res = self.vty.command('show subscriber cache')
Jacob Erlbeck207f4a52014-11-11 14:01:48 +0100206 self.assert_(res.find('1234567890') < 0)
207
Jacob Erlbeckcb1db8b2015-02-03 13:47:53 +0100208 def testVtyGgsn(self):
209 self.vty.enable()
210 self.assertTrue(self.vty.verify('configure terminal', ['']))
211 self.assertEquals(self.vty.node(), 'config')
212 self.assertTrue(self.vty.verify('sgsn', ['']))
213 self.assertEquals(self.vty.node(), 'config-sgsn')
214 self.assertTrue(self.vty.verify('ggsn 0 remote-ip 127.99.99.99', ['']))
215 self.assertTrue(self.vty.verify('ggsn 0 gtp-version 1', ['']))
216 self.assertTrue(self.vty.verify('apn * ggsn 0', ['']))
217 self.assertTrue(self.vty.verify('apn apn1.test ggsn 0', ['']))
218 self.assertTrue(self.vty.verify('apn apn1.test ggsn 1', ['% a GGSN with id 1 has not been defined']))
219 self.assertTrue(self.vty.verify('apn apn1.test imsi-prefix 123456 ggsn 0', ['']))
220 self.assertTrue(self.vty.verify('apn apn2.test imsi-prefix 123456 ggsn 0', ['']))
221 res = self.vty.command("show running-config")
222 self.assert_(res.find('ggsn 0 remote-ip 127.99.99.99') >= 0)
223 self.assert_(res.find('ggsn 0 gtp-version 1') >= 0)
224 self.assert_(res.find('apn * ggsn 0') >= 0)
225 self.assert_(res.find('apn apn1.test ggsn 0') >= 0)
226 self.assert_(res.find('apn apn1.test imsi-prefix 123456 ggsn 0') >= 0)
227 self.assert_(res.find('apn apn2.test imsi-prefix 123456 ggsn 0') >= 0)
228
Holger Hans Peter Freyther9c20a5f2015-02-06 16:23:29 +0100229 def testVtyEasyAPN(self):
230 self.vty.enable()
231 self.assertTrue(self.vty.verify('configure terminal', ['']))
232 self.assertEquals(self.vty.node(), 'config')
233 self.assertTrue(self.vty.verify('sgsn', ['']))
234 self.assertEquals(self.vty.node(), 'config-sgsn')
235
236 res = self.vty.command("show running-config")
237 self.assertEquals(res.find("apn internet"), -1)
238
239 self.assertTrue(self.vty.verify("access-point-name internet.apn", ['']))
240 res = self.vty.command("show running-config")
241 self.assert_(res.find("apn internet.apn ggsn 0") >= 0)
242
243 self.assertTrue(self.vty.verify("no access-point-name internet.apn", ['']))
244 res = self.vty.command("show running-config")
245 self.assertEquals(res.find("apn internet"), -1)
246
Holger Hans Peter Freytherc15c61c2015-05-06 17:46:08 +0200247 def testVtyCDR(self):
248 self.vty.enable()
249 self.assertTrue(self.vty.verify('configure terminal', ['']))
250 self.assertEquals(self.vty.node(), 'config')
251 self.assertTrue(self.vty.verify('sgsn', ['']))
252 self.assertEquals(self.vty.node(), 'config-sgsn')
253
254 res = self.vty.command("show running-config")
255 self.assert_(res.find("no cdr filename") > 0)
256
257 self.vty.command("cdr filename bla.cdr")
258 res = self.vty.command("show running-config")
259 self.assertEquals(res.find("no cdr filename"), -1)
260 self.assert_(res.find(" cdr filename bla.cdr") > 0)
261
262 self.vty.command("no cdr filename")
263 res = self.vty.command("show running-config")
264 self.assert_(res.find("no cdr filename") > 0)
265 self.assertEquals(res.find(" cdr filename bla.cdr"), -1)
266
267 res = self.vty.command("show running-config")
268 self.assert_(res.find(" cdr interval 600") > 0)
269
270 self.vty.command("cdr interval 900")
271 res = self.vty.command("show running-config")
272 self.assert_(res.find(" cdr interval 900") > 0)
273 self.assertEquals(res.find(" cdr interval 600"), -1)
274
Jacob Erlbeck1b894022013-08-28 10:16:54 +0200275
Jacob Erlbeck6d233712013-10-23 11:24:15 +0200276def add_gbproxy_test(suite, workdir):
277 if not os.path.isfile(os.path.join(workdir, "src/gprs/osmo-gbproxy")):
278 print("Skipping the Gb-Proxy test")
279 return
280 test = unittest.TestLoader().loadTestsFromTestCase(TestVTYGbproxy)
281 suite.addTest(test)
282
Jacob Erlbeck144b8b12014-11-04 11:15:01 +0100283def add_sgsn_test(suite, workdir):
284 if not os.path.isfile(os.path.join(workdir, "src/gprs/osmo-sgsn")):
285 print("Skipping the SGSN test")
286 return
287 test = unittest.TestLoader().loadTestsFromTestCase(TestVTYSGSN)
288 suite.addTest(test)
289
Holger Hans Peter Freythereb0acb62013-06-24 15:47:34 +0200290if __name__ == '__main__':
291 import argparse
292 import sys
293
294 workdir = '.'
295
296 parser = argparse.ArgumentParser()
297 parser.add_argument("-v", "--verbose", dest="verbose",
298 action="store_true", help="verbose mode")
299 parser.add_argument("-p", "--pythonconfpath", dest="p",
300 help="searchpath for config")
301 parser.add_argument("-w", "--workdir", dest="w",
302 help="Working directory")
Neels Hofmeyr3f8a8f72017-02-28 02:43:29 +0100303 parser.add_argument("test_name", nargs="*", help="(parts of) test names to run, case-insensitive")
Holger Hans Peter Freythereb0acb62013-06-24 15:47:34 +0200304 args = parser.parse_args()
305
306 verbose_level = 1
307 if args.verbose:
308 verbose_level = 2
309
310 if args.w:
311 workdir = args.w
312
313 if args.p:
314 confpath = args.p
315
316 print "confpath %s, workdir %s" % (confpath, workdir)
317 os.chdir(workdir)
318 print "Running tests for specific VTY commands"
319 suite = unittest.TestSuite()
Jacob Erlbeck6d233712013-10-23 11:24:15 +0200320 add_gbproxy_test(suite, workdir)
Jacob Erlbeck144b8b12014-11-04 11:15:01 +0100321 add_sgsn_test(suite, workdir)
Neels Hofmeyr3f8a8f72017-02-28 02:43:29 +0100322
323 if args.test_name:
324 osmoutil.pick_tests(suite, *args.test_name)
325
Neels Hofmeyr0a45c1e2016-09-28 23:48:02 +0200326 res = unittest.TextTestRunner(verbosity=verbose_level, stream=sys.stdout).run(suite)
Holger Hans Peter Freythereb0acb62013-06-24 15:47:34 +0200327 sys.exit(len(res.errors) + len(res.failures))
Neels Hofmeyr23d37c92016-09-26 03:18:32 +0200328
Neels Hofmeyr0867b722016-09-28 23:28:06 +0200329# vim: shiftwidth=4 expandtab nocin ai