<p>Holger Freyther has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/13826">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">virtual: Make it possible to add tests to the ms driver<br><br>Introduce an Executor that forwards all testcase related methods to<br>a list of testcases. Allow to instantiate them by name and use the<br>result to access the statistics.<br><br>Change-Id: Ia65ee53987e92b24e6b8c40e1376bc74dc260180<br>---<br>M src/osmo_gsm_tester/ms_driver.py<br>M src/osmo_ms_driver/test_support.py<br>M suites/nitb_netreg_mass/register_default_mass.py<br>3 files changed, 82 insertions(+), 33 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-gsm-tester refs/changes/26/13826/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/osmo_gsm_tester/ms_driver.py b/src/osmo_gsm_tester/ms_driver.py</span><br><span>index dddedf7..355a03e 100644</span><br><span>--- a/src/osmo_gsm_tester/ms_driver.py</span><br><span>+++ b/src/osmo_gsm_tester/ms_driver.py</span><br><span>@@ -22,6 +22,7 @@</span><br><span> from osmo_ms_driver.simple_loop import SimpleLoop</span><br><span> from osmo_ms_driver.location_update_test import MassUpdateLocationTest</span><br><span> from osmo_ms_driver.starter import BinaryOptions, MobileTestStarter</span><br><span style="color: hsl(120, 100%, 40%);">+from osmo_ms_driver.test_support import TestExecutor</span><br><span> </span><br><span> import os.path</span><br><span> import shutil</span><br><span>@@ -39,14 +40,20 @@</span><br><span>         self._test_duration = timedelta(seconds=120)</span><br><span>         self._cdf = cdfs["ease_in_out"](self._time_start, self._time_step)</span><br><span>         self._loop = SimpleLoop()</span><br><span style="color: hsl(0, 100%, 40%);">-        self._test_case = None</span><br><span style="color: hsl(120, 100%, 40%);">+        self._executor = TestExecutor()</span><br><span>         self.event_server_sk_tmp_dir = None</span><br><span>         self._subscribers = []</span><br><span>         self._configured = False</span><br><span style="color: hsl(120, 100%, 40%);">+        self._results = {}</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        if len(self.event_server_path().encode()) > 107:</span><br><span style="color: hsl(120, 100%, 40%);">+        # Set-up and start the event server</span><br><span style="color: hsl(120, 100%, 40%);">+        event_server_path = self.event_server_path()</span><br><span style="color: hsl(120, 100%, 40%);">+        if len(event_server_path.encode()) > 107:</span><br><span>             raise log.Error('Path for event_server socket is longer than max allowed len for unix socket path (107):', self.event_server_path())</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+        self._ev_server = EventServer("ev_server", event_server_path)</span><br><span style="color: hsl(120, 100%, 40%);">+        self._ev_server.listen(self._loop)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>     def event_server_path(self):</span><br><span>         if self.event_server_sk_tmp_dir is None:</span><br><span>             self.event_server_sk_tmp_dir = tempfile.mkdtemp('', 'ogteventserversk')</span><br><span>@@ -83,27 +90,39 @@</span><br><span>         """Adds a subscriber to the list of subscribers."""</span><br><span>         self._subscribers.append(subscriber)</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+    def add_test(self, test_name, **kwargs):</span><br><span style="color: hsl(120, 100%, 40%);">+        """</span><br><span style="color: hsl(120, 100%, 40%);">+        Instantiates and returns a test for the given name.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        The instance created and added will be returned.</span><br><span style="color: hsl(120, 100%, 40%);">+        """</span><br><span style="color: hsl(120, 100%, 40%);">+        if test_name == 'update_location':</span><br><span style="color: hsl(120, 100%, 40%);">+            test = MassUpdateLocationTest("mass",</span><br><span style="color: hsl(120, 100%, 40%);">+                                          self._ev_server, self._results)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        # Verify that a test was instantiated.</span><br><span style="color: hsl(120, 100%, 40%);">+        if test_name is None:</span><br><span style="color: hsl(120, 100%, 40%);">+            raise Exception("Unknown test_name: " + test_name)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        # Add it to the executor and return it.</span><br><span style="color: hsl(120, 100%, 40%);">+        self._executor.add_test(test)</span><br><span style="color: hsl(120, 100%, 40%);">+        return test</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>     def configure(self):</span><br><span>         """</span><br><span>         Configures the subscribers, tests and registration server. Needs to be</span><br><span>         called after the complete configuration of this driver.</span><br><span>         """</span><br><span style="color: hsl(0, 100%, 40%);">-        event_server_path = self.event_server_path()</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        self._ev_server = EventServer("ev_server", event_server_path)</span><br><span style="color: hsl(0, 100%, 40%);">-        self._ev_server.listen(self._loop)</span><br><span style="color: hsl(0, 100%, 40%);">-        self._results = {}</span><br><span>         options = self.build_binary_options()</span><br><span>         self._starter = MobileTestStarter("mass", options, self._cdf,</span><br><span>                                           self._ev_server,</span><br><span>                                           util.Dir(self.event_server_sk_tmp_dir),</span><br><span>                                           self._results, suite_run=self._suite_run)</span><br><span style="color: hsl(0, 100%, 40%);">-        self._test_case = MassUpdateLocationTest("mass", self._ev_server, self._results)</span><br><span> </span><br><span>         for sub in self._subscribers:</span><br><span>             self._starter.subscriber_add(sub)</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        self._test_case.configure(len(self._subscribers))</span><br><span style="color: hsl(120, 100%, 40%);">+        self._executor.configure(len(self._subscribers))</span><br><span>         self._configured = True</span><br><span> </span><br><span>     def run_test(self):</span><br><span>@@ -114,34 +133,16 @@</span><br><span>         """</span><br><span>         if not self._configured:</span><br><span>             self.configure()</span><br><span style="color: hsl(0, 100%, 40%);">-        self._test_case.before_start()</span><br><span style="color: hsl(120, 100%, 40%);">+        self._executor.before_start()</span><br><span>         deadline = self._starter.start_all(self._loop, self._test_duration)</span><br><span style="color: hsl(0, 100%, 40%);">-        self._test_case.after_start()</span><br><span style="color: hsl(0, 100%, 40%);">-        self._test_case.wait_for_test(self._loop, deadline)</span><br><span style="color: hsl(120, 100%, 40%);">+        self._executor.after_start()</span><br><span style="color: hsl(120, 100%, 40%);">+        self._executor.wait_for_test(self._loop, deadline)</span><br><span> </span><br><span>     def print_stats(self):</span><br><span>         """</span><br><span>         Prints statistics about the test run.</span><br><span>         """</span><br><span style="color: hsl(0, 100%, 40%);">-        self._test_case.print_stats()</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    def get_stats(self):</span><br><span style="color: hsl(0, 100%, 40%);">-        """</span><br><span style="color: hsl(0, 100%, 40%);">-        Returns a statistical summary of the test.</span><br><span style="color: hsl(0, 100%, 40%);">-        """</span><br><span style="color: hsl(0, 100%, 40%);">-        return self._test_case.get_stats()</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    def get_result_values(self):</span><br><span style="color: hsl(0, 100%, 40%);">-        """</span><br><span style="color: hsl(0, 100%, 40%);">-        Returns the raw result values of the test run in any order.</span><br><span style="color: hsl(0, 100%, 40%);">-        """</span><br><span style="color: hsl(0, 100%, 40%);">-        return self._test_case.get_result_values()</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    def lus_less_than(self, acceptable_delay):</span><br><span style="color: hsl(0, 100%, 40%);">-        """</span><br><span style="color: hsl(0, 100%, 40%);">-        Returns the results that completed their LU within the acceptable delay.</span><br><span style="color: hsl(0, 100%, 40%);">-        """</span><br><span style="color: hsl(0, 100%, 40%);">-        return self._test_case.lus_less_than(acceptable_delay)</span><br><span style="color: hsl(120, 100%, 40%);">+        self._executor.print_stats()</span><br><span> </span><br><span>     def cleanup(self):</span><br><span>         """</span><br><span>diff --git a/src/osmo_ms_driver/test_support.py b/src/osmo_ms_driver/test_support.py</span><br><span>index cbfd444..f7910dd 100644</span><br><span>--- a/src/osmo_ms_driver/test_support.py</span><br><span>+++ b/src/osmo_ms_driver/test_support.py</span><br><span>@@ -18,6 +18,8 @@</span><br><span> from abc import ABCMeta</span><br><span> from osmo_gsm_tester import log</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+import time</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> def imsi_ki_gen():</span><br><span>     """</span><br><span>     Generate IMSIs and KIs to be used by test.</span><br><span>@@ -93,3 +95,48 @@</span><br><span>     def print_stats(self):</span><br><span>         """Prints statistics/results of the test."""</span><br><span>         pass</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+class TestExecutor(log.Origin):</span><br><span style="color: hsl(120, 100%, 40%);">+    """Execute/Wait for a list of tests to complete."""</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def __init__(self):</span><br><span style="color: hsl(120, 100%, 40%);">+        super().__init__(log.C_RUN, "executor")</span><br><span style="color: hsl(120, 100%, 40%);">+        self._tests = []</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def add_test(self, test):</span><br><span style="color: hsl(120, 100%, 40%);">+        self._tests.append(test)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def configure(self, num_subscriber):</span><br><span style="color: hsl(120, 100%, 40%);">+        for test in self._tests:</span><br><span style="color: hsl(120, 100%, 40%);">+            test.configure(num_subscriber)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def before_start(self):</span><br><span style="color: hsl(120, 100%, 40%);">+        for test in self._tests:</span><br><span style="color: hsl(120, 100%, 40%);">+            test.before_start()</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def after_start(self):</span><br><span style="color: hsl(120, 100%, 40%);">+        for test in self._tests:</span><br><span style="color: hsl(120, 100%, 40%);">+            test.after_start()</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def print_stats(self):</span><br><span style="color: hsl(120, 100%, 40%);">+        """Prints statistics/results of the test."""</span><br><span style="color: hsl(120, 100%, 40%);">+        for test in self._tests:</span><br><span style="color: hsl(120, 100%, 40%);">+            test.print_stats()</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def all_tests_completed(self):</span><br><span style="color: hsl(120, 100%, 40%);">+        """Returns true if all tests completed."""</span><br><span style="color: hsl(120, 100%, 40%);">+        for test in self._tests:</span><br><span style="color: hsl(120, 100%, 40%);">+            if not test.has_completed():</span><br><span style="color: hsl(120, 100%, 40%);">+                return False</span><br><span style="color: hsl(120, 100%, 40%);">+        return True</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def wait_for_test(self, loop, deadline):</span><br><span style="color: hsl(120, 100%, 40%);">+        """Waits up to the absolute deadline for all tests to complete."""</span><br><span style="color: hsl(120, 100%, 40%);">+        while not self.all_tests_completed():</span><br><span style="color: hsl(120, 100%, 40%);">+            now_time = time.clock_gettime(time.CLOCK_MONOTONIC)</span><br><span style="color: hsl(120, 100%, 40%);">+            sleep_time = deadline - now_time</span><br><span style="color: hsl(120, 100%, 40%);">+            if sleep_time < 0:</span><br><span style="color: hsl(120, 100%, 40%);">+                break</span><br><span style="color: hsl(120, 100%, 40%);">+            loop.schedule_timeout(sleep_time)</span><br><span style="color: hsl(120, 100%, 40%);">+            loop.select()</span><br><span>diff --git a/suites/nitb_netreg_mass/register_default_mass.py b/suites/nitb_netreg_mass/register_default_mass.py</span><br><span>index f4e5e80..d6782e7 100644</span><br><span>--- a/suites/nitb_netreg_mass/register_default_mass.py</span><br><span>+++ b/suites/nitb_netreg_mass/register_default_mass.py</span><br><span>@@ -10,6 +10,7 @@</span><br><span> nitb = suite.nitb()</span><br><span> bts = suite.bts()</span><br><span> ms_driver = suite.ms_driver()</span><br><span style="color: hsl(120, 100%, 40%);">+ul = ms_driver.add_test('update_location')</span><br><span> modems = suite.all_resources(suite.modem)</span><br><span> </span><br><span> print('Launching a simple network')</span><br><span>@@ -35,7 +36,7 @@</span><br><span> #</span><br><span> # 99% of LUs should complete</span><br><span> # 99% of successful LUs should complete within 10s.</span><br><span style="color: hsl(0, 100%, 40%);">-stats = ms_driver.get_stats()</span><br><span style="color: hsl(120, 100%, 40%);">+stats = ul.get_stats()</span><br><span> if len(modems) > 0 and stats.num_completed < 1:</span><br><span>     raise Exception("No run completed.")</span><br><span> completion_ratio = stats.num_completed / stats.num_attempted</span><br><span>@@ -46,7 +47,7 @@</span><br><span> </span><br><span> # Check how many results are below our threshold.</span><br><span> acceptable_delay = timedelta(seconds=30)</span><br><span style="color: hsl(0, 100%, 40%);">-quick_enough = len(ms_driver.lus_less_than(acceptable_delay))</span><br><span style="color: hsl(120, 100%, 40%);">+quick_enough = len(ul.lus_less_than(acceptable_delay))</span><br><span> latency_ratio = quick_enough / stats.num_attempted</span><br><span> if latency_ratio < 0.99:</span><br><span>     raise Exception("Latency ratio of %f%% lower than threshold." % (latency_ratio * 100.0))</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/13826">change 13826</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/13826"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-gsm-tester </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: Ia65ee53987e92b24e6b8c40e1376bc74dc260180 </div>
<div style="display:none"> Gerrit-Change-Number: 13826 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Holger Freyther <holger@freyther.de> </div>