blob: e8e543c9db8414d780c632f443d8f35af1bab573 [file] [log] [blame]
Holger Hans Peter Freytherb484aab2018-08-29 04:28:33 +01001# ms_driver: Launch OsmocomBB mobile's virtually connected to a BTS
2#
3# Copyright (C) 2018 by Holger Hans Peter Freyther
4#
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
7# published by the Free Software Foundation, either version 3 of the
8# License, or (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
18from datetime import timedelta
Holger Hans Peter Freyther792614f2018-11-05 06:23:39 +000019from . import log, util
Holger Hans Peter Freytherb484aab2018-08-29 04:28:33 +010020from osmo_ms_driver.cdf import cdfs
21from osmo_ms_driver.event_server import EventServer
22from osmo_ms_driver.simple_loop import SimpleLoop
23from osmo_ms_driver.location_update_test import MassUpdateLocationTest
Holger Hans Peter Freytherf658b832018-11-05 05:05:43 +000024from osmo_ms_driver.starter import BinaryOptions
Holger Hans Peter Freytherb484aab2018-08-29 04:28:33 +010025
26import os.path
27import shutil
28import tempfile
29
30class Subscriber(log.Origin):
31 def __init__(self, imsi, ki):
32 super().__init__(log.C_RUN, 'subscriber')
33 self._imsi = imsi
34 self._ki = ki
35 self._auth_algo = "comp128v1"
36 self._msisdn = None
37
38 def msisdn(self):
39 return self._msisdn
40
41 def set_msisdn(self, msisdn):
42 self._msisdn = msisdn
43
44 def imsi(self):
45 return self._imsi
46
47 def ki(self):
48 return self._ki
49
50 def auth_algo(self):
51 return self._auth_algo
52
53class MsDriver(log.Origin):
54
55 def __init__(self, suite_run):
56 super().__init__(log.C_RUN, 'ms-driver')
57 self._suite_run = suite_run
58
59 # TODO: take config out of the test scenario
60 self._num_ms = 10
61 self._time_start = timedelta(seconds=60)
62 self._time_step = timedelta(milliseconds=100)
63 self._test_duration = timedelta(seconds=120)
64 self._cdf = cdfs["ease_in_out"](self._time_start, self._time_step)
65 self._loop = SimpleLoop()
Holger Hans Peter Freytherb484aab2018-08-29 04:28:33 +010066 self._test_case = None
Holger Hans Peter Freytherd6d32062018-11-05 03:41:38 +000067 self.event_server_sk_tmp_dir = None
Holger Hans Peter Freytherb484aab2018-08-29 04:28:33 +010068
69 if len(self.event_server_path().encode()) > 107:
70 raise log.Error('Path for event_server socket is longer than max allowed len for unix socket path (107):', self.event_server_path())
71
72 def event_server_path(self):
73 if self.event_server_sk_tmp_dir is None:
74 self.event_server_sk_tmp_dir = tempfile.mkdtemp('', 'ogteventserversk')
75 return os.path.join(self.event_server_sk_tmp_dir, 'osmo_ms_driver.unix')
76
Holger Hans Peter Freytherbdc18d92018-11-05 06:49:48 +000077 def build_binary_options(self):
78 """Builds an instance of BinaryOptions.
79
80 Populates the BinaryOptions by searching the virtphy and mobile
81 application within the trial directory.
82 """
83
84 # Get the base directory for the virtphy/mobile application
Holger Hans Peter Freyther51ae2b52018-12-02 15:52:17 +000085 inst = util.Dir(os.path.abspath(self._suite_run.trial.get_inst('osmocom-bb')))
Holger Hans Peter Freytherbdc18d92018-11-05 06:49:48 +000086
87 # Assume these are dynamically linked and verify there is a lib dir.
88 lib = inst.child('lib')
89 if not os.path.isdir(lib):
90 raise RuntimeError('No lib/ in %r' % inst)
91 env = { 'LD_LIBRARY_PATH': util.prepend_library_path(lib) }
92
93 def check_and_return_binary(name):
94 """Checks the binary exists and returns the path."""
95 binary = inst.child('bin', name)
Holger Hans Peter Freyther6bf88222018-12-03 14:10:05 +000096 if not os.path.isfile(binary):
Holger Hans Peter Freytherbdc18d92018-11-05 06:49:48 +000097 raise RuntimeError('Binary missing: %r' % binary)
98 return binary
99
100 virtphy = check_and_return_binary('virtphy')
101 mobile = check_and_return_binary('mobile')
102 return BinaryOptions(virtphy, mobile, env)
103
Holger Hans Peter Freytherb484aab2018-08-29 04:28:33 +0100104 def configure(self):
105 """
106 Configures the subscribers, tests and registration server. Needs to be
107 called after the complete configuration of this driver.
108 """
109 event_server_path = self.event_server_path()
110
111 self._ev_server = EventServer("ev_server", event_server_path)
112 self._ev_server.listen(self._loop)
Holger Hans Peter Freytherbdc18d92018-11-05 06:49:48 +0000113 options = self.build_binary_options()
Holger Hans Peter Freytherf658b832018-11-05 05:05:43 +0000114 self._test_case = MassUpdateLocationTest("mass", options, self._num_ms, self._cdf,
Holger Hans Peter Freyther792614f2018-11-05 06:23:39 +0000115 self._ev_server,
Holger Hans Peter Freytherd51c2ea2018-12-03 14:38:06 +0000116 util.Dir(self.event_server_sk_tmp_dir),
Holger Hans Peter Freytherf743afb2018-11-05 06:07:57 +0000117 suite_run=self._suite_run)
Holger Hans Peter Freytherb484aab2018-08-29 04:28:33 +0100118
119 # TODO: We should pass subscribers down to the test and not get it from
120 # there.
121 self._subs = [Subscriber(imsi=mob.imsi(), ki=mob.ki()) for mob in self._test_case.mobiles()]
122
123
124 def ms_subscribers(self):
125 """
126 Returns a list of 'subscribers' that were configured in the
127 current scenario.
128 """
129 if not hasattr(self, '_subs'):
130 self.configure()
131 return self._subs
132
133 def run_test(self):
134 """
135 Runs the configured tests by starting the configured amount of mobile
136 devices according to their schedule. Returns once all tests succeeded
137 or the configured timeout has passed.
138 """
139 if not hasattr(self, '_subs'):
140 self.configure()
141 self._test_case.run_test(self._loop, self._test_duration)
142
143 def print_stats(self):
144 """
145 Prints statistics about the test run.
146 """
147 self._test_case.print_stats()
148
149 def cleanup(self):
150 """
Holger Hans Peter Freytherf743afb2018-11-05 06:07:57 +0000151 Cleans up the driver (e.g. AF_UNIX files).
Holger Hans Peter Freytherb484aab2018-08-29 04:28:33 +0100152 """
153
154 # Clean-up the temporary directory.
155 if self.event_server_sk_tmp_dir:
156 shutil.rmtree(path=self.event_server_sk_tmp_dir)
157
Holger Hans Peter Freytherb484aab2018-08-29 04:28:33 +0100158# vim: expandtab tabstop=4 shiftwidth=4