summaryrefslogtreecommitdiff
path: root/mason/tests/build.py
blob: d347eb9d7c56ebd929c4f9b89449b91f09ecf6b4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# Copyright 2014 Codethink Ltd

import cliapp
import json
import logging
import morphlib
import os
import urlparse

import mason


class Build(object):

    """A single build instance."""

    def __init__(self, name, controller):
        self.system_name = name
        self.controller = controller
        self.command = [
            'morph', 'build', self.system_name]

    def start(self):
        self.process = subprocess.Popen(self.command)

    def completed(self):
        return (self.process.poll() is not None)


class Runner(mason.util.JobRunner):

    """This thread handles running the build-deploy-build test,
    which is used to ensure that Baserock can build Baserock."""

    log = logging.getLogger("mason.tests.build.Runner")

    def __init__(self, worker_server, plugin_config, job_name):
        super(Runner, self).__init__(worker_server, plugin_config, job_name)

        self.total_steps = 3

    def do_job_steps(self):
        self.log.info('Step 1: Creating a workspace')
        self._create_workspace()

        self.log.info('Step 2: Building the systems')
        self._build_systems()

        #TODO: provide logs
        self.log.info('Step 3: Clean up')
        self._clean_up()

    def _do_git_config(self):
        cliapp.runcmd(['git', 'config', 'user.name', 'Mason Test Runner'])
        cliapp.runcmd(['git', 'config', 'user.email', 'mason@test.runner'])

    def _parse_controllers(self, conf):
        controllers = {}
        for arch, addr in (item.split(':') for item in conf['controllers']):
            controllers[arch] = addr
        return controllers

    def _prepare_builds(self, conf):
        cluster = self.morph_helper.load_morphology(conf['cluster-morphology'])
        systems = set(self.morph_helper.iterate_systems(cluster['systems']))
        controllers = self._parse_controllers(conf)
        builds = []
        for system_name in systems:
            system = self.morph_helper.load_morphology(system_name)
            if system['arch'] in controllers:
                builds.append(Build(system_name, controllers['arch']))
        return builds

    def _create_workspace(self):
        self.commit = self.job_arguments['ZUUL_COMMIT']
        self.project = self.job_arguments['ZUUL_PROJECT']
        self.ref = self.job_arguments['ZUUL_REF']
        self.workspace = '/root/mason-workspace'
        self.zuul_url = self.job_arguments['ZUUL_URL']

        url = urlparse.urlparse(self.zuul_url)
        self.defs_checkout = os.path.join(self.workspace,
                                          self.commit,
                                          url.hostname,
                                          '8080',
                                          self.project)
        self.morph_helper = mason.util.MorphologyHelper(self.defs_checkout)

        self._do_git_config()
        cliapp.runcmd(['morph', 'init', self.workspace])

        repo = 'http://%s:8080/%s' % (url.hostname, self.project)
        cliapp.runcmd(['morph', 'checkout', repo, self.commit],
                      cwd=self.workspace)

    def _build_systems(self):
        builds = self._prepare_builds(self.plugin_config['config'])
        os.chdir(self.defs_checkout)
        for build in builds:
            build.start()

        while not all(build.completed() for build in builds):
            time.sleep(1)

        fail = False
        for build in builds:
            if build.process.returncode != 0:
                fail = True
                sys.stderr.write(
                    'Building failed for %s\n' % build.system_name)
        if fail:
            raise cliapp.AppException('Building of systems failed.') 

    def _clean_up(self):
        cliapp.runcmd(['rm', '-rf', self.workspace])