class TestFastbootDeploy(StdoutTestCase): def setUp(self): super().setUp() self.factory = FastBootFactory() self.job = self.factory.create_fastboot_job( "sample_jobs/fastboot.yaml") def test_deploy_job(self): self.assertEqual(self.job.pipeline.job, self.job) self.assertIsInstance(self.job.device["device_info"], list) for action in self.job.pipeline.actions: self.assertEqual(action.job, self.job) def test_pipeline(self): description_ref = self.pipeline_reference("fastboot.yaml", job=self.job) self.assertEqual(description_ref, self.job.pipeline.describe(False)) @unittest.skipIf( infrastructure_error_multi_paths(["lxc-info", "img2simg", "simg2img"]), "lxc or img2simg or simg2img not installed", ) def test_lxc_api(self): job = self.factory.create_hikey_job("sample_jobs/hikey-oe.yaml") description_ref = self.pipeline_reference("hikey-oe.yaml", job=job) job.validate() self.assertEqual(description_ref, job.pipeline.describe(False)) self.assertIn(LxcProtocol.name, [protocol.name for protocol in job.protocols]) self.assertEqual(len(job.protocols), 1) self.assertIsNotNone(job.device.pre_os_command) select = [ action for action in job.pipeline.actions if action.name == "grub-sequence-action" ][0] self.assertIn(LxcProtocol.name, select.parameters.keys()) self.assertIn("protocols", select.parameters.keys()) self.assertIn(LxcProtocol.name, select.parameters["protocols"].keys()) self.assertEqual(len(select.parameters["protocols"][LxcProtocol.name]), 1) lxc_active = any([ protocol for protocol in job.protocols if protocol.name == LxcProtocol.name ]) self.assertTrue(lxc_active) for calling in select.parameters["protocols"][LxcProtocol.name]: self.assertEqual(calling["action"], select.name) self.assertEqual(calling["request"], "pre-os-command") deploy = [ action for action in job.pipeline.actions if action.name == "fastboot-deploy" ][0] self.assertIn(LxcProtocol.name, deploy.parameters.keys()) self.assertIn("protocols", deploy.parameters.keys()) self.assertIn(LxcProtocol.name, deploy.parameters["protocols"].keys()) self.assertEqual(len(deploy.parameters["protocols"][LxcProtocol.name]), 1) for calling in deploy.parameters["protocols"][LxcProtocol.name]: self.assertEqual(calling["action"], deploy.name) self.assertEqual(calling["request"], "pre-power-command") pair = ["pre-os-command", "pre-power-command"] action_list = { list(jaction.keys())[0] for jaction in job.parameters["actions"] } block = job.parameters["actions"] for action in action_list: for item in block: if action in item: if "protocols" in item[action]: caller = item[action]["protocols"][LxcProtocol.name] for call in caller: self.assertIn(call["request"], pair) @unittest.skipIf(infrastructure_error("lxc-info"), "lxc-info not installed") def test_fastboot_lxc(self): job = self.factory.create_hikey_job("sample_jobs/hi6220-hikey.yaml") description_ref = self.pipeline_reference("hi6220-hikey.yaml", job=job) self.assertEqual(description_ref, job.pipeline.describe(False)) self.assertEqual( job.device.pre_power_command, "/home/neil/lava-lab/shared/lab-scripts/usb_hub_control -u 12 -p 4000 -m sync", ) lxc_deploy = [ action for action in job.pipeline.actions if action.name == "lxc-deploy" ][0] overlay = [ action for action in lxc_deploy.pipeline.actions if action.name == "lava-overlay" ][0] testdef = [ action for action in overlay.pipeline.actions if action.name == "test-definition" ][0] job.validate() self.assertEqual( { "1.8.4.20": "4_android-optee", "1.8.4.4": "0_get-adb-serial", "1.8.4.12": "2_android-busybox", "1.8.4.8": "1_android-meminfo", "1.8.4.16": "3_android-ping-dns", }, testdef.get_namespace_data( action="test-runscript-overlay", label="test-runscript-overlay", key="testdef_levels", ), ) for testdef in testdef.test_list[0]: self.assertEqual("git", testdef["from"]) @unittest.skipIf(infrastructure_error("lxc-create"), "lxc-create not installed") def test_validate(self): try: self.job.pipeline.validate_actions() except JobError as exc: self.fail(exc) for action in self.job.pipeline.actions: self.assertEqual([], action.errors) def test_overlay(self): overlay = None action = self.job.pipeline.actions[0] self.assertEqual(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): action = self.job.pipeline.actions[1] self.assertEqual(action.parameters.get("namespace"), "tlxc") self.assertIn(action.parameters["method"], ["lxc", "fastboot"]) self.assertEqual(action.parameters["prompts"], ["root@(.*):/#"]) action = self.job.pipeline.actions[3] self.assertEqual(action.parameters.get("namespace"), "droid") self.assertIn(action.parameters["method"], ["lxc", "fastboot"]) self.assertEqual(action.parameters.get("prompts"), None) def test_testdefinitions(self): for action in self.job.pipeline.actions: if action.name == "test": # get the action & populate it self.assertEqual(len(action.parameters["definitions"]), 2) def test_udev_actions(self): self.factory = FastBootFactory() job = self.factory.create_db410c_job("sample_jobs/db410c.yaml") self.assertTrue(job.device.get("fastboot_via_uboot", True)) description_ref = self.pipeline_reference("db410c.yaml", job=job) self.assertEqual(description_ref, job.pipeline.describe(False)) boot = [ action for action in job.pipeline.actions if action.name == "fastboot-boot" ][0] @unittest.skipIf(infrastructure_error("lxc-start"), "lxc-start not installed") 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.pipeline.actions if action.name == "uboot-enter-fastboot" ][0] interrupt = [ action for action in enter.pipeline.actions if action.name == "bootloader-interrupt" ][0] self.assertTrue(interrupt.needs_interrupt) self.assertIsInstance(interrupt.params, dict) self.assertNotEqual(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.pipeline.actions if action.name == "uboot-enter-fastboot" ][0] interrupt = [ action for action in enter.pipeline.actions if action.name == "bootloader-interrupt" ][0] self.assertIsInstance(interrupt.params, dict) self.assertNotEqual(interrupt.params, {}) self.assertIn("interrupt_prompt", interrupt.params) self.assertTrue(interrupt.needs_interrupt) autologin = [ action for action in boot.pipeline.actions if action.name == "auto-login-action" ][0] self.assertTrue(autologin.booting) self.assertEqual( set(autologin.parameters.get("prompts")), set(["root@(.*):/#", "shell@am57xevm:/"]), ) self.assertIsNone(autologin.parameters.get("boot_message")) def test_sdm845_qcs(self): self.factory = FastBootFactory() job = self.factory.create_job("qcs404-evb-1k-01.jinja2", "sample_jobs/qcs404-evb-1k.yaml") # do not run job.validate() - power urls do not exist. description_ref = self.pipeline_reference("qcs404-evb-1k.yaml", job=job) self.assertEqual(description_ref, job.pipeline.describe(False)) job = self.factory.create_job("qcs404-evb-4k-01.jinja2", "sample_jobs/qcs404-evb-4k.yaml") # do not run job.validate() - power urls do not exist. description_ref = self.pipeline_reference("qcs404-evb-4k.yaml", job=job) self.assertEqual(description_ref, job.pipeline.describe(False)) 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 action = job.pipeline.actions[2] self.assertEqual(action.name, "fastboot-deploy") flash_order = [ action for action in action.pipeline.actions if action.name == "fastboot-flash-order-action" ][0] flash_action = [ action for action in flash_order.pipeline.actions if action.name == "fastboot-flash-action" ][0] flash_cmds = [ action.command for action in flash_order.pipeline.actions if action.name == "fastboot-flash-action" ] self.assertIsNotNone(flash_order) self.assertIsNotNone(flash_action) self.assertEqual(flash_action.timeout_exception, InfrastructureError) self.assertIsInstance(flash_order, FastbootFlashOrderAction) self.assertEqual(expected_flash_cmds, flash_cmds) @unittest.skipIf(infrastructure_error("lxc-start"), "lxc-start not installed") 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"] action = job.pipeline.actions[2] self.assertEqual(action.name, "fastboot-deploy") flash_order = [ action for action in action.pipeline.actions if action.name == "fastboot-flash-order-action" ][0] flash_cmds = [ action.command for action in flash_order.pipeline.actions if action.name == "fastboot-flash-action" ] self.assertIsNotNone(flash_order) self.assertIsInstance(flash_order, FastbootFlashOrderAction) self.assertEqual(expected_flash_cmds, flash_cmds) def test_fastboot_minus_lxc(self): # Do not run job.validate() since it will require some android tools # such as fastboot, adb, etc. to be installed. job = self.factory.create_fastboot_job( "sample_jobs/nexus4-minus-lxc.yaml") description_ref = self.pipeline_reference("nexus4-minus-lxc.yaml", job=job) self.assertEqual(description_ref, job.pipeline.describe(False)) # There shouldn't be any lxc defined lxc_name = is_lxc_requested(job) self.assertEqual(lxc_name, False) deploy = [ action for action in job.pipeline.actions if action.name == "fastboot-deploy" ][0] # No lxc requested, hence lxc_cmd_prefix is an empty list self.assertEqual([], lxc_cmd_prefix(job)) def test_db410c_minus_lxc(self): # Do not run job.validate() since it will require some android tools # such as fastboot, adb, etc. to be installed. job = self.factory.create_db410c_job( "sample_jobs/db410c-minus-lxc.yaml") description_ref = self.pipeline_reference("db410c-minus-lxc.yaml", job=job) self.assertEqual(description_ref, job.pipeline.describe(False)) # There shouldn't be any lxc defined lxc_name = is_lxc_requested(job) self.assertEqual(lxc_name, False) deploy = [ action for action in job.pipeline.actions if action.name == "fastboot-deploy" ][0] # No lxc requested, hence lxc_cmd_prefix is an empty list self.assertEqual([], lxc_cmd_prefix(job)) def test_fastboot_boot_commands(self): job = self.factory.create_job("imx8mq-evk-01.jinja2", "sample_jobs/imx8mq-evk.yaml") boot = [ action for action in job.pipeline.actions if action.name == "fastboot-boot" ][0] self.assertIn("commands", boot.parameters) self.assertEqual("191c51d6f060954b", job.device["fastboot_serial_number"]) self.assertIsInstance(boot.parameters["commands"], list) def test_fastboot_plus_reboot(self): job = self.factory.create_job( "imx8mq-evk-01.jinja2", "sample_jobs/imx8mq-evk-with-flash-reboot.yaml") description_ref = self.pipeline_reference( "imx8mq-evk-with-flash-reboot.yaml", job=job) self.assertEqual(description_ref, job.pipeline.describe(False))
class TestRecoveryMode(StdoutTestCase): def setUp(self): super().setUp() self.fastboot_factory = FastBootFactory() self.uboot_factory = UBootFactory() self.fastboot_job = self.fastboot_factory.create_hikey_bl_job( "sample_jobs/hi6220-recovery.yaml" ) self.uboot_job = self.uboot_factory.create_x15_bl_job( "sample_jobs/x15-recovery.yaml" ) @unittest.skipIf( infrastructure_error_multi_paths(["lxc-info", "img2simg", "simg2img"]), "lxc or img2simg or simg2img not installed", ) def test_structure_fastboot(self): self.assertIsNotNone(self.fastboot_job) self.fastboot_job.validate() description_ref = self.pipeline_reference( "hi6220-recovery.yaml", job=self.fastboot_job ) self.assertEqual(description_ref, self.fastboot_job.pipeline.describe(False)) requires_board_id = not allow_fs_label(self.fastboot_job.device) self.assertFalse(requires_board_id) if "device_info" in self.fastboot_job.device: for usb_device in self.fastboot_job.device["device_info"]: if ( usb_device.get("board_id", "") in ["", "0000000000"] and requires_board_id ): self.fail("[LXC_CREATE] board_id unset") @unittest.skipIf( infrastructure_error_multi_paths(["lxc-info", "img2simg", "simg2img"]), "lxc or img2simg or simg2img not installed", ) def test_structure_uboot(self): self.assertIsNotNone(self.uboot_job) self.uboot_job.validate() description_ref = self.pipeline_reference( "x15-recovery.yaml", job=self.uboot_job ) self.assertEqual(description_ref, self.uboot_job.pipeline.describe(False)) requires_board_id = not allow_fs_label(self.uboot_job.device) self.assertFalse(requires_board_id) if "device_info" in self.uboot_job.device: for usb_device in self.uboot_job.device["device_info"]: if ( usb_device.get("board_id", "") in ["", "1900d00f3b1400a2"] and requires_board_id ): self.fail("[LXC_CREATE] board_id unset") def test_fastboot_commands(self): enter = [ action for action in self.fastboot_job.pipeline.actions if action.name == "recovery-boot" ][0] mode = [ action for action in enter.pipeline.actions if action.name == "switch-recovery" ][0] recovery = self.fastboot_job.device["actions"]["deploy"]["methods"]["recovery"] self.assertIsNotNone(recovery["commands"].get(mode.mode)) self.assertEqual( [ "/home/neil/lava-lab/shared/lab-scripts/eth008_control -a 10.15.0.171 -r 1 -s off", "/home/neil/lava-lab/shared/lab-scripts/eth008_control -a 10.15.0.171 -r 2 -s on", ], recovery["commands"][mode.mode], ) self.assertEqual("recovery_mode", mode.mode) exit_mode = [ action for action in self.fastboot_job.pipeline.actions if action.name == "recovery-boot" ][1] mode = [ action for action in exit_mode.pipeline.actions if action.name == "switch-recovery" ][0] self.assertIsNotNone(recovery["commands"].get(mode.mode)) self.assertEqual( [ "/home/neil/lava-lab/shared/lab-scripts/eth008_control -a 10.15.0.171 -r 1 -s on", "/home/neil/lava-lab/shared/lab-scripts/eth008_control -a 10.15.0.171 -r 2 -s off", ], recovery["commands"][mode.mode], ) self.assertEqual("recovery_exit", mode.mode) def test_uboot_commands(self): enter = [ action for action in self.uboot_job.pipeline.actions if action.name == "recovery-boot" ][0] mode = [ action for action in enter.pipeline.actions if action.name == "switch-recovery" ][0] recovery = self.uboot_job.device["actions"]["deploy"]["methods"]["recovery"] self.assertIsNotNone(recovery["commands"].get(mode.mode)) self.assertEqual( [ "/usr/local/lab-scripts/eth008_control -a 192.168.0.32 -r 1 -s off", "/usr/local/lab-scripts/eth008_control -a 192.168.0.32 -r 2 -s off", "/usr/local/lab-scripts/eth008_control -a 192.168.0.32 -r 3 -s off", "/usr/local/lab-scripts/eth008_control -a 192.168.0.32 -r 4 -s off", ], recovery["commands"][mode.mode], ) self.assertEqual("recovery_mode", mode.mode) exit_mode = [ action for action in self.fastboot_job.pipeline.actions if action.name == "recovery-boot" ][1] mode = [ action for action in exit_mode.pipeline.actions if action.name == "switch-recovery" ][0] self.assertIsNotNone(recovery["commands"].get(mode.mode)) self.assertEqual( [ "/usr/local/lab-scripts/eth008_control -a 192.168.0.32 -r 1 -s on", "/usr/local/lab-scripts/eth008_control -a 192.168.0.32 -r 2 -s on", "/usr/local/lab-scripts/eth008_control -a 192.168.0.32 -r 3 -s on", "/usr/local/lab-scripts/eth008_control -a 192.168.0.32 -r 4 -s on", ], recovery["commands"][mode.mode], ) self.assertEqual("recovery_exit", mode.mode)
class TestDefinitions(StdoutTestCase): """ For compatibility until the V1 code is removed and we can start cleaning up Lava Test Shell. Parsing patterns in the Test Shell Definition YAML are problematic, difficult to debug and rely on internal python syntax. The fixupdict is even more confusing for all concerned. """ def setUp(self): super().setUp() self.testdef = os.path.join(os.path.dirname(__file__), "testdefs", "params.yaml") self.res_data = os.path.join(os.path.dirname(__file__), "testdefs", "result-data.txt") self.factory = UBootFactory() self.job = self.factory.create_bbb_job("sample_jobs/bbb-nfs-url.yaml") def test_pattern(self): self.assertTrue(os.path.exists(self.testdef)) with open(self.testdef, "r") as par: params = yaml_safe_load(par) self.assertIn("parse", params.keys()) line = "test1a: pass" self.assertEqual( r"(?P<test_case_id>.*-*):\s+(?P<result>(pass|fail))", params["parse"]["pattern"], ) match = re.search(params["parse"]["pattern"], line) self.assertIsNotNone(match) self.assertEqual(match.group(), line) self.assertEqual(match.group(1), "test1a") self.assertEqual(match.group(2), "pass") def test_v1_defaults(self): pattern = PatternFixup(testdef=None, count=0) # without a name from a testdef, the pattern is not valid. self.assertFalse(pattern.valid()) with open(self.testdef, "r") as par: params = yaml_safe_load(par) pattern = PatternFixup(testdef=params, count=0) self.assertTrue(pattern.valid()) @unittest.skipIf(check_rpcinfo(), "rpcinfo returns non-zero for nfs") @patch("lava_dispatcher.actions.deploy.tftp.which", return_value="/usr/bin/in.tftpd") def test_definition_lists(self, which_mock): self.job.validate() tftp_deploy = [ action for action in self.job.pipeline.actions if action.name == "tftp-deploy" ][0] prepare = [ action for action in tftp_deploy.pipeline.actions if action.name == "prepare-tftp-overlay" ][0] overlay = [ action for action in prepare.pipeline.actions if action.name == "lava-overlay" ][0] apply_o = [ action for action in prepare.pipeline.actions if action.name == "apply-overlay-tftp" ][0] self.assertIsInstance(apply_o.parameters.get("persistent_nfs"), dict) self.assertIsInstance( apply_o.parameters["persistent_nfs"].get("address"), str) definition = [ action for action in overlay.pipeline.actions if action.name == "test-definition" ][0] git_repos = [ action for action in definition.pipeline.actions if action.name == "git-repo-action" ] self.assertIn("common", self.job.context) self.assertIn("test-definition", self.job.context["common"]) self.assertIsNotNone( definition.get_namespace_data(action=definition.name, label="test-definition", key="testdef_index")) self.assertEqual( definition.get_namespace_data(action=definition.name, label="test-definition", key="testdef_index"), ["smoke-tests", "singlenode-advanced"], ) self.assertEqual( git_repos[0].get_namespace_data( action="test-runscript-overlay", label="test-runscript-overlay", key="testdef_levels", ), { "1.3.2.4.4": "0_smoke-tests", "1.3.2.4.8": "1_singlenode-advanced" }, ) self.assertEqual({repo.uuid for repo in git_repos}, {"4999_1.3.2.4.1", "4999_1.3.2.4.5"}) self.assertEqual( set(git_repos[0].get_namespace_data( action="test-runscript-overlay", label="test-runscript-overlay", key="testdef_levels", ).values()), {"1_singlenode-advanced", "0_smoke-tests"}, ) # fake up a run step with open(self.testdef, "r") as par: params = yaml_safe_load(par) self.assertEqual( r"(?P<test_case_id>.*-*):\s+(?P<result>(pass|fail))", params["parse"]["pattern"], ) self.job.context.setdefault("test", {}) for git_repo in git_repos: self.job.context["test"].setdefault(git_repo.uuid, {}) self.job.context["test"][git_repo.uuid]["testdef_pattern"] = { "pattern": params["parse"]["pattern"] } self.assertEqual( self.job.context["test"], { "4999_1.3.2.4.5": { "testdef_pattern": { "pattern": "(?P<test_case_id>.*-*):\\s+(?P<result>(pass|fail))" } }, "4999_1.3.2.4.1": { "testdef_pattern": { "pattern": "(?P<test_case_id>.*-*):\\s+(?P<result>(pass|fail))" } }, }, ) testdef_index = self.job.context["common"]["test-definition"][ "test-definition"]["testdef_index"] start_run = "0_smoke-tests" uuid_list = definition.get_namespace_data(action="repo-action", label="repo-action", key="uuid-list") self.assertIsNotNone(uuid_list) for key, value in enumerate(testdef_index): if start_run == "%s_%s" % (key, value): self.assertEqual("4999_1.3.2.4.1", uuid_list[key]) self.assertEqual( self.job.context["test"][uuid_list[key]]["testdef_pattern"] ["pattern"], "(?P<test_case_id>.*-*):\\s+(?P<result>(pass|fail))", ) def test_defined_pattern(self): """ For python3 support, need to resolve: TypeError: cannot use a bytes pattern on a string-like object TypeError: cannot use a string pattern on a bytes-like object whilst retaining re_pat as a compiled regular expression in the pexpect support. """ data = """test1a: pass test2a: fail test3a: skip \"test4a:\" \"unknown\" """ with open(self.testdef, "r") as par: params = yaml_safe_load(par) pattern = params["parse"]["pattern"] re_pat = re.compile(pattern, re.M) match = re.search(re_pat, data) if match: self.assertEqual(match.groupdict(), { "test_case_id": "test1a", "result": "pass" }) child = pexpect.spawn("cat", [self.res_data], encoding="utf-8") child.expect([re_pat, pexpect.EOF]) self.assertEqual(child.after.encode("utf-8"), b"test1a: pass") child.expect([re_pat, pexpect.EOF]) self.assertEqual(child.after.encode("utf-8"), b"test2a: fail") child.expect([re_pat, pexpect.EOF]) self.assertEqual(child.after, pexpect.EOF) @unittest.skipIf( infrastructure_error_multi_paths(["lxc-info", "img2simg", "simg2img"]), "lxc or img2simg or simg2img not installed", ) def test_deployment_data(self): job = self.factory.create_job("hi960-hikey-01.jinja2", "sample_jobs/hikey960-oe-aep.yaml") job.validate() description_ref = self.pipeline_reference("hikey960-oe-aep.yaml", job=job) self.assertEqual(description_ref, job.pipeline.describe(False)) lxc_deploy = [ action for action in job.pipeline.actions if action.name == "lxc-deploy" ][0] lxc_overlay = [ action for action in lxc_deploy.pipeline.actions if action.name == "lava-overlay" ][0] lxc_defs = [ action for action in lxc_overlay.pipeline.actions if action.name == "test-definition" ][0] lxc_installscript = [ action for action in lxc_defs.pipeline.actions if action.name == "test-install-overlay" ][0] fastboot_deploy = [ action for action in job.pipeline.actions if action.name == "fastboot-deploy" ][0] fastboot_overlay = [ action for action in fastboot_deploy.pipeline.actions if action.name == "lava-overlay" ][0] fastboot_defs = [ action for action in fastboot_overlay.pipeline.actions if action.name == "test-definition" ][0] fastboot_installscript = [ action for action in fastboot_defs.pipeline.actions if action.name == "test-install-overlay" ][0] self.assertIn("distro", lxc_installscript.parameters["deployment_data"].keys()) self.assertIn( "distro", list(lxc_installscript.parameters["deployment_data"].keys())) self.assertIn("distro", list(lxc_installscript.parameters["deployment_data"])) self.assertIn("distro", dict(lxc_installscript.parameters["deployment_data"])) self.assertEqual( "debian", lxc_installscript.parameters["deployment_data"]["distro"]) self.assertIn( "distro", fastboot_installscript.parameters["deployment_data"].keys()) self.assertIn( "distro", list(fastboot_installscript.parameters["deployment_data"].keys())) self.assertIn("distro", fastboot_installscript.parameters["deployment_data"]) self.assertIn( "distro", dict(fastboot_installscript.parameters["deployment_data"])) self.assertEqual( "oe", fastboot_installscript.parameters["deployment_data"]["distro"])
class TestGrubAction(StdoutTestCase): def setUp(self): super().setUp() self.factory = GrubFactory() @unittest.skipIf(infrastructure_error("mkimage"), "u-boot-tools not installed") @patch("lava_dispatcher.actions.deploy.tftp.which", return_value="/usr/bin/in.tftpd") def test_simulated_action(self, which_mock): job = self.factory.create_job("d02-01.jinja2", "sample_jobs/grub-ramdisk.yaml") self.assertIsNotNone(job) # uboot and uboot-ramdisk have the same pipeline structure description_ref = self.pipeline_reference("grub.yaml", job=job) self.assertEqual(description_ref, job.pipeline.describe(False)) self.assertIsNone(job.validate()) def test_tftp_pipeline(self): job = self.factory.create_job("d02-01.jinja2", "sample_jobs/grub-ramdisk.yaml") self.assertEqual( [action.name for action in job.pipeline.actions], ["tftp-deploy", "grub-main-action", "lava-test-retry", "finalize"], ) tftp = [ action for action in job.pipeline.actions if action.name == "tftp-deploy" ][0] self.assertTrue( tftp.get_namespace_data(action=tftp.name, label="tftp", key="ramdisk")) self.assertIsNotNone(tftp.pipeline) self.assertEqual( [action.name for action in tftp.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.pipeline.actions if hasattr(action, "key") ], ) self.assertIn( "kernel", [ action.key for action in tftp.pipeline.actions if hasattr(action, "key") ], ) self.assertIn( "dtb", [ action.key for action in tftp.pipeline.actions if hasattr(action, "key") ], ) self.assertNotIn("=", filesystem.tftpd_dir()) def test_device_d02(self): job = self.factory.create_job("d02-01.jinja2", "sample_jobs/grub-ramdisk.yaml") self.assertNotIn("connect", job.device["commands"]) self.assertEqual( job.device["commands"]["connections"]["uart0"]["connect"], "telnet ratchet 7003", ) self.assertEqual(job.device["commands"].get("interrupt", " "), " ") methods = job.device["actions"]["boot"]["methods"] self.assertIn("grub", methods) self.assertEqual( methods["grub"]["parameters"].get("bootloader_prompt"), "grub>") @unittest.skipIf(infrastructure_error("mkimage"), "u-boot-tools not installed") @patch("lava_dispatcher.actions.deploy.tftp.which", return_value="/usr/bin/in.tftpd") def test_grub_action(self, which_mock): job = self.factory.create_job("d02-01.jinja2", "sample_jobs/grub-ramdisk.yaml") job.validate() self.assertEqual(job.pipeline.errors, []) self.assertIn("grub", job.device["actions"]["boot"]["methods"]) params = job.device["actions"]["boot"]["methods"]["grub"]["parameters"] boot_message = params.get( "boot_message", job.device.get_constant("kernel-start-message")) self.assertIsNotNone(boot_message) for action in job.pipeline.actions: action.validate() if isinstance(action, GrubMainAction): self.assertIn("method", action.parameters) self.assertEqual("grub", action.parameters["method"]) if isinstance(action, TftpAction): self.assertIn("ramdisk", action.parameters) self.assertIn("kernel", action.parameters) self.assertIn("to", action.parameters) self.assertEqual("tftp", action.parameters["to"]) if isinstance(action, BootloaderInterruptAction): self.assertFalse(action.interrupt_newline) self.assertTrue(action.valid) def test_overlay_action(self): parameters = { "device_type": "d02", "job_name": "grub-standard-ramdisk", "job_timeout": "15m", "action_timeout": "5m", "priority": "medium", "actions": { "boot": { "method": "grub", "commands": "ramdisk", "prompts": ["linaro-test", "root@debian:~#"], }, "deploy": { "ramdisk": "initrd.gz", "kernel": "zImage", "dtb": "broken.dtb", }, }, } (rendered, _) = self.factory.create_device("d02-01.jinja2") device = NewDevice(yaml_safe_load(rendered)) job = Job(4212, parameters, None) job.device = device pipeline = Pipeline(job=job, parameters=parameters["actions"]["boot"]) job.pipeline = pipeline overlay = BootloaderCommandOverlay() pipeline.add_action(overlay) ip_addr = dispatcher_ip(None) parsed = [] kernel = parameters["actions"]["deploy"]["kernel"] ramdisk = parameters["actions"]["deploy"]["ramdisk"] dtb = parameters["actions"]["deploy"]["dtb"] substitution_dictionary = { "{SERVER_IP}": ip_addr, # the addresses need to be hexadecimal "{RAMDISK}": ramdisk, "{KERNEL}": kernel, "{DTB}": dtb, } params = device["actions"]["boot"]["methods"] commands = params["grub"]["ramdisk"]["commands"] self.assertIn("net_bootp", commands) self.assertIn( "linux (tftp,{SERVER_IP})/{KERNEL} console=ttyS0,115200 earlycon=uart8250,mmio32,0x80300000 root=/dev/ram0 ip=dhcp", commands, ) self.assertIn("initrd (tftp,{SERVER_IP})/{RAMDISK}", commands) self.assertIn("devicetree (tftp,{SERVER_IP})/{DTB}", commands) params["grub"]["ramdisk"]["commands"] = substitute( params["grub"]["ramdisk"]["commands"], substitution_dictionary) substituted_commands = params["grub"]["ramdisk"]["commands"] self.assertIs(type(substituted_commands), list) self.assertIn("net_bootp", substituted_commands) self.assertNotIn( "linux (tftp,{SERVER_IP})/{KERNEL} console=ttyS0,115200 earlycon=uart8250,mmio32,0x80300000 root=/dev/ram0 ip=dhcp", substituted_commands, ) self.assertIn( "linux (tftp,%s)/%s console=ttyS0,115200 earlycon=uart8250,mmio32,0x80300000 root=/dev/ram0 ip=dhcp" % (ip_addr, kernel), substituted_commands, ) self.assertNotIn("initrd (tftp,{SERVER_IP})/{RAMDISK}", parsed) self.assertNotIn("devicetree (tftp,{SERVER_IP})/{DTB}", parsed) @patch("lava_dispatcher.actions.deploy.tftp.which", return_value="/usr/bin/in.tftpd") def test_download_action(self, which_mock): job = self.factory.create_job("d02-01.jinja2", "sample_jobs/grub-nfs.yaml") for action in job.pipeline.actions: action.validate() if not action.valid: raise JobError(action.errors) self.assertTrue(action.valid) job.validate() self.assertEqual(job.pipeline.errors, []) deploy = None overlay = None extract = None for action in job.pipeline.actions: if action.name == "tftp-deploy": deploy = action if deploy: for action in deploy.pipeline.actions: if action.name == "prepare-tftp-overlay": overlay = action if overlay: for action in overlay.pipeline.actions: if action.name == "extract-nfsrootfs": extract = action test_dir = overlay.get_namespace_data(action="test", label="results", key="lava_test_results_dir") self.assertIsNotNone(test_dir) self.assertIn("/lava-", test_dir) self.assertIsNotNone(extract) self.assertEqual(extract.timeout.duration, 600) @patch("lava_dispatcher.actions.deploy.tftp.which", return_value="/usr/bin/in.tftpd") def test_reset_actions(self, which_mock): job = self.factory.create_job("d02-01.jinja2", "sample_jobs/grub-ramdisk.yaml") grub_action = None for action in job.pipeline.actions: action.validate() self.assertTrue(action.valid) if action.name == "grub-main-action": grub_action = action names = [r_action.name for r_action in grub_action.pipeline.actions] self.assertIn("connect-device", names) self.assertIn("reset-device", names) self.assertIn("bootloader-interrupt", names) self.assertIn("expect-shell-connection", names) self.assertIn("bootloader-commands", names) @patch("lava_dispatcher.actions.deploy.tftp.which", return_value="/usr/bin/in.tftpd") def test_grub_with_monitor(self, which_mock): job = self.factory.create_job("d02-01.jinja2", "sample_jobs/grub-ramdisk-monitor.yaml") job.validate() description_ref = self.pipeline_reference("grub-ramdisk-monitor.yaml", job=job) self.assertEqual(description_ref, job.pipeline.describe(False)) @patch("lava_dispatcher.actions.deploy.tftp.which", return_value="/usr/bin/in.tftpd") def test_grub_via_efi(self, which_mock): job = self.factory.create_mustang_job( "sample_jobs/mustang-grub-efi-nfs.yaml") self.assertIsNotNone(job) job.validate() description_ref = self.pipeline_reference("mustang-grub-efi-nfs.yaml", job=job) self.assertEqual(description_ref, job.pipeline.describe(False)) grub = [ action for action in job.pipeline.actions if action.name == "grub-main-action" ][0] menu = [ action for action in grub.pipeline.actions if action.name == "uefi-menu-interrupt" ][0] self.assertIn("item_class", menu.params) grub_efi = [ action for action in grub.pipeline.actions if action.name == "grub-efi-menu-selector" ][0] self.assertEqual("pxe-grub", grub_efi.commands) @unittest.skipIf(infrastructure_error("lxc-start"), "lxc-start not installed") def test_hikey_grub_efi(self): job = self.factory.create_hikey_job("sample_jobs/hikey-grub-lxc.yaml") self.assertIsNotNone(job) job.validate() description_ref = self.pipeline_reference("hikey-grub-efi.yaml", job=job) self.assertEqual(description_ref, job.pipeline.describe(False)) @unittest.skipIf( infrastructure_error_multi_paths(["lxc-info", "img2simg", "simg2img"]), "lxc or img2simg or simg2img not installed", ) def test_hikey_uart(self): job = self.factory.create_hikey_job("sample_jobs/hikey-console.yaml") self.assertIsNotNone(job) job.validate() description_ref = self.pipeline_reference("hikey-console.yaml", job=job) self.assertEqual(description_ref, job.pipeline.describe(False)) console = [ action for action in job.pipeline.actions if action.name == "secondary-shell-action" ][0] command = [ action for action in console.pipeline.actions if action.name == "connect-shell" ][0] self.assertEqual("isolation", command.parameters["namespace"]) self.assertEqual("uart0", command.hardware) self.assertIn("connections", job.device["commands"]) uart = job.device["commands"]["connections"][ command.hardware]["connect"] self.assertIn(command.command, uart) self.assertEqual("telnet localhost 4002", uart) tshells = [ action for action in job.pipeline.actions if action.name == "lava-test-retry" ] for shell in tshells: cn = shell.parameters.get("connection-namespace") if cn: self.assertEqual(shell.parameters["namespace"], "hikey-oe") self.assertNotEqual(shell.parameters["namespace"], "isolation") self.assertNotEqual(shell.parameters["namespace"], "tlxc") self.assertEqual(shell.parameters["connection-namespace"], "isolation") retry = [action for action in shell.pipeline.actions][0] self.assertEqual(retry.parameters["connection-namespace"], "isolation") else: self.assertNotEqual(shell.parameters["namespace"], "hikey-oe") self.assertNotEqual(shell.parameters["namespace"], "isolation") self.assertEqual(shell.parameters["namespace"], "tlxc") self.assertNotIn("connection-namespace", shell.parameters.keys()) menu = [ action for action in job.pipeline.actions if action.name == "grub-sequence-action" ][0] autologin = [ action for action in menu.pipeline.actions if action.name == "auto-login-action" ][0] self.assertIsNone(autologin.params) self.assertEqual(["login:"******"prompts")) menu = [ action for action in job.pipeline.actions if action.name == "secondary-shell-action" ][0] autologin = [ action for action in menu.pipeline.actions if action.name == "auto-login-action" ][0] self.assertIsNotNone(autologin.parameters) self.assertIn("isolation", autologin.job.test_info) self.assertIn("hikey-oe", autologin.job.test_info) self.assertIn("tlxc", autologin.job.test_info) @unittest.skipIf(infrastructure_error("lxc-start"), "lxc-start not installed") def test_hikey960_grub(self): job = self.factory.create_hikey960_job("sample_jobs/hikey960-oe.yaml") self.assertIsNotNone(job) job.validate() description_ref = self.pipeline_reference("hi960-grub-efi.yaml", job=job) self.assertEqual(description_ref, job.pipeline.describe(False)) deploy = [ action for action in job.pipeline.actions if action.name == "fastboot-deploy" ][0] flash_ord = [ action for action in deploy.pipeline.actions if action.name == "fastboot-flash-order-action" ][0] flash = [ action for action in flash_ord.pipeline.actions if action.name == "fastboot-flash-action" ][0] self.assertIsNotNone(flash.interrupt_prompt) self.assertEqual("Android Fastboot mode", flash.interrupt_prompt) self.assertIsNotNone(flash.interrupt_string) self.assertEqual(" ", flash.interrupt_string) grub_seq = [ action for action in job.pipeline.actions if action.name == "grub-sequence-action" ][0] self.assertIsNotNone(grub_seq) wait = [ action for action in grub_seq.pipeline.actions if action.name == "wait-fastboot-interrupt" ][0] self.assertIsNotNone(wait) login = [ action for action in grub_seq.pipeline.actions if action.name == "auto-login-action" ][0] self.assertIsNotNone(login) @patch("lava_dispatcher.actions.deploy.tftp.which", return_value="/usr/bin/in.tftpd") def test_synquacer_grub(self, which_mock): job = self.factory.create_job("synquacer-dtb-01.jinja2", "sample_jobs/synquacer-dtb.yaml") self.assertIsNotNone(job) job.validate() description_ref = self.pipeline_reference("synquacer_dtb.yaml", job=job) self.assertEqual(description_ref, job.pipeline.describe(False))