示例#1
0
    def validate(self):
        super(NbdAction, self).validate()
        if 'kernel' not in self.parameters:
            self.errors = "%s needs a kernel to deploy" % self.name
        if not self.valid:
            return
        if 'nbdroot' not in self.parameters:
            self.errors = "NBD deployment needs a 'nbdroot' parameter"
        if 'initrd' not in self.parameters:
            self.errors = "NBD deployment needs an 'initrd' parameter"
        # we cannot work with these when using nbd
        if 'nfsrootfs' in self.parameters or 'nfs_url' in self.parameters:
            self.errors = "nfsrootfs or nfs_url cannot be used with NBD deployment, use a e.g. ext3/4 filesystem as 'nbdroot=' parameter"
        if 'ramdisk' in self.parameters:
            self.errors = "ramdisk cannot be used with NBD deployment, use a e.g. ext3/4 filesystem as 'initrd' parameter"

        # Extract the 3 last path elements. See action.mkdtemp()
        suffix = os.path.join(*self.tftp_dir.split('/')[-2:])
        self.set_namespace_data(action="tftp-deploy",
                                label='tftp',
                                key='suffix',
                                value=suffix)
        # we need tftp _and_ xnbd-server
        self.errors = infrastructure_error('in.tftpd')
        self.errors = infrastructure_error('xnbd-server')

        # Check that the tmp directory is in the nbdd_dir or in /tmp for the
        # unit tests
        tftpd_directory = os.path.realpath(tftpd_dir())
        tftp_dir = os.path.realpath(self.tftp_dir)
        tmp_dir = tempfile.gettempdir()
        if not tftp_dir.startswith(tftpd_directory) and \
           not tftp_dir.startswith(tmp_dir):
            self.errors = "tftpd directory is not configured correctly, see /etc/default/tftpd-hpa"
示例#2
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
示例#3
0
class TestLxcDeploy(StdoutTestCase):  # pylint: disable=too-many-public-methods
    def setUp(self):
        super(TestLxcDeploy, self).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)
示例#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)
示例#5
0
 def validate(self):
     super(UBootPrepareKernelAction, self).validate()
     if 'parameters' not in self.job.device['actions']['deploy']:
         return
     self.params = self.job.device['actions']['deploy']['parameters']
     self.kernel_type = self.get_namespace_data(action='download-action',
                                                label='type',
                                                key='kernel')
     self.bootcommand = None
     if 'parameters' not in self.job.device:
         if self.kernel_type:
             self.errors = "Kernel boot type is not supported by this device."
     if self.kernel_type:
         self.set_namespace_data(action=self.name,
                                 label='prepared-kernel',
                                 key='exists',
                                 value=True)
         self.bootcommand = map_kernel_uboot(
             self.kernel_type, self.job.device.get('parameters', None))
         self.kernel_type = str(self.kernel_type).lower()
         if self.bootcommand not in self.job.device['parameters']:
             self.errors = "Requested kernel boot type '%s' is not supported by this device." % self.bootcommand
         if self.kernel_type == "bootm" or self.kernel_type == "bootz" or self.kernel_type == "booti":
             self.errors = "booti, bootm and bootz are deprecated, please use 'image', 'uimage' or 'zimage'"
         self.errors = infrastructure_error('mkimage')
         if 'mkimage_arch' not in self.params:
             self.errors = "Missing architecture for uboot mkimage support (mkimage_arch in u-boot parameters)"
         if self.bootcommand == 'bootm' and self.kernel_type != 'uimage':
             self.mkimage_conversion = True
     self.set_namespace_data(action='uboot-prepare-kernel',
                             label='bootcommand',
                             key='bootcommand',
                             value=self.bootcommand)
示例#6
0
    def run(self, connection, max_end_time, args=None):
        connection = super(XnbdAction, self).run(connection, max_end_time,
                                                 args)
        self.logger.debug("%s: starting xnbd-server", self.name)
        # pull from parameters - as previously set
        self.nbd_server_port = self.parameters['lava-xnbd']['port']
        self.nbd_server_ip = self.parameters['lava-xnbd']['ip']
        self.nbd_root = self.parameters['lava-xnbd']['nbdroot']
        self.logger.debug("NBD-IP: %s, NBD-PORT: %s, NBD-ROOT: %s",
                          self.nbd_server_ip, self.nbd_server_port,
                          self.nbd_root)
        nbd_cmd = [
            'xnbd-server', '--logpath',
            '/tmp/xnbd.log.%s' % self.nbd_server_port, '--daemon', '--target',
            '--lport',
            '%s' % self.nbd_server_port,
            '%s/%s' % (os.path.realpath(tftpd_dir()), self.nbd_root)
        ]
        command_output = self.run_command(nbd_cmd, allow_fail=False)

        if command_output and 'error' in command_output:
            self.errors = infrastructure_error('xnbd-server: %s' %
                                               command_output)
        self.logger.debug("%s: starting xnbd-server done", self.name)
        return connection
示例#7
0
    def validate(self):
        super(DockerAction, self).validate()
        err = infrastructure_error("docker")
        if err is not None:
            self.errors = err
            return

        # Print docker version
        try:
            out = subprocess.check_output(
                ["docker", "version", "-f", "{{.Server.Version}}"])
            out = out.decode("utf-8").strip("\n")
            self.logger.debug("docker server, installed at version: %s", out)
            out = subprocess.check_output(
                ["docker", "version", "-f", "{{.Client.Version}}"])
            out = out.decode("utf-8").strip("\n")
            self.logger.debug("docker client, installed at version: %s", out)
        except subprocess.CalledProcessError as exc:
            raise InfrastructureError("Unable to call '%s': %s" %
                                      (exc.cmd, exc.output))
        except OSError:
            raise InfrastructureError("Command 'docker' does not exist")

        # check docker image name
        # The string should be safe for command line inclusion
        image_name = self.parameters["image"]
        if re.compile("^[a-z0-9._:/-]+$").match(image_name) is None:
            self.errors = "image_name '%s' is invalid" % image_name
        self.set_namespace_data(action=self.name,
                                label='image',
                                key='name',
                                value=image_name)
示例#8
0
 def validate(self):
     super(Scp, self).validate()
     params = self._check_params()
     self.errors = infrastructure_error('scp')
     if 'ssh' not in self.job.device['actions']['deploy']['methods']:
         self.errors = "Unable to use %s without ssh deployment" % self.name
     if 'ssh' not in self.job.device['actions']['boot']['methods']:
         self.errors = "Unable to use %s without ssh boot" % self.name
     if self.get_namespace_data(action='prepare-scp-overlay',
                                label="prepare-scp-overlay",
                                key=self.key):
         self.primary = False
     elif 'host' not in self.job.device['actions']['deploy']['methods'][
             'ssh']:
         self.errors = "Invalid device or job configuration, missing host."
     if not self.primary and len(
             self.get_namespace_data(action='prepare-scp-overlay',
                                     label="prepare-scp-overlay",
                                     key=self.key)) != 1:
         self.errors = "Invalid number of host_keys"
     if self.primary:
         host_address = self.job.device['actions']['deploy']['methods'][
             'ssh']['host']
         if not host_address:
             self.errors = "Unable to retrieve ssh_host address for primary connection."
     if 'port' in self.job.device['actions']['deploy']['methods']['ssh']:
         port = str(
             self.job.device['actions']['deploy']['methods']['ssh']['port'])
         if not port.isdigit():
             self.errors = "Port was set but was not a digit"
     if self.valid:
         self.scp.append('scp')
         if 'options' in params:
             self.scp.extend(params['options'])
示例#9
0
 def _check_command(self):
     exe = ''
     try:
         exe = self.command.split(' ')[0]
     except AttributeError:
         self.errors = "Unable to parse the connection command %s" % self.command
     self.errors = infrastructure_error(exe)
示例#10
0
 def validate(self):
     super(FlashPyOCDAction, self).validate()
     boot = self.job.device['actions']['boot']['methods']['pyocd']
     pyocd_binary = boot['parameters']['command']
     self.errors = infrastructure_error(pyocd_binary)
     self.base_command = [pyocd_binary]
     self.base_command.extend(boot['parameters'].get('options', []))
     if self.job.device['board_id'] == '0000000000':
         self.errors = "board_id unset"
     substitutions = {}
     self.base_command.extend(['--board', self.job.device['board_id']])
     namespace = self.parameters['namespace']
     for action in self.data[namespace]['download-action'].keys():
         pyocd_full_command = []
         image_arg = self.get_namespace_data(action='download-action',
                                             label=action,
                                             key='image_arg')
         action_arg = self.get_namespace_data(action='download-action',
                                              label=action,
                                              key='file')
         if image_arg:
             if not isinstance(image_arg, str):
                 self.errors = "image_arg is not a string (try quoting it)"
                 continue
             substitutions["{%s}" % action] = action_arg
             pyocd_full_command.extend(self.base_command)
             pyocd_full_command.extend(
                 substitute([image_arg], substitutions))
             self.exec_list.append(pyocd_full_command)
         else:
             pyocd_full_command.extend(self.base_command)
             pyocd_full_command.extend([action_arg])
             self.exec_list.append(pyocd_full_command)
     if len(self.exec_list) < 1:
         self.errors = "No PyOCD command to execute"
示例#11
0
 def validate(self):
     super(LxcAction, self).validate()
     self.logger.info("lxc, installed at version: %s",
                      debian_package_version(pkg='lxc', split=False))
     protocols = [protocol.name for protocol in self.job.protocols]
     if LxcProtocol.name not in protocols:
         self.logger.debug("Missing protocol '%s' in %s",
                           LxcProtocol.name, protocols)
         self.errors = "Missing protocol '%s'" % LxcProtocol.name
     self.errors = infrastructure_error('lxc-create')
示例#12
0
class TestKvmUefi(StdoutTestCase):  # pylint: disable=too-many-public-methods
    def setUp(self):
        super(TestKvmUefi, self).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)
示例#13
0
    def validate(self):
        super(PrepareFITAction, self).validate()

        self.errors = infrastructure_error('mkimage')

        deploy_params = self.job.device['actions']['deploy'].get('parameters')
        if deploy_params is None:
            self.errors = "Missing parameters in deploy action"
        elif 'mkimage_arch' not in deploy_params:
            self.errors = "Missing mkimage_arch parameter for FIT support"
        else:
            self.deploy_params = deploy_params

        device_params = self.job.device.get('parameters')
        if device_params is None:
            self.errors = "Missing device parameters"
        elif 'load_address' not in device_params:
            self.errors = "Missing load_address from device parameters"
        else:
            self.device_params = device_params
示例#14
0
 def validate(self):
     """
     The unit test skips if schroot is not installed, the action marks the
     pipeline as invalid if schroot is not installed.
     """
     if 'schroot' not in self.parameters:
         return
     if 'schroot' not in self.job.device['actions']['boot']['methods']:
         self.errors = "No schroot support in device boot methods"
         return
     self.errors = infrastructure_error('schroot')
     # device parameters are for ssh
     params = self.job.device['actions']['boot']['methods']
     if 'command' not in params['schroot']:
         self.errors = "Missing schroot command in device configuration"
         return
     if 'name' not in params['schroot']:
         self.errors = "Missing schroot name in device configuration"
         return
     self.schroot = params['schroot']['name']
     self.command = params['schroot']['command']
示例#15
0
 def validate(self):
     super(LxcCreateUdevRuleAction, self).validate()
     self.errors = infrastructure_error('udevadm')
     if 'device_info' in self.job.device \
        and not isinstance(self.job.device.get('device_info'), list):
         self.errors = "device_info unset"
     # If we are allowed to use a filesystem label, we don't require a board_id
     # By default, we do require a board_id (serial)
     requires_board_id = not allow_fs_label(self.job.device)
     try:
         if 'device_info' in self.job.device:
             for usb_device in self.job.device['device_info']:
                 if usb_device.get('board_id', '') in ['', '0000000000'] \
                         and requires_board_id:
                     self.errors = "board_id unset"
                 if usb_device.get('usb_vendor_id', '') == '0000':
                     self.errors = 'usb_vendor_id unset'
                 if usb_device.get('usb_product_id', '') == '0000':
                     self.errors = 'usb_product_id unset'
     except TypeError:
         self.errors = "Invalid parameters for %s" % self.name
示例#16
0
 def validate(self):
     super(ConnectSsh, self).validate()
     params = self._check_params()
     self.errors = infrastructure_error('ssh')
     if 'host' in self.job.device['actions']['deploy']['methods']['ssh']:
         self.primary = True
         self.host = self.job.device['actions']['deploy']['methods']['ssh'][
             'host']
     if self.valid:
         self.command = ['ssh']
         if 'options' in params:
             self.command.extend(params['options'])
         # add arguments to ignore host key checking of the host device
         self.command.extend([
             '-o', 'UserKnownHostsFile=/dev/null', '-o',
             'StrictHostKeyChecking=no'
         ])
         if self.identity_file:
             # add optional identity file
             self.command.extend(['-i', self.identity_file])
         self.command.extend(self.ssh_port)
示例#17
0
 def validate(self):
     super(CompressRamdisk, self).validate()
     if not self.parameters.get('ramdisk', None):  # idempotency
         return
     if not self.parameters['ramdisk'].get('install_modules', True) and \
             not self.parameters['ramdisk'].get('install_overlay', True):
         self.skip = True
         return
     if 'parameters' in self.job.device['actions']['deploy']:
         self.add_header = self.job.device['actions']['deploy'][
             'parameters'].get('add_header', None)
         if self.add_header is not None:
             if self.add_header == 'u-boot':
                 self.errors = infrastructure_error('mkimage')
                 if 'mkimage_arch' not in self.job.device['actions'][
                         'deploy']['parameters']:
                     self.errors = "Missing architecture for uboot mkimage support (mkimage_arch in deploy parameters)"
                     return
                 self.mkimage_arch = self.job.device['actions']['deploy'][
                     'parameters']['mkimage_arch']
             else:
                 self.errors = "ramdisk: add_header: unknown header type"
示例#18
0
 def validate(self):
     super(PersistentNFSOverlay, self).validate()
     persist = self.parameters.get('persistent_nfs', None)
     if not persist:
         return
     if 'address' not in persist:
         self.errors = "Missing address for persistent NFS"
         return
     if ':' not in persist['address']:
         self.errors = "Unrecognised NFS URL: '%s'" % self.parameters[
             'persistent_nfs']['address']
         return
     nfs_server, dirname = persist['address'].split(':')
     self.errors = infrastructure_error('rpcinfo')
     self.errors = rpcinfo_nfs(nfs_server)
     self.set_namespace_data(action=self.name,
                             label='nfs_address',
                             key='nfsroot',
                             value=dirname)
     self.set_namespace_data(action=self.name,
                             label='nfs_address',
                             key='serverip',
                             value=nfs_server)
示例#19
0
    def validate(self):
        super(TftpAction, self).validate()
        if 'kernel' not in self.parameters:
            self.errors = "%s needs a kernel to deploy" % self.name
        if not self.valid:
            return
        if 'nfs_url' in self.parameters:
            self.errors = "Use a persistent_nfs dictionary instead of nfs_url"
        if 'nfsrootfs' in self.parameters and 'persistent_nfs' in self.parameters:
            self.errors = "Only one of nfsrootfs or persistent_nfs can be specified"
        # Extract the 3 last path elements. See action.mkdtemp()
        suffix = os.path.join(*self.tftp_dir.split('/')[-2:])
        self.set_namespace_data(action=self.name, label='tftp', key='suffix', value=suffix)
        self.errors = infrastructure_error('in.tftpd')

        # Check that the tmp directory is in the tftpd_dir or in /tmp for the
        # unit tests
        tftpd_directory = os.path.realpath(tftpd_dir())
        tftp_dir = os.path.realpath(self.tftp_dir)
        tmp_dir = tempfile.gettempdir()
        if not tftp_dir.startswith(tftpd_directory) and \
           not tftp_dir.startswith(tmp_dir):
            self.errors = "tftpd directory is not configured correctly, see /etc/default/tftpd-hpa"
示例#20
0
 def validate(self):
     super(ApplyOverlaySparseImage, self).validate()
     self.errors = infrastructure_error('/usr/bin/simg2img')
     self.errors = infrastructure_error('/bin/mount')
     self.errors = infrastructure_error('/bin/umount')
     self.errors = infrastructure_error('/usr/bin/img2simg')
示例#21
0
class TestRemovable(StdoutTestCase):  # pylint: disable=too-many-public-methods
    def test_device_parameters(self):
        """
        Test that the correct parameters have been set for the device
        """
        cubie = NewDevice(
            os.path.join(os.path.dirname(__file__), '../devices/cubie1.yaml'))
        self.assertIsNotNone(cubie['parameters']['media'].get('usb', None))
        self.assertIsNotNone(cubie.get('commands', None))
        self.assertIsNotNone(cubie.get('actions', None))
        self.assertIsNotNone(cubie['actions'].get('deploy', None))
        self.assertIsNotNone(cubie['actions']['deploy'].get('methods', None))
        self.assertIn('usb', cubie['actions']['deploy']['methods'])
        self.assertIsNotNone(cubie['actions'].get('boot', None))
        self.assertIsNotNone(cubie['actions']['boot'].get('methods', None))
        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('boot_message', u_boot_params['parameters'])
        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
        """
        cubie = NewDevice(
            os.path.join(os.path.dirname(__file__), '../devices/cubie1.yaml'))
        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
        """
        cubie = NewDevice(
            os.path.join(os.path.dirname(__file__), '../devices/cubie1.yaml'))
        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):
        cubie = NewDevice(
            os.path.join(os.path.dirname(__file__), '../devices/cubie1.yaml'))
        self._check_deployment(cubie, 'cubietruck-removable.yaml')

    def test_writer_deployment(self):
        cubie = NewDevice(
            os.path.join(os.path.dirname(__file__), '../devices/cubie1.yaml'))
        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()
        bbb = NewDevice(
            os.path.join(os.path.dirname(__file__), '../devices/bbb-01.yaml'))
        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()
        cubie = NewDevice(
            os.path.join(os.path.dirname(__file__), '../devices/cubie1.yaml'))
        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', None))
        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)
        self.assertEqual(commands, [
            'usb start', 'usb info', 'setenv autoload no',
            "setenv initrd_high '0xffffffff'", "setenv fdt_high '0xffffffff'",
            'setenv initrd_addr_r ${ramdisk_addr_r}',
            "setenv loadkernel 'load usb 0:1 ${kernel_addr_r} /boot/vmlinuz-3.16.0-4-armmp-lpae'",
            "setenv loadinitrd 'load usb 0:1 ${initrd_addr_r} /boot/initrd.img-3.16.0-4-armmp-lpae.u-boot; setenv initrd_size ${filesize}'",
            "setenv loadfdt 'load usb 0:1 ${fdt_addr_r} /boot/dtb-3.16.0-4-armmp-lpae'",
            "setenv bootargs 'console=ttyS0,115200n8 root=UUID=159d17cc-697c-4125-95a0-a3775e1deabe ip=dhcp'",
            "setenv bootcmd 'run loadkernel; run loadinitrd; run loadfdt; bootz 0x42000000 0x43300000 0x43000000'",
            'boot'
        ])
示例#22
0
class TestFastbootDeploy(StdoutTestCase):  # pylint: disable=too-many-public-methods
    def setUp(self):
        super(TestFastbootDeploy, self).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.assertIsNone(
            job.device.pre_os_command
        )  # FIXME: a real device config would typically need this.
        uefi_menu = [
            action for action in job.pipeline.actions
            if action.name == 'uefi-menu-action'
        ][0]
        select = [
            action for action in uefi_menu.internal_pipeline.actions
            if action.name == 'uefi-menu-selector'
        ][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))
        uefi_menu = [
            action for action in job.pipeline.actions
            if action.name == 'uefi-menu-action'
        ][0]
        self.assertIn('commands', uefi_menu.parameters)
        self.assertIn('fastboot', uefi_menu.parameters['commands'])
        self.assertEqual(
            job.device.pre_power_command,
            '/usr/local/lab-scripts/usb_hub_control -p 8000 -m sync -u 06')
        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.3.20': '4_android-optee',
                '1.8.3.4': '0_get-adb-serial',
                '1.8.3.12': '2_android-busybox',
                '1.8.3.8': '1_android-meminfo',
                '1.8.3.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
                self.assertIn(action.parameters['method'], ['lxc', 'fastboot'])
                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)

    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))
        self.assertEqual('', self.job.device.power_command)
        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]
        print(autologin.booting)
        print(autologin.parameters.get('prompts', None))
        self.assertIsNone(autologin.parameters.get('boot_message', None))

    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_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_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)
示例#23
0
def check_missing_path(testcase, exception, path):
    if isinstance(exception, InfrastructureError):
        if not infrastructure_error(path):
            testcase.fail(exception)
示例#24
0
def allow_missing_path(function, testcase, path):
    try:
        function()
    except InfrastructureError as exc:
        if not infrastructure_error(path):
            testcase.fail(exc)
示例#25
0
class TestDefinitionParams(StdoutTestCase):  # pylint: disable=too-many-public-methods
    def setUp(self):
        super(TestDefinitionParams, self).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)
示例#26
0
 def validate(self):
     super(ApplyLxcOverlay, self).validate()
     self.errors = infrastructure_error('tar')
     if not os.path.exists(self.lava_test_dir):
         self.errors = "Missing lava-test-runner: %s" % self.lava_test_dir
示例#27
0
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'])
示例#28
0
 def validate(self):
     if 'lxc' not in self.job.device['actions']['boot']['methods']:
         return
     super(ConnectLxc, self).validate()
     self.errors = infrastructure_error('lxc-attach')
示例#29
0
class TestUbootAction(StdoutTestCase):  # pylint: disable=too-many-public-methods
    def setUp(self):
        super(TestUbootAction, self).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())
        self.assertEqual(job.device['device_type'], 'beaglebone-black')

    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', None),
            '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']
        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()
        cubie = NewDevice(
            os.path.join(os.path.dirname(__file__), '../devices/cubie1.yaml'))
        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))
示例#30
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)