def test_job_parameters(self): """ Test that the job parameters match expected structure """ self.maxDiff = None # pylint: disable=invalid-name 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, "", output_dir='/tmp/') job.logger = DummyLogger() try: job.validate() except JobError: self.fail(job.pipeline.errors) sample_job_data.close() description_ref = pipeline_reference('cubietruck-removable.yaml') self.assertEqual(description_ref, job.pipeline.describe(False)) 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['download']['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'], cubie['parameters']['media']['usb']) self.assertIsNotNone(mass_storage.get_namespace_data(action='storage-deploy', label='u-boot', key='device')) u_boot_params = cubie['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_ssh_job(self): self.assertIsNotNone(self.job) self.job.validate() self.assertEqual([], self.job.pipeline.errors) # Check Pipeline description_ref = pipeline_reference('ssh-deploy.yaml') self.assertEqual(description_ref, self.job.pipeline.describe(False))
def test_lxc_api(self): job = self.factory.create_hikey_job('sample_jobs/hikey-oe.yaml', mkdtemp()) description_ref = pipeline_reference('hikey-oe.yaml') 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')
def test_job(self): with open(self.filename) as yaml_data: alpha_data = yaml.load(yaml_data) self.assertIn('protocols', alpha_data) self.assertIn(VlandProtocol.name, alpha_data['protocols']) with open(self.filename) as sample_job_data: parser = JobParser() job = parser.parse(sample_job_data, self.device, 4212, None, output_dir='/tmp/') description_ref = pipeline_reference('bbb-group-vland-alpha.yaml') self.assertEqual(description_ref, job.pipeline.describe(False)) job.validate() self.assertNotEqual([], [protocol.name for protocol in job.protocols if protocol.name == MultinodeProtocol.name]) ret = {"message": {"kvm01": {"vlan_name": "name", "vlan_tag": 6}}, "response": "ack"} self.assertEqual(('name', 6), (ret['message']['kvm01']['vlan_name'], ret['message']['kvm01']['vlan_tag'],)) self.assertIn('protocols', job.parameters) self.assertIn(VlandProtocol.name, job.parameters['protocols']) self.assertIn(MultinodeProtocol.name, job.parameters['protocols']) vprotocol = [vprotocol for vprotocol in job.protocols if vprotocol.name == VlandProtocol.name][0] self.assertTrue(vprotocol.valid) self.assertEqual(vprotocol.names, {'vlan_one': 'arbitraryg000', 'vlan_two': 'arbitraryg001'}) self.assertFalse(vprotocol.check_timeout(120, {'request': 'no call'})) self.assertRaises(JobError, vprotocol.check_timeout, 60, 'deploy_vlans') self.assertRaises(JobError, vprotocol.check_timeout, 60, {'request': 'deploy_vlans'}) self.assertTrue(vprotocol.check_timeout(120, {'request': 'deploy_vlans'})) for vlan_name in job.parameters['protocols'][VlandProtocol.name]: if vlan_name == 'yaml_line': continue self.assertIn(vlan_name, vprotocol.params) self.assertIn('switch', vprotocol.params[vlan_name]) self.assertIn('port', vprotocol.params[vlan_name])
def test_guest_ssh(self): self.assertIsNotNone(self.guest_job) self.guest_job.validate() self.assertEqual([], self.guest_job.pipeline.errors) scp_overlay = [ item for item in self.guest_job.pipeline.actions if item.name == 'scp-overlay' ] environment = scp_overlay[0].get_common_data('environment', 'env_dict') self.assertIsNotNone(environment) self.assertIn('LANG', environment.keys()) self.assertIn('C', environment.values()) self.assertEqual(len(scp_overlay), 1) overlay = [ item for item in scp_overlay[0].internal_pipeline.actions if item.name == 'lava-overlay' ] multinode = [ item for item in overlay[0].internal_pipeline.actions if item.name == 'lava-multinode-overlay' ] self.assertEqual(len(multinode), 1) # Check Pipeline description_ref = pipeline_reference('ssh-guest.yaml') self.assertEqual(description_ref, self.guest_job.pipeline.describe(False))
def test_job_parameters(self): """ Test that the job parameters match expected structure """ self.maxDiff = None # pylint: disable=invalid-name 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, None, None, output_dir='/tmp/') try: job.validate() except JobError: self.fail(job.pipeline.errors) sample_job_data.close() description_ref = pipeline_reference('cubietruck-removable.yaml') self.assertEqual(description_ref, job.pipeline.describe(False)) 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['download']['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'], cubie['parameters']['media']['usb']) self.assertIsNotNone(mass_storage.get_common_data('u-boot', 'device')) u_boot_params = cubie['actions']['boot']['methods']['u-boot'] self.assertEqual(mass_storage.get_common_data('bootloader_prompt', 'prompt'), u_boot_params['parameters']['bootloader_prompt'])
def test_cmsis_pipeline(self): factory = Cmsis_Factory() job = factory.create_k64f_job( 'sample_jobs/zephyr-frdm-k64f-cmsis-test-kernel-common.yaml') job.device['actions']['boot']['methods']['cmsis-dap']['parameters'][ 'usb_mass_device'] = '/dev/null' job.validate() description_ref = pipeline_reference('cmsis.yaml') self.assertEqual(description_ref, job.pipeline.describe(False))
def test_simulated_action(self): job = self.factory.create_job('sample_jobs/ipxe-ramdisk.yaml') self.assertIsNotNone(job) description_ref = pipeline_reference('ipxe.yaml') self.assertEqual(description_ref, job.pipeline.describe(False)) self.assertIsNone(job.validate()) self.assertEqual(job.device['device_type'], 'x86')
def test_pipeline(self): description_ref = pipeline_reference('kvm-inline.yaml') self.assertEqual(description_ref, self.job.pipeline.describe(False)) self.assertEqual(len(self.job.pipeline.describe()), 4) for action in self.job.pipeline.actions: if isinstance(action, DeployAction): overlay = action.pipeline.children[action.pipeline][3] testdef = overlay.internal_pipeline.actions[1] inline_repo = testdef.internal_pipeline.actions[0] break # Test the InlineRepoAction directly location = mkdtemp() inline_repo.data['lava-overlay'] = {'location': location} inline_repo.data['test-definition'] = {'overlay_dir': location} inline_repo.run(None) yaml_file = os.path.join( location, 'tests/0_smoke-tests-inline/inline/smoke-tests-basic.yaml') self.assertTrue(os.path.exists(yaml_file)) with open(yaml_file, 'r') as f_in: testdef = yaml.load(f_in) expected_testdef = { 'metadata': { 'description': 'Basic system test command for Linaro Ubuntu images', 'devices': [ 'panda', 'panda-es', 'arndale', 'vexpress-a9', 'vexpress-tc2' ], 'format': 'Lava-Test Test Definition 1.0', 'name': 'smoke-tests-basic', 'os': ['ubuntu'], 'scope': ['functional'], 'yaml_line': 39 }, 'run': { 'steps': [ 'lava-test-case linux-INLINE-pwd --shell pwd', 'lava-test-case linux-INLINE-uname --shell uname -a', 'lava-test-case linux-INLINE-vmstat --shell vmstat', 'lava-test-case linux-INLINE-ifconfig --shell ifconfig -a', 'lava-test-case linux-INLINE-lscpu --shell lscpu', 'lava-test-case linux-INLINE-lsusb --shell lsusb', 'lava-test-case linux-INLINE-lsb_release --shell lsb_release -a' ], 'yaml_line': 53 }, 'yaml_line': 38 } self.assertEqual(testdef, expected_testdef)
def test_simulated_action(self): factory = Factory() job = factory.create_job('sample_jobs/ipxe-ramdisk.yaml') self.assertIsNotNone(job) description_ref = pipeline_reference('ipxe.yaml') self.assertEqual(description_ref, job.pipeline.describe(False)) self.assertIsNone(job.validate()) self.assertEqual(job.device['device_type'], 'x86')
def test_simulated_action(self): job = self.factory.create_job('sample_jobs/grub-ramdisk.yaml') self.assertIsNotNone(job) # uboot and uboot-ramdisk have the same pipeline structure description_ref = pipeline_reference('grub.yaml') self.assertEqual(description_ref, job.pipeline.describe(False)) self.assertIsNone(job.validate()) self.assertEqual(job.device['device_type'], 'd02')
def test_simulated_action(self): factory = Factory() job = factory.create_bbb_job('sample_jobs/uboot-ramdisk.yaml') self.assertIsNotNone(job) # uboot and uboot-ramdisk have the same pipeline structure description_ref = pipeline_reference('uboot.yaml') self.assertEqual(description_ref, job.pipeline.describe(False)) self.assertIsNone(job.validate()) self.assertEqual(job.device['device_type'], 'beaglebone-black')
def test_uefi_job(self): self.assertIsNotNone(self.job) self.job.validate() uefi_menu = [action for action in self.job.pipeline.actions if action.name == 'uefi-menu-action'][0] selector = [action for action in uefi_menu.internal_pipeline.actions if action.name == 'uefi-menu-selector'][0] self.assertEqual( selector.selector.prompt, "Start:" ) self.assertIsInstance(selector.items, list) description_ref = pipeline_reference('mustang-uefi.yaml') self.assertEqual(description_ref, self.job.pipeline.describe(False)) # just dummy strings substitution_dictionary = { '{SERVER_IP}': '10.4.0.1', '{RAMDISK}': None, '{KERNEL}': 'uImage', '{DTB}': 'mustang.dtb', '{NFSROOTFS}': 'tmp/tmp21dfed/', '{TEST_MENU_NAME}': 'LAVA NFS Test Image' } for block in selector.items: if 'select' in block: if 'enter' in block['select']: block['select']['enter'] = substitute([block['select']['enter']], substitution_dictionary) if 'items' in block['select']: block['select']['items'] = substitute(block['select']['items'], substitution_dictionary) count = 0 check_block = [ {'items': ['Boot Manager'], 'wait': 'Choice:'}, {'items': ['Remove Boot Device Entry'], 'fallback': 'Return to Main Menu', 'wait': 'Delete entry'}, {'items': ['LAVA NFS Test Image'], 'wait': 'Choice:'}, {'items': ['Add Boot Device Entry'], 'wait': 'Select the Boot Device:'}, {'items': ['TFTP on MAC Address: 00:01:73:69:5A:EF'], 'wait': 'Get the IP address from DHCP:'}, {'enter': ['y'], 'wait': 'Get the TFTP server IP address:'}, {'enter': ['10.4.0.1'], 'wait': 'File path of the EFI Application or the kernel :'}, {'enter': ['uImage'], 'wait': 'Is an EFI Application?'}, {'enter': ['n'], 'wait': 'Boot Type:'}, {'enter': ['f'], 'wait': 'Add an initrd:'}, {'enter': ['n'], 'wait': 'Get the IP address from DHCP:'}, {'enter': ['y'], 'wait': 'Get the TFTP server IP address:'}, {'enter': ['10.4.0.1'], 'wait': 'File path of the FDT :'}, {'enter': ['mustang.dtb'], 'wait': 'Arguments to pass to the binary:'}, {'enter': ['console=ttyS0,115200 earlyprintk=uart8250-32bit,0x1c020000 debug root=/dev/nfs rw ' 'nfsroot=10.4.0.1:tmp/tmp21dfed/,tcp,hard,intr ip=dhcp'], 'wait': 'Description for this new Entry:'}, {'enter': ['LAVA NFS Test Image'], 'wait': 'Choice:'}, {'items': ['Return to main menu'], 'wait': 'Start:'}, {'items': ['LAVA NFS Test Image']}, ] for item in selector.items: self.assertEqual( item['select'], check_block[count]) count += 1
def test_grub_via_efi(self): job = self.factory.create_mustang_job('sample_jobs/mustang-grub-efi-nfs.yaml') self.assertIsNotNone(job) job.validate() description_ref = pipeline_reference('mustang-grub-efi-nfs.yaml') self.assertEqual(description_ref, job.pipeline.describe(False)) grub = [action for action in job.pipeline.actions if action.name == 'grub-main-action'][0] menu = [action for action in grub.internal_pipeline.actions if action.name == 'uefi-menu-interrupt'][0] self.assertIn('item_class', menu.params) grub_efi = [action for action in grub.internal_pipeline.actions if action.name == 'grub-efi-menu-selector'][0] self.assertEqual('pxe-grub', grub_efi.commands)
def test_multi_uboot(self): self.assertIsNotNone(self.job) description_ref = pipeline_reference('uboot-multiple.yaml') self.assertEqual(description_ref, self.job.pipeline.describe(False)) deploy = [action for action in self.job.pipeline.actions if action.name == 'tftp-deploy'][0] downloads = [action for action in deploy.internal_pipeline.actions if action.name == 'download_retry'] for download in downloads: if download.key == 'nfsrootfs': # if using root, the path would be appended. self.assertIn(DISPATCHER_DOWNLOAD_DIR, download.path) else: self.assertIn(tftpd_dir(), download.path)
def test_pipeline(self): description_ref = pipeline_reference('kvm-command.yaml') import yaml with open('/tmp/test.yaml', 'w') as describe: yaml.dump(self.job.pipeline.describe(False), describe) self.assertEqual(description_ref, self.job.pipeline.describe(False)) command = [ action for action in self.job.pipeline.actions if action.name == 'user-command' ][0] self.assertEqual(command.parameters['name'], 'user_command_to_run') self.assertEqual(command.timeout.duration, 60)
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 = pipeline_reference('uboot-ramdisk-inline-commands.yaml') 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_pipeline(self): description_ref = pipeline_reference('kvm.yaml') 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] self.assertIn( 'persistent-nfs-overlay', [action.name for action in overlay.internal_pipeline.actions]) self.assertEqual(description_ref, self.job.pipeline.describe(False))
def test_guest_ssh(self): self.assertIsNotNone(self.guest_job) self.guest_job.validate() self.assertEqual([], self.guest_job.pipeline.errors) scp_overlay = [item for item in self.guest_job.pipeline.actions if item.name == 'scp-overlay'] environment = scp_overlay[0].get_common_data('environment', 'env_dict') self.assertIsNotNone(environment) self.assertIn('LANG', environment.keys()) self.assertIn('C', environment.values()) self.assertEqual(len(scp_overlay), 1) overlay = [item for item in scp_overlay[0].internal_pipeline.actions if item.name == 'lava-overlay'] multinode = [item for item in overlay[0].internal_pipeline.actions if item.name == 'lava-multinode-overlay'] self.assertEqual(len(multinode), 1) # Check Pipeline description_ref = pipeline_reference('ssh-guest.yaml') self.assertEqual(description_ref, self.guest_job.pipeline.describe(False))
def test_pipeline(self): description_ref = pipeline_reference('kvm-inline.yaml') self.assertEqual(description_ref, self.job.pipeline.describe(False)) self.assertEqual(len(self.job.pipeline.describe()), 4) inline_repo = None for action in self.job.pipeline.actions: if isinstance(action, DeployAction): self.assertIsNotNone(action.internal_pipeline.actions[2]) overlay = action.pipeline.children[action.pipeline][2] self.assertIsNotNone(overlay.internal_pipeline.actions[2]) testdef = overlay.internal_pipeline.actions[2] self.assertIsNotNone(testdef.internal_pipeline.actions[0]) inline_repo = testdef.internal_pipeline.actions[0] break # Test the InlineRepoAction directly self.assertIsNotNone(inline_repo) location = mkdtemp() # other actions have not been run, so fake up inline_repo.data['lava_test_results_dir'] = location inline_repo.data['lava-overlay'] = {'location': location} inline_repo.data['test-definition'] = {'overlay_dir': location} inline_repo.run(None) yaml_file = os.path.join(location, '0/tests/0_smoke-tests-inline/inline/smoke-tests-basic.yaml') self.assertTrue(os.path.exists(yaml_file)) with open(yaml_file, 'r') as f_in: testdef = yaml.load(f_in) expected_testdef = {'metadata': {'description': 'Basic system test command for Linaro Ubuntu images', 'devices': ['panda', 'panda-es', 'arndale', 'vexpress-a9', 'vexpress-tc2'], 'format': 'Lava-Test Test Definition 1.0', 'name': 'smoke-tests-basic', 'os': ['ubuntu'], 'scope': ['functional'], 'yaml_line': 39}, 'run': {'steps': ['lava-test-case linux-INLINE-pwd --shell pwd', 'lava-test-case linux-INLINE-uname --shell uname -a', 'lava-test-case linux-INLINE-vmstat --shell vmstat', 'lava-test-case linux-INLINE-ifconfig --shell ifconfig -a', 'lava-test-case linux-INLINE-lscpu --shell lscpu', 'lava-test-case linux-INLINE-lsusb --shell lsusb', 'lava-test-case linux-INLINE-lsb_release --shell lsb_release -a'], 'yaml_line': 53}, 'yaml_line': 38} self.assertEqual(set(testdef), set(expected_testdef))
def test_udev_actions(self): self.factory = FastBootFactory() job = self.factory.create_db410c_job('sample_jobs/db410c.yaml', mkdtemp()) self.assertTrue(job.device.get('fastboot_via_uboot', True)) self.assertEqual('', self.job.device.power_command) description_ref = pipeline_reference('db410c.yaml') self.assertEqual(description_ref, job.pipeline.describe(False)) boot = [ action for action in job.pipeline.actions if action.name == 'fastboot-boot' ][0] wait = [ action for action in boot.internal_pipeline.actions if action.name == 'wait-usb-device' ][0] self.assertEqual(wait.device_actions, ['remove'])
def test_multi_uboot(self): self.assertIsNotNone(self.job) description_ref = pipeline_reference('uboot-multiple.yaml') self.assertEqual(description_ref, self.job.pipeline.describe(False)) deploy = [ action for action in self.job.pipeline.actions if action.name == 'tftp-deploy' ][0] downloads = [ action for action in deploy.internal_pipeline.actions if action.name == 'download_retry' ] for download in downloads: if download.key == 'nfsrootfs': # if using root, the path would be appended. self.assertIn(DISPATCHER_DOWNLOAD_DIR, download.path) else: self.assertIn(tftpd_dir(), download.path)
def test_fastboot_lxc(self): job = self.factory.create_hikey_job('sample_jobs/hi6220-hikey.yaml', mkdtemp()) description_ref = pipeline_reference('hi6220-hikey.yaml') 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.7.3.20': '4_android-optee', '1.7.3.4': '0_get-adb-serial', '1.7.3.12': '2_android-busybox', '1.7.3.8': '1_android-meminfo', '1.7.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'])
def test_deploy_parameters(self): factory = UBootFactory() job = factory.create_bbb_job('sample_jobs/kexec.yaml') self.assertIsNotNone(job) # Check Pipeline description_ref = pipeline_reference('kexec.yaml') self.assertEqual(description_ref, job.pipeline.describe(False)) # Check kexec specific options job.validate() self.assertIsInstance(job.pipeline.actions[2], TestShellRetry) self.assertIsInstance(job.pipeline.actions[3], BootKexecAction) kexec = job.pipeline.actions[3] self.assertIsInstance(kexec.internal_pipeline.actions[0], KexecAction) self.assertIsInstance(kexec.internal_pipeline.actions[1], AutoLoginAction) self.assertIsInstance(kexec.internal_pipeline.actions[2], ExpectShellSession) self.assertIsInstance(kexec.internal_pipeline.actions[3], ExportDeviceEnvironment) self.assertIn('kernel', kexec.parameters) self.assertIn('command', kexec.parameters) self.assertIn('method', kexec.parameters) self.assertIn('dtb', kexec.parameters) self.assertIn('options', kexec.parameters) self.assertIn('kernel-config', kexec.parameters) self.assertTrue(kexec.valid) self.assertEqual( '/sbin/kexec --load /home/vmlinux --dtb /home/dtb --initrd /home/initrd --reuse-cmdline', kexec.internal_pipeline.actions[0].load_command ) self.assertEqual( '/sbin/kexec -e', kexec.internal_pipeline.actions[0].command ) self.assertIsNotNone(kexec.internal_pipeline.actions[0].parameters['boot_message']) self.assertIsNotNone(kexec.internal_pipeline.actions[0].name) self.assertIsNotNone(kexec.internal_pipeline.actions[0].level) self.assertEqual(kexec.internal_pipeline.actions[0].timeout.duration, 45)
def test_job_parameters(self): """ Test that the job parameters match expected structure """ self.maxDiff = None # pylint: disable=invalid-name 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, output_dir="/tmp/") try: job.validate() except JobError: self.fail(job.pipeline.errors) description_ref = pipeline_reference("cubietruck-removable.yaml") self.assertEqual(description_ref, job.pipeline.describe(False)) 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["download"] 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"], cubie["parameters"]["media"]["usb"]) self.assertIsNotNone(mass_storage.get_common_data("u-boot", "device")) u_boot_params = cubie["actions"]["boot"]["methods"]["u-boot"] self.assertEqual( mass_storage.get_common_data("bootloader_prompt", "prompt"), u_boot_params["parameters"]["bootloader_prompt"], )
def test_deploy_parameters(self): factory = Factory() job = factory.create_bbb_job('sample_jobs/kexec.yaml') self.assertIsNotNone(job) # Check Pipeline description_ref = pipeline_reference('kexec.yaml') self.assertEqual(description_ref, job.pipeline.describe(False)) # Check kexec specific options job.validate() self.assertIsInstance(job.pipeline.actions[2], TestShellRetry) self.assertIsInstance(job.pipeline.actions[3], BootKexecAction) kexec = job.pipeline.actions[3] self.assertIsInstance(kexec.internal_pipeline.actions[0], KexecAction) self.assertIsInstance(kexec.internal_pipeline.actions[1], AutoLoginAction) self.assertIsInstance(kexec.internal_pipeline.actions[2], ExpectShellSession) self.assertIsInstance(kexec.internal_pipeline.actions[3], ExportDeviceEnvironment) self.assertIn('kernel', kexec.parameters) self.assertIn('command', kexec.parameters) self.assertIn('method', kexec.parameters) self.assertIn('dtb', kexec.parameters) self.assertIn('options', kexec.parameters) self.assertIn('kernel-config', kexec.parameters) self.assertTrue(kexec.valid) self.assertEqual( '/sbin/kexec --load /home/vmlinux --dtb /home/dtb --initrd /home/initrd --reuse-cmdline', kexec.internal_pipeline.actions[0].load_command ) self.assertEqual( '/sbin/kexec -e', kexec.internal_pipeline.actions[0].command ) self.assertIsNotNone(kexec.internal_pipeline.actions[0].parameters['boot_message']) self.assertEqual(kexec.internal_pipeline.actions[0].timeout.duration, 45)
def test_basic_structure(self): self.assertIsNotNone(self.job) self.job.validate() self.assertEqual([], self.job.pipeline.errors) description_ref = pipeline_reference('kvm-repeat.yaml') self.assertEqual(description_ref, self.job.pipeline.describe(False))
def test_job(self): with open(self.filename) as yaml_data: alpha_data = yaml.load(yaml_data) self.assertIn('protocols', alpha_data) self.assertIn(VlandProtocol.name, alpha_data['protocols']) with open(self.filename) as sample_job_data: parser = JobParser() job = parser.parse(sample_job_data, self.device, 4212, None, None, None, output_dir='/tmp/') description_ref = pipeline_reference('bbb-group-vland-alpha.yaml') self.assertEqual(description_ref, job.pipeline.describe(False)) job.validate() self.assertNotEqual([], [ protocol.name for protocol in job.protocols if protocol.name == MultinodeProtocol.name ]) ret = { "message": { "kvm01": { "vlan_name": "name", "vlan_tag": 6 } }, "response": "ack" } self.assertEqual(('name', 6), ( ret['message']['kvm01']['vlan_name'], ret['message']['kvm01']['vlan_tag'], )) self.assertIn('protocols', job.parameters) self.assertIn(VlandProtocol.name, job.parameters['protocols']) self.assertIn(MultinodeProtocol.name, job.parameters['protocols']) vprotocol = [ vprotocol for vprotocol in job.protocols if vprotocol.name == VlandProtocol.name ][0] self.assertTrue(vprotocol.valid) self.assertEqual(vprotocol.names, {'vlan_one': '4212vlanone'}) self.assertFalse(vprotocol.check_timeout(120, {'request': 'no call'})) self.assertRaises(JobError, vprotocol.check_timeout, 60, 'deploy_vlans') self.assertRaises(JobError, vprotocol.check_timeout, 60, {'request': 'deploy_vlans'}) self.assertTrue( vprotocol.check_timeout(120, {'request': 'deploy_vlans'})) for vlan_name in job.parameters['protocols'][VlandProtocol.name]: if vlan_name == 'yaml_line': continue self.assertIn(vlan_name, vprotocol.params) self.assertIn('switch', vprotocol.params[vlan_name]) self.assertIn('port', vprotocol.params[vlan_name]) self.assertIn('iface', vprotocol.params[vlan_name]) params = job.parameters['protocols'][vprotocol.name] names = [] for key, value in params.items(): if key == 'yaml_line': continue names.append(",".join([key, vprotocol.params[key]['iface']])) # this device only has one interface with interface tags self.assertEqual(names, ['vlan_one,eth1'])
def test_pixel_job(self): self.factory = FastBootFactory() job = self.factory.create_nexus5x_job('sample_jobs/pixel.yaml', mkdtemp()) description_ref = pipeline_reference('pixel.yaml') self.assertEqual(description_ref, job.pipeline.describe(False))
def test_basic_structure(self): self.assertIsNotNone(self.job) allow_missing_path(self.job.validate, self, 'qemu-system-x86_64') self.assertEqual([], self.job.pipeline.errors) description_ref = pipeline_reference('kvm-repeat.yaml') self.assertEqual(description_ref, self.job.pipeline.describe(False))
def test_multi_uboot(self): self.assertIsNotNone(self.job) description_ref = pipeline_reference('uboot-multiple.yaml') self.assertEqual(description_ref, self.job.pipeline.describe(False))
def test_pipeline(self): description_ref = pipeline_reference('kvm-inline.yaml') self.assertEqual(description_ref, self.job.pipeline.describe(False)) self.assertEqual(len(self.job.pipeline.describe()), 4) inline_repo = None for action in self.job.pipeline.actions: if isinstance(action, DeployAction): self.assertIsNotNone(action.internal_pipeline.actions[2]) overlay = action.pipeline.actions[2] self.assertIsNotNone(overlay.internal_pipeline.actions[2]) testdef = overlay.internal_pipeline.actions[2] self.assertIsNotNone(testdef.internal_pipeline.actions[0]) inline_repo = testdef.internal_pipeline.actions[0] break # Test the InlineRepoAction directly self.assertIsNotNone(inline_repo) location = mkdtemp() # other actions have not been run, so fake up inline_repo.set_namespace_data(action='test', label='results', key='lava_test_results_dir', value=location) inline_repo.set_namespace_data(action='test', label='test-definition', key='overlay_dir', value=location) inline_repo.set_namespace_data(action='test', label='shared', key='location', value=location) inline_repo.set_namespace_data(action='test', label='test-definiton', key='overlay_dir', value=location) inline_repo.run(None, None) yaml_file = os.path.join( location, '0/tests/0_smoke-tests-inline/inline/smoke-tests-basic.yaml') self.assertTrue(os.path.exists(yaml_file)) with open(yaml_file, 'r') as f_in: testdef = yaml.load(f_in) expected_testdef = { 'metadata': { 'description': 'Basic system test command for Linaro Ubuntu images', 'devices': [ 'panda', 'panda-es', 'arndale', 'vexpress-a9', 'vexpress-tc2' ], 'format': 'Lava-Test Test Definition 1.0', 'name': 'smoke-tests-basic', 'os': ['ubuntu'], 'scope': ['functional'], 'yaml_line': 39 }, 'run': { 'steps': [ 'lava-test-case linux-INLINE-pwd --shell pwd', 'lava-test-case linux-INLINE-uname --shell uname -a', 'lava-test-case linux-INLINE-vmstat --shell vmstat', 'lava-test-case linux-INLINE-ifconfig --shell ifconfig -a', 'lava-test-case linux-INLINE-lscpu --shell lscpu', 'lava-test-case linux-INLINE-lsusb --shell lsusb', 'lava-test-case linux-INLINE-lsb_release --shell lsb_release -a' ], 'yaml_line': 53 }, 'yaml_line': 38 } self.assertEqual(set(testdef), set(expected_testdef))
def test_guest_ssh(self): self.assertIsNotNone(self.guest_job) description_ref = pipeline_reference('bbb-ssh-guest.yaml') self.assertEqual(description_ref, self.guest_job.pipeline.describe(False)) self.guest_job.validate() multinode = [protocol for protocol in self.guest_job.protocols if protocol.name == MultinodeProtocol.name][0] self.assertEqual(int(multinode.system_timeout.duration), 900) self.assertEqual([], self.guest_job.pipeline.errors) self.assertEqual(len([item for item in self.guest_job.pipeline.actions if item.name == 'scp-overlay']), 1) scp_overlay = [item for item in self.guest_job.pipeline.actions if item.name == 'scp-overlay'][0] prepare = [item for item in scp_overlay.internal_pipeline.actions if item.name == 'prepare-scp-overlay'][0] self.assertEqual(prepare.host_keys, ['ipv4']) self.assertEqual(prepare.get_common_data(prepare.name, 'overlay'), prepare.host_keys) params = prepare.parameters['protocols'][MultinodeProtocol.name] for call_dict in [call for call in params if 'action' in call and call['action'] == prepare.name]: del call_dict['yaml_line'] if 'message' in call_dict: del call_dict['message']['yaml_line'] if 'timeout' in call_dict: del call_dict['timeout']['yaml_line'] self.assertEqual( call_dict, { 'action': 'prepare-scp-overlay', 'message': {'ipaddr': '$ipaddr'}, 'messageID': 'ipv4', 'request': 'lava-wait', 'timeout': {'minutes': 5} }, ) login = [action for action in self.guest_job.pipeline.actions if action.name == 'login-ssh'][0] scp = [action for action in login.internal_pipeline.actions if action.name == 'scp-deploy'][0] self.assertFalse(scp.primary) ssh = [action for action in login.internal_pipeline.actions if action.name == 'prepare-ssh'][0] self.assertFalse(ssh.primary) self.assertIsNotNone(scp.scp) self.assertFalse(scp.primary) self.assertIn('host_key', login.parameters['parameters']) self.assertIn('hostID', login.parameters['parameters']) self.assertIn( # ipv4 login.parameters['parameters']['hostID'], prepare.host_keys) prepare.set_common_data(MultinodeProtocol.name, 'ipv4', {'ipaddr': u'172.16.200.165'}) self.assertEqual(prepare.get_common_data(prepare.name, 'overlay'), prepare.host_keys) self.assertIn( login.parameters['parameters']['host_key'], prepare.get_common_data(MultinodeProtocol.name, login.parameters['parameters']['hostID'])) host_data = prepare.get_common_data(MultinodeProtocol.name, login.parameters['parameters']['hostID']) self.assertEqual( host_data[login.parameters['parameters']['host_key']], u'172.16.200.165' ) data = scp_overlay.get_common_data(MultinodeProtocol.name, 'ipv4') if 'protocols' in scp_overlay.parameters: for params in scp_overlay.parameters['protocols'][MultinodeProtocol.name]: (replacement_key, placeholder) = [(key, value) for key, value in params['message'].items() if key != 'yaml_line'][0] self.assertEqual(data[replacement_key], u'172.16.200.165') self.assertEqual(placeholder, '$ipaddr') environment = scp_overlay.get_common_data('environment', 'env_dict') self.assertIsNotNone(environment) self.assertIn('LANG', environment.keys()) self.assertIn('C', environment.values()) overlay = [item for item in scp_overlay.internal_pipeline.actions if item.name == 'lava-overlay'] self.assertIn('action', overlay[0].parameters['protocols'][MultinodeProtocol.name][0]) self.assertIn('message', overlay[0].parameters['protocols'][MultinodeProtocol.name][0]) self.assertIn('timeout', overlay[0].parameters['protocols'][MultinodeProtocol.name][0]) msg_dict = overlay[0].parameters['protocols'][MultinodeProtocol.name][0]['message'] for key, value in msg_dict.items(): if 'yaml_line' == key: continue self.assertTrue(value.startswith('$')) self.assertFalse(key.startswith('$')) self.assertIn('request', overlay[0].parameters['protocols'][MultinodeProtocol.name][0]) multinode = [item for item in overlay[0].internal_pipeline.actions if item.name == 'lava-multinode-overlay'] self.assertEqual(len(multinode), 1) # Check Pipeline description_ref = pipeline_reference('ssh-guest.yaml') self.assertEqual(description_ref, self.guest_job.pipeline.describe(False))
def test_qemu_nfs(self): self.assertIsNotNone(self.job) description_ref = 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)
def test_job_reference(self): description_ref = pipeline_reference('qemu-debian-installer.yaml') self.assertEqual(description_ref, self.job.pipeline.describe(False))
def test_uefi_job(self): self.assertIsNotNone(self.job) self.job.validate() uefi_menu = [ action for action in self.job.pipeline.actions if action.name == 'uefi-menu-action' ][0] selector = [ action for action in uefi_menu.internal_pipeline.actions if action.name == 'uefi-menu-selector' ][0] self.assertEqual(selector.selector.prompt, "Start:") self.assertIsInstance(selector.items, list) description_ref = pipeline_reference('mustang-uefi.yaml') self.assertEqual(description_ref, self.job.pipeline.describe(False)) # just dummy strings substitution_dictionary = { '{SERVER_IP}': '10.4.0.1', '{RAMDISK}': None, '{KERNEL}': 'uImage', '{DTB}': 'mustang.dtb', '{NFSROOTFS}': 'tmp/tmp21dfed/', '{TEST_MENU_NAME}': 'LAVA NFS Test Image' } for block in selector.items: if 'select' in block: if 'enter' in block['select']: block['select']['enter'] = substitute( [block['select']['enter']], substitution_dictionary) if 'items' in block['select']: block['select']['items'] = substitute( block['select']['items'], substitution_dictionary) count = 0 check_block = [ { 'items': ['Boot Manager'], 'wait': 'Choice:' }, { 'items': ['Remove Boot Device Entry'], 'fallback': 'Return to Main Menu', 'wait': 'Delete entry' }, { 'items': ['LAVA NFS Test Image'], 'wait': 'Choice:' }, { 'items': ['Add Boot Device Entry'], 'wait': 'Select the Boot Device:' }, { 'items': ['TFTP on MAC Address: 00:01:73:69:5A:EF'], 'wait': 'Get the IP address from DHCP:' }, { 'enter': ['y'], 'wait': 'Get the TFTP server IP address:' }, { 'enter': ['10.4.0.1'], 'wait': 'File path of the EFI Application or the kernel :' }, { 'enter': ['uImage'], 'wait': 'Is an EFI Application?' }, { 'enter': ['n'], 'wait': 'Boot Type:' }, { 'enter': ['f'], 'wait': 'Add an initrd:' }, { 'enter': ['n'], 'wait': 'Get the IP address from DHCP:' }, { 'enter': ['y'], 'wait': 'Get the TFTP server IP address:' }, { 'enter': ['10.4.0.1'], 'wait': 'File path of the FDT :' }, { 'enter': ['mustang.dtb'], 'wait': 'Arguments to pass to the binary:' }, { 'enter': [ 'console=ttyS0,115200 earlyprintk=uart8250-32bit,0x1c020000 debug root=/dev/nfs rw ' 'nfsroot=10.4.0.1:tmp/tmp21dfed/,tcp,hard,intr ip=dhcp' ], 'wait': 'Description for this new Entry:' }, { 'enter': ['LAVA NFS Test Image'], 'wait': 'Choice:' }, { 'items': ['Return to main menu'], 'wait': 'Start:' }, { 'items': ['LAVA NFS Test Image'] }, ] for item in selector.items: self.assertEqual(item['select'], check_block[count]) count += 1
def test_job_reference(self): description_ref = pipeline_reference("qemu-debian-installer.yaml") self.assertEqual(description_ref, self.job.pipeline.describe(False))
def test_pipeline(self): description_ref = pipeline_reference('fastboot.yaml') self.assertEqual(description_ref, self.job.pipeline.describe(False))
def test_pipeline(self): description_ref = pipeline_reference('kvm.yaml') 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] self.assertIn('persistent-nfs-overlay', [action.name for action in overlay.internal_pipeline.actions]) self.assertEqual(description_ref, self.job.pipeline.describe(False))
def test_guest_ssh(self): # pylint: disable=too-many-locals,too-many-statements self.assertIsNotNone(self.guest_job) description_ref = pipeline_reference('bbb-ssh-guest.yaml') self.assertEqual(description_ref, self.guest_job.pipeline.describe(False)) self.guest_job.validate() multinode = [ protocol for protocol in self.guest_job.protocols if protocol.name == MultinodeProtocol.name ][0] self.assertEqual(int(multinode.system_timeout.duration), 900) self.assertEqual([], self.guest_job.pipeline.errors) self.assertEqual( len([ item for item in self.guest_job.pipeline.actions if item.name == 'scp-overlay' ]), 1) scp_overlay = [ item for item in self.guest_job.pipeline.actions if item.name == 'scp-overlay' ][0] prepare = [ item for item in scp_overlay.internal_pipeline.actions if item.name == 'prepare-scp-overlay' ][0] self.assertEqual(prepare.host_keys, ['ipv4']) self.assertEqual( prepare.get_namespace_data(action=prepare.name, label=prepare.name, key='overlay'), prepare.host_keys) params = prepare.parameters['protocols'][MultinodeProtocol.name] for call_dict in [ call for call in params if 'action' in call and call['action'] == prepare.name ]: del call_dict['yaml_line'] if 'message' in call_dict: del call_dict['message']['yaml_line'] if 'timeout' in call_dict: del call_dict['timeout']['yaml_line'] self.assertEqual( call_dict, { 'action': 'prepare-scp-overlay', 'message': { 'ipaddr': '$ipaddr' }, 'messageID': 'ipv4', 'request': 'lava-wait', 'timeout': { 'minutes': 5 } }, ) login = [ action for action in self.guest_job.pipeline.actions if action.name == 'login-ssh' ][0] scp = [ action for action in login.internal_pipeline.actions if action.name == 'scp-deploy' ][0] self.assertFalse(scp.primary) ssh = [ action for action in login.internal_pipeline.actions if action.name == 'prepare-ssh' ][0] self.assertFalse(ssh.primary) self.assertIsNotNone(scp.scp) self.assertFalse(scp.primary) self.assertIn('host_key', login.parameters['parameters']) self.assertIn('hostID', login.parameters['parameters']) self.assertIn( # ipv4 login.parameters['parameters']['hostID'], prepare.host_keys) prepare.set_namespace_data(action=MultinodeProtocol.name, label=MultinodeProtocol.name, key='ipv4', value={'ipaddr': '172.16.200.165'}) self.assertEqual( prepare.get_namespace_data(action=prepare.name, label=prepare.name, key='overlay'), prepare.host_keys) self.assertIn( login.parameters['parameters']['host_key'], prepare.get_namespace_data( action=MultinodeProtocol.name, label=MultinodeProtocol.name, key=login.parameters['parameters']['hostID'])) host_data = prepare.get_namespace_data( action=MultinodeProtocol.name, label=MultinodeProtocol.name, key=login.parameters['parameters']['hostID']) self.assertEqual(host_data[login.parameters['parameters']['host_key']], '172.16.200.165') data = scp_overlay.get_namespace_data(action=MultinodeProtocol.name, label=MultinodeProtocol.name, key='ipv4') if 'protocols' in scp_overlay.parameters: for params in scp_overlay.parameters['protocols'][ MultinodeProtocol.name]: (replacement_key, placeholder) = [ (key, value) for key, value in params['message'].items() if key != 'yaml_line' ][0] self.assertEqual(data[replacement_key], '172.16.200.165') self.assertEqual(placeholder, '$ipaddr') environment = scp_overlay.get_namespace_data(action=prepare.name, label='environment', key='env_dict') self.assertIsNotNone(environment) self.assertIn('LANG', environment.keys()) self.assertIn('C', environment.values()) overlay = [ item for item in scp_overlay.internal_pipeline.actions if item.name == 'lava-overlay' ] self.assertIn( 'action', overlay[0].parameters['protocols'][MultinodeProtocol.name][0]) self.assertIn( 'message', overlay[0].parameters['protocols'][MultinodeProtocol.name][0]) self.assertIn( 'timeout', overlay[0].parameters['protocols'][MultinodeProtocol.name][0]) msg_dict = overlay[0].parameters['protocols'][ MultinodeProtocol.name][0]['message'] for key, value in msg_dict.items(): if key == 'yaml_line': continue self.assertTrue(value.startswith('$')) self.assertFalse(key.startswith('$')) self.assertIn( 'request', overlay[0].parameters['protocols'][MultinodeProtocol.name][0]) multinode = [ item for item in overlay[0].internal_pipeline.actions if item.name == 'lava-multinode-overlay' ] self.assertEqual(len(multinode), 1) # Check Pipeline description_ref = pipeline_reference('ssh-guest.yaml') self.assertEqual(description_ref, self.guest_job.pipeline.describe(False))
def test_pipeline(self): description_ref = pipeline_reference('kvm-local.yaml') self.assertEqual(description_ref, self.job.pipeline.describe(False))
def test_grub_with_monitor(self): job = self.factory.create_job('sample_jobs/grub-ramdisk-monitor.yaml') job.validate() description_ref = pipeline_reference('grub-ramdisk-monitor.yaml') self.assertEqual(description_ref, job.pipeline.describe(False))