[PATCH] osmo-gsm-tester[master]: Move Test class to its own test.py module

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

Pau Espin Pedrol gerrit-no-reply at lists.osmocom.org
Thu Nov 9 13:51:47 UTC 2017


Review at  https://gerrit.osmocom.org/4764

Move Test class to its own test.py module

Change-Id: I9c8d67f598466ba52a4827ff77027b9eae85929a
---
M selftest/suite_test.ok
M src/osmo_gsm_tester/report.py
M src/osmo_gsm_tester/suite.py
A src/osmo_gsm_tester/test.py
4 files changed, 148 insertions(+), 123 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/osmo-gsm-tester refs/changes/64/4764/1

diff --git a/selftest/suite_test.ok b/selftest/suite_test.ok
index cd5a9e7..79c37cc 100644
--- a/selftest/suite_test.ok
+++ b/selftest/suite_test.ok
@@ -110,7 +110,7 @@
 ----------------------------------------------
 tst test_error.py:[LINENR]: I am 'test_suite' / 'test_error.py:[LINENR]'  [test_suite↪test_error.py:[LINENR]]  [test_error.py:[LINENR]]
 tst test_error.py:[LINENR]: ERR: AssertionError: test_error.py:[LINENR]: assert False  [test_suite↪test_error.py:[LINENR]]  [test_error.py:[LINENR]: assert False]
-tst test_error.py:[LINENR]: Test FAILED (N.N sec)  [test_suite↪test_error.py:[LINENR]]  [suite.py:[LINENR]]
+tst test_error.py:[LINENR]: Test FAILED (N.N sec)  [test_suite↪test_error.py:[LINENR]]  [test.py:[LINENR]]
 ---------------------------------------------------------------------
 trial test_suite FAIL
 ---------------------------------------------------------------------
@@ -133,7 +133,7 @@
 ----------------------------------------------
 tst test_fail.py:[LINENR]: I am 'test_suite' / 'test_fail.py:[LINENR]'  [test_suite↪test_fail.py:[LINENR]]  [test_fail.py:[LINENR]]
 tst test_fail.py:[LINENR]: ERR: EpicFail: This failure is expected  [test_suite↪test_fail.py:[LINENR]]  [test_fail.py:[LINENR]]
-tst test_fail.py:[LINENR]: Test FAILED (N.N sec)  [test_suite↪test_fail.py:[LINENR]]  [suite.py:[LINENR]]
+tst test_fail.py:[LINENR]: Test FAILED (N.N sec)  [test_suite↪test_fail.py:[LINENR]]  [test.py:[LINENR]]
 ---------------------------------------------------------------------
 trial test_suite FAIL
 ---------------------------------------------------------------------
@@ -155,7 +155,7 @@
 trial test_suite test_fail_raise.py
 ----------------------------------------------
 tst test_fail_raise.py:[LINENR]: ERR: ExpectedFail: This failure is expected  [test_suite↪test_fail_raise.py:[LINENR]]  [test_fail_raise.py:[LINENR]: raise ExpectedFail('This failure is expected')]
-tst test_fail_raise.py:[LINENR]: Test FAILED (N.N sec)  [test_suite↪test_fail_raise.py:[LINENR]]  [suite.py:[LINENR]]
+tst test_fail_raise.py:[LINENR]: Test FAILED (N.N sec)  [test_suite↪test_fail_raise.py:[LINENR]]  [test.py:[LINENR]]
 ---------------------------------------------------------------------
 trial test_suite FAIL
 ---------------------------------------------------------------------
@@ -233,7 +233,7 @@
 tst hello_world.py:[LINENR]: one  [test_suite↪hello_world.py:[LINENR]]  [hello_world.py:[LINENR]]
 tst hello_world.py:[LINENR]: two  [test_suite↪hello_world.py:[LINENR]]  [hello_world.py:[LINENR]]
 tst hello_world.py:[LINENR]: three  [test_suite↪hello_world.py:[LINENR]]  [hello_world.py:[LINENR]]
-tst hello_world.py:[LINENR] Test passed (N.N sec)  [test_suite↪hello_world.py]  [suite.py:[LINENR]]
+tst hello_world.py:[LINENR] Test passed (N.N sec)  [test_suite↪hello_world.py]  [test.py:[LINENR]]
 ---------------------------------------------------------------------
 trial test_suite PASS
 ---------------------------------------------------------------------
@@ -311,7 +311,7 @@
 tst hello_world.py:[LINENR]: one  [test_suite↪hello_world.py:[LINENR]]  [hello_world.py:[LINENR]]
 tst hello_world.py:[LINENR]: two  [test_suite↪hello_world.py:[LINENR]]  [hello_world.py:[LINENR]]
 tst hello_world.py:[LINENR]: three  [test_suite↪hello_world.py:[LINENR]]  [hello_world.py:[LINENR]]
-tst hello_world.py:[LINENR] Test passed (N.N sec)  [test_suite↪hello_world.py]  [suite.py:[LINENR]]
+tst hello_world.py:[LINENR] Test passed (N.N sec)  [test_suite↪hello_world.py]  [test.py:[LINENR]]
 ---------------------------------------------------------------------
 trial test_suite PASS
 ---------------------------------------------------------------------
diff --git a/src/osmo_gsm_tester/report.py b/src/osmo_gsm_tester/report.py
index 82b2f13..a53504b 100644
--- a/src/osmo_gsm_tester/report.py
+++ b/src/osmo_gsm_tester/report.py
@@ -21,7 +21,7 @@
 import math
 from datetime import datetime
 import xml.etree.ElementTree as et
-from . import log, suite
+from . import log, suite, test
 
 def trial_to_junit_write(trial, junit_path):
     elements = et.ElementTree(element=trial_to_junit(trial))
@@ -48,20 +48,20 @@
         testsuite.append(testcase)
     return testsuite
 
-def test_to_junit(test):
+def test_to_junit(t):
     testcase = et.Element('testcase')
-    testcase.set('name', test.name())
-    testcase.set('time', str(math.ceil(test.duration)))
-    if test.status == suite.Test.SKIP:
+    testcase.set('name', t.name())
+    testcase.set('time', str(math.ceil(t.duration)))
+    if t.status == test.Test.SKIP:
         skip = et.SubElement(testcase, 'skipped')
-    elif test.status == suite.Test.FAIL:
+    elif t.status == test.Test.FAIL:
         failure = et.SubElement(testcase, 'failure')
-        failure.set('type', test.fail_type or 'failure')
-        failure.text = test.fail_message
-        if test.fail_tb:
+        failure.set('type', t.fail_type or 'failure')
+        failure.text = t.fail_message
+        if t.fail_tb:
             system_err = et.SubElement(testcase, 'system-err')
-            system_err.text = test.fail_tb
-    elif test.status != suite.Test.PASS:
+            system_err.text = t.fail_tb
+    elif t.status != test.Test.PASS:
         error = et.SubElement(testcase, 'error')
         error.text = 'could not run'
     return testcase
@@ -102,12 +102,12 @@
     msgs.extend([test_to_text(t) for t in suite.tests])
     return '\n    '.join(msgs)
 
-def test_to_text(test):
-    msgs = ['%s: %s' % (test.status, test.name())]
-    if test.start_timestamp:
-        msgs.append('(%.1f sec)' % test.duration)
-    if test.status == suite.Test.FAIL:
-        msgs.append('%s: %s' % (test.fail_type, test.fail_message))
+def test_to_text(t):
+    msgs = ['%s: %s' % (t.status, t.name())]
+    if t.start_timestamp:
+        msgs.append('(%.1f sec)' % t.duration)
+    if t.status == test.Test.FAIL:
+        msgs.append('%s: %s' % (t.fail_type, t.fail_message))
     return ' '.join(msgs)
 
 # vim: expandtab tabstop=4 shiftwidth=4
diff --git a/src/osmo_gsm_tester/suite.py b/src/osmo_gsm_tester/suite.py
index 5b9df76..25aef35 100644
--- a/src/osmo_gsm_tester/suite.py
+++ b/src/osmo_gsm_tester/suite.py
@@ -20,11 +20,9 @@
 import os
 import sys
 import time
-import traceback
 import pprint
-from . import config, log, template, util, resource, schema, event_loop
-from . import osmo_nitb, osmo_hlr, osmo_mgcpgw, osmo_mgw, osmo_msc, osmo_bsc, osmo_stp, modem, esme, sms
-from . import testenv
+from . import config, log, template, util, resource, schema, event_loop, test
+from . import osmo_nitb, osmo_hlr, osmo_mgcpgw, osmo_mgw, osmo_msc, osmo_bsc, osmo_stp, modem, esme
 
 class Timeout(Exception):
     pass
@@ -59,94 +57,6 @@
                 continue
             self.test_basenames.append(basename)
 
-
-class Test(log.Origin):
-    UNKNOWN = 'UNKNOWN'
-    SKIP = 'skip'
-    PASS = 'pass'
-    FAIL = 'FAIL'
-
-    _run_dir = None
-
-    def __init__(self, suite_run, test_basename):
-        self.basename = test_basename
-        super().__init__(log.C_TST, self.basename)
-        self.suite_run = suite_run
-        self.path = os.path.join(self.suite_run.definition.suite_dir, self.basename)
-        self.status = Test.UNKNOWN
-        self.start_timestamp = 0
-        self.duration = 0
-        self.fail_type = None
-        self.fail_message = None
-
-    def get_run_dir(self):
-        if self._run_dir is None:
-            self._run_dir = util.Dir(self.suite_run.get_run_dir().new_dir(self._name))
-        return self._run_dir
-
-    def run(self):
-        try:
-            log.large_separator(self.suite_run.trial.name(), self.suite_run.name(), self.name(), sublevel=3)
-            self.status = Test.UNKNOWN
-            self.start_timestamp = time.time()
-            testenv.setup(self.suite_run, self, sys.modules[__name__], event_loop, sms)
-            with self.redirect_stdout():
-                util.run_python_file('%s.%s' % (self.suite_run.definition.name(), self.basename),
-                                     self.path)
-            if self.status == Test.UNKNOWN:
-                 self.set_pass()
-        except Exception as e:
-            if hasattr(e, 'msg'):
-                msg = e.msg
-            else:
-                msg = str(e)
-            if isinstance(e, AssertionError):
-                # AssertionError lacks further information on what was
-                # asserted. Find the line where the code asserted:
-                msg += log.get_src_from_exc_info(sys.exc_info())
-            # add source file information to failure report
-            if hasattr(e, 'origins'):
-                msg += ' [%s]' % e.origins
-            tb_str = traceback.format_exc()
-            if isinstance(e, resource.NoResourceExn):
-                tb_str += self.suite_run.resource_status_str()
-            self.set_fail(type(e).__name__, msg, tb_str, log.get_src_from_exc_info())
-        except BaseException as e:
-            # when the program is aborted by a signal (like Ctrl-C), escalate to abort all.
-            self.err('TEST RUN ABORTED: %s' % type(e).__name__)
-            raise
-
-    def name(self):
-        l = log.get_line_for_src(self.path)
-        if l is not None:
-            return '%s:%s' % (self._name, l)
-        return super().name()
-
-    def set_fail(self, fail_type, fail_message, tb_str=None, src=4):
-        self.status = Test.FAIL
-        self.duration = time.time() - self.start_timestamp
-        self.fail_type = fail_type
-        self.fail_message = fail_message
-
-        if tb_str is None:
-            # populate an exception-less call to set_fail() with traceback info
-            tb_str = ''.join(traceback.format_stack()[:-1])
-
-        self.fail_tb = tb_str
-        self.err('%s: %s' % (self.fail_type, self.fail_message), _src=src)
-        if self.fail_tb:
-            self.log(self.fail_tb, _level=log.L_TRACEBACK)
-        self.log('Test FAILED (%.1f sec)' % self.duration)
-
-    def set_pass(self):
-        self.status = Test.PASS
-        self.duration = time.time() - self.start_timestamp
-        self.log('Test passed (%.1f sec)' % self.duration)
-
-    def set_skip(self):
-        self.status = Test.SKIP
-        self.duration = 0
-
 class SuiteRun(log.Origin):
     UNKNOWN = 'UNKNOWN'
     PASS = 'PASS'
@@ -176,7 +86,7 @@
     def load_tests(self):
         self.tests = []
         for test_basename in self.definition.test_basenames:
-            self.tests.append(Test(self, test_basename))
+            self.tests.append(test.Test(self, test_basename))
 
     def register_for_cleanup(self, *obj):
         assert all([hasattr(o, 'cleanup') for o in obj])
@@ -243,12 +153,12 @@
             event_loop.register_poll_func(self.poll)
             if not self.reserved_resources:
                 self.reserve_resources()
-            for test in self.tests:
-                if names and not test.name() in names:
-                    test.set_skip()
+            for t in self.tests:
+                if names and not t.name() in names:
+                    t.set_skip()
                     continue
-                self.current_test = test
-                test.run()
+                self.current_test = t
+                t.run()
                 self.stop_processes()
                 self.objects_cleanup()
                 self.reserved_resources.put_all()
@@ -284,10 +194,10 @@
         passed = 0
         skipped = 0
         failed = 0
-        for test in self.tests:
-            if test.status == Test.PASS:
+        for t in self.tests:
+            if t.status == test.Test.PASS:
                 passed += 1
-            elif test.status == Test.FAIL:
+            elif t.status == test.Test.FAIL:
                 failed += 1
             else:
                 skipped += 1
diff --git a/src/osmo_gsm_tester/test.py b/src/osmo_gsm_tester/test.py
new file mode 100644
index 0000000..5fa857b
--- /dev/null
+++ b/src/osmo_gsm_tester/test.py
@@ -0,0 +1,115 @@
+# osmo_gsm_tester: test class
+#
+# Copyright (C) 2017 by sysmocom - s.f.m.c. GmbH
+#
+# Author: Pau Espin Pedrol <pespin at sysmocom.de>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import os
+import sys
+import time
+import traceback
+from . import testenv
+
+from . import log, util, resource, event_loop, suite, sms
+
+class Test(log.Origin):
+    UNKNOWN = 'UNKNOWN'
+    SKIP = 'skip'
+    PASS = 'pass'
+    FAIL = 'FAIL'
+
+    _run_dir = None
+
+    def __init__(self, suite_run, test_basename):
+        self.basename = test_basename
+        super().__init__(log.C_TST, self.basename)
+        self.suite_run = suite_run
+        self.path = os.path.join(self.suite_run.definition.suite_dir, self.basename)
+        self.status = Test.UNKNOWN
+        self.start_timestamp = 0
+        self.duration = 0
+        self.fail_type = None
+        self.fail_message = None
+
+    def get_run_dir(self):
+        if self._run_dir is None:
+            self._run_dir = util.Dir(self.suite_run.get_run_dir().new_dir(self._name))
+        return self._run_dir
+
+    def run(self):
+        try:
+            log.large_separator(self.suite_run.trial.name(), self.suite_run.name(), self.name(), sublevel=3)
+            self.status = Test.UNKNOWN
+            self.start_timestamp = time.time()
+            testenv.setup(self.suite_run, self, suite, event_loop, sms)
+            with self.redirect_stdout():
+                util.run_python_file('%s.%s' % (self.suite_run.definition.name(), self.basename),
+                                     self.path)
+            if self.status == Test.UNKNOWN:
+                 self.set_pass()
+        except Exception as e:
+            if hasattr(e, 'msg'):
+                msg = e.msg
+            else:
+                msg = str(e)
+            if isinstance(e, AssertionError):
+                # AssertionError lacks further information on what was
+                # asserted. Find the line where the code asserted:
+                msg += log.get_src_from_exc_info(sys.exc_info())
+            # add source file information to failure report
+            if hasattr(e, 'origins'):
+                msg += ' [%s]' % e.origins
+            tb_str = traceback.format_exc()
+            if isinstance(e, resource.NoResourceExn):
+                tb_str += self.suite_run.resource_status_str()
+            self.set_fail(type(e).__name__, msg, tb_str, log.get_src_from_exc_info())
+        except BaseException as e:
+            # when the program is aborted by a signal (like Ctrl-C), escalate to abort all.
+            self.err('TEST RUN ABORTED: %s' % type(e).__name__)
+            raise
+
+    def name(self):
+        l = log.get_line_for_src(self.path)
+        if l is not None:
+            return '%s:%s' % (self._name, l)
+        return super().name()
+
+    def set_fail(self, fail_type, fail_message, tb_str=None, src=4):
+        self.status = Test.FAIL
+        self.duration = time.time() - self.start_timestamp
+        self.fail_type = fail_type
+        self.fail_message = fail_message
+
+        if tb_str is None:
+            # populate an exception-less call to set_fail() with traceback info
+            tb_str = ''.join(traceback.format_stack()[:-1])
+
+        self.fail_tb = tb_str
+        self.err('%s: %s' % (self.fail_type, self.fail_message), _src=src)
+        if self.fail_tb:
+            self.log(self.fail_tb, _level=log.L_TRACEBACK)
+        self.log('Test FAILED (%.1f sec)' % self.duration)
+
+    def set_pass(self):
+        self.status = Test.PASS
+        self.duration = time.time() - self.start_timestamp
+        self.log('Test passed (%.1f sec)' % self.duration)
+
+    def set_skip(self):
+        self.status = Test.SKIP
+        self.duration = 0
+
+# vim: expandtab tabstop=4 shiftwidth=4

-- 
To view, visit https://gerrit.osmocom.org/4764
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I9c8d67f598466ba52a4827ff77027b9eae85929a
Gerrit-PatchSet: 1
Gerrit-Project: osmo-gsm-tester
Gerrit-Branch: master
Gerrit-Owner: Pau Espin Pedrol <pespin at sysmocom.de>



More information about the gerrit-log mailing list