summaryrefslogtreecommitdiff
path: root/mason/tests/build.py
diff options
context:
space:
mode:
authorMichael Drake <michael.drake@codethink.co.uk>2015-02-20 09:51:58 +0000
committerMichael Drake <michael.drake@codethink.co.uk>2015-03-09 17:01:23 +0000
commit7fb68b7f377583dac40634338870583baaa2fe65 (patch)
tree79f5b9ca28f2038e47d663292526cd76dce1749c /mason/tests/build.py
parent009b22cc1c79e0576e9d21218be1983aea87e5da (diff)
downloadsystem-tests-baserock/mason-v2.tar.gz
Add mason 'build', 'test' and 'upload' as Zuul pluginsbaserock/mason-v2
Much of this code comes from the release-* scripts in Baserock's defintions repo. At the moment, only build, build_test and artifact_upload plugins are implemented. Also note that the test build run on a deployed instance in the build_test plugin currently builds master rather than the ref of the proposed change being tested. This is still adequate as that system is itself built from the ref of the proposed change.
Diffstat (limited to 'mason/tests/build.py')
-rw-r--r--mason/tests/build.py128
1 files changed, 128 insertions, 0 deletions
diff --git a/mason/tests/build.py b/mason/tests/build.py
new file mode 100644
index 0000000..625252d
--- /dev/null
+++ b/mason/tests/build.py
@@ -0,0 +1,128 @@
+# Copyright 2014 Codethink Ltd
+#
+# 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 cliapp
+import json
+import logging
+import morphlib
+import os
+import subprocess
+import time
+import urlparse
+
+import mason
+
+
+class Build(object):
+
+ """A single build instance."""
+
+ def __init__(self, name, controller, logfile):
+ self.system_name = name
+ self.controller = controller
+ self.log_path = logfile
+ self.logfile = open(logfile, 'w+')
+ #TODO: use distbuild not local build
+ self.command = [
+ 'morph', 'build', self.system_name]
+
+ def start(self):
+ self.process = subprocess.Popen(self.command, stdout=self.logfile, stderr=self.logfile)
+
+ def completed(self):
+ return (self.process.poll() is not None)
+
+ def close_log(self):
+ self.logfile.close()
+
+
+class Runner(mason.runners.JobRunner):
+
+ """Test that the built system will deploy and run
+
+ This 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 = 4
+
+ def run_job(self):
+ self.log.debug('Got job: %s', self.job_arguments)
+
+ self.log.info('Step 1: Creating a workspace')
+ self._create_workspace()
+
+ self.log.info('Step 2: Prepare build log directory')
+ self._prepare_build_log_dir()
+
+ self.log.info('Step 3: Building the systems')
+ try:
+ self._build_systems()
+ except Exception as e:
+ self._remove_workspace()
+ raise e
+
+ self.log.info('Step 4: Clean up')
+ self._clean_up()
+
+ @staticmethod
+ def _parse_controllers(conf):
+ return dict(item.split(':', 1) for item in conf['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)
+ print 'loaded %s' % system_name
+ if system['arch'] in controllers:
+ logfile = os.path.join(self.logdir, '%s.log' % system['name'])
+ builds.append(Build(system_name, controllers[system['arch']], logfile))
+ print 'prepared builds'
+ return builds
+
+ @mason.util.job_step
+ def _prepare_build_log_dir(self):
+ self.logdir = '/var/www/logs/%s-%s/build' % \
+ (self.project, self.commit[:7])
+ if not os.path.exists(self.logdir):
+ os.makedirs(self.logdir)
+
+ @mason.util.job_step
+ def _build_systems(self):
+ builds = self._prepare_builds(self.plugin_config['config'])
+ os.chdir(self.defs_checkout)
+ for build in builds:
+ build.start()
+ # TODO: Don't force serialisation when we change to distbuild.
+ while not build.completed():
+ time.sleep(1)
+
+ fail = False
+ for build in builds:
+ build.close_log()
+ if build.process.returncode != 0:
+ fail = True
+ logging.error('Building failed for %s. Log is at %s.' %
+ (build.system_name, build.log_path))
+ if fail:
+ raise cliapp.AppException('Building of systems failed.')