def create_custom_job(self, template, job_data, job_ctx=None, validate=True): if validate: validate_job(job_data, strict=False) if job_ctx: job_data["context"] = job_ctx else: job_ctx = job_data.get("context") (data, device_dict) = self.create_device(template, job_ctx) device = NewDevice(yaml.safe_load(data)) print("####### Device configuration #######") print(data) print("#######") try: parser = JobParser() job = parser.parse(yaml.dump(job_data), device, 4999, None, "") except (ConfigurationError, TypeError) as exc: print("####### Parser exception ########") print(device) print("#######") raise ConfigurationError("Invalid device: %s" % exc) job.logger = DummyLogger() return job
def test_job_protocols(self): self.factory.ensure_tag('usb-eth') self.factory.ensure_tag('sata') self.factory.bbb1.tags = Tag.objects.filter(name='usb-eth') self.factory.bbb1.save() self.factory.cubie1.tags = Tag.objects.filter(name='sata') self.factory.cubie1.save() target_group = "unit-test-only" job_dict = split_multinode_yaml(self.factory.make_vland_job(), target_group) client_job = job_dict['client'][0] client_handle, client_file_name = tempfile.mkstemp() yaml.dump(client_job, open(client_file_name, 'w')) # YAML device file, as required by lava-dispatch --target device_yaml_file = os.path.realpath( os.path.join(os.path.dirname(__file__), 'devices', 'bbb-01.yaml')) self.assertTrue(os.path.exists(device_yaml_file)) parser = JobParser() bbb_device = NewDevice(device_yaml_file) with open(client_file_name) as sample_job_data: bbb_job = parser.parse(sample_job_data, bbb_device, 4212, None, "") os.close(client_handle) os.unlink(client_file_name) self.assertIn('protocols', bbb_job.parameters) self.assertIn(VlandProtocol.name, bbb_job.parameters['protocols']) self.assertIn(MultinodeProtocol.name, bbb_job.parameters['protocols'])
def test_configure(self): with open(self.filename) as yaml_data: alpha_data = yaml_safe_load(yaml_data) self.assertIn("protocols", alpha_data) self.assertTrue(VlandProtocol.accepts(alpha_data)) vprotocol = VlandProtocol(alpha_data, self.job_id) vprotocol.set_up() with open(self.filename) as sample_job_data: parser = JobParser() job = parser.parse(sample_job_data, self.device, 4212, None, "") ret = vprotocol.configure(self.device, job) if not ret: print(vprotocol.errors) self.assertTrue(ret) nodes = {} for name in vprotocol.names: vlan = vprotocol.params[name] # self.assertNotIn('tags', vlan) uid = " ".join([vlan["switch"], str(vlan["port"])]) nodes[uid] = name self.assertEqual(len(nodes.keys()), len(vprotocol.names)) self.assertIn("vlan_one", vprotocol.names) self.assertNotIn("vlan_two", vprotocol.names) self.assertIn("switch", vprotocol.params["vlan_one"]) self.assertIn("port", vprotocol.params["vlan_one"]) self.assertIsNotNone(vprotocol.multinode_protocol) (rendered, _) = self.factory.create_device("bbb-01.jinja2") bbb2 = NewDevice(yaml_safe_load(rendered)) bbb2["parameters"]["interfaces"]["eth0"]["switch"] = "192.168.0.2" bbb2["parameters"]["interfaces"]["eth0"]["port"] = "6" bbb2["parameters"]["interfaces"]["eth1"]["switch"] = "192.168.0.2" bbb2["parameters"]["interfaces"]["eth1"]["port"] = "4" self.assertEqual( vprotocol.params, { "vlan_one": { "switch": "192.168.0.2", "iface": "eth1", "port": 7, "tags": ["100M", "RJ45", "10M"], } }, ) # already configured the vland protocol in the same job self.assertTrue(vprotocol.configure(bbb2, job)) self.assertEqual( vprotocol.params, { "vlan_one": { "switch": "192.168.0.2", "iface": "eth1", "port": 7, "tags": ["100M", "RJ45", "10M"], } }, ) self.assertTrue(vprotocol.valid) self.assertEqual(vprotocol.names, {"vlan_one": "4212vlanone"})
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
def test_writer_job_parameters(self): """ Test that the job parameters with a writer tool match expected structure """ (rendered, _) = self.factory.create_device('cubie1.jinja2') cubie = NewDevice(yaml.safe_load(rendered)) job = self._check_valid_job(cubie, 'cubietruck-removable-with-writer.yaml') self._check_job_parameters(cubie, job, 'writer')
def create_job(self, sample_job, device_file): # pylint: disable=no-self-use device = NewDevice(os.path.join(os.path.dirname(__file__), device_file)) j_yaml = os.path.join(os.path.dirname(__file__), sample_job) with open(j_yaml) as sample_job_data: parser = JobParser() job = parser.parse(sample_job_data, device, 4212, None, "") job.logger = DummyLogger() return job
def test_device_constants(self): device = NewDevice( os.path.join(os.path.dirname(__file__), '../devices/bbb-01.yaml')) self.assertIn('constants', device) self.assertEqual(device.get_constant('kernel-start-message'), "Linux version [0-9]") self.assertRaises(ConfigurationError, device.get_constant, ('non-existing-const'))
def setUp(self): super().setUp() self.device = NewDevice( os.path.join(os.path.dirname(__file__), '../devices/bbb-01.yaml')) bbb_yaml = os.path.join(os.path.dirname(__file__), 'sample_jobs/uboot-nfs.yaml') with open(bbb_yaml) as sample_job_data: self.job_data = yaml.load(sample_job_data)
def setUp(self): super().setUp() data = yaml_safe_load(Factory().create_device("bbb-01.jinja2")[0]) self.device = NewDevice(data) bbb_yaml = os.path.join(os.path.dirname(__file__), "sample_jobs/uboot-nfs.yaml") with open(bbb_yaml) as sample_job_data: self.job_data = yaml_safe_load(sample_job_data)
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 create_job(self, filename): # pylint: disable=no-self-use device = NewDevice(os.path.join(os.path.dirname(__file__), '../devices/x86-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, 4212, None, "") job.logger = DummyLogger() return job
def test_device_constants(self): factory = Factory() (rendered, _) = factory.create_device('bbb-01.jinja2') device = NewDevice(yaml.safe_load(rendered)) self.assertIn('constants', device) self.assertEqual(device.get_constant('kernel-start-message'), "Linux version [0-9]") self.assertRaises(ConfigurationError, device.get_constant, ('non-existing-const'))
def test_job_parameters(self): """ Test that the job parameters match expected structure """ (rendered, _) = self.factory.create_device("cubie1.jinja2") cubie = NewDevice(yaml_safe_load(rendered)) job = self._check_valid_job(cubie, "cubietruck-removable.yaml") self._check_job_parameters(cubie, job, "download")
def setUp(self): super(TestVland, self).setUp() self.filename = os.path.join(os.path.dirname(__file__), 'sample_jobs/bbb-group-vland-alpha.yaml') self.beta_filename = os.path.join( os.path.dirname(__file__), 'sample_jobs/bbb-group-vland-beta.yaml') self.device = NewDevice( os.path.join(os.path.dirname(__file__), '../devices/bbb-01.yaml')) self.job_id = "100"
def create_b2260_job(self, filename): device = NewDevice( os.path.join(os.path.dirname(__file__), "../devices/b2260-01.yaml")) with open(os.path.join(os.path.dirname(__file__), filename)) as f_in: parser = JobParser() job = parser.parse(f_in, device, 456, None, "") job.logger = DummyLogger() return job
def create_b2260_job(self, filename): # FIXME: b2260 Jinja2 template does not have flasher support. device = NewDevice( os.path.join(os.path.dirname(__file__), "devices/b2260-01.yaml")) with open(os.path.join(os.path.dirname(__file__), filename)) as f_in: parser = JobParser() job = parser.parse(f_in, device, 456, None, "") job.logger = DummyLogger() return job
def test_device_constants(self): factory = Factory() (rendered, _) = factory.create_device("bbb-01.jinja2") device = NewDevice(yaml_safe_load(rendered)) self.assertIn("constants", device) self.assertEqual(device.get_constant("kernel-start-message"), "Linux version [0-9]") self.assertRaises(ConfigurationError, device.get_constant, ("non-existing-const"))
def create_jaq_job(self, filename): device = NewDevice( os.path.join(os.path.dirname(__file__), "devices/jaq-01.yaml")) yaml = os.path.join(os.path.dirname(__file__), filename) with open(yaml) as sample_job_data: parser = JobParser() job = parser.parse(sample_job_data, device, 4212, None, "") job.logger = DummyLogger() return job
def create_adb_nuc_job(self, filename): # pylint: disable=no-self-use device = NewDevice( os.path.join(os.path.dirname(__file__), "devices/adb-nuc-01.yaml")) job_yaml = os.path.join(os.path.dirname(__file__), filename) with open(job_yaml) as sample_job_data: parser = JobParser() job = parser.parse(sample_job_data, device, 4577, None, "") job.logger = DummyLogger() return job
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 create_download_job(self, filename): # pylint: disable=no-self-use device = NewDevice( os.path.join(os.path.dirname(__file__), '../devices/db410c-01.yaml')) download_yaml = os.path.join(os.path.dirname(__file__), filename) with open(download_yaml) as sample_job_data: parser = JobParser() job = parser.parse(sample_job_data, device, 4212, None, "") return job
def test_overlay_action(self): # pylint: disable=too-many-locals parameters = { 'device_type': 'd02', 'job_name': 'grub-standard-ramdisk', 'job_timeout': '15m', 'action_timeout': '5m', 'priority': 'medium', 'actions': { 'boot': { 'method': 'grub', 'commands': 'ramdisk', 'prompts': ['linaro-test', 'root@debian:~#'] }, 'deploy': { 'ramdisk': 'initrd.gz', 'kernel': 'zImage', 'dtb': 'broken.dtb' } } } (rendered, _) = self.factory.create_device('d02-01.jinja2') device = NewDevice(yaml.load(rendered)) job = Job(4212, parameters, None) job.device = device pipeline = Pipeline(job=job, parameters=parameters['actions']['boot']) job.pipeline = pipeline overlay = BootloaderCommandOverlay() pipeline.add_action(overlay) ip_addr = dispatcher_ip(None) parsed = [] kernel = parameters['actions']['deploy']['kernel'] ramdisk = parameters['actions']['deploy']['ramdisk'] dtb = parameters['actions']['deploy']['dtb'] substitution_dictionary = { '{SERVER_IP}': ip_addr, # the addresses need to be hexadecimal '{RAMDISK}': ramdisk, '{KERNEL}': kernel, '{DTB}': dtb } params = device['actions']['boot']['methods'] commands = params['grub']['ramdisk']['commands'] self.assertIn('net_bootp', commands) self.assertIn("linux (tftp,{SERVER_IP})/{KERNEL} console=ttyS0,115200 earlycon=uart8250,mmio32,0x80300000 root=/dev/ram0 ip=dhcp", commands) self.assertIn('initrd (tftp,{SERVER_IP})/{RAMDISK}', commands) self.assertIn('devicetree (tftp,{SERVER_IP})/{DTB}', commands) params['grub']['ramdisk']['commands'] = substitute(params['grub']['ramdisk']['commands'], substitution_dictionary) substituted_commands = params['grub']['ramdisk']['commands'] self.assertIs(type(substituted_commands), list) self.assertIn('net_bootp', substituted_commands) self.assertNotIn("linux (tftp,{SERVER_IP})/{KERNEL} console=ttyS0,115200 earlycon=uart8250,mmio32,0x80300000 root=/dev/ram0 ip=dhcp", substituted_commands) self.assertIn("linux (tftp,%s)/%s console=ttyS0,115200 earlycon=uart8250,mmio32,0x80300000 root=/dev/ram0 ip=dhcp" % (ip_addr, kernel), substituted_commands) self.assertNotIn('initrd (tftp,{SERVER_IP})/{RAMDISK}', parsed) self.assertNotIn('devicetree (tftp,{SERVER_IP})/{DTB}', parsed)
def create_x15_bl_job(self, filename): (data, device_dict) = self.create_x15_bl_device("x15-bl-01") device = NewDevice(yaml.safe_load(data)) self.validate_data("x15-bl-01", device_dict) uboot_yaml = os.path.join(os.path.dirname(__file__), filename) with open(uboot_yaml) as sample_job_data: parser = JobParser() job = parser.parse(sample_job_data, device, 4213, None, "") job.logger = DummyLogger() return job
def create_hikey_aep_job(self, filename): # pylint: disable=no-self-use device = NewDevice( os.path.join(os.path.dirname(__file__), '../devices/hi6220-hikey-01.yaml')) job_yaml = os.path.join(os.path.dirname(__file__), filename) with open(job_yaml) as sample_job_data: parser = JobParser() job = parser.parse(sample_job_data, device, 4577, None, "") job.logger = DummyLogger() return job
def setUp(self): super().setUp() self.filename = os.path.join(os.path.dirname(__file__), "sample_jobs/bbb-group-vland-alpha.yaml") self.beta_filename = os.path.join( os.path.dirname(__file__), "sample_jobs/bbb-group-vland-beta.yaml") self.factory = Factory() (rendered, _) = self.factory.create_device("bbb-01.jinja2") self.device = NewDevice(yaml_safe_load(rendered)) self.job_id = "100"
def create_hikey_bl_job(self, filename): (data, device_dict) = self.create_hikey_bl_device('hi6220-hikey-01') device = NewDevice(yaml.load(data)) self.validate_data('hi6220-hikey-01', device_dict) fastboot_yaml = os.path.join(os.path.dirname(__file__), filename) with open(fastboot_yaml) as sample_job_data: parser = JobParser() job = parser.parse(sample_job_data, device, 4212, None, "") job.logger = DummyLogger() return job
def test_prompt_from_job(self, which_mock): """ Support setting the prompt after login via the job Loads a known YAML, adds a prompt to the dict and re-parses the job. Checks that the prompt is available in the expect_shell_connection action. """ job = self.factory.create_job("x86-01.jinja2", "sample_jobs/ipxe-ramdisk.yaml") job.validate() bootloader = [ action for action in job.pipeline.actions if action.name == "bootloader-action" ][0] retry = [ action for action in bootloader.pipeline.actions if action.name == "bootloader-retry" ][0] expect = [ action for action in retry.pipeline.actions if action.name == "expect-shell-connection" ][0] check = expect.parameters (rendered, _) = self.factory.create_device("x86-01.jinja2") device = NewDevice(yaml_safe_load(rendered)) extra_yaml = os.path.join(os.path.dirname(__file__), "sample_jobs/ipxe.yaml") with open(extra_yaml) as data: sample_job_string = data.read() parser = JobParser() sample_job_data = yaml_safe_load(sample_job_string) boot = [item["boot"] for item in sample_job_data["actions"] if "boot" in item][ 0 ] self.assertIsNotNone(boot) sample_job_string = yaml_safe_dump(sample_job_data) job = parser.parse(sample_job_string, device, 4212, None, "") job.logger = DummyLogger() job.validate() bootloader = [ action for action in job.pipeline.actions if action.name == "bootloader-action" ][0] retry = [ action for action in bootloader.pipeline.actions if action.name == "bootloader-retry" ][0] expect = [ action for action in retry.pipeline.actions if action.name == "expect-shell-connection" ][0]
def test_configure(self): with open(self.filename) as yaml_data: alpha_data = yaml.safe_load(yaml_data) self.assertIn('protocols', alpha_data) self.assertTrue(VlandProtocol.accepts(alpha_data)) vprotocol = VlandProtocol(alpha_data, self.job_id) vprotocol.set_up() with open(self.filename) as sample_job_data: parser = JobParser() job = parser.parse(sample_job_data, self.device, 4212, None, "") ret = vprotocol.configure(self.device, job) if not ret: print(vprotocol.errors) self.assertTrue(ret) nodes = {} for name in vprotocol.names: vlan = vprotocol.params[name] # self.assertNotIn('tags', vlan) uid = ' '.join([vlan['switch'], str(vlan['port'])]) nodes[uid] = name self.assertEqual(len(nodes.keys()), len(vprotocol.names)) self.assertIn('vlan_one', vprotocol.names) self.assertNotIn('vlan_two', vprotocol.names) self.assertIn('switch', vprotocol.params['vlan_one']) self.assertIn('port', vprotocol.params['vlan_one']) self.assertIsNotNone(vprotocol.multinode_protocol) (rendered, _) = self.factory.create_device('bbb-01.jinja2') bbb2 = NewDevice(yaml.safe_load(rendered)) bbb2['parameters']['interfaces']['eth0']['switch'] = '192.168.0.2' bbb2['parameters']['interfaces']['eth0']['port'] = '6' bbb2['parameters']['interfaces']['eth1']['switch'] = '192.168.0.2' bbb2['parameters']['interfaces']['eth1']['port'] = '4' self.assertEqual( vprotocol.params, { 'vlan_one': { 'switch': '192.168.0.2', 'iface': 'eth1', 'port': 7, 'tags': ['100M', 'RJ45', '10M'] } }) # already configured the vland protocol in the same job self.assertTrue(vprotocol.configure(bbb2, job)) self.assertEqual( vprotocol.params, { 'vlan_one': { 'switch': '192.168.0.2', 'iface': 'eth1', 'port': 7, 'tags': ['100M', 'RJ45', '10M'] } }) self.assertTrue(vprotocol.valid) self.assertEqual(vprotocol.names, {'vlan_one': '4212vlanone'})
def test_device_parser(self): job_parser = JobParser() device = NewDevice( os.path.join(os.path.dirname(__file__), '../devices/bbb-01.yaml')) self.assertIn('power_state', device) self.assertFalse(hasattr(device, 'power_state')) sample_job_file = os.path.join(os.path.dirname(__file__), 'sample_jobs/uboot-ramdisk.yaml') with open(sample_job_file) as sample_job_data: job = job_parser.parse(sample_job_data, device, 4212, None, "") uboot_action = None for action in job.pipeline.actions: if isinstance(action, DeployAction): self.assertIn('ramdisk', action.parameters) if isinstance(action, BootAction): self.assertIn('method', action.parameters) self.assertEqual('u-boot', action.parameters['method']) methods = device['actions']['boot']['methods'] self.assertIn('ramdisk', methods['u-boot']) self.assertIn('bootloader_prompt', methods['u-boot']['parameters']) self.assertIsNotNone(methods[action.parameters['method']][ action.parameters['commands']]['commands']) for line in methods[action.parameters['method']][ action.parameters['commands']]['commands']: self.assertIsNotNone(line) self.assertIsInstance(action, UBootAction) uboot_action = action self.assertIsNotNone(uboot_action) uboot_action.validate() self.assertTrue(uboot_action.valid) for action in uboot_action.internal_pipeline.actions: if isinstance(action, BootloaderInterruptAction): self.assertIn('power-on', action.job.device['commands']) self.assertIn('hard_reset', action.job.device['commands']) self.assertIn('connect', action.job.device['commands']) self.assertEqual( action.job.device['commands']['connect'].split(' ')[0], 'telnet') if isinstance(action, UBootAction): self.assertIn('method', action.parameters) self.assertIn('commands', action.parameters) self.assertIn('ramdisk', action.parameters['u-boot']) self.assertIn(action.parameters['commands'], action.parameters[action.parameters['method']]) self.assertIn( 'commands', action.parameters[action.parameters['method']][ action.parameters['commands']]) self.assertIsNotNone(action.parameters['u-boot']['ramdisk']) self.assertIsInstance( action.parameters['u-boot']['ramdisk']['commands'], list) self.assertTrue( len(action.parameters['u-boot']['ramdisk']['commands']) > 2 )
def create_qemu_installer_job(self): (rendered, _) = self.create_device("kvm01.jinja2") device = NewDevice(yaml_safe_load(rendered)) sample_job_file = os.path.join( os.path.dirname(__file__), "sample_jobs/qemu-debian-installer.yaml") parser = JobParser() with open(sample_job_file) as sample_job_data: job = parser.parse(sample_job_data, device, 4212, None, "") job.logger = DummyLogger() return job