Ejemplo n.º 1
0
class Pyocd_Factory(Factory):  # pylint: disable=too-few-public-methods
    """
    Not Model based, this is not a Django factory.
    Factory objects are dispatcher based classes, independent
    of any database objects.
    """

    @unittest.skipIf(infrastructure_error('pyocd-flashtool'), 'pyocd-flashtool not installed')
    def create_k64f_job(self, filename):  # pylint: disable=no-self-use
        device = NewDevice(os.path.join(os.path.dirname(__file__), '../devices/frdm-k64f-01.yaml'))
        y_file = os.path.join(os.path.dirname(__file__), filename)
        with open(y_file) as sample_job_data:
            parser = JobParser()
            job = parser.parse(sample_job_data, device, 4999, None, "")
        job.logger = DummyLogger()
        return job

    @unittest.skipIf(infrastructure_error('pyocd-flashtool'), 'pyocd-flashtool not installed')
    def create_k64f_job_with_power(self, filename):  # pylint: disable=no-self-use
        device = NewDevice(os.path.join(os.path.dirname(__file__), '../devices/frdm-k64f-01-with-power.yaml'))
        y_file = os.path.join(os.path.dirname(__file__), filename)
        with open(y_file) as sample_job_data:
            parser = JobParser()
            job = parser.parse(sample_job_data, device, 5999, None, "")
        job.logger = DummyLogger()
        return job
Ejemplo n.º 2
0
class TestLxcDeploy(StdoutTestCase):  # pylint: disable=too-many-public-methods
    def setUp(self):
        super().setUp()
        factory = LxcFactory()
        self.job = factory.create_lxc_job('sample_jobs/lxc.yaml')

    def test_deploy_job(self):
        self.assertEqual(self.job.pipeline.job, self.job)
        for action in self.job.pipeline.actions:
            if isinstance(action, DeployAction):
                self.assertEqual(action.job, self.job)

    def test_pipeline(self):
        description_ref = self.pipeline_reference('lxc.yaml')
        self.assertEqual(description_ref, self.job.pipeline.describe(False))

    @unittest.skipIf(infrastructure_error('lxc-create'),
                     'lxc-create not installed')
    def test_validate(self):
        try:
            self.job.pipeline.validate_actions()
        except JobError as exc:
            self.fail(exc)
        for action in self.job.pipeline.actions:
            self.assertEqual([], action.errors)

    @unittest.skipIf(infrastructure_error('lxc-create'),
                     'lxc-create not installed')
    def test_create(self):
        for action in self.job.pipeline.actions:
            if isinstance(action, LxcCreateAction):
                self.assertEqual(action.lxc_data['lxc_name'],
                                 'pipeline-lxc-test-4577')
                self.assertEqual(action.lxc_data['lxc_distribution'], 'debian')
                self.assertEqual(action.lxc_data['lxc_release'], 'sid')
                self.assertEqual(action.lxc_data['lxc_arch'], 'amd64')
                self.assertEqual(action.lxc_data['lxc_template'], 'debian')
                self.assertEqual(action.lxc_data['lxc_mirror'],
                                 'http://ftp.us.debian.org/debian/')
                self.assertEqual(
                    action.lxc_data['lxc_security_mirror'],
                    'http://mirror.csclub.uwaterloo.ca/debian-security/')

    @unittest.skipIf(infrastructure_error('lxc-start'),
                     'lxc-start not installed')
    def test_boot(self):
        for action in self.job.pipeline.actions:
            if isinstance(action, BootAction):
                # get the action & populate it
                self.assertEqual(action.parameters['method'], 'lxc')
                self.assertEqual(action.parameters['prompts'],
                                 ['root@(.*):/#'])

    def test_testdefinitions(self):
        for action in self.job.pipeline.actions:
            if action.name == 'test':
                # get the action & populate it
                self.assertEqual(len(action.parameters['definitions']), 2)
Ejemplo n.º 3
0
class PyocdFactory(Factory):  # pylint: disable=too-few-public-methods
    """
    Not Model based, this is not a Django factory.
    Factory objects are dispatcher based classes, independent
    of any database objects.
    """

    @unittest.skipIf(infrastructure_error('pyocd-flashtool'), 'pyocd-flashtool not installed')
    def create_k64f_job(self, filename):
        return self.create_job('frdm-k64f-01.jinja2', filename)

    @unittest.skipIf(infrastructure_error('pyocd-flashtool'), 'pyocd-flashtool not installed')
    def create_k64f_job_with_power(self, filename):  # pylint: disable=no-self-use
        return self.create_job('frdm-k64f-power-01.jinja2', filename)
Ejemplo n.º 4
0
class TestUbootUMSAction(StdoutTestCase):  # pylint: disable=too-many-public-methods
    def setUp(self):
        super(TestUbootUMSAction, self).setUp()
        self.factory = UBootUMSFactory()

    @unittest.skipIf(infrastructure_error('dd'), "dd not installed")
    def test_ums_action(self):
        job = self.factory.create_warp7_job('sample_jobs/warp7-ums.yaml')
        self.assertIsNotNone(job)

        description_ref = self.pipeline_reference('uboot-ums.yaml', job=job)
        self.assertEqual(description_ref, job.pipeline.describe(False))

        self.assertIsNone(job.validate())
        self.assertEqual(job.device['device_type'], 'imx7s-warp')
        uboot = [
            action for action in job.pipeline.actions
            if action.name == 'uboot-action'
        ][0]
        retry = [
            action for action in uboot.internal_pipeline.actions
            if action.name == 'uboot-retry'
        ][0]
        flash = [
            action for action in retry.internal_pipeline.actions
            if action.name == 'flash-uboot-ums'
        ][0]
        self.assertEqual("ums", flash.parameters['commands'])
        self.assertEqual("/dev/vde", flash.usb_mass_device)
Ejemplo n.º 5
0
class TestKvmUefi(StdoutTestCase):  # pylint: disable=too-many-public-methods

    def setUp(self):
        super().setUp()
        factory = Factory()
        self.job = factory.create_kvm_job('sample_jobs/kvm-uefi.yaml')

    @unittest.skipIf(infrastructure_error('qemu-system-x86_64'),
                     'qemu-system-x86_64 not installed')
    def test_uefi_path(self):
        deploy = [action for action in self.job.pipeline.actions if action.name == 'deployimages'][0]
        downloaders = [action for action in deploy.internal_pipeline.actions if action.name == 'download-retry']
        self.assertEqual(len(downloaders), 2)
        uefi_download = downloaders[0]
        image_download = downloaders[1]
        self.assertEqual(image_download.key, 'disk1')
        uefi_dir = uefi_download.get_namespace_data(action='deployimages', label='image', key='uefi_dir')
        self.assertIsNotNone(uefi_dir)
        self.assertTrue(os.path.exists(uefi_dir))  # no download has taken place, but the directory needs to exist
        self.assertFalse(uefi_dir.endswith('bios-256k.bin'))
        boot = [action for action in self.job.pipeline.actions if action.name == 'boot-image-retry'][0]
        qemu = [action for action in boot.internal_pipeline.actions if action.name == 'boot-qemu-image'][0]
        execute = [action for action in qemu.internal_pipeline.actions if action.name == 'execute-qemu'][0]
        self.job.validate()
        self.assertIn('-L', execute.sub_command)
        self.assertIn(uefi_dir, execute.sub_command)
Ejemplo n.º 6
0
class TestQemuNFS(StdoutTestCase):

    def setUp(self):
        super().setUp()
        factory = Factory()
        self.job = factory.create_job('kvm02.jinja2', 'sample_jobs/qemu-nfs.yaml')
        self.job.logger = DummyLogger()

    @unittest.skipIf(infrastructure_error('qemu-system-aarch64'),
                     'qemu-system-arm not installed')
    @unittest.skipIf(not os.path.exists(SYS_CLASS_KVM), "Cannot use --enable-kvm")
    def test_qemu_nfs(self):
        self.assertIsNotNone(self.job)
        description_ref = self.pipeline_reference('qemu-nfs.yaml')
        self.assertEqual(description_ref, self.job.pipeline.describe(False))

        boot = [action for action in self.job.pipeline.actions if action.name == 'boot-image-retry'][0]
        qemu = [action for action in boot.internal_pipeline.actions if action.name == 'boot-qemu-image'][0]
        execute = [action for action in qemu.internal_pipeline.actions if action.name == 'execute-qemu'][0]
        self.job.validate()
        self.assertNotEqual([], [line for line in execute.sub_command if line.startswith('-kernel')])
        self.assertEqual(1, len([line for line in execute.sub_command if line.startswith('-kernel')]))
        self.assertIn('vmlinuz', [line for line in execute.sub_command if line.startswith('-kernel')][0])

        self.assertNotEqual([], [line for line in execute.sub_command if line.startswith('-initrd')])
        self.assertEqual(1, len([line for line in execute.sub_command if line.startswith('-initrd')]))
        self.assertIn('initrd.img', [line for line in execute.sub_command if line.startswith('-initrd')][0])

        self.assertEqual([], [line for line in execute.sub_command if '/dev/nfs' in line])
        self.assertEqual([], [line for line in execute.sub_command if 'nfsroot' in line])

        args = execute.methods['qemu-nfs']['parameters']['append']['nfsrootargs']
        self.assertIn('{NFS_SERVER_IP}', args)
        self.assertIn('{NFSROOTFS}', args)

        substitutions = execute.substitutions
        substitutions["{NFSROOTFS}"] = 'root_dir'
        params = execute.methods['qemu-nfs']['parameters']['append']
        # console=ttyAMA0 root=/dev/nfs nfsroot=10.3.2.1:/var/lib/lava/dispatcher/tmp/dirname,tcp,hard,intr ip=dhcp
        append = [
            'console=%s' % params['console'],
            'root=/dev/nfs',
            '%s' % substitute([params['nfsrootargs']], substitutions)[0],
            "%s" % params['ipargs']
        ]
        execute.sub_command.append('--append')
        execute.sub_command.append('"%s"' % ' '.join(append))
        kernel_cmdline = ' '.join(execute.sub_command)
        self.assertIn('console=ttyAMA0', kernel_cmdline)
        self.assertIn('/dev/nfs', kernel_cmdline)
        self.assertIn('root_dir,tcp,hard,intr', kernel_cmdline)
        self.assertIn('smp', kernel_cmdline)
        self.assertIn('cpu host', kernel_cmdline)
Ejemplo n.º 7
0
    def test_branch(self):
        git = vcs.GitHelper('git')
        self.assertEqual(git.clone('git.clone1', branch='testing'),
                         'f2589a1b7f0cfc30ad6303433ba4d5db1a542c2d')
        self.assertTrue(
            os.path.exists(os.path.join(self.tmpdir, "git.clone1", ".git")))

    def test_no_history(self):
        git = vcs.GitHelper('git')
        self.assertEqual(git.clone('git.clone1', history=False),
                         'a7af835862da0e0592eeeac901b90e8de2cf5b67')
        self.assertFalse(
            os.path.exists(os.path.join(self.tmpdir, "git.clone1", ".git")))


@unittest.skipIf(infrastructure_error('bzr'), "bzr not installed")
class TestBzr(StdoutTestCase):  # pylint: disable=too-many-public-methods
    def setUp(self):
        super().setUp()
        self.cwd = os.getcwd()

        # Go into a temp dirctory
        self.tmpdir = tempfile.mkdtemp()
        os.chdir(self.tmpdir)
        self.env = {
            'BZR_HOME': self.tmpdir,
            'BZR_LOG': os.path.join(self.tmpdir, "bzr.log")
        }

        # Create a Git repository with two commits
        subprocess.check_output(
class TestConnection(StdoutTestCase):  # pylint: disable=too-many-public-methods
    def setUp(self):
        super(TestConnection, self).setUp()
        factory = ConnectionFactory()
        self.job = factory.create_ssh_job('sample_jobs/ssh-deploy.yaml')
        self.guest_job = factory.create_bbb_job(
            'sample_jobs/bbb-ssh-guest.yaml')
        logging.getLogger('dispatcher').addHandler(logging.NullHandler())

    @unittest.skipIf(infrastructure_error('schroot'), "schroot not installed")
    def test_ssh_job(self):
        self.assertIsNotNone(self.job)
        self.job.validate()
        self.assertEqual([], self.job.pipeline.errors)
        # Check Pipeline
        description_ref = self.pipeline_reference('ssh-deploy.yaml')
        self.assertEqual(description_ref, self.job.pipeline.describe(False))

    @unittest.skipIf(infrastructure_error('schroot'), "schroot not installed")
    def test_ssh_authorize(self):
        overlay = [
            action for action in self.job.pipeline.actions
            if action.name == 'scp-overlay'
        ][0]
        prepare = [
            action for action in overlay.internal_pipeline.actions
            if action.name == 'lava-overlay'
        ][0]
        authorize = [
            action for action in prepare.internal_pipeline.actions
            if action.name == 'ssh-authorize'
        ][0]
        self.assertFalse(authorize.active)
        self.job.validate()
        # only secondary connections set 'active' which then copies the identity file into the overlay.
        self.assertFalse(authorize.active)

    def test_ssh_identity(self):
        params = {
            'tftp': 'None',
            'usb': 'None',
            'ssh': {
                'host':
                '172.16.200.165',
                'options': [
                    '-o', 'Compression=yes', '-o',
                    'UserKnownHostsFile=/dev/null', '-o',
                    'PasswordAuthentication=no', '-o',
                    'StrictHostKeyChecking=no', '-o', 'LogLevel=FATAL', '-l',
                    'root ', '-p', 22
                ],
                'identity_file':
                'dynamic_vm_keys/lava'
            }
        }
        check = check_ssh_identity_file(params)
        self.assertIsNone(check[0])
        self.assertIsNotNone(check[1])
        self.assertEqual(os.path.basename(check[1]), 'lava')

    @unittest.skipIf(infrastructure_error('schroot'), "schroot not installed")
    def test_ssh_params(self):
        self.assertTrue(
            any('ssh' in item
                for item in self.job.device['actions']['deploy']['methods']))
        params = self.job.device['actions']['deploy']['methods']
        identity = os.path.realpath(
            os.path.join(__file__, '../../', params['ssh']['identity_file']))
        self.assertTrue(os.path.exists(identity))
        test_command = [
            'ssh', '-o', 'Compression=yes', '-o', 'PasswordAuthentication=no',
            '-o', 'LogLevel=FATAL', '-o', 'UserKnownHostsFile=/dev/null', '-o',
            'StrictHostKeyChecking=no', '-i', identity, '-p', '8022'
        ]
        self.job.validate()
        login = [
            action for action in self.job.pipeline.actions
            if action.name == 'login-ssh'
        ][0]
        self.assertIn(
            'ssh-connection',
            [action.name for action in login.internal_pipeline.actions])
        primary = [
            action for action in login.internal_pipeline.actions
            if action.name == 'ssh-connection'
        ][0]
        prepare = [
            action for action in login.internal_pipeline.actions
            if action.name == 'prepare-ssh'
        ][0]
        self.assertTrue(prepare.primary)
        self.assertEqual(identity, primary.identity_file)
        self.assertEqual(primary.host, params['ssh']['host'])
        self.assertEqual(int(primary.ssh_port[1]), params['ssh']['port'])
        self.assertEqual(test_command, primary.command)
        # idempotency check
        self.job.validate()
        self.assertEqual(identity, primary.identity_file)
        self.assertEqual(test_command, primary.command)
        bad_port = {
            'host':
            'localhost',
            'port':
            'bob',
            'options': [
                '-o', 'Compression=yes', '-o', 'UserKnownHostsFile=/dev/null',
                '-o', 'PasswordAuthentication=no', '-o',
                'StrictHostKeyChecking=no', '-o', 'LogLevel=FATAL'
            ],
            'identity_file':
            'dynamic_vm_keys/lava'
        }
        self.job.device['actions']['deploy']['methods']['ssh'] = bad_port
        with self.assertRaises(JobError):
            self.job.validate()

    @unittest.skipIf(infrastructure_error('schroot'), "schroot not installed")
    def test_scp_command(self):
        self.job.validate()
        login = [
            action for action in self.guest_job.pipeline.actions
            if action.name == 'login-ssh'
        ][0]
        scp = [
            action for action in login.internal_pipeline.actions
            if action.name == 'scp-deploy'
        ][0]
        self.assertIsNotNone(scp)
        # FIXME: schroot needs to make use of scp
        self.assertNotIn('ssh', scp.scp)
        self.assertFalse(scp.primary)

    @unittest.skipIf(infrastructure_error('schroot'), "schroot not installed")
    def test_tar_command(self):
        self.job.validate()
        login = [
            item for item in self.job.pipeline.actions
            if item.name == 'login-ssh'
        ][0]
        tar_flags = login.get_namespace_data(action='scp-overlay',
                                             label='scp-overlay',
                                             key='tar_flags')
        self.assertIsNotNone(tar_flags)
        self.assertEqual('--warning no-timestamp', tar_flags)

    @unittest.skipIf(infrastructure_error('schroot'), "schroot not installed")
    def test_schroot_params(self):
        self.assertIn('schroot-login',
                      [action.name for action in self.job.pipeline.actions])
        schroot = [
            action for action in self.job.pipeline.actions
            if action.name == "schroot-login"
        ][0]
        self.job.validate()
        schroot.run_command(
            ['schroot', '-i', '-c', schroot.parameters['schroot']])
        if any("Chroot not found" in chk
               for chk in schroot.errors) or not schroot.valid:
            # schroot binary found but no matching chroot configured - skip test
            self.skipTest("no schroot support for %s" %
                          schroot.parameters['schroot'])
        bad_chroot = 'unobtainium'
        schroot.run_command(['schroot', '-i', '-c', bad_chroot])
        if not any("Chroot not found" in chk
                   for chk in schroot.errors) or schroot.valid:
            self.fail("Failed to catch a missing schroot name")

        self.assertIsInstance(schroot, SchrootAction)
        self.assertEqual(schroot.parameters['schroot'], 'unstable')
        boot_act = [
            boot['boot'] for boot in self.job.parameters['actions']
            if 'boot' in boot and 'schroot' in boot['boot']
        ][0]
        self.assertEqual(boot_act['schroot'], schroot.parameters['schroot'])

    def test_primary_ssh(self):
        factory = ConnectionFactory()
        job = factory.create_ssh_job('sample_jobs/primary-ssh.yaml')
        job.validate()
        overlay = [
            action for action in job.pipeline.actions
            if action.name == 'scp-overlay'
        ][0]
        self.assertIsNotNone(overlay.parameters['deployment_data'])
        tar_flags = overlay.parameters['deployment_data'][
            'tar_flags'] if 'tar_flags' in overlay.parameters[
                'deployment_data'].keys() else ''
        self.assertIsNotNone(tar_flags)

    def test_guest_ssh(self):  # pylint: disable=too-many-locals,too-many-statements
        self.assertIsNotNone(self.guest_job)
        description_ref = self.pipeline_reference('bbb-ssh-guest.yaml',
                                                  job=self.guest_job)
        self.assertEqual(description_ref,
                         self.guest_job.pipeline.describe(False))
        self.guest_job.validate()
        multinode = [
            protocol for protocol in self.guest_job.protocols
            if protocol.name == MultinodeProtocol.name
        ][0]
        self.assertEqual(int(multinode.system_timeout.duration), 900)
        self.assertEqual([], self.guest_job.pipeline.errors)
        self.assertEqual(
            len([
                item for item in self.guest_job.pipeline.actions
                if item.name == 'scp-overlay'
            ]), 1)
        scp_overlay = [
            item for item in self.guest_job.pipeline.actions
            if item.name == 'scp-overlay'
        ][0]
        prepare = [
            item for item in scp_overlay.internal_pipeline.actions
            if item.name == 'prepare-scp-overlay'
        ][0]
        self.assertEqual(prepare.host_keys, ['ipv4'])
        self.assertEqual(
            prepare.get_namespace_data(action=prepare.name,
                                       label=prepare.name,
                                       key='overlay'), prepare.host_keys)
        params = prepare.parameters['protocols'][MultinodeProtocol.name]
        for call_dict in [
                call for call in params
                if 'action' in call and call['action'] == prepare.name
        ]:
            del call_dict['yaml_line']
            if 'message' in call_dict:
                del call_dict['message']['yaml_line']
            if 'timeout' in call_dict:
                del call_dict['timeout']['yaml_line']
            self.assertEqual(
                call_dict,
                {
                    'action': 'prepare-scp-overlay',
                    'message': {
                        'ipaddr': '$ipaddr'
                    },
                    'messageID': 'ipv4',
                    'request': 'lava-wait',
                    'timeout': {
                        'minutes': 5
                    }
                },
            )
        login = [
            action for action in self.guest_job.pipeline.actions
            if action.name == 'login-ssh'
        ][0]
        scp = [
            action for action in login.internal_pipeline.actions
            if action.name == 'scp-deploy'
        ][0]
        self.assertFalse(scp.primary)
        ssh = [
            action for action in login.internal_pipeline.actions
            if action.name == 'prepare-ssh'
        ][0]
        self.assertFalse(ssh.primary)
        self.assertIsNotNone(scp.scp)
        self.assertFalse(scp.primary)
        autologin = [
            action for action in login.internal_pipeline.actions
            if action.name == 'auto-login-action'
        ][0]
        self.assertIsNone(autologin.params)
        self.assertIn('host_key', login.parameters['parameters'])
        self.assertIn('hostID', login.parameters['parameters'])
        self.assertIn(  # ipv4
            login.parameters['parameters']['hostID'], prepare.host_keys)
        prepare.set_namespace_data(action=MultinodeProtocol.name,
                                   label=MultinodeProtocol.name,
                                   key='ipv4',
                                   value={'ipaddr': '172.16.200.165'})
        self.assertEqual(
            prepare.get_namespace_data(action=prepare.name,
                                       label=prepare.name,
                                       key='overlay'), prepare.host_keys)
        self.assertIn(
            login.parameters['parameters']['host_key'],
            prepare.get_namespace_data(
                action=MultinodeProtocol.name,
                label=MultinodeProtocol.name,
                key=login.parameters['parameters']['hostID']))
        host_data = prepare.get_namespace_data(
            action=MultinodeProtocol.name,
            label=MultinodeProtocol.name,
            key=login.parameters['parameters']['hostID'])
        self.assertEqual(host_data[login.parameters['parameters']['host_key']],
                         '172.16.200.165')
        data = scp_overlay.get_namespace_data(action=MultinodeProtocol.name,
                                              label=MultinodeProtocol.name,
                                              key='ipv4')
        if 'protocols' in scp_overlay.parameters:
            for params in scp_overlay.parameters['protocols'][
                    MultinodeProtocol.name]:
                (replacement_key, placeholder) = [
                    (key, value) for key, value in params['message'].items()
                    if key != 'yaml_line'
                ][0]
                self.assertEqual(data[replacement_key], '172.16.200.165')
                self.assertEqual(placeholder, '$ipaddr')
        environment = scp_overlay.get_namespace_data(action=prepare.name,
                                                     label='environment',
                                                     key='env_dict')
        self.assertIsNotNone(environment)
        self.assertIn('LANG', environment.keys())
        self.assertIn('C', environment.values())
        overlay = [
            item for item in scp_overlay.internal_pipeline.actions
            if item.name == 'lava-overlay'
        ]
        self.assertIn(
            'action',
            overlay[0].parameters['protocols'][MultinodeProtocol.name][0])
        self.assertIn(
            'message',
            overlay[0].parameters['protocols'][MultinodeProtocol.name][0])
        self.assertIn(
            'timeout',
            overlay[0].parameters['protocols'][MultinodeProtocol.name][0])
        msg_dict = overlay[0].parameters['protocols'][
            MultinodeProtocol.name][0]['message']
        for key, value in msg_dict.items():
            if key == 'yaml_line':
                continue
            self.assertTrue(value.startswith('$'))
            self.assertFalse(key.startswith('$'))
        self.assertIn(
            'request',
            overlay[0].parameters['protocols'][MultinodeProtocol.name][0])
        multinode = [
            item for item in overlay[0].internal_pipeline.actions
            if item.name == 'lava-multinode-overlay'
        ]
        self.assertEqual(len(multinode), 1)
        # Check Pipeline
        description_ref = self.pipeline_reference('ssh-guest.yaml',
                                                  job=self.guest_job)
        self.assertEqual(description_ref,
                         self.guest_job.pipeline.describe(False))
Ejemplo n.º 9
0
 def validate(self):
     super(ApplyNexellLxcOverlay, self).validate()
     self.errors = infrastructure_error('tar')
Ejemplo n.º 10
0
class TestQemuNFS(StdoutTestCase):
    def setUp(self):
        super(TestQemuNFS, self).setUp()
        device = NewDevice(
            os.path.join(os.path.dirname(__file__), '../devices/kvm03.yaml'))
        kvm_yaml = os.path.join(os.path.dirname(__file__),
                                'sample_jobs/qemu-nfs.yaml')
        parser = JobParser()
        try:
            with open(kvm_yaml) as sample_job_data:
                job = parser.parse(sample_job_data, device, 4212, None, "")
        except NotImplementedError as exc:
            print(exc)
            # some deployments listed in basics.yaml are not implemented yet
            return None
        self.job = job
        self.job.logger = DummyLogger()

    @unittest.skipIf(infrastructure_error('qemu-system-aarch64'),
                     'qemu-system-arm not installed')
    def test_qemu_nfs(self):
        self.assertIsNotNone(self.job)
        description_ref = self.pipeline_reference('qemu-nfs.yaml')
        self.assertEqual(description_ref, self.job.pipeline.describe(False))

        boot = [
            action for action in self.job.pipeline.actions
            if action.name == 'boot-image-retry'
        ][0]
        qemu = [
            action for action in boot.internal_pipeline.actions
            if action.name == 'boot-qemu-image'
        ][0]
        execute = [
            action for action in qemu.internal_pipeline.actions
            if action.name == 'execute-qemu'
        ][0]
        self.job.validate()
        self.assertNotEqual([], [
            line for line in execute.sub_command if line.startswith('-kernel')
        ])
        self.assertEqual(
            1,
            len([
                line for line in execute.sub_command
                if line.startswith('-kernel')
            ]))
        self.assertIn('vmlinuz', [
            line for line in execute.sub_command if line.startswith('-kernel')
        ][0])

        self.assertNotEqual([], [
            line for line in execute.sub_command if line.startswith('-initrd')
        ])
        self.assertEqual(
            1,
            len([
                line for line in execute.sub_command
                if line.startswith('-initrd')
            ]))
        self.assertIn('initrd.img', [
            line for line in execute.sub_command if line.startswith('-initrd')
        ][0])

        self.assertEqual(
            [], [line for line in execute.sub_command if '/dev/nfs' in line])
        self.assertEqual(
            [], [line for line in execute.sub_command if 'nfsroot' in line])

        args = execute.methods['qemu-nfs']['parameters']['append'][
            'nfsrootargs']
        self.assertIn('{NFS_SERVER_IP}', args)
        self.assertIn('{NFSROOTFS}', args)

        substitutions = execute.substitutions
        substitutions["{NFSROOTFS}"] = 'root_dir'
        params = execute.methods['qemu-nfs']['parameters']['append']
        # console=ttyAMA0 root=/dev/nfs nfsroot=10.3.2.1:/var/lib/lava/dispatcher/tmp/dirname,tcp,hard,intr ip=dhcp
        append = [
            'console=%s' % params['console'], 'root=/dev/nfs',
            '%s' % substitute([params['nfsrootargs']], substitutions)[0],
            "%s" % params['ipargs']
        ]
        execute.sub_command.append('--append')
        execute.sub_command.append('"%s"' % ' '.join(append))
        kernel_cmdline = ' '.join(execute.sub_command)
        self.assertIn('console=ttyAMA0', kernel_cmdline)
        self.assertIn('/dev/nfs', kernel_cmdline)
        self.assertIn('root_dir,tcp,hard,intr', kernel_cmdline)
        self.assertIn('smp', kernel_cmdline)
        self.assertIn('cortex-a57', kernel_cmdline)
Ejemplo n.º 11
0
class TestRemovable(StdoutTestCase):  # pylint: disable=too-many-public-methods

    def setUp(self):
        super().setUp()
        self.factory = Factory()

    def test_device_parameters(self):
        """
        Test that the correct parameters have been set for the device
        """
        (rendered, _) = self.factory.create_device('cubie2.jinja2')
        cubie = NewDevice(yaml.safe_load(rendered))
        self.assertIsNotNone(cubie['parameters']['media'].get('usb'))
        self.assertIsNotNone(cubie.get('commands'))
        self.assertIsNotNone(cubie.get('actions'))
        self.assertIsNotNone(cubie['actions'].get('deploy'))
        self.assertIsNotNone(cubie['actions']['deploy'].get('methods'))
        self.assertIn('usb', cubie['actions']['deploy']['methods'])
        self.assertIsNotNone(cubie['actions'].get('boot'))
        self.assertIsNotNone(cubie['actions']['boot'].get('methods'))
        self.assertIn('u-boot', cubie['actions']['boot']['methods'])
        u_boot_params = cubie['actions']['boot']['methods']['u-boot']
        self.assertIn('usb', u_boot_params)
        self.assertIn('commands', u_boot_params['usb'])
        self.assertIn('parameters', u_boot_params)
        self.assertIn('bootloader_prompt', u_boot_params['parameters'])

    def _check_valid_job(self, device, test_file):
        self.maxDiff = None  # pylint: disable=invalid-name
        job_parser = JobParser()
        sample_job_file = os.path.join(os.path.dirname(__file__), 'sample_jobs/{}'.format(test_file))
        with open(sample_job_file) as sample_job_data:
            job = job_parser.parse(sample_job_data, device, 4212, None, "")
        job.logger = DummyLogger()
        try:
            job.validate()
        except JobError:
            self.fail(job.pipeline.errors)
        description_ref = self.pipeline_reference(test_file, job=job)
        self.assertEqual(description_ref, job.pipeline.describe(False))
        return job

    def _check_job_parameters(self, device, job, agent_key):
        mass_storage = None  # deploy
        for action in job.pipeline.actions:
            if isinstance(action, DeployAction):
                if isinstance(action, MassStorage):
                    self.assertTrue(action.valid)
                    agent = action.parameters[agent_key]['tool']
                    self.assertTrue(agent.startswith('/'))  # needs to be a full path but on the device, so avoid os.path
                    self.assertIn(action.parameters['device'], job.device['parameters']['media']['usb'])
                    mass_storage = action
        self.assertIsNotNone(mass_storage)
        self.assertIn('device', mass_storage.parameters)
        self.assertIn(mass_storage.parameters['device'], device['parameters']['media']['usb'])
        self.assertIsNotNone(mass_storage.get_namespace_data(action='storage-deploy', label='u-boot', key='device'))
        u_boot_params = device['actions']['boot']['methods']['u-boot']
        self.assertEqual(mass_storage.get_namespace_data(action='uboot-retry', label='bootloader_prompt', key='prompt'), u_boot_params['parameters']['bootloader_prompt'])

    def test_job_parameters(self):
        """
        Test that the job parameters match expected structure
        """
        (rendered, _) = self.factory.create_device('cubie1.jinja2')
        cubie = NewDevice(yaml.safe_load(rendered))
        job = self._check_valid_job(cubie, 'cubietruck-removable.yaml')
        self._check_job_parameters(cubie, job, 'download')

    def test_writer_job_parameters(self):
        """
        Test that the job parameters with a writer tool match expected structure
        """
        (rendered, _) = self.factory.create_device('cubie1.jinja2')
        cubie = NewDevice(yaml.safe_load(rendered))
        job = self._check_valid_job(cubie, 'cubietruck-removable-with-writer.yaml')
        self._check_job_parameters(cubie, job, 'writer')

    def _check_deployment(self, device, test_file):
        job_parser = JobParser()
        job = self._check_valid_job(device, test_file)
        self.assertIn('usb', device['parameters']['media'].keys())
        deploy_params = [methods for methods in job.parameters['actions'] if 'deploy' in methods.keys()][1]['deploy']
        self.assertIn('device', deploy_params)
        self.assertIn(deploy_params['device'], device['parameters']['media']['usb'])
        self.assertIn('uuid', device['parameters']['media']['usb'][deploy_params['device']])
        self.assertIn('device_id', device['parameters']['media']['usb'][deploy_params['device']])
        self.assertNotIn('boot_part', device['parameters']['media']['usb'][deploy_params['device']])
        deploy_action = [action for action in job.pipeline.actions if action.name == 'storage-deploy'][0]
        tftp_deploy_action = [action for action in job.pipeline.actions if action.name == 'tftp-deploy'][0]
        self.assertIsNotNone(deploy_action)
        test_dir = deploy_action.get_namespace_data(action='test', label='results', key='lava_test_results_dir', parameters=tftp_deploy_action.parameters)
        self.assertIsNotNone(test_dir)
        self.assertIn('/lava-', test_dir)
        self.assertIsInstance(deploy_action, MassStorage)
        img_params = deploy_action.parameters.get('images', deploy_action.parameters)
        self.assertIn('image', img_params)
        dd_action = [action for action in deploy_action.internal_pipeline.actions if action.name == 'dd-image'][0]
        self.assertEqual(
            dd_action.boot_params[dd_action.parameters['device']]['uuid'],
            'usb-SanDisk_Ultra_20060775320F43006019-0:0')
        self.assertIsNotNone(dd_action.get_namespace_data(action=dd_action.name, label='u-boot', key='boot_part'))
        self.assertIsNotNone(dd_action.get_namespace_data(action='uboot-from-media', label='uuid', key='boot_part'))
        self.assertEqual('0', '%s' % dd_action.get_namespace_data(action=dd_action.name, label='u-boot', key='boot_part'))
        self.assertIsInstance(dd_action.get_namespace_data(action='uboot-from-media', label='uuid', key='boot_part'), str)
        self.assertEqual('0:1', dd_action.get_namespace_data(action='uboot-from-media', label='uuid', key='boot_part'))
        self.assertIsNotNone(dd_action.get_namespace_data(
            action='uboot-prepare-kernel', label='bootcommand', key='bootcommand'))

    def test_deployment(self):
        (rendered, _) = self.factory.create_device('cubie1.jinja2')
        cubie = NewDevice(yaml.safe_load(rendered))
        self._check_deployment(cubie, 'cubietruck-removable.yaml')

    def test_writer_deployment(self):
        (rendered, _) = self.factory.create_device('cubie1.jinja2')
        cubie = NewDevice(yaml.safe_load(rendered))
        self._check_deployment(cubie, 'cubietruck-removable-with-writer.yaml')

    def test_juno_deployment(self):
        factory = RemovableFactory()
        job = factory.create_job('sample_jobs/juno-uboot-removable.yaml', '../devices/juno-uboot.yaml')
        job.logger = DummyLogger()
        job.validate()
        self.assertEqual(job.pipeline.errors, [])
        self.assertIn('usb', job.device['parameters']['media'].keys())
        deploy_params = [methods for methods in job.parameters['actions'] if 'deploy' in methods.keys()][1]['deploy']
        self.assertIn('device', deploy_params)
        self.assertIn(deploy_params['device'], job.device['parameters']['media']['usb'])
        self.assertIn('uuid', job.device['parameters']['media']['usb'][deploy_params['device']])
        self.assertIn('device_id', job.device['parameters']['media']['usb'][deploy_params['device']])
        self.assertNotIn('boot_part', job.device['parameters']['media']['usb'][deploy_params['device']])
        tftp_deploys = [action for action in job.pipeline.actions if action.name == 'tftp-deploy']
        self.assertEqual(len(tftp_deploys), 2)
        first_deploy = tftp_deploys[0]
        second_deploy = tftp_deploys[1]
        self.assertIsNotNone(first_deploy)
        self.assertIsNotNone(second_deploy)
        self.assertEqual('openembedded', first_deploy.parameters['namespace'])
        self.assertEqual('android', second_deploy.parameters['namespace'])
        self.assertNotIn('deployment_data', first_deploy.parameters)
        self.assertNotIn('deployment_data', second_deploy.parameters)
        storage_deploy_action = [action for action in job.pipeline.actions if action.name == 'storage-deploy'][0]
        download_action = [
            action for action in storage_deploy_action.internal_pipeline.actions if action.name == 'download-retry'][0]
        self.assertIsNotNone(download_action)
        self.assertEqual('android', storage_deploy_action.parameters['namespace'])

    def test_mustang_deployment(self):
        factory = RemovableFactory()
        job = factory.create_job('sample_jobs/mustang-secondary-media.yaml', '../devices/mustang-media.yaml')
        job.validate()
        description_ref = self.pipeline_reference('mustang-media.yaml', job=job)
        self.assertEqual(description_ref, job.pipeline.describe(False))
        self.assertIn('sata', job.device['parameters']['media'].keys())
        deploy_params = [methods for methods in job.parameters['actions'] if 'deploy' in methods.keys()][1]['deploy']
        self.assertIn('device', deploy_params)
        self.assertIn(deploy_params['device'], job.device['parameters']['media']['sata'])
        self.assertIn('uuid', job.device['parameters']['media']['sata'][deploy_params['device']])
        self.assertIn('device_id', job.device['parameters']['media']['sata'][deploy_params['device']])
        self.assertEqual('hd0', job.device['parameters']['media']['sata'][deploy_params['device']]['grub_interface'])
        grub_deploys = [action for action in job.pipeline.actions if action.name == 'grub-main-action']
        self.assertEqual(len(grub_deploys), 2)
        first_deploy = grub_deploys[0]
        second_deploy = grub_deploys[1]
        self.assertEqual('nfsdeploy', first_deploy.parameters['namespace'])
        self.assertEqual('satadeploy', second_deploy.parameters['namespace'])

    def test_secondary_media(self):
        factory = RemovableFactory()
        job = factory.create_job('sample_jobs/mustang-secondary-media.yaml', '../devices/mustang-media.yaml')
        job.validate()
        grub_nfs = [action for action in job.pipeline.actions if action.name == 'grub-main-action' and action.parameters['namespace'] == 'nfsdeploy'][0]
        media_action = [action for action in grub_nfs.internal_pipeline.actions if action.name == 'bootloader-from-media'][0]
        self.assertEqual(None, media_action.get_namespace_data(action='download-action', label='file', key='kernel'))
        self.assertEqual(None, media_action.get_namespace_data(action='compress-ramdisk', label='file', key='ramdisk'))
        self.assertEqual(None, media_action.get_namespace_data(action='download-action', label='file', key='dtb'))
        self.assertEqual(None, media_action.get_namespace_data(action=media_action.name, label='file', key='root'))
        grub_main = [action for action in job.pipeline.actions if action.name == 'grub-main-action' and action.parameters['namespace'] == 'satadeploy'][0]
        media_action = [action for action in grub_main.internal_pipeline.actions if action.name == 'bootloader-from-media'][0]
        self.assertIsInstance(media_action, BootloaderSecondaryMedia)
        self.assertIsNotNone(media_action.get_namespace_data(action='download-action', label='file', key='kernel'))
        self.assertIsNotNone(media_action.get_namespace_data(action='compress-ramdisk', label='file', key='ramdisk'))
        self.assertIsNotNone(media_action.get_namespace_data(action='download-action', label='file', key='ramdisk'))
        self.assertEqual('', media_action.get_namespace_data(action='download-action', label='file', key='dtb'))
        self.assertIsNotNone(media_action.get_namespace_data(action=media_action.name, label='uuid', key='root'))
        self.assertIsNotNone(media_action.get_namespace_data(action=media_action.name, label='uuid', key='boot_part'))

    @unittest.skipIf(infrastructure_error('mkimage'), "u-boot-tools not installed")
    def test_primary_media(self):
        """
        Test that definitions of secondary media do not block submissions using primary media
        """
        job_parser = JobParser()
        (rendered, _) = self.factory.create_device('bbb-01.jinja2')
        bbb = NewDevice(yaml.safe_load(rendered))
        sample_job_file = os.path.join(os.path.dirname(__file__), 'sample_jobs/uboot-ramdisk.yaml')
        with open(sample_job_file) as sample_job_data:
            job = job_parser.parse(sample_job_data, bbb, 4212, None, "")
        job.logger = DummyLogger()
        job.validate()
        self.assertEqual(job.pipeline.errors, [])
        self.assertIn('usb', bbb['parameters']['media'].keys())

    def test_substitutions(self):
        """
        Test substitution of secondary media values into u-boot commands

        Unlike most u-boot calls, removable knows in advance all the values it needs to substitute
        into the boot commands for the secondary deployment as these are fixed by the device config
        and the image details from the job submission.
        """
        job_parser = JobParser()
        (rendered, _) = self.factory.create_device('cubie1.jinja2')
        cubie = NewDevice(yaml.safe_load(rendered))
        sample_job_file = os.path.join(os.path.dirname(__file__), 'sample_jobs/cubietruck-removable.yaml')
        with open(sample_job_file) as sample_job_data:
            job = job_parser.parse(sample_job_data, cubie, 4212, None, "")
        job.logger = DummyLogger()
        job.validate()
        boot_params = [
            methods for methods in job.parameters['actions'] if 'boot' in methods.keys()][1]['boot']
        self.assertIn('ramdisk', boot_params)
        self.assertIn('kernel', boot_params)
        self.assertIn('dtb', boot_params)
        self.assertIn('root_uuid', boot_params)
        self.assertIn('boot_part', boot_params)
        self.assertNotIn('type', boot_params)
        self.assertGreater(len(job.pipeline.actions), 1)
        self.assertIsNotNone(job.pipeline.actions[1].internal_pipeline)
        u_boot_action = [action for action in job.pipeline.actions if action.name == 'uboot-action'][1]
        overlay = [action for action in u_boot_action.internal_pipeline.actions if action.name == 'bootloader-overlay'][0]
        self.assertIsNotNone(overlay.get_namespace_data(action='storage-deploy', label='u-boot', key='device'))

        methods = cubie['actions']['boot']['methods']
        self.assertIn('u-boot', methods)
        self.assertIn('usb', methods['u-boot'])
        self.assertIn('commands', methods['u-boot']['usb'])
        commands_list = methods['u-boot']['usb']['commands']
        device_id = u_boot_action.get_namespace_data(action='storage-deploy', label='u-boot', key='device')
        self.assertIsNotNone(device_id)
        kernel_type = u_boot_action.parameters['kernel_type']
        bootcommand = map_kernel_uboot(kernel_type, device_params=cubie.get('parameters'))
        substitutions = {
            '{BOOTX}': "%s %s %s %s" % (
                bootcommand,
                cubie['parameters'][bootcommand]['kernel'],
                cubie['parameters'][bootcommand]['ramdisk'],
                cubie['parameters'][bootcommand]['dtb'],),
            '{RAMDISK}': boot_params['ramdisk'],
            '{KERNEL}': boot_params['kernel'],
            '{DTB}': boot_params['dtb'],
            '{ROOT}': boot_params['root_uuid'],
            '{ROOT_PART}': "%s:%s" % (
                cubie['parameters']['media']['usb'][device_id]['device_id'],
                u_boot_action.parameters['boot_part']
            )
        }
        self.assertEqual('bootz 0x42000000 0x43300000 0x43000000', substitutions['{BOOTX}'])
        self.assertEqual('/boot/initrd.img-3.16.0-4-armmp-lpae.u-boot', substitutions['{RAMDISK}'])
        commands = substitute(commands_list, substitutions)
        print(commands)
        self.assertEqual(
            commands,
            [
                'usb start',
                'setenv autoload no',
                'load usb 0:0:1 {KERNEL_ADDR} /boot/vmlinuz-3.16.0-4-armmp-lpae',
                'load usb 0:0:1 {RAMDISK_ADDR} /boot/initrd.img-3.16.0-4-armmp-lpae.u-boot',
                'setenv initrd_size ${filesize}',
                'load usb 0:0:1 {DTB_ADDR} /boot/dtb-3.16.0-4-armmp-lpae',
                'console=ttyS0,115200n8 root=UUID=159d17cc-697c-4125-95a0-a3775e1deabe  ip=dhcp',
                'bootz 0x42000000 0x43300000 0x43000000'
            ]
        )
Ejemplo n.º 12
0
def check_missing_path(testcase, exception, path):
    if isinstance(exception, InfrastructureError):
        if not infrastructure_error(path):
            testcase.fail(exception)
Ejemplo n.º 13
0
class TestBootloaderAction(StdoutTestCase):  # pylint: disable=too-many-public-methods
    def setUp(self):
        super().setUp()
        self.factory = Factory()

    def test_simulated_action(self):
        job = self.factory.create_job('x86-01.jinja2',
                                      'sample_jobs/ipxe-ramdisk.yaml')
        self.assertIsNotNone(job)

        description_ref = self.pipeline_reference('ipxe.yaml', job=job)
        self.assertEqual(description_ref, job.pipeline.describe(False))

        self.assertIsNone(job.validate())

    def test_tftp_pipeline(self):
        job = self.factory.create_job('x86-01.jinja2',
                                      'sample_jobs/ipxe-ramdisk.yaml')
        self.assertEqual([action.name for action in job.pipeline.actions], [
            'tftp-deploy', 'bootloader-action', 'lava-test-retry', 'finalize'
        ])
        tftp = [
            action for action in job.pipeline.actions
            if action.name == 'tftp-deploy'
        ][0]
        self.assertTrue(
            tftp.get_namespace_data(action=tftp.name,
                                    label='tftp',
                                    key='ramdisk'))
        self.assertIsNotNone(tftp.internal_pipeline)
        self.assertEqual(
            [action.name for action in tftp.internal_pipeline.actions], [
                'download-retry', 'download-retry', 'download-retry',
                'prepare-tftp-overlay', 'lxc-create-udev-rule-action',
                'deploy-device-env'
            ])
        self.assertIn('ramdisk', [
            action.key for action in tftp.internal_pipeline.actions
            if hasattr(action, 'key')
        ])
        self.assertIn('kernel', [
            action.key for action in tftp.internal_pipeline.actions
            if hasattr(action, 'key')
        ])

    def test_device_x86(self):
        job = self.factory.create_job('x86-02.jinja2',
                                      'sample_jobs/ipxe-ramdisk.yaml')
        self.assertEqual(
            job.device['commands']['connections']['uart0']['connect'],
            'telnet bumblebee 8003')
        self.assertEqual(job.device['commands'].get('interrupt', ' '), ' ')
        methods = job.device['actions']['boot']['methods']
        self.assertIn('ipxe', methods)
        self.assertEqual(
            methods['ipxe']['parameters'].get('bootloader_prompt'), 'iPXE>')

    def test_bootloader_action(self):
        job = self.factory.create_job('x86-01.jinja2',
                                      'sample_jobs/ipxe-ramdisk.yaml')
        job.validate()
        self.assertEqual(job.pipeline.errors, [])
        self.assertIn('ipxe', job.device['actions']['boot']['methods'])
        params = job.device['actions']['boot']['methods']['ipxe']['parameters']
        boot_message = params.get(
            'boot_message', job.device.get_constant('kernel-start-message'))
        self.assertIsNotNone(boot_message)
        bootloader_action = [
            action for action in job.pipeline.actions
            if action.name == 'bootloader-action'
        ][0]
        bootloader_retry = [
            action for action in bootloader_action.internal_pipeline.actions
            if action.name == 'bootloader-retry'
        ][0]
        commands = [
            action for action in bootloader_retry.internal_pipeline.actions
            if action.name == 'bootloader-commands'
        ][0]
        self.assertEqual(commands.character_delay, 500)
        for action in job.pipeline.actions:
            action.validate()
            if isinstance(action, BootloaderAction):
                self.assertIn('method', action.parameters)
                self.assertEqual('ipxe', action.parameters['method'])
                self.assertEqual(
                    'reboot: Restarting system',
                    action.parameters.get('parameters', {}).get(
                        'shutdown-message',
                        job.device.get_constant('shutdown-message')))
            if isinstance(action, TftpAction):
                self.assertIn('ramdisk', action.parameters)
                self.assertIn('kernel', action.parameters)
                self.assertIn('to', action.parameters)
                self.assertEqual('tftp', action.parameters['to'])
            self.assertTrue(action.valid)

    def test_overlay_action(self):  # pylint: disable=too-many-locals
        parameters = {
            'device_type': 'x86',
            'job_name': 'ipxe-pipeline',
            'job_timeout': '15m',
            'action_timeout': '5m',
            'priority': 'medium',
            'actions': {
                'boot': {
                    'method': 'ipxe',
                    'commands': 'ramdisk',
                    'prompts': ['linaro-test', 'root@debian:~#']
                },
                'deploy': {
                    'ramdisk': 'initrd.gz',
                    'kernel': 'zImage',
                }
            }
        }
        (rendered, _) = self.factory.create_device('x86-01.jinja2')
        device = NewDevice(yaml.safe_load(rendered))
        job = Job(4212, parameters, None)
        job.device = device
        pipeline = Pipeline(job=job, parameters=parameters['actions']['boot'])
        job.pipeline = pipeline
        overlay = BootloaderCommandOverlay()
        pipeline.add_action(overlay)
        ip_addr = dispatcher_ip(None)
        kernel = parameters['actions']['deploy']['kernel']
        ramdisk = parameters['actions']['deploy']['ramdisk']

        substitution_dictionary = {
            '{SERVER_IP}': ip_addr,
            '{RAMDISK}': ramdisk,
            '{KERNEL}': kernel,
            '{LAVA_MAC}': "00:00:00:00:00:00"
        }
        params = device['actions']['boot']['methods']
        params['ipxe']['ramdisk']['commands'] = substitute(
            params['ipxe']['ramdisk']['commands'], substitution_dictionary)

        commands = params['ipxe']['ramdisk']['commands']
        self.assertIs(type(commands), list)
        self.assertIn("dhcp net0", commands)
        self.assertIn(
            "set console console=ttyS0,115200n8 lava_mac=00:00:00:00:00:00",
            commands)
        self.assertIn("set extraargs  ip=dhcp", commands)
        self.assertNotIn(
            "kernel tftp://{SERVER_IP}/{KERNEL} ${extraargs} ${console}",
            commands)
        self.assertNotIn("initrd tftp://{SERVER_IP}/{RAMDISK}", commands)
        self.assertIn("boot", commands)

    def test_download_action(self):
        job = self.factory.create_job('x86-01.jinja2', 'sample_jobs/ipxe.yaml')
        for action in job.pipeline.actions:
            action.validate()
            self.assertTrue(action.valid)
        job.validate()
        self.assertEqual(job.pipeline.errors, [])
        deploy = None
        overlay = None
        extract = None
        for action in job.pipeline.actions:
            if action.name == 'tftp-deploy':
                deploy = action
        if deploy:
            for action in deploy.internal_pipeline.actions:
                if action.name == 'prepare-tftp-overlay':
                    overlay = action
        if overlay:
            for action in overlay.internal_pipeline.actions:
                if action.name == 'extract-nfsrootfs':
                    extract = action
        test_dir = overlay.get_namespace_data(action='test',
                                              label='results',
                                              key='lava_test_results_dir')
        self.assertIsNotNone(test_dir)
        self.assertIn('/lava-', test_dir)
        self.assertIsNotNone(extract)
        self.assertEqual(extract.timeout.duration, 120)

    def test_reset_actions(self):
        job = self.factory.create_job('x86-01.jinja2', 'sample_jobs/ipxe.yaml')
        bootloader_action = None
        bootloader_retry = None
        reset_action = None
        for action in job.pipeline.actions:
            action.validate()
            self.assertTrue(action.valid)
            if action.name == 'bootloader-action':
                bootloader_action = action
        names = [
            r_action.name
            for r_action in bootloader_action.internal_pipeline.actions
        ]
        self.assertIn('connect-device', names)
        self.assertIn('bootloader-retry', names)
        for action in bootloader_action.internal_pipeline.actions:
            if action.name == 'bootloader-retry':
                bootloader_retry = action
        names = [
            r_action.name
            for r_action in bootloader_retry.internal_pipeline.actions
        ]
        self.assertIn('reset-device', names)
        self.assertIn('bootloader-interrupt', names)
        self.assertIn('expect-shell-connection', names)
        self.assertIn('bootloader-commands', names)
        for action in bootloader_retry.internal_pipeline.actions:
            if action.name == 'reset-device':
                reset_action = action
        names = [
            r_action.name
            for r_action in reset_action.internal_pipeline.actions
        ]
        self.assertIn('pdu-reboot', names)

    @unittest.skipIf(infrastructure_error('telnet'), "telnet not installed")
    def test_prompt_from_job(self):  # pylint: disable=too-many-locals
        """
        Support setting the prompt after login via the job

        Loads a known YAML, adds a prompt to the dict and re-parses the job.
        Checks that the prompt is available in the expect_shell_connection action.
        """
        job = self.factory.create_job('x86-01.jinja2',
                                      'sample_jobs/ipxe-ramdisk.yaml')
        job.validate()
        bootloader = [
            action for action in job.pipeline.actions
            if action.name == 'bootloader-action'
        ][0]
        retry = [
            action for action in bootloader.internal_pipeline.actions
            if action.name == 'bootloader-retry'
        ][0]
        expect = [
            action for action in retry.internal_pipeline.actions
            if action.name == 'expect-shell-connection'
        ][0]
        check = expect.parameters
        (rendered, _) = self.factory.create_device('x86-01.jinja2')
        device = NewDevice(yaml.safe_load(rendered))
        extra_yaml = os.path.join(os.path.dirname(__file__),
                                  'sample_jobs/ipxe.yaml')
        with open(extra_yaml) as data:
            sample_job_string = data.read()
        parser = JobParser()
        sample_job_data = yaml.safe_load(sample_job_string)
        boot = [
            item['boot'] for item in sample_job_data['actions']
            if 'boot' in item
        ][0]
        self.assertIsNotNone(boot)
        sample_job_string = yaml.dump(sample_job_data)
        job = parser.parse(sample_job_string, device, 4212, None, "")
        job.logger = DummyLogger()
        job.validate()
        bootloader = [
            action for action in job.pipeline.actions
            if action.name == 'bootloader-action'
        ][0]
        retry = [
            action for action in bootloader.internal_pipeline.actions
            if action.name == 'bootloader-retry'
        ][0]
        expect = [
            action for action in retry.internal_pipeline.actions
            if action.name == 'expect-shell-connection'
        ][0]

    def test_xz_nfs(self):
        job = self.factory.create_job('x86-01.jinja2',
                                      'sample_jobs/ipxe-nfs.yaml')
        # this job won't validate as the .xz nfsrootfs URL is a fiction
        self.assertRaises(JobError, job.validate)
        tftp_deploy = [
            action for action in job.pipeline.actions
            if action.name == 'tftp-deploy'
        ][0]
        prepare = [
            action for action in tftp_deploy.internal_pipeline.actions
            if action.name == 'prepare-tftp-overlay'
        ][0]
        nfs = [
            action for action in prepare.internal_pipeline.actions
            if action.name == 'extract-nfsrootfs'
        ][0]
        self.assertIn('compression', nfs.parameters['nfsrootfs'])
        self.assertEqual(nfs.parameters['nfsrootfs']['compression'], 'xz')

    def test_ipxe_with_monitor(self):
        job = self.factory.create_job('x86-01.jinja2',
                                      'sample_jobs/ipxe-monitor.yaml')
        job.validate()
        description_ref = self.pipeline_reference('ipxe-monitor.yaml', job=job)
        self.assertEqual(description_ref, job.pipeline.describe(False))
Ejemplo n.º 14
0
class TestUbootTemplates(BaseTemplate.BaseTemplateCases):
    """
    Test rendering of jinja2 templates

    When adding or modifying a jinja2 template, add or update the test here.
    Use realistic data - complete exports of the device dictionary preferably.
    Set debug to True to see the content of the rendered templates
    Set system to True to use the system templates - note that this requires
    that the templates in question are in sync with the branch upon which the
    test is run. Therefore, if the templates should be the same, this can be
    used to check that the templates are correct. If there are problems, check
    for a template with a .dpkg-dist extension. Check the diff between the
    checkout and the system file matches the difference between the system file
    and the dpkg-dist version. If the diffs match, copy the dpkg-dist onto the
    system file.
    """
    def test_armada375_template(self):
        """
        Test the armada-375 template as if it was a device dictionary
        """
        data = """
{% extends 'base-uboot.jinja2' %}
{% set console_device = console_device|default('ttyS0') %}
{% set baud_rate = baud_rate|default(115200) %}
{% set bootloader_prompt = bootloader_prompt|default('Marvell>>') %}
{% set bootm_kernel_addr = '0x02080000' %}
{% set bootm_ramdisk_addr = '0x02880000' %}
{% set bootm_dtb_addr = '0x02000000' %}
{% set base_ip_args = 'ip=dhcp' %}
{% set uboot_mkimage_arch = 'arm' %}
{% set append_dtb = true %}
{% set use_xip = true %}
{% set uboot_bootx_cmd = "bootm {KERNEL_ADDR} {RAMDISK_ADDR}" %}
        """
        self.assertTrue(self.validate_data('armada-375-01', data))
        template_dict = prepare_jinja_template('armada-375-01',
                                               data,
                                               raw=False)
        params = template_dict['actions']['deploy']['parameters']
        self.assertIsNotNone(params)
        self.assertIn('use_xip', params)
        self.assertIn('append_dtb', params)
        self.assertTrue(params['use_xip'])
        self.assertTrue(params['append_dtb'])
        params = template_dict['actions']['boot']['methods']['u-boot'][
            'ramdisk']['commands']
        for line in params:
            if 'run loadkernel' in line:
                self.assertIn('bootm', line)

    def test_beaglebone_black_template(self):
        data = """{% extends 'beaglebone-black.jinja2' %}
{% set map = {'eth0': {'lngswitch03': 19}, 'eth1': {'lngswitch03': 8}} %}
{% set hard_reset_command = '/usr/bin/pduclient --daemon localhost --hostname lngpdu01 --command reboot --port 19' %}
{% set tags = {'eth0': ['1G', '100M'], 'eth1': ['100M']} %}
{% set interfaces = ['eth0', 'eth1'] %}
{% set sysfs = {'eth0': '/sys/devices/platform/ocp/4a100000.ethernet/net/eth0',
'eth1': '/sys/devices/platform/ocp/47400000.usb/47401c00.usb/musb-hdrc.1.auto/usb1/1-1/1-1:1.0/net/eth1'} %}
{% set power_off_command = '/usr/bin/pduclient --daemon localhost --hostname lngpdu01 --command off --port 19' %}
{% set mac_addr = {'eth0': '90:59:af:5e:69:fd', 'eth1': '00:e0:4c:53:44:58'} %}
{% set power_on_command = '/usr/bin/pduclient --daemon localhost --hostname lngpdu01 --command on --port 19' %}
{% set connection_command = 'telnet localhost 7333' %}"""
        self.assertTrue(self.validate_data('staging-bbb-01', data))
        template_dict = prepare_jinja_template('staging-bbb-01',
                                               data,
                                               raw=False)
        self.assertIsNotNone(
            template_dict['actions']['deploy']['methods']['ssh']['host'])
        self.assertEqual(
            '', template_dict['actions']['deploy']['methods']['ssh']['host'])
        self.assertNotEqual(
            'None',
            template_dict['actions']['deploy']['methods']['ssh']['host'])
        data += "{% set ssh_host = '192.168.0.10' %}"
        template_dict = prepare_jinja_template('staging-bbb-01',
                                               data,
                                               raw=False)
        self.assertIsNotNone(
            template_dict['actions']['deploy']['methods']['ssh']['host'])
        self.assertEqual(
            '192.168.0.10',
            template_dict['actions']['deploy']['methods']['ssh']['host'])

    def test_b2260_template(self):
        data = """{% extends 'b2260.jinja2' %}"""
        self.assertTrue(self.validate_data('staging-b2260-01', data))
        template_dict = prepare_jinja_template('staging-b2260-01',
                                               data,
                                               raw=False)
        self.assertEqual({'seconds': 15},
                         template_dict['timeouts']['actions']['power-off'])

    def test_mustang_template(self):
        data = """{% extends 'mustang.jinja2' %}
{% set connection_command = 'telnet serial4 7012' %}
{% set hard_reset_command = '/usr/bin/pduclient --daemon staging-master --hostname pdu15 --command reboot --port 05' %}
{% set power_off_command = '/usr/bin/pduclient --daemon staging-master --hostname pdu15 --command off --port 05' %}
{% set power_on_command = '/usr/bin/pduclient --daemon staging-master --hostname pdu15 --command on --port 05' %}"""
        self.assertTrue(self.validate_data('staging-mustang-01', data))
        template_dict = prepare_jinja_template('staging-mustang-01',
                                               data,
                                               raw=False)
        self.assertIsInstance(template_dict['parameters']['text_offset'], str)
        commands = template_dict['actions']['boot']['methods']['u-boot'][
            'ramdisk']['commands']
        for line in commands:
            if 'setenv initrd_high' in line:
                self.fail('Mustang should not have initrd_high set')
            if 'setenv fdt_high' in line:
                self.fail('Mustang should not have fdt_high set')

    def test_rpi3_32_template(self):
        checked = False
        data = """{% extends 'bcm2837-rpi-3-b-32.jinja2' %}"""
        self.assertTrue(self.validate_data('staging-rpi3-01', data))

        # test appending to kernel args
        context = {'extra_kernel_args': 'extra_arg=extra_val'}
        template_dict = prepare_jinja_template('staging-rpi3-01',
                                               data,
                                               job_ctx=context,
                                               raw=False)
        commands = template_dict['actions']['boot']['methods']['u-boot'][
            'ramdisk']['commands']
        self.assertIsNotNone(commands)
        self.assertIsInstance(commands, list)
        for line in commands:
            if 'setenv bootargs' in line:
                self.assertIn("earlycon=", line)
                self.assertIn("extra_arg=extra_val", line)
                checked = True
        self.assertTrue(checked)

        # test overwriting kernel args
        checked = False
        context = {'custom_kernel_args': 'custom_arg=custom_val'}
        template_dict = prepare_jinja_template('staging-rpi3-01',
                                               data,
                                               job_ctx=context,
                                               raw=False)
        commands = template_dict['actions']['boot']['methods']['u-boot'][
            'ramdisk']['commands']
        self.assertIsNotNone(commands)
        self.assertIsInstance(commands, list)
        for line in commands:
            if 'setenv bootargs' in line:
                self.assertNotIn("earlycon=", line)
                self.assertIn("custom_arg=custom_val", line)
                checked = True
        self.assertTrue(checked)

    def test_panda_template(self):
        logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
        logger = logging.getLogger('unittests')
        logger.disabled = True
        logger.propagate = False
        data = """{% extends 'panda.jinja2' %}
{% set connection_command = 'telnet serial4 7012' %}
{% set hard_reset_command = '/usr/bin/pduclient --daemon staging-master --hostname pdu15 --command reboot --port 05' %}
{% set power_off_command = '/usr/bin/pduclient --daemon staging-master --hostname pdu15 --command off --port 05' %}
{% set power_on_command = '/usr/bin/pduclient --daemon staging-master --hostname pdu15 --command on --port 05' %}"""
        self.assertTrue(self.validate_data('staging-panda-01', data))
        context = {'extra_kernel_args': 'intel_mmio=on mmio=on'}
        template_dict = prepare_jinja_template('staging-panda-01',
                                               data,
                                               job_ctx=context,
                                               raw=False)
        self.assertIn('bootloader-commands',
                      template_dict['timeouts']['actions'])
        self.assertEqual(
            180.0,
            Timeout.parse(
                template_dict['timeouts']['actions']['bootloader-commands']))
        commands = template_dict['actions']['boot']['methods']['u-boot'][
            'ramdisk']['commands']
        checked = False
        self.assertIsNotNone(commands)
        self.assertIsInstance(commands, list)
        self.assertIn('usb start', commands)
        for line in commands:
            if 'setenv bootargs' in line:
                self.assertIn('console=ttyO2', line)
                self.assertIn(' ' + context['extra_kernel_args'] + ' ', line)
                checked = True
        self.assertTrue(checked)
        checked = False
        for line in commands:
            if 'setenv initrd_high' in line:
                checked = True
        self.assertTrue(checked)

    def test_juno_uboot_template(self):
        data = """{% extends 'juno-uboot.jinja2' %}
{% set connection_command = 'telnet serial4 7001' %}
{% set hard_reset_command = '/usr/local/lab-scripts/snmp_pdu_control --hostname pdu18 --command reboot --port 10 --delay 10' %}
{% set power_off_command = '/usr/local/lab-scripts/snmp_pdu_control --hostname pdu18 --command off --port 10 --delay 10' %}
{% set power_on_command = '/usr/local/lab-scripts/snmp_pdu_control --hostname pdu18 --command on --port 10 --delay 10' %}
{% set usb_label = 'SanDiskCruzerBlade' %}
{% set usb_uuid = 'usb-SanDisk_Cruzer_Blade_20060266531DA442AD42-0:0' %}
{% set usb_device_id = 0 %}
{% set nfs_uboot_bootcmd = (
"          - setenv bootcmd 'dhcp; setenv serverip {SERVER_IP}; run loadkernel; run loadinitrd; run loadfdt; {BOOTX}'
          - boot") %}"""
        self.assertTrue(self.validate_data('staging-juno-01', data))
        template_dict = prepare_jinja_template('staging-juno-01',
                                               data,
                                               raw=False)
        self.assertIsNotNone(template_dict)

    def test_cubietruck_template(self):
        data = """{% extends 'cubietruck.jinja2' %}
{% set usb_label = 'SanDisk_Ultra' %}
{% set sata_label = 'ST160LM003' %}
{% set uuid_required = False %}
{% set usb_uuid = "usb-SanDisk_Ultra_20060775320F43006019-0:0" %}
{% set sata_uuid = "ata-ST160LM003_HN-M160MBB_S2SYJ9KC102184" %}
{% set connection_command = 'telnet localhost 6002' %}
{% set console_device = 'ttyfake1' %}"""
        self.assertTrue(self.validate_data('staging-cubietruck-01', data))
        template_dict = prepare_jinja_template('staging-cubietruck-01',
                                               data,
                                               raw=False)
        self.assertIsNotNone(template_dict)
        self.assertIn('u-boot', template_dict['actions']['boot']['methods'])
        self.assertIn('SanDisk_Ultra',
                      template_dict['parameters']['media']['usb'])
        self.assertEqual(
            template_dict['parameters']['media']['usb']['SanDisk_Ultra']
            ['device_id'], 0)
        self.assertEqual(
            template_dict['parameters']['media']['usb']['SanDisk_Ultra']
            ['uuid'], 'usb-SanDisk_Ultra_20060775320F43006019-0:0')
        self.assertIn('ST160LM003',
                      template_dict['parameters']['media']['sata'])
        self.assertIn(
            'uboot_interface',
            template_dict['parameters']['media']['sata']['ST160LM003'])
        self.assertEqual(
            'scsi', template_dict['parameters']['media']['sata']['ST160LM003']
            ['uboot_interface'])
        self.assertIn(
            'uuid', template_dict['parameters']['media']['sata']['ST160LM003'])
        self.assertIn(
            'ata-ST160LM003_HN-M160MBB_S2SYJ9KC102184',
            template_dict['parameters']['media']['sata']['ST160LM003']['uuid'])
        self.assertIn('ssh', template_dict['actions']['boot']['methods'])

    def test_extra_nfs_opts(self):
        data = """{% extends 'panda.jinja2' %}
{% set connection_command = 'telnet serial4 7012' %}
{% set hard_reset_command = '/usr/bin/pduclient --daemon staging-master --hostname pdu15 --command reboot --port 05' %}
{% set power_off_command = '/usr/bin/pduclient --daemon staging-master --hostname pdu15 --command off --port 05' %}
{% set power_on_command = '/usr/bin/pduclient --daemon staging-master --hostname pdu15 --command on --port 05' %}"""
        job_ctx = {}
        template_dict = prepare_jinja_template('staging-panda-01',
                                               data,
                                               job_ctx=job_ctx,
                                               raw=False)
        for line in template_dict['actions']['boot']['methods']['u-boot'][
                'nfs']['commands']:
            if line.startswith("setenv nfsargs"):
                self.assertIn(',tcp,hard,intr ', line)
                self.assertNotIn('nfsvers', line)
        job_ctx = {'extra_nfsroot_args': ',nolock,nfsvers=3'}
        template_dict = prepare_jinja_template('staging-panda-01',
                                               data,
                                               job_ctx=job_ctx,
                                               raw=False)
        for line in template_dict['actions']['boot']['methods']['u-boot'][
                'nfs']['commands']:
            if line.startswith("setenv nfsargs"):
                self.assertIn(',tcp,hard,intr,nolock,nfsvers=3 ', line)
        commands = template_dict['actions']['boot']['methods']['u-boot'][
            'ramdisk']['commands']
        checked = False
        for line in commands:
            if 'setenv initrd_high' in line:
                checked = True
        self.assertTrue(checked)

    def test_juno_uboot_vland_template(self):
        data = """{% extends 'juno-uboot.jinja2' %}
{% set map = {'iface0': {'lngswitch03': 19}, 'iface1': {'lngswitch03': 8}} %}
{% set hard_reset_command = '/usr/local/lab-scripts/snmp_pdu_control --hostname lngpdu01 --command reboot --port 19' %}
{% set tags = {'iface0': [], 'iface1': ['RJ45', '10M', '100M']} %}
{% set interfaces = ['iface0', 'iface1'] %}
{% set device_mac = '90:59:af:5e:69:fd' %}
{% set sysfs = {'iface0': '/sys/devices/platform/ocp/4a100000.ethernet/net/',
'iface1': '/sys/devices/platform/ocp/47400000.usb/47401c00.usb/musb-hdrc.1.auto/usb1/1-1/1-1:1.0/net/'} %}
{% set power_off_command = '/usr/local/lab-scripts/snmp_pdu_control --hostname lngpdu01 --command off --port 19' %}
{% set mac_addr = {'iface0': '90:59:af:5e:69:fd', 'iface1': '00:e0:4c:53:44:58'} %}
{% set power_on_command = '/usr/local/lab-scripts/snmp_pdu_control --hostname lngpdu01 --command on --port 19' %}
{% set connection_command = 'telnet localhost 7333' %}"""
        self.assertTrue(self.validate_data('staging-x86-01', data))
        template_dict = prepare_jinja_template('staging-qemu-01',
                                               data,
                                               raw=False)
        self.assertIn('interfaces', template_dict['parameters'])
        self.assertIn('iface0', template_dict['parameters']['interfaces'])
        self.assertIn('port',
                      template_dict['parameters']['interfaces']['iface0'])
        self.assertIn('target', template_dict['parameters']['interfaces'])
        self.assertIn('ip',
                      template_dict['parameters']['interfaces']['target'])
        self.assertIsNone(
            template_dict['parameters']['interfaces']['target']['ip'])
        self.assertIsNotNone(
            template_dict['parameters']['interfaces']['target']['mac'])

    @unittest.skipIf(infrastructure_error('lxc-info'),
                     "lxc-info not installed")
    def test_panda_lxc_template(self):
        logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
        logger = logging.getLogger('unittests')
        logger.disabled = True
        logger.propagate = False
        logger = logging.getLogger('dispatcher')
        logging.disable(logging.DEBUG)
        logger.disabled = True
        logger.propagate = False
        data = """{% extends 'panda.jinja2' %}
{% set power_off_command = '/usr/local/lab-scripts/snmp_pdu_control --hostname pdu15 --command off --port 07' %}
{% set hard_reset_command = '/usr/local/lab-scripts/snmp_pdu_control --hostname pdu15 --command reboot --port 07' %}
{% set connection_command = 'telnet serial4 7010' %}
{% set power_on_command = '/usr/local/lab-scripts/snmp_pdu_control --hostname pdu15 --command on --port 07' %}"""
        self.assertTrue(self.validate_data('staging-panda-01', data))
        template_dict = prepare_jinja_template('staging-panda-01',
                                               data,
                                               raw=False)
        fdesc, device_yaml = tempfile.mkstemp()
        os.write(fdesc, yaml.dump(template_dict).encode())
        panda = NewDevice(device_yaml)
        lxc_yaml = os.path.join(os.path.dirname(__file__), 'devices',
                                'panda-lxc-aep.yaml')
        with open(lxc_yaml) as sample_job_data:
            parser = JobParser()
            job = parser.parse(sample_job_data, panda, 4577, None, "")
        os.close(fdesc)
        job.logger = DummyLogger()
        job.logger.disabled = True
        job.logger.propagate = False
        job.validate()

    def test_ethaddr(self):
        data = """{% extends 'b2260.jinja2' %}
{% set hard_reset_command = '/usr/local/lab-scripts/snmp_pdu_control --port 14 --hostname pdu18 --command reboot' %}
{% set power_off_command = '/usr/local/lab-scripts/snmp_pdu_control --port 14 --hostname pdu18 --command off' %}
{% set connection_command = 'telnet localhost 7114' %}
{% set power_on_command = '/usr/local/lab-scripts/snmp_pdu_control --port 14 --hostname pdu18 --command on' %}
{% set uboot_mac_addr = '00:80:e1:12:81:30' %}"""
        self.assertTrue(self.validate_data('staging-b2260-01', data))
        template_dict = prepare_jinja_template('staging-b2260-01',
                                               data,
                                               raw=False)
        ethaddr = False
        for command in template_dict['actions']['boot']['methods']['u-boot'][
                'ramdisk']['commands']:
            if command.startswith('setenv ethaddr'):
                self.assertEqual(command, 'setenv ethaddr 00:80:e1:12:81:30')
                ethaddr = True
        self.assertTrue(ethaddr)
        ethaddr = False
        for command in template_dict['actions']['boot']['methods']['u-boot'][
                'nfs']['commands']:
            if command.startswith('setenv ethaddr'):
                self.assertEqual(command, 'setenv ethaddr 00:80:e1:12:81:30')
                ethaddr = True
        self.assertTrue(ethaddr)

    def test_ip_args(self):
        data = """{% extends 'arndale.jinja2' %}
{% set power_off_command = '/usr/local/lab-scripts/snmp_pdu_control --hostname pdu15 --command off --port 07' %}
{% set hard_reset_command = '/usr/local/lab-scripts/snmp_pdu_control --hostname pdu15 --command reboot --port 07' %}
{% set connection_command = 'telnet serial4 7010' %}
{% set power_on_command = '/usr/local/lab-scripts/snmp_pdu_control --hostname pdu15 --command on --port 07' %}"""
        self.assertTrue(self.validate_data('staging-arndale-01', data))
        template_dict = prepare_jinja_template('staging-panda-01',
                                               data,
                                               raw=False)
        for line in template_dict['actions']['boot']['methods']['u-boot'][
                'ramdisk']['commands']:
            if line.startswith("setenv nfsargs"):
                self.assertIn('ip=:::::eth0:dhcp', line)
                self.assertNotIn('ip=dhcp', line)
            elif line.startswith("setenv bootargs"):
                self.assertIn("drm_kms_helper.edid_firmware=edid-1920x1080.fw",
                              line)

    def test_d03(self):
        data = """{% extends 'd03.jinja2' %}
{% set hard_reset_command = '/usr/bin/pduclient --daemon services --hostname pdu09 --command reboot --port 07' %}
{% set grub_installed_device = '(hd2,gpt1)' %}
{% set power_off_command = '/usr/bin/pduclient --daemon services --hostname pdu09 --command off --port 07' %}
{% set connection_command = 'telnet localhost 7001' %}
{% set power_on_command = '/usr/bin/pduclient --daemon services --hostname pdu09 --command on --port 07' %}
{% set boot_character_delay = 30 %}"""
        self.assertTrue(self.validate_data('staging-d03-01', data))
        template_dict = prepare_jinja_template('staging-d03-01',
                                               data,
                                               raw=False)
        self.assertIn('character_delays', template_dict)
        self.assertIn('boot', template_dict['character_delays'])
        self.assertNotIn('test', template_dict['character_delays'])
        self.assertEqual(30, template_dict['character_delays']['boot'])

    def test_juno_vexpress_template(self):
        data = """{% extends 'juno.jinja2' %}
    {% set connection_command = 'telnet serial4 7001' %}
    {% set hard_reset_command = '/usr/local/lab-scripts/snmp_pdu_control --hostname pdu18 --command reboot --port 10 --delay 10' %}
    {% set power_off_command = '/usr/local/lab-scripts/snmp_pdu_control --hostname pdu18 --command off --port 10 --delay 10' %}
    {% set power_on_command = '/usr/local/lab-scripts/snmp_pdu_control --hostname pdu18 --command on --port 10 --delay 10' %}
    {% set usb_label = 'SanDiskCruzerBlade' %}
    {% set usb_uuid = 'usb-SanDisk_Cruzer_Blade_20060266531DA442AD42-0:0' %}
    {% set usb_device_id = 0 %}
    {% set nfs_uboot_bootcmd = (
    "          - setenv bootcmd 'dhcp; setenv serverip {SERVER_IP}; run loadkernel; run loadinitrd; run loadfdt; {BOOTX}'
              - boot") %}"""
        self.assertTrue(self.validate_data('staging-juno-01', data))
        test_template = prepare_jinja_template('staging-juno-01',
                                               data,
                                               raw=True)
        rendered = test_template.render()
        template_dict = yaml.safe_load(rendered)
        self.assertIsNotNone(template_dict)
        self.assertEqual({'boot': 30}, template_dict['character_delays'])
        self.assertIn('error-messages', template_dict['constants']['u-boot'])
        self.assertEqual(
            'juno#', template_dict['actions']['boot']['methods']['u-boot']
            ['parameters']['bootloader_prompt'])
        self.assertEqual(
            'Shell>', template_dict['actions']['boot']['methods']['uefi']
            ['parameters']['bootloader_prompt'])
        self.assertEqual(
            'Start:', template_dict['actions']['boot']['methods']['uefi-menu']
            ['parameters']['bootloader_prompt'])

        rendered = test_template.render(bootloader_prompt="vexpress>")
        template_dict = yaml.safe_load(rendered)
        self.assertIsNotNone(template_dict)
        self.assertEqual({'boot': 30}, template_dict['character_delays'])
        self.assertIn('error-messages', template_dict['constants']['u-boot'])
        self.assertEqual(
            'vexpress>', template_dict['actions']['boot']['methods']['u-boot']
            ['parameters']['bootloader_prompt'])
        self.assertEqual(
            'Shell>', template_dict['actions']['boot']['methods']['uefi']
            ['parameters']['bootloader_prompt'])
        self.assertEqual(
            'Start:', template_dict['actions']['boot']['methods']['uefi-menu']
            ['parameters']['bootloader_prompt'])

    def test_imx8m_template(self):
        fastboot_cmd_order = [
            'update', 'ptable', 'partition', 'hyp', 'modem', 'rpm', 'sbl1',
            'sbl2', 'sec', 'tz', 'aboot', 'boot', 'rootfs', 'vendor', 'system',
            'cache', 'userdata'
        ]

        rendered = self.render_device_dictionary_file('imx8m-01.jinja2')
        template_dict = yaml.safe_load(rendered)
        self.assertIsNotNone(template_dict)
        self.assertIn('error-messages', template_dict['constants']['u-boot'])
        self.assertEqual(
            'u-boot=>', template_dict['actions']['boot']['methods']['u-boot']
            ['parameters']['bootloader_prompt'])

        context = {'bootloader_prompt': 'imx8m=>'}
        rendered = self.render_device_dictionary_file('imx8m-01.jinja2',
                                                      context)
        template_dict = yaml.safe_load(rendered)
        self.assertIsNotNone(template_dict)
        self.assertIn('error-messages', template_dict['constants']['u-boot'])
        self.assertEqual(
            'imx8m=>', template_dict['actions']['boot']['methods']['u-boot']
            ['parameters']['bootloader_prompt'])

        for cmd in template_dict['flash_cmds_order']:
            idx = template_dict['flash_cmds_order'].index(cmd)
            self.assertEqual(cmd, fastboot_cmd_order[idx])
        # test overwriting kernel args
        checked = False
        context = {'console_device': 'ttyUSB1'}
        rendered = self.render_device_dictionary_file('imx8m-01.jinja2',
                                                      context)
        template_dict = yaml.safe_load(rendered)
        commands = template_dict['actions']['boot']['methods']['u-boot'][
            'ramdisk']['commands']
        self.assertIsNotNone(commands)
        self.assertIsInstance(commands, list)
        for line in commands:
            if 'setenv bootargs' in line:
                self.assertIn("console=ttyUSB1", line)
                checked = True
        self.assertTrue(checked)

    def test_xilinx_zcu102(self):
        with open(
                os.path.join(os.path.dirname(__file__), 'devices',
                             'zcu102.jinja2')) as zcu:
            data = zcu.read()
        self.assertTrue(self.validate_data('zcu-01', data))
        template_dict = prepare_jinja_template('zcu-01', data, raw=False)
        self.assertIn('u-boot', template_dict['actions']['boot']['methods'])
        self.assertIn('ramdisk',
                      template_dict['actions']['boot']['methods']['u-boot'])
        commands = template_dict['actions']['boot']['methods']['u-boot'][
            'ramdisk']['commands']
        for command in commands:
            if not command.startswith('setenv loadkernel'):
                continue
            self.assertNotIn('tftp ', command)
            self.assertIn('tftpb', command)

        for command in commands:
            if not command.startswith('setenv bootargs'):
                continue
            self.assertNotIn('console=ttyS0,115200n8', command)
            self.assertNotIn('console=', command)
            self.assertNotIn('console=ttyO0', command)
            self.assertNotIn('115200n8', command)
            self.assertNotIn('n8', command)

    def test_flasher(self):
        data = """{% extends 'b2260.jinja2' %}
{% set flasher_deploy_commands = ['flashing', 'something --else'] %}
"""
        self.assertTrue(self.validate_data('staging-b2260-01', data))
        template_dict = prepare_jinja_template('staging-b2260-01',
                                               data,
                                               raw=False)
        self.assertEqual(['flashing', 'something --else'],
                         template_dict['actions']['deploy']['methods']
                         ['flasher']['commands'])

    def test_user_command(self):
        data = """{% extends 'b2260.jinja2' %}
{% set user_commands = {'set_boot_to_usb': {'do': '/bin/true', 'undo': '/bin/true'},
                        'set_boot_to_sd': {'do': '/bin/true', 'undo': '/bin/true'}} %}
"""
        self.assertTrue(self.validate_data('staging-b2260-01', data))
        template_dict = prepare_jinja_template('staging-b2260-01',
                                               data,
                                               raw=False)
        self.assertEqual(
            {
                'set_boot_to_usb': {
                    'do': '/bin/true',
                    'undo': '/bin/true'
                },
                'set_boot_to_sd': {
                    'do': '/bin/true',
                    'undo': '/bin/true'
                }
            }, template_dict['commands']['users'])

    def test_meson8b_template(self):
        template_dict = self.render_device_dictionary_file(
            'meson8b-odroidc1-1.jinja2', raw=False)
        self.assertIsNotNone(template_dict)
        template_dict['constants']['u-boot'].get('interrupt_ctrl_list',
                                                 self.fail)
        self.assertEqual(
            template_dict['constants']['u-boot']['interrupt_ctrl_list'], ['c'])
Ejemplo n.º 15
0
class TestUbootAction(StdoutTestCase):  # pylint: disable=too-many-public-methods
    def setUp(self):
        super().setUp()
        self.factory = UBootFactory()

    @unittest.skipIf(infrastructure_error('mkimage'),
                     "u-boot-tools not installed")
    def test_simulated_action(self):
        job = self.factory.create_bbb_job('sample_jobs/uboot-ramdisk.yaml')
        self.assertIsNotNone(job)

        # uboot and uboot-ramdisk have the same pipeline structure
        description_ref = self.pipeline_reference('uboot.yaml', job=job)
        self.assertEqual(description_ref, job.pipeline.describe(False))

        self.assertIsNone(job.validate())

    def test_tftp_pipeline(self):
        job = self.factory.create_bbb_job('sample_jobs/uboot-ramdisk.yaml')
        self.assertEqual(
            [action.name for action in job.pipeline.actions],
            ['tftp-deploy', 'uboot-action', 'lava-test-retry', 'finalize'])
        tftp = [
            action for action in job.pipeline.actions
            if action.name == 'tftp-deploy'
        ][0]
        self.assertTrue(
            tftp.get_namespace_data(action=tftp.name,
                                    label='tftp',
                                    key='ramdisk'))
        self.assertIsNotNone(tftp.internal_pipeline)
        self.assertEqual(
            [action.name for action in tftp.internal_pipeline.actions], [
                'download-retry', 'download-retry', 'download-retry',
                'prepare-tftp-overlay', 'lxc-create-udev-rule-action',
                'deploy-device-env'
            ])
        self.assertIn('ramdisk', [
            action.key for action in tftp.internal_pipeline.actions
            if hasattr(action, 'key')
        ])
        self.assertIn('kernel', [
            action.key for action in tftp.internal_pipeline.actions
            if hasattr(action, 'key')
        ])
        self.assertIn('dtb', [
            action.key for action in tftp.internal_pipeline.actions
            if hasattr(action, 'key')
        ])
        self.assertNotIn('=', tftpd_dir())
        job.validate()
        tftp.validate()
        self.assertEqual([], tftp.errors)

    def test_device_bbb(self):
        job = self.factory.create_bbb_job('sample_jobs/uboot.yaml')
        self.assertEqual(
            job.device['commands']['connections']['uart0']['connect'],
            'telnet localhost 6000')
        self.assertEqual(job.device['commands'].get('interrupt', ' '), ' ')
        methods = job.device['actions']['boot']['methods']
        self.assertIn('u-boot', methods)
        self.assertEqual(
            methods['u-boot']['parameters'].get('bootloader_prompt'), 'U-Boot')

    @unittest.skipIf(infrastructure_error('mkimage'),
                     "u-boot-tools not installed")
    def test_uboot_action(self):
        job = self.factory.create_bbb_job('sample_jobs/uboot-ramdisk.yaml')
        job.validate()
        self.assertEqual(job.pipeline.errors, [])
        self.assertIn('u-boot', job.device['actions']['boot']['methods'])
        params = job.device['actions']['deploy']['parameters']
        self.assertIn('mkimage_arch', params)
        boot_message = params.get(
            'boot_message', job.device.get_constant('kernel-start-message'))
        self.assertIsNotNone(boot_message)
        for action in job.pipeline.actions:
            action.validate()
            if isinstance(action, UBootAction):
                self.assertIn('method', action.parameters)
                self.assertEqual('u-boot', action.parameters['method'])
                self.assertEqual(
                    'reboot: Restarting system',
                    action.parameters.get('parameters', {}).get(
                        'shutdown-message',
                        job.device.get_constant('shutdown-message')))
            if isinstance(action, TftpAction):
                self.assertIn('ramdisk', action.parameters)
                self.assertIn('kernel', action.parameters)
                self.assertIn('to', action.parameters)
                self.assertEqual('tftp', action.parameters['to'])
            if isinstance(action, CompressRamdisk):
                self.assertEqual(action.mkimage_arch, 'arm')
            self.assertTrue(action.valid)

    def test_fastboot_uboot(self):  # pylint: disable=too-many-locals
        job = self.factory.create_x15_job('sample_jobs/x15-uboot.yaml')
        job.validate()
        description_ref = self.pipeline_reference('x15-uboot.yaml', job=job)
        self.assertEqual(description_ref, job.pipeline.describe(False))
        deploy = [
            action for action in job.pipeline.actions
            if action.name == 'fastboot-deploy'
        ][0]
        enter = [
            action for action in deploy.internal_pipeline.actions
            if action.name == 'uboot-enter-fastboot'
        ][0]
        interrupt = [
            action for action in enter.internal_pipeline.actions
            if action.name == 'bootloader-interrupt'
        ][0]
        self.assertIsNotNone(interrupt.params)
        self.assertNotEqual(interrupt.params, {})
        self.assertEqual('u-boot', interrupt.method)

    def test_x15_uboot_nfs(self):  # pylint: disable=too-many-locals
        job = self.factory.create_x15_job('sample_jobs/x15-nfs.yaml')
        job.validate()
        description_ref = self.pipeline_reference('x15-nfs.yaml', job=job)
        self.assertEqual(description_ref, job.pipeline.describe(False))
        tftp_deploy = [
            action for action in job.pipeline.actions
            if action.name == 'tftp-deploy'
        ][0]
        prepare = [
            action for action in tftp_deploy.internal_pipeline.actions
            if action.name == 'prepare-tftp-overlay'
        ][0]
        nfs = [
            action for action in prepare.internal_pipeline.actions
            if action.name == 'extract-nfsrootfs'
        ][0]
        self.assertIn('compression', nfs.parameters['nfsrootfs'])
        self.assertEqual(nfs.parameters['nfsrootfs']['compression'], 'gz')

    def test_juno_uboot_nfs(self):
        job = self.factory.create_juno_job('sample_jobs/juno-uboot-nfs.yaml')
        job.validate()
        description_ref = self.pipeline_reference('juno-uboot-nfs.yaml',
                                                  job=job)
        self.assertEqual(description_ref, job.pipeline.describe(False))

    def test_overlay_action(self):  # pylint: disable=too-many-locals
        parameters = {
            'device_type': 'beaglebone-black',
            'job_name': 'uboot-pipeline',
            'job_timeout': '15m',
            'action_timeout': '5m',
            'priority': 'medium',
            'actions': {
                'boot': {
                    'method': 'u-boot',
                    'commands': 'ramdisk',
                    'type': 'bootz',
                    'prompts': ['linaro-test', 'root@debian:~#']
                },
                'deploy': {
                    'ramdisk': 'initrd.gz',
                    'kernel': 'zImage',
                    'dtb': 'broken.dtb'
                }
            }
        }
        device = NewDevice(
            os.path.join(os.path.dirname(__file__), '../devices/bbb-01.yaml'))
        job = Job(4212, parameters, None)
        job.device = device
        pipeline = Pipeline(job=job, parameters=parameters['actions']['boot'])
        job.pipeline = pipeline
        overlay = BootloaderCommandOverlay()
        pipeline.add_action(overlay)
        ip_addr = dispatcher_ip(None)
        parsed = []
        kernel_addr = job.device['parameters'][
            overlay.parameters['type']]['ramdisk']
        ramdisk_addr = job.device['parameters'][
            overlay.parameters['type']]['ramdisk']
        dtb_addr = job.device['parameters'][overlay.parameters['type']]['dtb']
        kernel = parameters['actions']['deploy']['kernel']
        ramdisk = parameters['actions']['deploy']['ramdisk']
        dtb = parameters['actions']['deploy']['dtb']

        substitution_dictionary = {
            '{SERVER_IP}':
            ip_addr,
            # the addresses need to be hexadecimal
            '{KERNEL_ADDR}':
            kernel_addr,
            '{DTB_ADDR}':
            dtb_addr,
            '{RAMDISK_ADDR}':
            ramdisk_addr,
            '{BOOTX}':
            "%s %s %s %s" %
            (overlay.parameters['type'], kernel_addr, ramdisk_addr, dtb_addr),
            '{RAMDISK}':
            ramdisk,
            '{KERNEL}':
            kernel,
            '{DTB}':
            dtb
        }
        params = device['actions']['boot']['methods']
        params['u-boot']['ramdisk']['commands'] = substitute(
            params['u-boot']['ramdisk']['commands'], substitution_dictionary)

        commands = params['u-boot']['ramdisk']['commands']
        self.assertIs(type(commands), list)
        self.assertIn("setenv loadkernel 'tftp ${kernel_addr_r} zImage'",
                      commands)
        self.assertIn(
            "setenv loadinitrd 'tftp ${initrd_addr_r} initrd.gz; setenv initrd_size ${filesize}'",
            commands)
        self.assertIn("setenv loadfdt 'tftp ${fdt_addr_r} broken.dtb'",
                      commands)
        self.assertNotIn("setenv kernel_addr_r '{KERNEL_ADDR}'", commands)
        self.assertNotIn("setenv initrd_addr_r '{RAMDISK_ADDR}'", commands)
        self.assertNotIn("setenv fdt_addr_r '{DTB_ADDR}'", commands)

        for line in params['u-boot']['ramdisk']['commands']:
            line = line.replace('{SERVER_IP}', ip_addr)
            # the addresses need to be hexadecimal
            line = line.replace('{KERNEL_ADDR}', kernel_addr)
            line = line.replace('{DTB_ADDR}', dtb_addr)
            line = line.replace('{RAMDISK_ADDR}', ramdisk_addr)
            line = line.replace(
                '{BOOTX}',
                "%s %s %s %s" % (overlay.parameters['type'], kernel_addr,
                                 ramdisk_addr, dtb_addr))
            line = line.replace('{RAMDISK}', ramdisk)
            line = line.replace('{KERNEL}', kernel)
            line = line.replace('{DTB}', dtb)
            parsed.append(line)
        self.assertIn("setenv loadkernel 'tftp ${kernel_addr_r} zImage'",
                      parsed)
        self.assertIn(
            "setenv loadinitrd 'tftp ${initrd_addr_r} initrd.gz; setenv initrd_size ${filesize}'",
            parsed)
        self.assertIn("setenv loadfdt 'tftp ${fdt_addr_r} broken.dtb'", parsed)
        self.assertNotIn("setenv kernel_addr_r '{KERNEL_ADDR}'", parsed)
        self.assertNotIn("setenv initrd_addr_r '{RAMDISK_ADDR}'", parsed)
        self.assertNotIn("setenv fdt_addr_r '{DTB_ADDR}'", parsed)

    def test_boot_commands(self):
        job = self.factory.create_bbb_job(
            'sample_jobs/uboot-ramdisk-inline-commands.yaml')
        job.validate()
        uboot = [
            action for action in job.pipeline.actions
            if action.name == 'uboot-action'
        ][0]
        overlay = [
            action for action in uboot.internal_pipeline.actions
            if action.name == 'bootloader-overlay'
        ][0]
        self.assertEqual(
            overlay.commands,
            ['a list', 'of commands', 'with a {KERNEL_ADDR} substitution'])

    @unittest.skipIf(infrastructure_error('xnbd-server'),
                     "xnbd-server not installed")
    def test_nbd_boot(self):
        job = self.factory.create_bbb_job('sample_jobs/bbb-initrd-nbd.yaml')
        job.validate()
        self.assertEqual(job.pipeline.errors, [])
        description_ref = self.pipeline_reference('bbb-initrd-nbd.yaml',
                                                  job=job)
        self.assertEqual(description_ref, job.pipeline.describe(False))
        # Fixme: more asserts
        self.assertIn('u-boot', job.device['actions']['boot']['methods'])
        params = job.device['actions']['deploy']['parameters']
        self.assertIsNotNone(params)
        for action in job.pipeline.actions:
            action.validate()
            if isinstance(action, UBootAction):
                self.assertIn('method', action.parameters)
                self.assertEqual('u-boot', action.parameters['method'])
            elif isinstance(action, TftpAction):
                self.assertIn('initrd', action.parameters)
                self.assertIn('kernel', action.parameters)
                self.assertIn('nbdroot', action.parameters)
                self.assertIn('to', action.parameters)
                self.assertEqual('nbd', action.parameters['to'])
            self.assertTrue(action.valid)
        uboot = [
            action for action in job.pipeline.actions
            if action.name == 'uboot-action'
        ][0]
        overlay = [
            action for action in uboot.internal_pipeline.actions
            if action.name == 'bootloader-overlay'
        ][0]
        for setenv in overlay.commands:
            if 'setenv nbdbasekargs' in setenv:
                self.assertIn('rw', setenv.split("'")[1])
                self.assertIn('${extraargs}', setenv.split("'")[1])
                self.assertEqual(3, len(setenv.split("'")))

    def test_transfer_media(self):
        """
        Test adding the overlay to existing rootfs
        """
        job = self.factory.create_bbb_job(
            'sample_jobs/uboot-ramdisk-inline-commands.yaml')
        job.validate()
        description_ref = self.pipeline_reference(
            'uboot-ramdisk-inline-commands.yaml', job=job)
        self.assertEqual(description_ref, job.pipeline.describe(False))
        uboot = [
            action for action in job.pipeline.actions
            if action.name == 'uboot-action'
        ][0]
        retry = [
            action for action in uboot.internal_pipeline.actions
            if action.name == 'uboot-retry'
        ][0]
        transfer = [
            action for action in retry.internal_pipeline.actions
            if action.name == 'overlay-unpack'
        ][0]
        self.assertIn('transfer_overlay', transfer.parameters)
        self.assertIn('download_command',
                      transfer.parameters['transfer_overlay'])
        self.assertIn('unpack_command',
                      transfer.parameters['transfer_overlay'])

    def test_download_action(self):
        job = self.factory.create_bbb_job('sample_jobs/uboot.yaml')
        for action in job.pipeline.actions:
            action.validate()
            self.assertTrue(action.valid)
        job.validate()
        self.assertEqual(job.pipeline.errors, [])
        deploy = None
        overlay = None
        extract = None
        for action in job.pipeline.actions:
            if action.name == 'tftp-deploy':
                deploy = action
        if deploy:
            for action in deploy.internal_pipeline.actions:
                if action.name == 'prepare-tftp-overlay':
                    overlay = action
        if overlay:
            for action in overlay.internal_pipeline.actions:
                if action.name == 'extract-nfsrootfs':
                    extract = action
        test_dir = overlay.get_namespace_data(action='test',
                                              label='results',
                                              key='lava_test_results_dir')
        self.assertIsNotNone(test_dir)
        self.assertIn('/lava-', test_dir)
        self.assertIsNotNone(extract)
        self.assertEqual(extract.timeout.duration, 240)

    def test_reset_actions(self):
        job = self.factory.create_bbb_job('sample_jobs/uboot.yaml')
        uboot_action = None
        uboot_retry = None
        reset_action = None
        for action in job.pipeline.actions:
            action.validate()
            self.assertTrue(action.valid)
            if action.name == 'uboot-action':
                uboot_action = action
        names = [
            r_action.name
            for r_action in uboot_action.internal_pipeline.actions
        ]
        self.assertIn('connect-device', names)
        self.assertIn('uboot-retry', names)
        for action in uboot_action.internal_pipeline.actions:
            if action.name == 'uboot-retry':
                uboot_retry = action
        names = [
            r_action.name for r_action in uboot_retry.internal_pipeline.actions
        ]
        self.assertIn('reset-device', names)
        self.assertIn('bootloader-interrupt', names)
        self.assertIn('expect-shell-connection', names)
        self.assertIn('bootloader-commands', names)
        for action in uboot_retry.internal_pipeline.actions:
            if action.name == 'reset-device':
                reset_action = action
        names = [
            r_action.name
            for r_action in reset_action.internal_pipeline.actions
        ]
        self.assertIn('pdu-reboot', names)

    def test_secondary_media(self):
        """
        Test UBootSecondaryMedia validation
        """
        job_parser = JobParser()
        (rendered, _) = self.factory.create_device('cubie1.jinja2')
        cubie = NewDevice(yaml.safe_load(rendered))
        sample_job_file = os.path.join(
            os.path.dirname(__file__), 'sample_jobs/cubietruck-removable.yaml')
        sample_job_data = open(sample_job_file)
        job = job_parser.parse(sample_job_data, cubie, 4212, None, "")
        job.logger = DummyLogger()
        job.validate()
        sample_job_data.close()
        uboot_action = [
            action for action in job.pipeline.actions
            if action.name == 'uboot-action'
            and action.parameters['namespace'] == 'boot2'
        ][0]
        u_boot_media = [
            action for action in uboot_action.internal_pipeline.actions
            if action.name == 'uboot-from-media'
            and action.parameters['namespace'] == 'boot2'
        ][0]
        self.assertIsInstance(u_boot_media, UBootSecondaryMedia)
        self.assertEqual([], u_boot_media.errors)
        self.assertEqual(u_boot_media.parameters['kernel'],
                         '/boot/vmlinuz-3.16.0-4-armmp-lpae')
        self.assertEqual(
            u_boot_media.parameters['kernel'],
            u_boot_media.get_namespace_data(action='download-action',
                                            label='file',
                                            key='kernel'))
        self.assertEqual(
            u_boot_media.parameters['ramdisk'],
            u_boot_media.get_namespace_data(action='compress-ramdisk',
                                            label='file',
                                            key='ramdisk'))
        self.assertEqual(
            u_boot_media.parameters['dtb'],
            u_boot_media.get_namespace_data(action='download-action',
                                            label='file',
                                            key='dtb'))
        # use the base class name so that uboot-from-media can pick up the value reliably.
        self.assertEqual(
            u_boot_media.parameters['root_uuid'],
            u_boot_media.get_namespace_data(action='bootloader-from-media',
                                            label='uuid',
                                            key='root'))
        device = u_boot_media.get_namespace_data(action='storage-deploy',
                                                 label='u-boot',
                                                 key='device')
        self.assertIsNotNone(device)
        part_reference = '%s:%s' % (
            job.device['parameters']['media']['usb'][device]['device_id'],
            u_boot_media.parameters['boot_part'])
        self.assertEqual(
            part_reference,
            u_boot_media.get_namespace_data(action=u_boot_media.name,
                                            label='uuid',
                                            key='boot_part'))
        self.assertEqual(part_reference, "0:1")

    def test_xz_nfs(self):
        job = self.factory.create_bbb_job('sample_jobs/uboot-nfs.yaml')
        # this job won't validate as the .xz nfsrootfs URL is a fiction
        self.assertRaises(JobError, job.validate)
        tftp_deploy = [
            action for action in job.pipeline.actions
            if action.name == 'tftp-deploy'
        ][0]
        prepare = [
            action for action in tftp_deploy.internal_pipeline.actions
            if action.name == 'prepare-tftp-overlay'
        ][0]
        nfs = [
            action for action in prepare.internal_pipeline.actions
            if action.name == 'extract-nfsrootfs'
        ][0]
        self.assertIn('compression', nfs.parameters['nfsrootfs'])
        self.assertEqual(nfs.parameters['nfsrootfs']['compression'], 'xz')

    def test_prefix(self):
        job = self.factory.create_bbb_job('sample_jobs/bbb-skip-install.yaml')
        job.validate()
        tftp_deploy = [
            action for action in job.pipeline.actions
            if action.name == 'tftp-deploy'
        ][0]
        prepare = [
            action for action in tftp_deploy.internal_pipeline.actions
            if action.name == 'prepare-tftp-overlay'
        ][0]
        nfs = [
            action for action in prepare.internal_pipeline.actions
            if action.name == 'extract-nfsrootfs'
        ][0]
        self.assertIn('prefix', nfs.parameters['nfsrootfs'])
        self.assertEqual(nfs.parameters['nfsrootfs']['prefix'], 'jessie/')
        self.assertEqual(nfs.param_key, 'nfsrootfs')

    def test_zcu102(self):
        job = self.factory.create_zcu102_job('sample_jobs/zcu102-ramdisk.yaml')
        job.validate()
        self.assertEqual(job.pipeline.errors, [])
        description_ref = self.pipeline_reference('zcu102-ramdisk.yaml',
                                                  job=job)
        self.assertEqual(description_ref, job.pipeline.describe(False))

    def test_imx8m(self):
        job = self.factory.create_job('imx8m-01.jinja2',
                                      'sample_jobs/imx8m.yaml')
        self.assertIsNotNone(job)
        job.validate()
        self.assertEqual(job.pipeline.errors, [])
        description_ref = self.pipeline_reference('imx8m.yaml', job=job)
        self.assertEqual(description_ref, job.pipeline.describe(False))
        deploy = [
            action for action in job.pipeline.actions
            if action.name == 'fastboot-deploy'
        ][0]
        fastboot = [
            action for action in deploy.internal_pipeline.actions
            if action.name == 'uboot-enter-fastboot'
        ][0]
        bootloader = [
            action for action in fastboot.internal_pipeline.actions
            if action.name == 'bootloader-interrupt'
        ][0]
        self.assertEqual('u-boot', bootloader.method)
Ejemplo n.º 16
0
 def validate(self):
     super(ConnectTelnet, self).validate()
     self.errors = infrastructure_error('telnet')
     if 'prompts' not in self.parameters:
         self.errors = "Unable to identify test image prompts from parameters."
class TestDepthchargeAction(StdoutTestCase):
    def setUp(self):
        super(TestDepthchargeAction, self).setUp()
        self.factory = DepthchargeFactory()

    @unittest.skipIf(infrastructure_error('mkimage'), "mkimage not installed")
    def test_depthcharge(self):
        job = self.factory.create_jaq_job('sample_jobs/depthcharge.yaml')
        self.assertIsNotNone(job)

        description_ref = self.pipeline_reference('depthcharge.yaml', job=job)
        self.assertEqual(description_ref, job.pipeline.describe(False))

        self.assertIsNone(job.validate())
        self.assertEqual(job.device['device_type'], 'rk3288-veyron-jaq')

        self.assertEqual([action.name for action in job.pipeline.actions],
                         ['tftp-deploy', 'depthcharge-action', 'finalize'])

        tftp = [
            action for action in job.pipeline.actions
            if action.name == 'tftp-deploy'
        ][0]
        prep_overlay = [
            action for action in tftp.pipeline.actions
            if action.name == 'prepare-tftp-overlay'
        ][0]
        prep_kernel = [
            action for action in prep_overlay.pipeline.actions
            if action.name == 'prepare-kernel'
        ][0]
        self.assertEqual(
            [action.name for action in prep_kernel.internal_pipeline.actions],
            ['prepare-fit'])

        prep_fit = [
            action for action in prep_kernel.pipeline.actions
            if action.name == 'prepare-fit'
        ][0]
        params = {
            'arch': 'neo-gothic',
            'load_addr': '0x1234',
            'kernel': '/some/zImage',
            'dtb': '/some/file.dtb',
            'ramdisk': '/some/ramdisk.cpio',
            'fit_path': '/does/not/exist',
        }
        cmd_ref = 'mkimage \
-D "-I dts -O dtb -p 2048" \
-f auto \
-A {arch} \
-O linux \
-T kernel \
-C None \
-d {kernel} \
-a {load_addr} \
-b {dtb} \
-i {ramdisk} \
{fit_path}'.format(**params)
        cmd = prep_fit._make_mkimage_command(params)
        self.assertEqual(cmd_ref, ' '.join(cmd))

        depthcharge = [
            action for action in job.pipeline.actions
            if action.name == 'depthcharge-action'
        ][0]
        self.assertEqual(
            [action.name for action in depthcharge.internal_pipeline.actions],
            ['depthcharge-overlay', 'connect-device', 'depthcharge-retry'])

        retry = [
            action for action in depthcharge.internal_pipeline.actions
            if action.name == 'depthcharge-retry'
        ][0]
        self.assertEqual(
            [action.name for action in retry.internal_pipeline.actions],
            ['reset-device', 'depthcharge-start', 'bootloader-commands'])
Ejemplo n.º 18
0
class TestFastbootDeploy(StdoutTestCase):  # pylint: disable=too-many-public-methods
    def setUp(self):
        super().setUp()
        self.factory = FastBootFactory()
        self.job = self.factory.create_fastboot_job(
            'sample_jobs/fastboot.yaml')

    def test_deploy_job(self):
        self.assertEqual(self.job.pipeline.job, self.job)
        self.assertIsInstance(self.job.device['device_info'], list)
        for action in self.job.pipeline.actions:
            if isinstance(action, DeployAction):
                self.assertEqual(action.job, self.job)

    def test_pipeline(self):
        description_ref = self.pipeline_reference('fastboot.yaml')
        self.assertEqual(description_ref, self.job.pipeline.describe(False))

    @unittest.skipIf(
        infrastructure_error_multi_paths(['lxc-info', 'img2simg', 'simg2img']),
        "lxc or img2simg or simg2img not installed")
    def test_lxc_api(self):
        job = self.factory.create_hikey_job('sample_jobs/hikey-oe.yaml')
        description_ref = self.pipeline_reference('hikey-oe.yaml', job=job)
        job.validate()
        self.assertEqual(description_ref, job.pipeline.describe(False))
        self.assertIn(LxcProtocol.name,
                      [protocol.name for protocol in job.protocols])
        self.assertEqual(len(job.protocols), 1)
        self.assertIsNotNone(job.device.pre_os_command)
        select = [
            action for action in job.pipeline.actions
            if action.name == 'grub-sequence-action'
        ][0]
        self.assertIn(LxcProtocol.name, select.parameters.keys())
        self.assertIn('protocols', select.parameters.keys())
        self.assertIn(LxcProtocol.name, select.parameters['protocols'].keys())
        self.assertEqual(len(select.parameters['protocols'][LxcProtocol.name]),
                         1)
        lxc_active = any([
            protocol for protocol in job.protocols
            if protocol.name == LxcProtocol.name
        ])
        self.assertTrue(lxc_active)
        for calling in select.parameters['protocols'][LxcProtocol.name]:
            self.assertEqual(calling['action'], select.name)
            self.assertEqual(calling['request'], 'pre-os-command')
        deploy = [
            action for action in job.pipeline.actions
            if action.name == 'fastboot-deploy'
        ][0]
        self.assertIn(LxcProtocol.name, deploy.parameters.keys())
        self.assertIn('protocols', deploy.parameters.keys())
        self.assertIn(LxcProtocol.name, deploy.parameters['protocols'].keys())
        self.assertEqual(len(deploy.parameters['protocols'][LxcProtocol.name]),
                         1)
        for calling in deploy.parameters['protocols'][LxcProtocol.name]:
            self.assertEqual(calling['action'], deploy.name)
            self.assertEqual(calling['request'], 'pre-power-command')
        pair = ['pre-os-command', 'pre-power-command']
        action_list = {
            list(jaction.keys())[0]
            for jaction in job.parameters['actions']
        }
        block = job.parameters['actions']
        for action in action_list:
            for item in block:
                if action in item:
                    if 'protocols' in item[action]:
                        caller = (item[action]['protocols'][LxcProtocol.name])
                        for call in caller:
                            self.assertIn(call['request'], pair)

    @unittest.skipIf(infrastructure_error('lxc-info'),
                     "lxc-info not installed")
    def test_fastboot_lxc(self):
        job = self.factory.create_hikey_job('sample_jobs/hi6220-hikey.yaml')

        description_ref = self.pipeline_reference('hi6220-hikey.yaml', job=job)
        self.assertEqual(description_ref, job.pipeline.describe(False))
        self.assertEqual(
            job.device.pre_power_command,
            '/home/neil/lava-lab/shared/lab-scripts/usb_hub_control -u 12 -p 4000 -m sync'
        )
        lxc_deploy = [
            action for action in job.pipeline.actions
            if action.name == 'lxc-deploy'
        ][0]
        overlay = [
            action for action in lxc_deploy.internal_pipeline.actions
            if action.name == 'lava-overlay'
        ][0]
        testdef = [
            action for action in overlay.internal_pipeline.actions
            if action.name == 'test-definition'
        ][0]
        job.validate()
        self.assertEqual(
            {
                '1.8.4.20': '4_android-optee',
                '1.8.4.4': '0_get-adb-serial',
                '1.8.4.12': '2_android-busybox',
                '1.8.4.8': '1_android-meminfo',
                '1.8.4.16': '3_android-ping-dns'
            },
            testdef.get_namespace_data(action='test-runscript-overlay',
                                       label='test-runscript-overlay',
                                       key='testdef_levels'))
        for testdef in testdef.test_list[0]:
            self.assertEqual('git', testdef['from'])

    @unittest.skipIf(infrastructure_error('lxc-create'),
                     'lxc-create not installed')
    def test_validate(self):
        try:
            self.job.pipeline.validate_actions()
        except JobError as exc:
            self.fail(exc)
        for action in self.job.pipeline.actions:
            self.assertEqual([], action.errors)

    def test_overlay(self):
        overlay = None
        for action in self.job.pipeline.actions:
            self.assertIsNotNone(action.name)
            if isinstance(action, DeployAction):
                if action.parameters['namespace'] == 'tlxc':
                    overlay = [
                        action for action in action.pipeline.actions
                        if action.name == 'lava-overlay'
                    ][0]
        self.assertIsNotNone(overlay)
        # these tests require that lava-dispatcher itself is installed, not just running tests from a git clone
        self.assertTrue(os.path.exists(overlay.lava_test_dir))
        self.assertIsNot(overlay.lava_test_dir, '/')
        self.assertNotIn('lava_multi_node_test_dir', dir(overlay))
        self.assertNotIn('lava_multi_node_cache_file', dir(overlay))
        self.assertNotIn('lava_lmp_test_dir', dir(overlay))
        self.assertNotIn('lava_lmp_cache_file', dir(overlay))
        self.assertIsNotNone(
            overlay.parameters['deployment_data']['lava_test_results_dir'])
        self.assertIsNotNone(
            overlay.parameters['deployment_data']['lava_test_sh_cmd'])
        self.assertEqual(overlay.parameters['deployment_data']['distro'],
                         'debian')
        self.assertIsNotNone(overlay.parameters['deployment_data']
                             ['lava_test_results_part_attr'])
        self.assertIsNotNone(
            glob.glob(os.path.join(overlay.lava_test_dir, 'lava-*')))

    @unittest.skipIf(infrastructure_error('lxc-attach'),
                     'lxc-attach not installed')
    def test_boot(self):
        for action in self.job.pipeline.actions:
            if isinstance(action, BootAction):
                # get the action & populate it
                if action.parameters.get('namespace') == 'tlxc':
                    self.assertIn(action.parameters['method'],
                                  ['lxc', 'fastboot'])
                    self.assertEqual(action.parameters['prompts'],
                                     ['root@(.*):/#'])
                if action.parameters.get('namespace') == 'droid':
                    self.assertIn(action.parameters['method'],
                                  ['lxc', 'fastboot'])
                    self.assertEqual(action.parameters.get('prompts'), None)

    def test_testdefinitions(self):
        for action in self.job.pipeline.actions:
            if action.name == 'test':
                # get the action & populate it
                self.assertEqual(len(action.parameters['definitions']), 2)

    def test_udev_actions(self):
        self.factory = FastBootFactory()
        job = self.factory.create_db410c_job('sample_jobs/db410c.yaml')
        self.assertTrue(job.device.get('fastboot_via_uboot', True))
        description_ref = self.pipeline_reference('db410c.yaml', job=job)
        self.assertEqual(description_ref, job.pipeline.describe(False))
        boot = [
            action for action in job.pipeline.actions
            if action.name == 'fastboot-boot'
        ][0]

    def test_x15_job(self):
        self.factory = FastBootFactory()
        job = self.factory.create_x15_job('sample_jobs/x15.yaml')
        job.validate()
        description_ref = self.pipeline_reference('x15.yaml', job=job)
        self.assertEqual(description_ref, job.pipeline.describe(False))
        deploy = [
            action for action in job.pipeline.actions
            if action.name == 'fastboot-deploy'
        ][0]
        enter = [
            action for action in deploy.internal_pipeline.actions
            if action.name == 'uboot-enter-fastboot'
        ][0]
        interrupt = [
            action for action in enter.internal_pipeline.actions
            if action.name == 'bootloader-interrupt'
        ][0]
        self.assertTrue(interrupt.needs_interrupt)
        self.assertIsInstance(interrupt.params, dict)
        self.assertNotEqual(interrupt.params, {})
        self.assertIn('mkimage_arch', interrupt.params)
        self.assertIn('interrupt_prompt', interrupt.params)
        boot = [
            action for action in job.pipeline.actions
            if action.name == 'fastboot-boot'
        ][0]
        enter = [
            action for action in boot.internal_pipeline.actions
            if action.name == 'uboot-enter-fastboot'
        ][0]
        interrupt = [
            action for action in enter.internal_pipeline.actions
            if action.name == 'bootloader-interrupt'
        ][0]
        self.assertIsInstance(interrupt.params, dict)
        self.assertNotEqual(interrupt.params, {})
        self.assertIn('mkimage_arch', interrupt.params)
        self.assertIn('interrupt_prompt', interrupt.params)
        self.assertTrue(interrupt.needs_interrupt)
        autologin = [
            action for action in boot.internal_pipeline.actions
            if action.name == 'auto-login-action'
        ][0]
        self.assertTrue(autologin.booting)
        self.assertEqual(set(autologin.parameters.get('prompts')),
                         set(['root@(.*):/#', 'shell@am57xevm:/']))
        self.assertIsNone(autologin.parameters.get('boot_message'))

    def test_nexus5x_job(self):
        self.factory = FastBootFactory()
        job = self.factory.create_nexus5x_job('sample_jobs/nexus5x.yaml')
        # do not run job.validate() - urls no longer exist.
        description_ref = self.pipeline_reference('nexus5x.yaml', job=job)
        self.assertEqual(description_ref, job.pipeline.describe(False))

    def test_pixel_job(self):
        self.factory = FastBootFactory()
        job = self.factory.create_pixel_job('sample_jobs/pixel.yaml')
        # do not run job.validate() - urls no longer exist.
        description_ref = self.pipeline_reference('pixel.yaml', job=job)
        self.assertEqual(description_ref, job.pipeline.describe(False))

    def test_flash_cmds_order(self):
        self.factory = FastBootFactory()
        job = self.factory.create_db410c_job('sample_jobs/db410c.yaml')
        # The expected_flash_cmds list ensures the following:
        # 1. Order of flash commands.
        # 2. Number / Count of flash commands.
        # 3. 'cdt' flash command is not part of draganboard-410c's device
        #    dictionary, but ensure that it gets added in the final flash
        #    commands list.
        expected_flash_cmds = [
            'partition', 'hyp', 'rpm', 'sbl1', 'tz', 'aboot', 'cdt', 'boot',
            'rootfs'
        ]
        flash_order = None
        for action in job.pipeline.actions:
            self.assertIsNotNone(action.name)
            if isinstance(action, DeployAction):
                if action.name == 'fastboot-deploy':
                    flash_order = [
                        action for action in action.pipeline.actions
                        if action.name == 'fastboot-flash-order-action'
                    ][0]
                    flash_action = [
                        action for action in flash_order.pipeline.actions
                        if action.name == 'fastboot-flash-action'
                    ][0]
                    flash_cmds = [
                        action.command
                        for action in flash_order.pipeline.actions
                        if action.name == 'fastboot-flash-action'
                    ]
        self.assertIsNotNone(flash_order)
        self.assertIsNotNone(flash_action)
        self.assertEqual(flash_action.timeout_exception, InfrastructureError)
        self.assertIsInstance(flash_order, FastbootFlashOrderAction)
        self.assertEqual(expected_flash_cmds, flash_cmds)

    def test_hikey960_fastboot(self):
        job = self.factory.create_hikey960_job(
            'sample_jobs/hikey960-aosp.yaml')
        self.assertIsNotNone(job)
        job.validate()
        description_ref = self.pipeline_reference('hi960-aosp-efi.yaml',
                                                  job=job)
        self.assertEqual(description_ref, job.pipeline.describe(False))
        flash_order = None
        expected_flash_cmds = ['boot', 'system', 'userdata', 'cache']
        for action in job.pipeline.actions:
            self.assertIsNotNone(action.name)
            if isinstance(action, DeployAction):
                if action.name == 'fastboot-deploy':
                    flash_order = [
                        action for action in action.pipeline.actions
                        if action.name == 'fastboot-flash-order-action'
                    ][0]
                    flash_cmds = [
                        action.command
                        for action in flash_order.pipeline.actions
                        if action.name == 'fastboot-flash-action'
                    ]
        self.assertIsNotNone(flash_order)
        self.assertIsInstance(flash_order, FastbootFlashOrderAction)
        self.assertEqual(expected_flash_cmds, flash_cmds)

    def test_fastboot_minus_lxc(self):
        # Do not run job.validate() since it will require some android tools
        # such as fastboot, adb, etc. to be installed.
        job = self.factory.create_fastboot_job(
            'sample_jobs/nexus4-minus-lxc.yaml')
        description_ref = self.pipeline_reference('nexus4-minus-lxc.yaml',
                                                  job=job)
        self.assertEqual(description_ref, job.pipeline.describe(False))
        # There shouldn't be any lxc defined
        lxc_name = is_lxc_requested(job)
        self.assertEqual(lxc_name, False)
        deploy = [
            action for action in job.pipeline.actions
            if action.name == 'fastboot-deploy'
        ][0]
        # No lxc requested, hence lxc_cmd_prefix is an empty list
        self.assertEqual([], lxc_cmd_prefix(job))

    def test_db410c_minus_lxc(self):
        # Do not run job.validate() since it will require some android tools
        # such as fastboot, adb, etc. to be installed.
        job = self.factory.create_db410c_job(
            'sample_jobs/db410c-minus-lxc.yaml')
        description_ref = self.pipeline_reference('db410c-minus-lxc.yaml',
                                                  job=job)
        self.assertEqual(description_ref, job.pipeline.describe(False))
        # There shouldn't be any lxc defined
        lxc_name = is_lxc_requested(job)
        self.assertEqual(lxc_name, False)
        deploy = [
            action for action in job.pipeline.actions
            if action.name == 'fastboot-deploy'
        ][0]
        # No lxc requested, hence lxc_cmd_prefix is an empty list
        self.assertEqual([], lxc_cmd_prefix(job))

    def test_fastboot_boot_commands(self):
        job = self.factory.create_job('imx8m-01.jinja2',
                                      'sample_jobs/imx8m.yaml')
        boot = [
            action for action in job.pipeline.actions
            if action.name == 'fastboot-boot'
        ][0]
        self.assertIn('commands', boot.parameters)
        self.assertEqual('130651d6f060954b',
                         job.device['fastboot_serial_number'])
        self.assertIsInstance(boot.parameters['commands'], list)
Ejemplo n.º 19
0
        git = vcs.GitHelper('git')
        self.assertRaises(InfrastructureError, git.clone, 'foo.bar', True,
                          'badhash')

    def test_branch(self):
        git = vcs.GitHelper('git')
        self.assertEqual(git.clone('git.clone1', branch='testing'), 'f2589a1b7f0cfc30ad6303433ba4d5db1a542c2d')
        self.assertTrue(os.path.exists(os.path.join(self.tmpdir, "git.clone1", ".git")))

    def test_no_history(self):
        git = vcs.GitHelper('git')
        self.assertEqual(git.clone('git.clone1', history=False), 'a7af835862da0e0592eeeac901b90e8de2cf5b67')
        self.assertFalse(os.path.exists(os.path.join(self.tmpdir, "git.clone1", ".git")))


@unittest.skipIf(infrastructure_error('bzr'), "bzr not installed")
class TestBzr(StdoutTestCase):  # pylint: disable=too-many-public-methods

    def setUp(self):
        super(TestBzr, self).setUp()
        self.cwd = os.getcwd()

        # Go into a temp dirctory
        self.tmpdir = tempfile.mkdtemp()
        os.chdir(self.tmpdir)
        self.env = {'BZR_HOME': self.tmpdir, 'BZR_LOG': self.tmpdir}

        # Create a Git repository with two commits
        subprocess.check_output(['bzr', 'init', 'repo'], env=self.env, stderr=subprocess.STDOUT)
        os.chdir('repo')
        with open('test.txt', 'w') as datafile:
Ejemplo n.º 20
0
class TestDeviceEnvironment(StdoutTestCase):  # pylint: disable=too-many-public-methods
    """
    Test parsing of device environment support
    """
    def test_empty_device_environment(self):
        factory = Factory()
        data = None
        job_parser = JobParser()
        (rendered, _) = factory.create_device('bbb-01.jinja2')
        device = NewDevice(yaml.load(rendered))
        sample_job_file = os.path.join(os.path.dirname(__file__),
                                       'sample_jobs/uboot-ramdisk.yaml')
        with open(sample_job_file) as sample_job_data:
            job = job_parser.parse(sample_job_data,
                                   device,
                                   4212,
                                   None,
                                   "",
                                   env_dut=data)
        self.assertEqual(job.parameters['env_dut'], None)

    @unittest.skipIf(infrastructure_error('mkimage'),
                     "u-boot-tools not installed")
    def test_device_environment_validity(self):  # pylint: disable=invalid-name
        """
        Use non-YAML syntax a bit like existing device config syntax.
        Ensure this syntax is picked up as invalid.
        """
        data = """
# YAML syntax.
overrides:
 DEBEMAIL = "*****@*****.**"
 DEBFULLNAME: "Neil Williams"
        """
        factory = Factory()
        job_parser = JobParser()
        (rendered, _) = factory.create_device('bbb-01.jinja2')
        device = NewDevice(yaml.load(rendered))
        sample_job_file = os.path.join(os.path.dirname(__file__),
                                       'sample_jobs/uboot-ramdisk.yaml')
        with open(sample_job_file) as sample_job_data:
            job = job_parser.parse(sample_job_data,
                                   device,
                                   4212,
                                   None,
                                   "",
                                   env_dut=data)
        job.logger = DummyLogger()
        self.assertEqual(job.parameters['env_dut'], data)
        with self.assertRaises(JobError):
            job.validate()

    @unittest.skipIf(infrastructure_error('mkimage'),
                     "u-boot-tools not installed")
    def test_device_environment(self):
        data = """
# YAML syntax.
overrides:
 DEBEMAIL: "*****@*****.**"
 DEBFULLNAME: "Neil Williams"
        """
        factory = Factory()
        job_parser = JobParser()
        (rendered, _) = factory.create_device('bbb-01.jinja2')
        device = NewDevice(yaml.load(rendered))
        sample_job_file = os.path.join(os.path.dirname(__file__),
                                       'sample_jobs/uboot-ramdisk.yaml')
        with open(sample_job_file) as sample_job_data:
            job = job_parser.parse(sample_job_data,
                                   device,
                                   4212,
                                   None,
                                   "",
                                   env_dut=data)
        job.logger = DummyLogger()
        self.assertEqual(job.parameters['env_dut'], data)
        job.validate()
        boot_actions = [
            action.internal_pipeline.actions for action in job.pipeline.actions
            if action.name == 'uboot-action'
        ][0]
        retry = [
            action for action in boot_actions if action.name == 'uboot-retry'
        ][0]
        boot_env = [
            action for action in retry.internal_pipeline.actions
            if action.name == 'export-device-env'
        ][0]
        found = False
        for line in boot_env.env:
            if 'DEBFULLNAME' in line:
                found = True
                # assert that the string containing a space still contains that space and is quoted
                self.assertIn('\\\'Neil Williams\\\'', line)
        self.assertTrue(found)
Ejemplo n.º 21
0
class TestDefinitionParams(StdoutTestCase):  # pylint: disable=too-many-public-methods
    def setUp(self):
        super().setUp()
        self.factory = Factory()
        self.job = self.factory.create_kvm_job('sample_jobs/kvm-params.yaml')

    def test_job_without_tests(self):
        boot = finalize = None
        allow_missing_path(self.job.pipeline.validate_actions, self,
                           'qemu-system-x86_64')
        deploy = [
            action for action in self.job.pipeline.actions
            if action.name == 'deployimages'
        ][0]
        overlay = [
            action for action in deploy.internal_pipeline.actions
            if action.name == 'lava-overlay'
        ][0]
        testdef = [
            action for action in overlay.internal_pipeline.actions
            if action.name == 'test-definition'
        ][0]
        for action in self.job.pipeline.actions:
            self.assertNotIsInstance(action, TestDefinitionAction)
            self.assertNotIsInstance(action, OverlayAction)
            boot = self.job.pipeline.actions[1]
            finalize = self.job.pipeline.actions[3]
        self.assertIsInstance(overlay, OverlayAction)
        self.assertIsInstance(testdef, TestDefinitionAction)
        test = testdef.internal_pipeline.actions[1]
        install = testdef.internal_pipeline.actions[2]
        runsh = testdef.internal_pipeline.actions[3]
        self.assertIsInstance(deploy, DeployImagesAction)
        self.assertIsInstance(boot, BootAction)
        self.assertIsInstance(finalize, FinalizeAction)
        self.assertEqual(len(self.job.pipeline.actions),
                         4)  # deploy, boot, test, finalize
        self.assertNotIn('test_params', testdef.parameters)
        self.assertIsInstance(install, TestInstallAction)
        self.assertIsInstance(runsh, TestRunnerAction)
        self.assertIsNot(list(install.parameters.items()), [])
        testdef = {
            'params': {
                'VARIABLE_NAME_1': 'value_1',
                'VARIABLE_NAME_2': 'value_2'
            }
        }
        content = test.handle_parameters(testdef)
        self.assertEqual(
            set(content), {
                '###default parameters from test definition###\n',
                "VARIABLE_NAME_1='value_1'\n", "VARIABLE_NAME_2='value_2'\n",
                '######\n', '###test parameters from job submission###\n',
                "VARIABLE_NAME_1='eth2'\n", "VARIABLE_NAME_2='wlan0'\n",
                '######\n'
            })
        testdef = {
            'parameters': {
                'VARIABLE_NAME_1': 'value_1',
                'VARIABLE_NAME_2': 'value_2'
            }
        }
        content = test.handle_parameters(testdef)
        self.assertEqual(
            set(content), {
                '###default parameters from test definition###\n',
                "VARIABLE_NAME_1='value_1'\n", "VARIABLE_NAME_2='value_2'\n",
                '######\n', '###test parameters from job submission###\n',
                "VARIABLE_NAME_1='eth2'\n", "VARIABLE_NAME_2='wlan0'\n",
                '######\n'
            })

    @unittest.skipIf(infrastructure_error('git'), 'git not installed')
    def test_install_repos(self):
        job = self.factory.create_kvm_job('sample_jobs/kvm-install.yaml')
        allow_missing_path(self.job.pipeline.validate_actions, self,
                           'qemu-system-x86_64')
        deploy = [
            action for action in job.pipeline.actions
            if action.name == 'deployimages'
        ][0]
        overlay = [
            action for action in deploy.internal_pipeline.actions
            if action.name == 'lava-overlay'
        ][0]
        testdef = [
            action for action in overlay.internal_pipeline.actions
            if action.name == 'test-definition'
        ][0]
        test_install = [
            action for action in testdef.internal_pipeline.actions
            if action.name == 'test-install-overlay'
        ][0]
        self.assertIsNotNone(test_install)
        yaml_file = os.path.join(os.path.dirname(__file__),
                                 './testdefs/install.yaml')
        self.assertTrue(os.path.exists(yaml_file))
        with open(yaml_file, 'r') as test_file:
            testdef = yaml.safe_load(test_file)
        repos = testdef['install'].get('git-repos', [])
        self.assertIsNotNone(repos)
        self.assertIsInstance(repos, list)
        for repo in repos:
            self.assertIsNotNone(repo)
        runner_path = tempfile.mkdtemp()
        test_install.install_git_repos(testdef, runner_path)
        shutil.rmtree(runner_path)
Ejemplo n.º 22
0
class TestGrubAction(StdoutTestCase):  # pylint: disable=too-many-public-methods
    def setUp(self):
        super().setUp()
        self.factory = GrubFactory()

    @unittest.skipIf(infrastructure_error('mkimage'),
                     "u-boot-tools not installed")
    def test_simulated_action(self):
        job = self.factory.create_job('d02-01.jinja2',
                                      'sample_jobs/grub-ramdisk.yaml')
        self.assertIsNotNone(job)

        # uboot and uboot-ramdisk have the same pipeline structure
        description_ref = self.pipeline_reference('grub.yaml', job=job)
        self.assertEqual(description_ref, job.pipeline.describe(False))

        self.assertIsNone(job.validate())

    def test_tftp_pipeline(self):
        job = self.factory.create_job('d02-01.jinja2',
                                      'sample_jobs/grub-ramdisk.yaml')
        self.assertEqual(
            [action.name for action in job.pipeline.actions],
            ['tftp-deploy', 'grub-main-action', 'lava-test-retry', 'finalize'])
        tftp = [
            action for action in job.pipeline.actions
            if action.name == 'tftp-deploy'
        ][0]
        self.assertTrue(
            tftp.get_namespace_data(action=tftp.name,
                                    label='tftp',
                                    key='ramdisk'))
        self.assertIsNotNone(tftp.internal_pipeline)
        self.assertEqual(
            [action.name for action in tftp.internal_pipeline.actions], [
                'download-retry', 'download-retry', 'download-retry',
                'prepare-tftp-overlay', 'lxc-create-udev-rule-action',
                'deploy-device-env'
            ])
        self.assertIn('ramdisk', [
            action.key for action in tftp.internal_pipeline.actions
            if hasattr(action, 'key')
        ])
        self.assertIn('kernel', [
            action.key for action in tftp.internal_pipeline.actions
            if hasattr(action, 'key')
        ])
        self.assertIn('dtb', [
            action.key for action in tftp.internal_pipeline.actions
            if hasattr(action, 'key')
        ])
        self.assertNotIn('=', tftpd_dir())

    def test_device_d02(self):
        job = self.factory.create_job('d02-01.jinja2',
                                      'sample_jobs/grub-ramdisk.yaml')
        self.assertNotIn('connect', job.device['commands'])
        self.assertEqual(
            job.device['commands']['connections']['uart0']['connect'],
            'telnet ratchet 7003')
        self.assertEqual(job.device['commands'].get('interrupt', ' '), ' ')
        methods = job.device['actions']['boot']['methods']
        self.assertIn('grub', methods)
        self.assertEqual(
            methods['grub']['parameters'].get('bootloader_prompt'), 'grub>')

    @unittest.skipIf(infrastructure_error('mkimage'),
                     "u-boot-tools not installed")
    def test_grub_action(self):
        job = self.factory.create_job('d02-01.jinja2',
                                      'sample_jobs/grub-ramdisk.yaml')
        job.validate()
        self.assertEqual(job.pipeline.errors, [])
        self.assertIn('grub', job.device['actions']['boot']['methods'])
        params = job.device['actions']['boot']['methods']['grub']['parameters']
        boot_message = params.get(
            'boot_message', job.device.get_constant('kernel-start-message'))
        self.assertIsNotNone(boot_message)
        for action in job.pipeline.actions:
            action.validate()
            if isinstance(action, GrubMainAction):
                self.assertIn('method', action.parameters)
                self.assertEqual('grub', action.parameters['method'])
            if isinstance(action, TftpAction):
                self.assertIn('ramdisk', action.parameters)
                self.assertIn('kernel', action.parameters)
                self.assertIn('to', action.parameters)
                self.assertEqual('tftp', action.parameters['to'])
            if isinstance(action, BootloaderInterruptAction):
                self.assertFalse(action.interrupt_newline)
            self.assertTrue(action.valid)

    def test_overlay_action(self):  # pylint: disable=too-many-locals
        parameters = {
            'device_type': 'd02',
            'job_name': 'grub-standard-ramdisk',
            'job_timeout': '15m',
            'action_timeout': '5m',
            'priority': 'medium',
            'actions': {
                'boot': {
                    'method': 'grub',
                    'commands': 'ramdisk',
                    'prompts': ['linaro-test', 'root@debian:~#']
                },
                'deploy': {
                    'ramdisk': 'initrd.gz',
                    'kernel': 'zImage',
                    'dtb': 'broken.dtb'
                }
            }
        }
        (rendered, _) = self.factory.create_device('d02-01.jinja2')
        device = NewDevice(yaml.safe_load(rendered))
        job = Job(4212, parameters, None)
        job.device = device
        pipeline = Pipeline(job=job, parameters=parameters['actions']['boot'])
        job.pipeline = pipeline
        overlay = BootloaderCommandOverlay()
        pipeline.add_action(overlay)
        ip_addr = dispatcher_ip(None)
        parsed = []
        kernel = parameters['actions']['deploy']['kernel']
        ramdisk = parameters['actions']['deploy']['ramdisk']
        dtb = parameters['actions']['deploy']['dtb']

        substitution_dictionary = {
            '{SERVER_IP}': ip_addr,
            # the addresses need to be hexadecimal
            '{RAMDISK}': ramdisk,
            '{KERNEL}': kernel,
            '{DTB}': dtb
        }
        params = device['actions']['boot']['methods']
        commands = params['grub']['ramdisk']['commands']
        self.assertIn('net_bootp', commands)
        self.assertIn(
            "linux (tftp,{SERVER_IP})/{KERNEL} console=ttyS0,115200 earlycon=uart8250,mmio32,0x80300000 root=/dev/ram0 ip=dhcp",
            commands)
        self.assertIn('initrd (tftp,{SERVER_IP})/{RAMDISK}', commands)
        self.assertIn('devicetree (tftp,{SERVER_IP})/{DTB}', commands)

        params['grub']['ramdisk']['commands'] = substitute(
            params['grub']['ramdisk']['commands'], substitution_dictionary)
        substituted_commands = params['grub']['ramdisk']['commands']
        self.assertIs(type(substituted_commands), list)
        self.assertIn('net_bootp', substituted_commands)
        self.assertNotIn(
            "linux (tftp,{SERVER_IP})/{KERNEL} console=ttyS0,115200 earlycon=uart8250,mmio32,0x80300000 root=/dev/ram0 ip=dhcp",
            substituted_commands)
        self.assertIn(
            "linux (tftp,%s)/%s console=ttyS0,115200 earlycon=uart8250,mmio32,0x80300000 root=/dev/ram0 ip=dhcp"
            % (ip_addr, kernel), substituted_commands)
        self.assertNotIn('initrd (tftp,{SERVER_IP})/{RAMDISK}', parsed)
        self.assertNotIn('devicetree (tftp,{SERVER_IP})/{DTB}', parsed)

    def test_download_action(self):
        job = self.factory.create_job('d02-01.jinja2',
                                      'sample_jobs/grub-nfs.yaml')
        for action in job.pipeline.actions:
            action.validate()
            if not action.valid:
                raise JobError(action.errors)
            self.assertTrue(action.valid)
        job.validate()
        self.assertEqual(job.pipeline.errors, [])
        deploy = None
        overlay = None
        extract = None
        for action in job.pipeline.actions:
            if action.name == 'tftp-deploy':
                deploy = action
        if deploy:
            for action in deploy.internal_pipeline.actions:
                if action.name == 'prepare-tftp-overlay':
                    overlay = action
        if overlay:
            for action in overlay.internal_pipeline.actions:
                if action.name == 'extract-nfsrootfs':
                    extract = action
        test_dir = overlay.get_namespace_data(action='test',
                                              label='results',
                                              key='lava_test_results_dir')
        self.assertIsNotNone(test_dir)
        self.assertIn('/lava-', test_dir)
        self.assertIsNotNone(extract)
        self.assertEqual(extract.timeout.duration, 600)

    def test_reset_actions(self):
        job = self.factory.create_job('d02-01.jinja2',
                                      'sample_jobs/grub-ramdisk.yaml')
        grub_action = None
        for action in job.pipeline.actions:
            action.validate()
            self.assertTrue(action.valid)
            if action.name == 'grub-main-action':
                grub_action = action
        names = [
            r_action.name for r_action in grub_action.internal_pipeline.actions
        ]
        self.assertIn('connect-device', names)
        self.assertIn('reset-device', names)
        self.assertIn('bootloader-interrupt', names)
        self.assertIn('expect-shell-connection', names)
        self.assertIn('bootloader-commands', names)

    def test_grub_with_monitor(self):
        job = self.factory.create_job('d02-01.jinja2',
                                      'sample_jobs/grub-ramdisk-monitor.yaml')
        job.validate()
        description_ref = self.pipeline_reference('grub-ramdisk-monitor.yaml',
                                                  job=job)
        self.assertEqual(description_ref, job.pipeline.describe(False))

    def test_grub_via_efi(self):
        job = self.factory.create_mustang_job(
            'sample_jobs/mustang-grub-efi-nfs.yaml')
        self.assertIsNotNone(job)
        job.validate()
        description_ref = self.pipeline_reference('mustang-grub-efi-nfs.yaml',
                                                  job=job)
        self.assertEqual(description_ref, job.pipeline.describe(False))
        grub = [
            action for action in job.pipeline.actions
            if action.name == 'grub-main-action'
        ][0]
        menu = [
            action for action in grub.internal_pipeline.actions
            if action.name == 'uefi-menu-interrupt'
        ][0]
        self.assertIn('item_class', menu.params)
        grub_efi = [
            action for action in grub.internal_pipeline.actions
            if action.name == 'grub-efi-menu-selector'
        ][0]
        self.assertEqual('pxe-grub', grub_efi.commands)

    def test_hikey_grub_efi(self):
        job = self.factory.create_hikey_job('sample_jobs/hikey-grub-lxc.yaml')
        self.assertIsNotNone(job)
        job.validate()
        description_ref = self.pipeline_reference('hikey-grub-efi.yaml',
                                                  job=job)
        self.assertEqual(description_ref, job.pipeline.describe(False))

    @unittest.skipIf(
        infrastructure_error_multi_paths(['lxc-info', 'img2simg', 'simg2img']),
        "lxc or img2simg or simg2img not installed")
    def test_hikey_uart(self):
        job = self.factory.create_hikey_job('sample_jobs/hikey-console.yaml')
        self.assertIsNotNone(job)
        job.validate()
        description_ref = self.pipeline_reference('hikey-console.yaml',
                                                  job=job)
        self.assertEqual(description_ref, job.pipeline.describe(False))
        console = [
            action for action in job.pipeline.actions
            if action.name == 'secondary-shell-action'
        ][0]
        command = [
            action for action in console.internal_pipeline.actions
            if action.name == 'connect-shell'
        ][0]
        self.assertEqual('isolation', command.parameters['namespace'])
        self.assertEqual('uart0', command.hardware)
        self.assertIn('connections', job.device['commands'])
        uart = job.device['commands']['connections'][
            command.hardware]['connect']
        self.assertIn(command.command, uart)
        self.assertEqual('telnet localhost 4002', uart)
        tshells = [
            action for action in job.pipeline.actions
            if action.name == 'lava-test-retry'
        ]
        for shell in tshells:
            cn = shell.parameters.get('connection-namespace')
            if cn:
                self.assertEqual(shell.parameters['namespace'], 'hikey-oe')
                self.assertNotEqual(shell.parameters['namespace'], 'isolation')
                self.assertNotEqual(shell.parameters['namespace'], 'tlxc')
                self.assertEqual(shell.parameters['connection-namespace'],
                                 'isolation')
                retry = [action
                         for action in shell.internal_pipeline.actions][0]
                self.assertEqual(retry.parameters['connection-namespace'],
                                 'isolation')
            else:
                self.assertNotEqual(shell.parameters['namespace'], 'hikey-oe')
                self.assertNotEqual(shell.parameters['namespace'], 'isolation')
                self.assertEqual(shell.parameters['namespace'], 'tlxc')
                self.assertNotIn('connection-namespace',
                                 shell.parameters.keys())
        menu = [
            action for action in job.pipeline.actions
            if action.name == 'grub-sequence-action'
        ][0]
        autologin = [
            action for action in menu.internal_pipeline.actions
            if action.name == 'auto-login-action'
        ][0]
        self.assertIsNone(autologin.params)
        self.assertEqual(['login:'******'prompts'))
        menu = [
            action for action in job.pipeline.actions
            if action.name == 'secondary-shell-action'
        ][0]
        autologin = [
            action for action in menu.internal_pipeline.actions
            if action.name == 'auto-login-action'
        ][0]
        self.assertIsNotNone(autologin.parameters)
        self.assertIn('test_info', autologin.parameters)
        self.assertIn('isolation', autologin.parameters['test_info'])
        self.assertIn('hikey-oe', autologin.parameters['test_info'])
        self.assertIn('tlxc', autologin.parameters['test_info'])

    def test_hikey960_grub(self):
        job = self.factory.create_hikey960_job('sample_jobs/hikey960-oe.yaml')
        self.assertIsNotNone(job)
        job.validate()
        description_ref = self.pipeline_reference('hi960-grub-efi.yaml',
                                                  job=job)
        self.assertEqual(description_ref, job.pipeline.describe(False))
        deploy = [
            action for action in job.pipeline.actions
            if action.name == 'fastboot-deploy'
        ][0]
        flash_ord = [
            action for action in deploy.internal_pipeline.actions
            if action.name == 'fastboot-flash-order-action'
        ][0]
        flash = [
            action for action in flash_ord.internal_pipeline.actions
            if action.name == 'fastboot-flash-action'
        ][0]
        self.assertIsNotNone(flash.interrupt_prompt)
        self.assertEqual('Android Fastboot mode', flash.interrupt_prompt)
        self.assertIsNotNone(flash.interrupt_string)
        self.assertEqual(' ', flash.interrupt_string)
        grub_seq = [
            action for action in job.pipeline.actions
            if action.name == 'grub-sequence-action'
        ][0]
        self.assertIsNotNone(grub_seq)
        wait = [
            action for action in grub_seq.internal_pipeline.actions
            if action.name == 'wait-fastboot-interrupt'
        ][0]
        self.assertIsNotNone(wait)
        login = [
            action for action in grub_seq.internal_pipeline.actions
            if action.name == 'auto-login-action'
        ][0]
        self.assertIsNotNone(login)

    def test_synquacer_grub(self):
        job = self.factory.create_job('synquacer-dtb-01.jinja2',
                                      'sample_jobs/synquacer-dtb.yaml')
        self.assertIsNotNone(job)
        job.validate()
        description_ref = self.pipeline_reference('synquacer_dtb.yaml',
                                                  job=job)
        self.assertEqual(description_ref, job.pipeline.describe(False))
Ejemplo n.º 23
0
def allow_missing_path(function, testcase, path):
    try:
        function()
    except InfrastructureError as exc:
        if not infrastructure_error(path):
            testcase.fail(exc)