summaryrefslogtreecommitdiff
path: root/mason/tests/build.py
diff options
context:
space:
mode:
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.')