summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <lars.wirzenius@codethink.co.uk>2012-02-27 16:00:51 +0000
committerLars Wirzenius <lars.wirzenius@codethink.co.uk>2012-02-27 16:00:51 +0000
commit4f5bcd48ba02a2913a7f45edb0ada7a0e73c01ba (patch)
tree369d06f509c12f3b8a00a632d34cc4c19cc9580d
parent42a9f54d191940dd1a155e91363fb5041ca63c05 (diff)
downloadmorph-4f5bcd48ba02a2913a7f45edb0ada7a0e73c01ba.tar.gz
Remove the system testing subcommands and related code
This we a proof-of-concept, and we want to explore various options of how to do this, so let's not keep the code in morph. The code also has no tests, so it is already likely to have bit-rotted. If we decide we want to, we can always resurrect it from git history.
-rwxr-xr-xmorph61
-rw-r--r--morphlib/__init__.py1
-rw-r--r--morphlib/tester.py155
3 files changed, 0 insertions, 217 deletions
diff --git a/morph b/morph
index 720c3054..3325b556 100755
--- a/morph
+++ b/morph
@@ -80,16 +80,6 @@ class Morph(cliapp.Application):
'build things in a staging chroot '
'(require real root to use)')
- self.settings.boolean(['test-console'],
- 'show what the system outputs on the serial '
- 'console during tests')
- self.settings.integer(['test-timeout'],
- 'abort test if system doesn\'t produce '
- 'expected output in TIMEOUT seconds '
- '(default: %default)',
- metavar='TIMEOUT',
- default=10)
-
self.settings.string_list(['worker'],
'IP or host name of a machine to distribute '
'build work to',
@@ -152,57 +142,6 @@ class Morph(cliapp.Application):
return ret
- def cmd_testsysimg(self, args):
- '''Run tests for a built system image.
-
- Command line arguments are the filename of the system image,
- and the filenames of the Python modules that contain the test
- "stories". Each module must have a variable called "story",
- which is a list of tuples. Each tuple is either two strings
- (one to send, the other a regular expression for what is expected
- in return), or two strings and a timeout in seconds.
-
- testsysimg runs the image under KVM, and accesses it via a
- serial console, and runs the test stories, one by one.
-
- '''
-
- if not args:
- raise cliapp.AppException('Missing command line arguments. '
- 'Run with --help to see usage.')
-
- system = morphlib.tester.KvmSystem(args[0],
- verbose=self.settings['test-console'],
- timeout=self.settings['test-timeout'])
-
- for filename in args[1:]:
- self.msg('Running %s' % filename)
- module = morphlib.tester.load_module(filename)
- story_steps = getattr(module, 'story')
- story = morphlib.tester.TestStory(system, story_steps, self.msg)
- story.run()
- self.msg('Finished OK.')
-
- def cmd_test(self, args):
- '''Build and test a system morphology.
-
- The tests are specified in the morphology's test-stories field.
-
- '''
-
- for morph, built in self.cmd_build(args):
- if morph.kind == 'system':
- self.msg('running tests on system %s' % morph.name)
- assert len(built) == 1
- image_filename = built.values()[0]
- morphdir = os.path.dirname(morph.filename)
- stories = [os.path.join(morphdir, x)
- for x in morph.test_stories]
- self.cmd_testsysimg([image_filename] + stories)
- else:
- self.msg('not testing %s %s (not a system)' %
- (morph.kind, morph.name))
-
def cmd_show_dependencies(self, args):
'''Dumps the dependency tree of all input morphologies.'''
diff --git a/morphlib/__init__.py b/morphlib/__init__.py
index 7c2f66bb..db1a8dfd 100644
--- a/morphlib/__init__.py
+++ b/morphlib/__init__.py
@@ -35,6 +35,5 @@ import savefile
import sourcemanager
import stopwatch
import tempdir
-import tester
import util
diff --git a/morphlib/tester.py b/morphlib/tester.py
deleted file mode 100644
index 569199d7..00000000
--- a/morphlib/tester.py
+++ /dev/null
@@ -1,155 +0,0 @@
-# Copyright (C) 2011-2012 Codethink Limited
-#
-# 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; version 2 of the License.
-#
-# 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, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-
-import imp
-import os
-import re
-import select
-import subprocess
-import sys
-import time
-
-
-class Timeout(Exception):
-
- def __str__(self):
- buf, regexp = self.args
- return 'Cannot find %s in %s' % (repr(regexp), repr(buf))
-
-
-class System(object):
-
- '''Abstract interface to a system.
-
- The interface allows starting and stopping the system, and interacting
- with its via a serial console.
-
- '''
-
- def start(self):
- '''Start the system.'''
- raise NotImplementedError()
-
- def stop(self):
- '''Stop the system.'''
- raise NotImplementedError()
-
- def waitfor(self, regexp, timeout):
- '''Wait system to output a match for ``regexp`` on the serial console.
-
- If timeout is exceeded, raise Timeout.
-
- '''
- raise NotImplementedError()
-
- def send(self, text):
- '''Send TEXT via the serial console to the system.'''
- raise NotImplementedError()
-
-
-class KvmSystem(System):
-
- '''A system running under KVM.'''
-
- def __init__(self, image_filename, verbose=False, timeout=None):
- self.image_filename = image_filename
- self.verbose = verbose
- self.timeout = timeout
- self.p = None
- self.stdin_buf = ''
- self.stdout_buf = ''
-
- def start(self):
- self.p = subprocess.Popen(['kvm', '-nographic', self.image_filename],
- stdin=subprocess.PIPE,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
-
- def stop(self):
- self.p.terminate()
- self.p.wait()
-
- def _io(self, timeout):
- r, w, x = select.select([self.p.stdout], [self.p.stdin], [], timeout)
- if self.p.stdout in r:
- byte = self.p.stdout.read(1)
- if byte:
- if self.verbose:
- sys.stdout.write(byte)
- sys.stdout.flush()
- self.stdout_buf += byte
- elif self.p.stdin in w:
- if self.stdin_buf:
- byte = self.stdin_buf[0]
- self.p.stdin.write(byte)
- self.p.stdin.flush()
- self.stdin_buf = self.stdin_buf[1:]
- else:
- if self.verbose:
- sys.stdout.write('_')
- sys.stdout.flush()
-
- def waitfor(self, regexp, timeout=None):
- pat = re.compile(regexp, re.DOTALL | re.MULTILINE)
- started = time.time()
- timeout = timeout if timeout is not None else self.timeout
- remaining = timeout
- while not pat.search(self.stdout_buf) and remaining > 0:
- self._io(remaining)
- remaining = (started + timeout) - time.time()
- m = pat.search(self.stdout_buf)
- if not m:
- raise Timeout(self.stdout_buf, regexp)
- self.stdout_buf = self.stdout_buf[m.end():]
-
- def send(self, text):
- self.stdin_buf += text
-
-
-class TestStory(object):
-
- '''Execute a test story.'''
-
- def __init__(self, system, steps, msg):
- self.system = system
- self.steps = steps
- self.msg = msg
-
- def run(self):
- self.system.start()
- for t in self.steps:
- if len(t) == 2:
- send, expect = t
- timeout = None
- else:
- assert len(t) == 3
- send, expect, timeout = t
- self.msg('Sending: %s' % repr(send))
- self.msg('Expecting: %s' % repr(expect))
- self.system.send(send)
- self.system.waitfor(expect, timeout=timeout)
- self.system.stop()
-
-
-def load_module(filename):
- for t in imp.get_suffixes():
- suffix, mode, kind = t
- if filename.endswith(suffix):
- module_name = os.path.basename(filename[:-len(suffix)])
- with open(filename, mode) as f:
- return imp.load_module(module_name, f, filename, t)
- raise Exception("Unknown module: %s" % filename)
-