~pwlars/lava-test/uninstall

« back to all changes in this revision

Viewing changes to abrek/testdef.py

  • Committer: Paul Larson
  • Date: 2010-06-28 15:59:07 UTC
  • mfrom: (4.2.10 abrek-install)
  • Revision ID: paul.larson@canonical.com-20100628155907-uq2qbfoc3oggrbr2
Add support for installing tests.  Specifically, this lets you:
 * defining tests
 * defining install steps for a test
 * downloading tests and checking md5sums
 * installing dependencies
 * example provided as well

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
import hashlib
 
2
import os
 
3
import shutil
 
4
import sys
 
5
from commands import getstatusoutput
 
6
 
 
7
import abrek.config
 
8
from abrek.utils import geturl
 
9
 
 
10
class AbrekTest(object):
 
11
    """
 
12
    This can be used by test definition files to create an object that
 
13
    contains the building blocks for installing tests, running them,
 
14
    and parsing the results.
 
15
 
 
16
    testname - name of the test or test suite
 
17
    version - version of the test or test suite
 
18
    installer - AbrekInstaller instance to use
 
19
    runner - AbrekRunner instance to use
 
20
    parser - AbrekParser instance to use
 
21
    """
 
22
 
 
23
    def __init__(self, testname, version="", installer=None, runner=None,
 
24
                 parser=None):
 
25
        self.config = abrek.config.AbrekConfig()
 
26
        self.testname = testname
 
27
        self.version = version
 
28
        self.installer = installer
 
29
        self.runner = runner
 
30
        self.parser = parser
 
31
        self.origdir = os.path.abspath(os.curdir)
 
32
 
 
33
    def install(self):
 
34
        """
 
35
        Install the test suite.  This creates an install directory under
 
36
        the user's XDG_DATA_HOME directory to mark that the test is installed.
 
37
        The installer's install() method is then called from this directory
 
38
        to complete any test specific install that may be needed.
 
39
        """
 
40
        if self.installer:
 
41
            path = os.path.join(self.config.installdir, self.testname)
 
42
            if os.path.exists(path):
 
43
                raise RuntimeError, "%s is already installed" % self.testname
 
44
            os.makedirs(path)
 
45
            os.chdir(path)
 
46
            rc = self.installer.install()
 
47
            if rc:
 
48
                self.uninstall()
 
49
                raise RuntimeError, "An error was detected during", \
 
50
                                    "installation, cleaning up"
 
51
 
 
52
    def uninstall(self):
 
53
        """
 
54
        Uninstalling just recursively removes the test specific directory
 
55
        under the user's XDG_DATA_HOME directory.  This will both mark
 
56
        the test as removed, and clean up any files that were downloaded
 
57
        or installed under that directory.  Dependencies are intentionally
 
58
        not removed by this.
 
59
        """
 
60
        os.chdir(self.origdir)
 
61
        path = os.path.join(self.config.installdir, self.testname)
 
62
        if os.path.exists(path):
 
63
            shutil.rmtree(path)
 
64
 
 
65
    def run(self):
 
66
        if self.runner:
 
67
            return self.runner.run()
 
68
 
 
69
    def parse(self,results):
 
70
        if self.parser:
 
71
            return self.parser.parse(results)
 
72
 
 
73
class AbrekTestInstaller(object):
 
74
    """
 
75
    Base class for defining an installer object.  This class can be used
 
76
    as-is for simple installers, or extended for more advanced funcionality.
 
77
 
 
78
    steps - list of steps to be executed in a shell
 
79
    deps - list of dependencies to apt-get install before running the steps
 
80
    url - location from which the test suite should be downloaded
 
81
    md5 - md5sum to check the integrety of the download
 
82
    """
 
83
 
 
84
    def __init__(self, steps=[], deps=[], url="", md5="", **kwargs):
 
85
        self.steps = steps
 
86
        self.deps = deps
 
87
        self.url = url
 
88
        self.md5 = md5
 
89
 
 
90
    def _installdeps(self):
 
91
        if not self.deps:
 
92
            return 0
 
93
        cmd = "sudo apt-get install %s", " ".join(self.deps)
 
94
        rc,output = getstatusoutput(cmd)
 
95
        if rc:
 
96
            raise RuntimeError, "Dependency installation failed"
 
97
 
 
98
    def _download(self):
 
99
        """
 
100
        Download the file specified by the url and check the md5.
 
101
        Return the path and filename if successful, otherwise return None
 
102
        """
 
103
        if not self.url:
 
104
            return 0
 
105
        filename = geturl(self.url)
 
106
        #If the file does not exist, then the download was not successful
 
107
        if not os.path.exists(filename):
 
108
            return None
 
109
        if self.md5:
 
110
            checkmd5 = hashlib.md5()
 
111
            with open(filename, 'rb') as fd:
 
112
                for data in fd.read(0x10000):
 
113
                    checkmd5.update(data)
 
114
            if checkmd5.hexdigest() != self.md5:
 
115
                raise RuntimeError, "Unexpected md5sum downloading %s" % \
 
116
                                    filename
 
117
                return None
 
118
        return filename
 
119
 
 
120
    def _runsteps(self):
 
121
        for cmd in self.steps:
 
122
            rc,output = getstatusoutput(cmd)
 
123
 
 
124
    def install(self):
 
125
        self._installdeps()
 
126
        self._download()
 
127
        self._runsteps()
 
128
 
 
129
def testloader(testname):
 
130
    """
 
131
    Load the test definition, which can be either an individual
 
132
    file, or a directory with an __init__.py
 
133
    """
 
134
    importpath = "abrek.test_definitions.%s" % testname
 
135
    try:
 
136
        mod = __import__(importpath)
 
137
    except ImportError:
 
138
        print "unknown test '%s'" % testname
 
139
        sys.exit(1)
 
140
    for i in importpath.split('.')[1:]:
 
141
        mod = getattr(mod,i)
 
142
    try:
 
143
        base = mod.testdir.testobj
 
144
    except AttributeError:
 
145
        base = mod.testobj
 
146
 
 
147
    return base
 
148