summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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)
-