예제 #1
0
 def test_runs_subaction(self):
     pipe = Pipeline()
     pipe.add_action(self.sub0)
     pipe.add_action(self.sub1)
     pipe.run_actions(None, None)
     self.assertTrue(self.sub0.ran)
     self.assertTrue(self.sub1.ran)
     self.assertNotEqual(self.sub0.timeout.elapsed_time, 0)
     self.assertNotEqual(self.sub1.timeout.elapsed_time, 0)
예제 #2
0
 def test_runs_subaction(self):
     pipe = Pipeline()
     pipe.add_action(self.sub0)
     pipe.add_action(self.sub1)
     pipe.run_actions(None)
     self.assertTrue(self.sub0.ran)
     self.assertTrue(self.sub1.ran)
     self.assertNotEqual(self.sub0.elapsed_time, 0)
     self.assertNotEqual(self.sub1.elapsed_time, 0)
예제 #3
0
class MountAction(DeployAction):
    """
    Depending on the type of deployment, this needs to perform
    an OffsetAction, LoopCheckAction, LoopMountAction
    """

    def __init__(self):
        super(MountAction, self).__init__()
        self.name = "mount_action"
        self.description = "mount with offset"
        self.summary = "mount loop"

    def validate(self):
        if not self.job:
            raise RuntimeError("No job object supplied to action")
        self.internal_pipeline.validate_actions()

    def populate(self):
        """
        Needs to take account of the deployment type / image type etc.
        to determine which actions need to be added to the internal pipeline
        as part of the deployment selection step.
        """
        if not self.job:
            raise RuntimeError("No job object supplied to action")
        # FIXME: not all mount operations will need these actions
        self.internal_pipeline = Pipeline(parent=self, job=self.job)
        self.internal_pipeline.add_action(OffsetAction())
        # FIXME: LoopCheckAction and LoopMountAction should be in only one Action
        self.internal_pipeline.add_action(LoopCheckAction())
        self.internal_pipeline.add_action(LoopMountAction())

    def run(self, connection, args=None):
        if self.internal_pipeline:
            connection = self.internal_pipeline.run_actions(connection, args)
        else:
            # FIXME: this is a bug that should not happen (using assert?)
            raise RuntimeError("Deployment failed to generate a mount pipeline.")
        return connection
예제 #4
0
class MountAction(DeployAction):
    """
    Depending on the type of deployment, this needs to perform
    an OffsetAction, LoopCheckAction, LoopMountAction
    """

    def __init__(self):
        super(MountAction, self).__init__()
        self.name = "mount_action"
        self.description = "mount with offset"
        self.summary = "mount loop"

    def validate(self):
        if not self.job:
            raise RuntimeError("No job object supplied to action")
        self.internal_pipeline.validate_actions()

    def populate(self):
        """
        Needs to take account of the deployment type / image type etc.
        to determine which actions need to be added to the internal pipeline
        as part of the deployment selection step.
        """
        if not self.job:
            raise RuntimeError("No job object supplied to action")
        # FIXME: not all mount operations will need these actions
        self.internal_pipeline = Pipeline(parent=self, job=self.job)
        self.internal_pipeline.add_action(OffsetAction())
        self.internal_pipeline.add_action(LoopCheckAction())
        self.internal_pipeline.add_action(LoopMountAction())

    def run(self, connection, args=None):
        if self.internal_pipeline:
            connection = self.internal_pipeline.run_actions(connection, args)
        else:
            raise RuntimeError("Deployment failed to generate a mount pipeline.")
        return connection
예제 #5
0
    def test_change_connection(self):

        pipe = Pipeline()
        pipe.add_action(TestFakeActions.MakeNewConnection())
        conn = object()
        self.assertIsNot(conn, pipe.run_actions(conn))
예제 #6
0
    def test_keep_connection(self):

        pipe = Pipeline()
        pipe.add_action(TestFakeActions.KeepConnection())
        conn = object()
        self.assertIs(conn, pipe.run_actions(conn))
class TestDefinitionAction(TestAction):
    def __init__(self):
        """
        The TestDefinitionAction installs each test definition into
        the overlay. It does not execute the scripts in the test
        definition, that is the job of the TestAction class.
        One TestDefinitionAction handles all test definitions for
        the current job.
        In addition, a TestOverlayAction is added to the pipeline
        to handle parts of the overlay which are test definition dependent.
        """
        super(TestDefinitionAction, self).__init__()
        self.name = "test-definition"
        self.description = "load test definitions into image"
        self.summary = "loading test definitions"

    def populate(self):
        """
        validate allows this to be a lot simpler, no need
        to check if the key exists each time.
        """
        index = {}
        self.internal_pipeline = Pipeline(parent=self, job=self.job)
        for testdef in self.parameters['test']['definitions']:
            if testdef['from'] == 'git':
                handler = GitRepoAction()
            elif testdef['from'] == 'bzr':
                handler = BzrRepoAction()
            elif testdef['from'] == 'tar':
                handler = TarRepoAction()
            elif testdef['from'] == 'url':
                handler = UrlRepoAction()
            else:
                self.errors = "unsupported handler"
                raise JobError("unsupported testdef handler: %s %s" %
                               (testdef, testdef['from']))
            # set the full set of job YAML parameters for this handler as handler parameters.
            handler.parameters = testdef
            # store the correct test_name before incrementing the local index dict
            handler.parameters['test_name'] = "%s_%s" % (len(
                index.keys()), handler.parameters['name'])
            index[len(index.keys())] = handler.parameters['name']
            self.internal_pipeline.add_action(handler)
            # FIXME: the outer pipeline may add unwanted data to the parameters['test']
        self.internal_pipeline.add_action(TestOverlayAction())

    def validate(self):
        if not self.job:
            self.errors = "missing job object"
        if 'test' not in self.parameters:
            self.errors = "testaction without test parameters"
            # runtimeerror?
        if 'definitions' not in self.parameters['test']:
            self.errors = "test action without definition"
        for testdef in self.parameters['test']['definitions']:
            if 'from' not in testdef:
                self.errors = "missing 'from' field in test definition %s" % testdef
            if testdef['from'] is 'git':
                repository = str(testdef['repository'])
                if not repository.endswith('.git'):
                    self.errors = "git specified but repository does not look like git"

        self.internal_pipeline.validate_actions()
        if self.errors:  # FIXME: call from the base class
            self._log("Validation failed")
            raise JobError("Invalid job data: %s\n" % '\n'.join(self.errors))

    def _inject_testdef_parameters(self,
                                   fout):  # FIXME: needs a separate action
        # inject default parameters that were defined in yaml first
        fout.write('###default parameters from yaml###\n')
        if 'params' in self.testdef:
            for def_param_name, def_param_value in self.testdef[
                    'params'].items():
                fout.write('%s=\'%s\'\n' % (def_param_name, def_param_value))
        fout.write('######\n')
        # inject the parameters that was set in json
        fout.write('###test parameters from json###\n')
        if self._sw_sources and 'test_params' in self._sw_sources[
                0] and self._sw_sources[0]['test_params'] != '':
            _test_params_temp = eval(self._sw_sources[0]['test_params'])
            for param_name, param_value in _test_params_temp.items():
                fout.write('%s=\'%s\'\n' % (param_name, param_value))
        fout.write('######\n')

    def copy_test(self, hostdir,
                  targetdir):  # FIXME: needs porting to the new classes
        """Copy the files needed to run this test to the device.

        :param hostdir: The location on the device filesystem to copy too.
        :param targetdir: The location `hostdir` will have when the device
            boots.
        """

        with open('%s/testdef_metadata' % hostdir, 'w') as f:
            f.write(yaml.safe_dump(self.testdef_metadata))

        if self.skip_install != "all":
            if 'install' in self.testdef:
                if self.skip_install != 'repos':
                    self._create_repos(hostdir)
                self._create_target_install(hostdir, targetdir)

    def run(self, connection, args=None):
        """
        Puts the requested test definition files into the overlay

        :param connection: Connection object, if any.
        :param args: Not used.
        :return: the received Connection.
        """
        self._log("Loading test definitions")
        # developer hack - if the image hasn't been downloaded this time, it may already contain old files
        # should really be an rmtree but it is only here to save developer time on downloads...
        if os.path.exists(self.data['mount_action']['mntdir']):
            os.unlink('%s/lava-test-runner.conf' %
                      self.data['mount_action']['mntdir'])
        connection = self.internal_pipeline.run_actions(connection)
        with open(
                '%s/lava-test-runner.conf' %
                self.data['mount_action']['mntdir'], 'a') as runner_conf:
            for handler in self.internal_pipeline.actions:
                if isinstance(handler, RepoAction) or isinstance(
                        handler, UrlRepoAction):
                    runner_conf.write(handler.runner)
                if isinstance(handler, TestAction
                              ):  # FIXME: separate actions for copy & inject
                    # run copy_test
                    hostdir = self.data['mount_action']['mntdir']
                    targetdir = ''
        return connection
예제 #8
0
    def test_change_connection(self):

        pipe = Pipeline()
        pipe.add_action(TestFakeActions.MakeNewConnection())
        conn = object()
        self.assertIsNot(conn, pipe.run_actions(conn, None))
예제 #9
0
    def test_keep_connection(self):

        pipe = Pipeline()
        pipe.add_action(TestFakeActions.KeepConnection())
        conn = object()
        self.assertIs(conn, pipe.run_actions(conn, None))