class TestDownloadDeploy(StdoutTestCase): # pylint: disable=too-many-public-methods def setUp(self): super().setUp() self.factory = Factory() self.job = self.factory.create_job( "db410c-01.jinja2", "sample_jobs/download.yaml" ) def test_deploy_job(self): self.assertEqual(self.job.pipeline.job, self.job) self.assertIsInstance(self.job.device["device_info"], list) for action in self.job.pipeline.actions: if isinstance(action, DeployAction): self.assertEqual(action.job, self.job) def test_pipeline(self): description_ref = self.pipeline_reference("download.yaml") self.assertEqual(description_ref, self.job.pipeline.describe(False)) @unittest.skipIf( infrastructure_error_multi_paths(["lxc-info", "img2simg", "simg2img"]), "lxc or img2simg or simg2img not installed", ) def test_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_directories(self): job = self.factory.create_job("bbb-01.jinja2", "sample_jobs/download_dir.yaml") with self.assertRaises(JobError): job.validate()
def test_device_parser(self): job_parser = JobParser() factory = Factory() job = factory.create_job("bbb-01.jinja2", "sample_jobs/uboot-ramdisk.yaml") uboot_action = None device = job.device 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") self.assertTrue(action.interrupt_newline) 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 test_tc2_uefi_job(self, which_mock): factory = Factory() job = factory.create_job("tc2-01.jinja2", "sample_jobs/tc2.yaml") job.validate() self.assertEqual([], job.pipeline.errors) description_ref = self.pipeline_reference("tc2.yaml", job=self.job) self.assertEqual(description_ref, self.job.pipeline.describe(False)) self.assertIn("uefi-menu", job.device["actions"]["boot"]["methods"]) uefi_menu_block = job.device["actions"]["boot"]["methods"]["uefi-menu"] nfs_boot = uefi_menu_block["nfs"] block = [ step for step in nfs_boot if step["select"].get("wait") == "Description for this new Entry:" ] self.assertIsNotNone(block) self.assertEqual(len(block), 1) expected_nfs_args = "console=ttyAMA0,38400n8 root=/dev/nfs rw nfsroot={NFS_SERVER_IP}:{NFSROOTFS},tcp,hard,intr,vers=3 rootwait debug systemd.log_target=null user_debug=31 loglevel=9 ip=dhcp" self.assertEqual(block[0]["select"]["enter"], expected_nfs_args)
class TestLxcWithDevices(StdoutTestCase): def setUp(self): super().setUp() self.factory = LxcFactory() self.job = self.factory.create_bbb_lxc_job("sample_jobs/bbb-lxc.yaml") @unittest.skipIf(infrastructure_error("lxc-start"), "lxc-start not installed") def test_lxc_feedback(self): # pylint: disable=too-many-locals self.assertIsNotNone(self.job) # validate with two test actions, lxc and device self.job.validate() drone_test = [ action for action in self.job.pipeline.actions if action.name == "lava-test-retry" ][0] self.assertNotEqual(10, drone_test.connection_timeout.duration) drone_shell = [ action for action in drone_test.internal_pipeline.actions if action.name == "lava-test-shell" ][0] self.assertEqual(10, drone_shell.connection_timeout.duration) @unittest.skipIf(infrastructure_error("lxc-start"), "lxc-start not installed") def test_lxc_with_device(self): # pylint: disable=too-many-locals self.assertIsNotNone(self.job) # validate with two test actions, lxc and device self.job.validate() lxc_yaml = os.path.join(os.path.dirname(__file__), "sample_jobs/bbb-lxc.yaml") with open(lxc_yaml) as sample_job_data: data = yaml.safe_load(sample_job_data) lxc_deploy = [ action for action in self.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] test_def = [ action for action in overlay.internal_pipeline.actions if action.name == "test-definition" ][0] self.assertIsNotNone(test_def.level, test_def.test_list) runner = [ action for action in test_def.internal_pipeline.actions if action.name == "test-runscript-overlay" ][0] self.assertIsNotNone(runner.testdef_levels) tftp_deploy = [ action for action in self.job.pipeline.actions if action.name == "tftp-deploy" ][0] prepare = [ action for action in tftp_deploy.internal_pipeline.actions if action.name == "prepare-tftp-overlay" ][0] overlay = [ action for action in prepare.internal_pipeline.actions if action.name == "lava-overlay" ][0] test_def = [ action for action in overlay.internal_pipeline.actions if action.name == "test-definition" ][0] namespace = test_def.parameters.get("namespace") self.assertIsNotNone(namespace) test_actions = [ action for action in self.job.parameters["actions"] if "test" in action ] for action in test_actions: if "namespace" in action["test"]: if action["test"]["namespace"] == namespace: self.assertEqual(action["test"]["definitions"][0]["name"], "smoke-tests-bbb") namespace_tests = [ action["test"]["definitions"] for action in test_actions if "namespace" in action["test"] and action["test"]["namespace"] == namespace ] self.assertEqual(len(namespace_tests), 1) self.assertEqual(len(test_actions), 2) self.assertEqual("smoke-tests-bbb", namespace_tests[0][0]["name"]) self.assertEqual("smoke-tests-bbb", test_def.test_list[0][0]["name"]) self.assertIsNotNone(test_def.level, test_def.test_list) runner = [ action for action in test_def.internal_pipeline.actions if action.name == "test-runscript-overlay" ][0] self.assertIsNotNone(runner.testdef_levels) # remove the second test action data["actions"].pop() test_actions = [ action for action in data["actions"] if "test" in action ] self.assertEqual(len(test_actions), 1) self.assertEqual(test_actions[0]["test"]["namespace"], "probe") parser = JobParser() (rendered, _) = self.factory.create_device("bbb-01.jinja2") device = NewDevice(yaml.safe_load(rendered)) job = parser.parse(yaml.dump(data), device, 4577, None, "") job.logger = DummyLogger() job.validate() lxc_deploy = [ action for action in self.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] test_def = [ action for action in overlay.internal_pipeline.actions if action.name == "test-definition" ][0] self.assertIsNotNone(test_def.level, test_def.test_list) runner = [ action for action in test_def.internal_pipeline.actions if action.name == "test-runscript-overlay" ][0] self.assertIsNotNone(runner.testdef_levels) @unittest.skipIf(infrastructure_error("lxc-start"), "lxc-start not installed") def test_lxc_with_static_device(self): # pylint: disable=too-many-locals self.job = self.factory.create_hikey_aep_job( "sample_jobs/hi6220-hikey.yaml") self.job.validate() lxc_boot = [ action for action in self.job.pipeline.actions if action.name == "lxc-boot" ][0] lxc_static = [ action for action in lxc_boot.internal_pipeline.actions if action.name == "lxc-add-static" ][0] self.assertIsNotNone(lxc_static) self.assertIsInstance(self.job.device.get("static_info"), list) self.assertEqual(len(self.job.device.get("static_info")), 1) for board in self.job.device.get("static_info"): self.assertIsInstance(board, dict) self.assertIn("board_id", board) self.assertEqual(board["board_id"], "S/NO62200001") description_ref = self.pipeline_reference("hi6220-hikey.yaml", job=self.job) self.assertEqual(description_ref, self.job.pipeline.describe(False)) @unittest.skipIf(infrastructure_error("lxc-start"), "lxc-start not installed") def test_lxc_without_lxctest(self): # pylint: disable=too-many-locals lxc_yaml = os.path.join(os.path.dirname(__file__), "sample_jobs/bbb-lxc-notest.yaml") with open(lxc_yaml) as sample_job_data: data = yaml.safe_load(sample_job_data) parser = JobParser() (rendered, _) = self.factory.create_device("bbb-01.jinja2") device = NewDevice(yaml.safe_load(rendered)) job = parser.parse(yaml.dump(data), device, 4577, None, "") job.logger = DummyLogger() job.validate() lxc_deploy = [ action for action in job.pipeline.actions if action.name == "lxc-deploy" ][0] names = [ action.name for action in lxc_deploy.internal_pipeline.actions ] self.assertNotIn("prepare-tftp-overlay", names) namespace1 = lxc_deploy.parameters.get("namespace") tftp_deploy = [ action for action in job.pipeline.actions if action.name == "tftp-deploy" ][0] prepare = [ action for action in tftp_deploy.internal_pipeline.actions if action.name == "prepare-tftp-overlay" ][0] overlay = [ action for action in prepare.internal_pipeline.actions if action.name == "lava-overlay" ][0] test_def = [ action for action in overlay.internal_pipeline.actions if action.name == "test-definition" ][0] namespace = test_def.parameters.get("namespace") self.assertIsNotNone(namespace) self.assertIsNotNone(namespace1) self.assertNotEqual(namespace, namespace1) self.assertNotEqual(self.job.pipeline.describe(False), job.pipeline.describe(False)) test_actions = [ action for action in job.parameters["actions"] if "test" in action ] for action in test_actions: if "namespace" in action["test"]: if action["test"]["namespace"] == namespace: self.assertEqual(action["test"]["definitions"][0]["name"], "smoke-tests-bbb") else: self.fail("Found a test action not from the tftp boot") namespace_tests = [ action["test"]["definitions"] for action in test_actions if "namespace" in action["test"] and action["test"]["namespace"] == namespace ] self.assertEqual(len(namespace_tests), 1) self.assertEqual(len(test_actions), 1) description_ref = self.pipeline_reference("bbb-lxc-notest.yaml", job=job) self.assertEqual(description_ref, job.pipeline.describe(False)) def test_adb_nuc_job(self): self.factory = LxcFactory() job = self.factory.create_adb_nuc_job("sample_jobs/adb-nuc.yaml") description_ref = self.pipeline_reference("adb-nuc.yaml", job=job) self.assertEqual(description_ref, job.pipeline.describe(False)) @unittest.skipIf(infrastructure_error("lxc-start"), "lxc-start not installed") def test_iot_lxc(self): self.factory = Factory() job = self.factory.create_job("frdm-k64f-01.jinja2", "sample_jobs/frdm-k64f-lxc.yaml") job.validate() self.assertIsNotNone([ action for action in job.pipeline.actions if action.name == "lxc-deploy" ]) self.assertIsNotNone([ action for action in job.pipeline.actions if action.name == "lxc-boot" ]) description_ref = self.pipeline_reference("frdm-k64f-lxc.yaml", job=job) self.assertEqual(description_ref, job.pipeline.describe(False))
class TestKVMBasicDeploy(StdoutTestCase): # pylint: disable=too-many-public-methods def setUp(self): super().setUp() self.factory = Factory() job_ctx = { "arch": "amd64", "no_kvm": True, } # override to allow unit tests on all types of systems self.job = self.factory.create_job("qemu01.jinja2", "sample_jobs/kvm.yaml", job_ctx) def test_deploy_job(self): self.assertEqual(self.job.pipeline.job, self.job) for action in self.job.pipeline.actions: if isinstance(action, DeployAction): self.assertEqual(action.job, self.job) def test_pipeline(self): description_ref = self.pipeline_reference("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_validate(self): try: allow_missing_path(self.job.pipeline.validate_actions, self, "qemu-system-x86_64") except JobError as exc: self.fail(exc) for action in self.job.pipeline.actions: self.assertEqual([], action.errors) def test_available_architectures(self): job_ctx = {"arch": "unknown", "no_kvm": True} job = self.factory.create_job("qemu01.jinja2", "sample_jobs/kvm.yaml", job_ctx) self.assertIsNotNone(job.device["available_architectures"]) self.assertEqual(job.parameters["context"]["arch"], "unknown") self.assertRaises(JobError, job.pipeline.validate_actions) def test_overlay(self): overlay = None for action in self.job.pipeline.actions: self.assertIsNotNone(action.name) if isinstance(action, DeployAction): overlay = action.pipeline.actions[2] 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-*"))) def test_boot(self): for action in self.job.pipeline.actions: if isinstance(action, BootAction): # get the action & populate it self.assertEqual(action.parameters["method"], "qemu") self.assertEqual(action.parameters["prompts"], ["linaro-test", "root@debian:~#"]) params = action.parameters.get("auto_login") if "login_prompt" in params: self.assertEqual(params["login_prompt"], "login:"******"username" in params: self.assertEqual(params["username"], "root") def test_testdefinitions(self): for action in self.job.pipeline.actions: if action.name == "test": # get the action & populate it self.assertEqual(len(action.parameters["definitions"]), 2)
def setUp(self): super().setUp() factory = Factory() self.job = factory.create_job("kvm02.jinja2", "sample_jobs/qemu-nfs.yaml") self.job.logger = DummyLogger()
class TestDefinitionHandlers(StdoutTestCase): # pylint: disable=too-many-public-methods def setUp(self): super().setUp() self.factory = Factory() self.job = self.factory.create_job("qemu01.jinja2", "sample_jobs/kvm.yaml") with open( os.path.join(os.path.dirname(__file__), "testdefs", "params.yaml"), "r") as params: self.testdef = yaml.safe_load(params) def test_testdef(self): testdef = overlay = None for action in self.job.pipeline.actions: self.assertIsNotNone(action.name) if isinstance(action, DeployAction): overlay = action.pipeline.actions[2] testdef = overlay.internal_pipeline.actions[2] self.assertEqual(len(overlay.internal_pipeline.actions), 5) self.assertIsInstance(testdef, TestDefinitionAction) testdef.validate() self.assertEqual(testdef.run_levels, { "smoke-tests": 0, "singlenode-advanced": 0 }) if not testdef.valid: print(testdef.errors) self.assertTrue(testdef.valid) for repo_action in testdef.internal_pipeline.actions: if isinstance(repo_action, GitRepoAction): self.assertTrue(hasattr(repo_action, "accepts")) self.assertTrue(hasattr(repo_action, "priority")) elif isinstance(repo_action, TestOverlayAction): self.assertTrue(hasattr(repo_action, "test_uuid")) self.assertFalse(hasattr(repo_action, "accepts")) self.assertFalse(hasattr(repo_action, "priority")) else: self.fail( "%s does not match GitRepoAction or TestOverlayAction" % type(repo_action)) repo_action.validate() # FIXME # if hasattr(repo_action, 'uuid'): # repo_action.data['test'] = {repo_action.uuid: {}} # repo_action.store_testdef(self.testdef, 'git', 'abcdef') # self.assertEqual( # repo_action.data['test'][repo_action.uuid]['testdef_pattern'], # self.testdef['parse']) self.assertTrue(repo_action.valid) # FIXME: needs deployment_data to be visible during validation # self.assertNotEqual(repo_action.runner, None) self.assertIsNotNone( testdef.parameters["deployment_data"]["lava_test_results_dir"]) def test_name(self): deploy = [ action for action in self.job.pipeline.actions if action.name == "deployimages" ][0] overlay = [ action for action in deploy.internal_pipeline.actions if action.name == "lava-overlay" ][0] testdef = [ action for action in overlay.internal_pipeline.actions if action.name == "test-definition" ][0] testdef.validate() self.assertEqual([], testdef.errors) (rendered, _) = self.factory.create_device("kvm01.jinja2") device = yaml.safe_load(rendered) kvm_yaml = os.path.join(os.path.dirname(__file__), "sample_jobs/kvm.yaml") parser = JobParser() with open(kvm_yaml, "r") as sample_job_data: content = yaml.safe_load(sample_job_data) data = [ block["test"] for block in content["actions"] if "test" in block ][0] definitions = [ block for block in data["definitions"] if "path" in block ][0] definitions["name"] = "smoke tests" job = parser.parse(yaml.dump(content), device, 4212, None, "") deploy = [ action for action in job.pipeline.actions if action.name == "deployimages" ][0] overlay = [ action for action in deploy.internal_pipeline.actions if action.name == "lava-overlay" ][0] testdef = [ action for action in overlay.internal_pipeline.actions if action.name == "test-definition" ][0] testdef.validate() self.assertNotEqual([], testdef.errors) self.assertIn( "Invalid characters found in test definition name: smoke tests", job.pipeline.errors, ) def test_vcs_parameters(self): deploy = [ action for action in self.job.pipeline.actions if action.name == "deployimages" ][0] overlay = [ action for action in deploy.internal_pipeline.actions if action.name == "lava-overlay" ][0] testdef = [ action for action in overlay.internal_pipeline.actions if action.name == "test-definition" ][0] git_repos = [ action for action in testdef.internal_pipeline.actions if action.name == "git-repo-action" ] for git_repo in git_repos: if (git_repo.parameters["repository"] == "http://git.linaro.org/lava-team/lava-functional-tests.git" ): self.assertIn("revision", git_repo.parameters) self.assertIn("branch", git_repo.parameters) else: self.assertNotIn("revision", git_repo.parameters) self.assertNotIn("branch", git_repo.parameters) def test_overlay(self): script_list = [ "lava-add-keys", "lava-add-sources", "lava-background-process-start", "lava-background-process-stop", "lava-echo-ipv4", "lava-install-packages", "lava-installed-packages", "lava-os-build", "lava-probe-channel", "lava-probe-ip", "lava-target-ip", "lava-target-mac", "lava-target-storage", "lava-test-case", "lava-test-event", "lava-test-feedback", "lava-test-reference", "lava-test-runner", "lava-test-set", "lava-test-shell", "lava-test-raise", "lava-common-functions", ] overlay = None for action in self.job.pipeline.actions: if isinstance(action, DeployAction): for child in action.pipeline.actions: if isinstance(child, OverlayAction): overlay = child break self.assertIsInstance(overlay, OverlayAction) # Generic scripts scripts_to_copy = glob.glob( os.path.join(overlay.lava_test_dir, "lava-*")) distro_support_dir = "%s/distro/%s" % (overlay.lava_test_dir, "debian") for script in glob.glob(os.path.join(distro_support_dir, "lava-*")): scripts_to_copy.append(script) check_list = list( set([os.path.basename(scr) for scr in scripts_to_copy])) self.assertCountEqual(check_list, script_list) self.assertEqual( overlay.xmod, stat.S_IRWXU | stat.S_IXGRP | stat.S_IRGRP | stat.S_IXOTH | stat.S_IROTH, ) def test_overlay_override(self): job = self.factory.create_job("qemu01.jinja2", "sample_jobs/kvm-context.yaml") deploy = [ action for action in job.pipeline.actions if action.name == "deployimages" ][0] overlay = [ action for action in deploy.internal_pipeline.actions if action.name == "lava-overlay" ][0] self.assertEqual( "/sysroot/lava-%s", overlay.get_constant("lava_test_results_dir", "posix"))
class TestUefiShell(StdoutTestCase): def setUp(self): super().setUp() self.factory = Factory() self.job = self.factory.create_job("juno-r2-01.jinja2", "sample_jobs/juno-uefi-nfs.yaml") def test_shell_reference(self): self.job.validate() self.assertEqual([], self.job.pipeline.errors) description_ref = self.pipeline_reference("juno-uefi-nfs.yaml") self.assertEqual(description_ref, self.job.pipeline.describe(False)) def test_device_juno_uefi(self): job = self.job self.assertIsNotNone(job) self.assertIsNone(job.validate()) def test_shell_prompts(self): self.job.validate() params = self.job.device["actions"]["boot"]["methods"]["uefi"][ "parameters"] self.assertIn("shell_interrupt_prompt", params) self.assertIn("shell_menu", params) self.assertIn("bootloader_prompt", params) # Nfs Deploy checks deploy = [ action for action in self.job.pipeline.actions if action.name == "nfs-deploy" ][0] overlay = [ action for action in deploy.internal_pipeline.actions if action.name == "lava-overlay" ][0] self.assertIsNotNone(overlay) # Boot checks boot = [ action for action in self.job.pipeline.actions if action.name == "uefi-shell-main-action" ][0] commands = [ action for action in boot.internal_pipeline.actions if action.name == "bootloader-overlay" ][0] menu_connect = [ action for action in boot.internal_pipeline.actions if action.name == "menu-connect" ][0] menu_interrupt = [ action for action in boot.internal_pipeline.actions if action.name == "uefi-shell-menu-interrupt" ][0] menu_selector = [ action for action in boot.internal_pipeline.actions if action.name == "uefi-shell-menu-selector" ][0] shell_interrupt = [ action for action in boot.internal_pipeline.actions if action.name == "uefi-shell-menu-interrupt" ][0] boot_commands = [ action for action in boot.internal_pipeline.actions if action.name == "bootloader-commands" ][0] self.assertEqual("uefi", commands.method) self.assertFalse(commands.use_bootscript) self.assertIsNone(commands.lava_mac) self.assertIsNotNone(menu_connect) self.assertIn("bootloader_prompt", menu_interrupt.params) self.assertIn("interrupt_prompt", menu_interrupt.params) self.assertIn("boot_message", menu_interrupt.params) # First, menu drops to shell... self.assertEqual("UEFI Interactive Shell", menu_selector.boot_message) # ...then, shell commands boot to linux. self.assertEqual("Linux version", boot_commands.params["boot_message"]) self.assertIsNotNone(shell_interrupt) def test_no_menu_reference(self): job = self.factory.create_job( "juno-r2-01.jinja2", "sample_jobs/juno-uefi-nfs-no-menu.yaml") self.assertEqual([], job.pipeline.errors) description_ref = self.pipeline_reference("juno-uefi-nfs-no-menu.yaml", job=job) self.assertEqual(description_ref, job.pipeline.describe(False)) def test_no_menu(self): """ Tests that if shell_menu=='' that the menu is skipped """ job = self.factory.create_job( "juno-r2-01.jinja2", "sample_jobs/juno-uefi-nfs-no-menu.yaml") job.validate() params = job.device["actions"]["boot"]["methods"]["uefi"]["parameters"] self.assertIn("shell_interrupt_prompt", params) self.assertIn("shell_menu", params) self.assertIn("bootloader_prompt", params) # Nfs Deploy checks deploy = [ action for action in job.pipeline.actions if action.name == "nfs-deploy" ][0] overlay = [ action for action in deploy.internal_pipeline.actions if action.name == "lava-overlay" ][0] self.assertIsNotNone(overlay) # Boot checks boot = [ action for action in job.pipeline.actions if action.name == "uefi-shell-main-action" ][0] commands = [ action for action in boot.internal_pipeline.actions if action.name == "bootloader-overlay" ][0] boot_commands = [ action for action in boot.internal_pipeline.actions if action.name == "bootloader-commands" ][0] self.assertIsNotNone([ action for action in boot.internal_pipeline.actions if action.name == "uefi-shell-interrupt" ]) self.assertEqual( 0, len([ action for action in boot.internal_pipeline.actions if action.name == "uefi-shell-menu-interrupt" ]), ) self.assertEqual( 0, len([ action for action in boot.internal_pipeline.actions if action.name == "uefi-shell-menu-selector" ]), ) self.assertEqual("uefi", commands.method) self.assertFalse(commands.use_bootscript) self.assertIsNone(commands.lava_mac) # Shell commands boot to linux. self.assertEqual("Linux version", boot_commands.params["boot_message"])
class TestPowerAction(StdoutTestCase): # pylint: disable=too-many-public-methods def setUp(self): super().setUp() self.factory = Factory() def test_reset_nopower(self): job = self.factory.create_job("cubie1.jinja2", "sample_jobs/uboot-ramdisk.yaml") uboot_action = None names = [r_action.name for r_action in job.pipeline.actions] self.assertIn("uboot-action", names) uboot_action = [ action for action in job.pipeline.actions if action.name == "uboot-action" ][0] names = [ r_action.name for r_action in uboot_action.internal_pipeline.actions ] self.assertIn("uboot-retry", names) uboot_retry = [ action for action in uboot_action.pipeline.actions if action.name == "uboot-retry" ][0] names = [ r_action.name for r_action in uboot_retry.internal_pipeline.actions ] self.assertIn("reset-device", names) reset_device = [ action for action in uboot_retry.pipeline.actions if action.name == "reset-device" ][0] names = [ r_action.name for r_action in reset_device.internal_pipeline.actions ] self.assertEqual(["send-reboot-commands"], names) def test_reset_power(self): job = self.factory.create_job("bbb-01.jinja2", "sample_jobs/uboot-ramdisk.yaml") uboot_action = None names = [r_action.name for r_action in job.pipeline.actions] self.assertIn("uboot-action", names) uboot_action = [ action for action in job.pipeline.actions if action.name == "uboot-action" ][0] names = [ r_action.name for r_action in uboot_action.internal_pipeline.actions ] self.assertIn("uboot-retry", names) uboot_retry = [ action for action in uboot_action.pipeline.actions if action.name == "uboot-retry" ][0] names = [ r_action.name for r_action in uboot_retry.internal_pipeline.actions ] self.assertIn("reset-device", names) reset_device = [ action for action in uboot_retry.pipeline.actions if action.name == "reset-device" ][0] names = [ r_action.name for r_action in reset_device.internal_pipeline.actions ] self.assertEqual(["pdu-reboot"], names)
class TestBootloaderAction(StdoutTestCase): # pylint: disable=too-many-public-methods def setUp(self): super().setUp() self.factory = Factory() def test_simulated_action(self): job = self.factory.create_job("x86-01.jinja2", "sample_jobs/ipxe-ramdisk.yaml") self.assertIsNotNone(job) description_ref = self.pipeline_reference("ipxe.yaml", job=job) self.assertEqual(description_ref, job.pipeline.describe(False)) self.assertIsNone(job.validate()) def test_tftp_pipeline(self): job = self.factory.create_job("x86-01.jinja2", "sample_jobs/ipxe-ramdisk.yaml") self.assertEqual( [action.name for action in job.pipeline.actions], [ "tftp-deploy", "bootloader-action", "lava-test-retry", "finalize" ], ) tftp = [ action for action in job.pipeline.actions if action.name == "tftp-deploy" ][0] self.assertTrue( tftp.get_namespace_data(action=tftp.name, label="tftp", key="ramdisk")) self.assertIsNotNone(tftp.internal_pipeline) self.assertEqual( [action.name for action in tftp.internal_pipeline.actions], [ "download-retry", "download-retry", "download-retry", "prepare-tftp-overlay", "lxc-create-udev-rule-action", "deploy-device-env", ], ) self.assertIn( "ramdisk", [ action.key for action in tftp.internal_pipeline.actions if hasattr(action, "key") ], ) self.assertIn( "kernel", [ action.key for action in tftp.internal_pipeline.actions if hasattr(action, "key") ], ) def test_device_x86(self): job = self.factory.create_job("x86-02.jinja2", "sample_jobs/ipxe-ramdisk.yaml") self.assertEqual( job.device["commands"]["connections"]["uart0"]["connect"], "telnet bumblebee 8003", ) self.assertEqual(job.device["commands"].get("interrupt", " "), " ") methods = job.device["actions"]["boot"]["methods"] self.assertIn("ipxe", methods) self.assertEqual( methods["ipxe"]["parameters"].get("bootloader_prompt"), "iPXE>") def test_bootloader_action(self): job = self.factory.create_job("x86-01.jinja2", "sample_jobs/ipxe-ramdisk.yaml") job.validate() self.assertEqual(job.pipeline.errors, []) self.assertIn("ipxe", job.device["actions"]["boot"]["methods"]) params = job.device["actions"]["boot"]["methods"]["ipxe"]["parameters"] boot_message = params.get( "boot_message", job.device.get_constant("kernel-start-message")) self.assertIsNotNone(boot_message) bootloader_action = [ action for action in job.pipeline.actions if action.name == "bootloader-action" ][0] bootloader_retry = [ action for action in bootloader_action.internal_pipeline.actions if action.name == "bootloader-retry" ][0] commands = [ action for action in bootloader_retry.internal_pipeline.actions if action.name == "bootloader-commands" ][0] self.assertEqual(commands.character_delay, 500) for action in job.pipeline.actions: action.validate() if isinstance(action, BootloaderAction): self.assertIn("method", action.parameters) self.assertEqual("ipxe", action.parameters["method"]) self.assertEqual( "reboot: Restarting system", action.parameters.get("parameters", {}).get( "shutdown-message", job.device.get_constant("shutdown-message")), ) if isinstance(action, TftpAction): self.assertIn("ramdisk", action.parameters) self.assertIn("kernel", action.parameters) self.assertIn("to", action.parameters) self.assertEqual("tftp", action.parameters["to"]) self.assertTrue(action.valid) def test_overlay_action(self): # pylint: disable=too-many-locals parameters = { "device_type": "x86", "job_name": "ipxe-pipeline", "job_timeout": "15m", "action_timeout": "5m", "priority": "medium", "actions": { "boot": { "method": "ipxe", "commands": "ramdisk", "prompts": ["linaro-test", "root@debian:~#"], }, "deploy": { "ramdisk": "initrd.gz", "kernel": "zImage" }, }, } (rendered, _) = self.factory.create_device("x86-01.jinja2") device = NewDevice(yaml.safe_load(rendered)) job = Job(4212, parameters, None) job.device = device pipeline = Pipeline(job=job, parameters=parameters["actions"]["boot"]) job.pipeline = pipeline overlay = BootloaderCommandOverlay() pipeline.add_action(overlay) ip_addr = dispatcher_ip(None) kernel = parameters["actions"]["deploy"]["kernel"] ramdisk = parameters["actions"]["deploy"]["ramdisk"] substitution_dictionary = { "{SERVER_IP}": ip_addr, "{RAMDISK}": ramdisk, "{KERNEL}": kernel, "{LAVA_MAC}": "00:00:00:00:00:00", } params = device["actions"]["boot"]["methods"] params["ipxe"]["ramdisk"]["commands"] = substitute( params["ipxe"]["ramdisk"]["commands"], substitution_dictionary) commands = params["ipxe"]["ramdisk"]["commands"] self.assertIs(type(commands), list) self.assertIn("dhcp net0", commands) self.assertIn( "set console console=ttyS0,115200n8 lava_mac=00:00:00:00:00:00", commands) self.assertIn("set extraargs ip=dhcp", commands) self.assertNotIn( "kernel tftp://{SERVER_IP}/{KERNEL} ${extraargs} ${console}", commands) self.assertNotIn("initrd tftp://{SERVER_IP}/{RAMDISK}", commands) self.assertIn("boot", commands) @unittest.skipIf(infrastructure_error("xnbd-server"), "xnbd-server not installed") def test_nbd_boot(self): job = self.factory.create_job("x86-01.jinja2", "sample_jobs/up2-initrd-nbd.yaml") job.validate() self.assertEqual(job.pipeline.errors, []) description_ref = self.pipeline_reference("up2-initrd-nbd.yaml", job=job) self.assertEqual(description_ref, job.pipeline.describe(False)) # Fixme: more asserts self.assertIn("ipxe", job.device["actions"]["boot"]["methods"]) params = job.device["actions"]["boot"]["methods"]["ipxe"]["parameters"] for action in job.pipeline.actions: action.validate() if isinstance(action, BootloaderAction): self.assertIn("method", action.parameters) self.assertEqual("ipxe", action.parameters["method"]) if isinstance(action, TftpAction): self.assertIn("initrd", action.parameters) self.assertIn("kernel", action.parameters) self.assertIn("nbdroot", action.parameters) self.assertIn("to", action.parameters) self.assertEqual("nbd", action.parameters["to"]) self.assertTrue(action.valid) def test_download_action(self): job = self.factory.create_job("x86-01.jinja2", "sample_jobs/ipxe.yaml") for action in job.pipeline.actions: action.validate() self.assertTrue(action.valid) job.validate() self.assertEqual(job.pipeline.errors, []) deploy = None overlay = None extract = None for action in job.pipeline.actions: if action.name == "tftp-deploy": deploy = action if deploy: for action in deploy.internal_pipeline.actions: if action.name == "prepare-tftp-overlay": overlay = action if overlay: for action in overlay.internal_pipeline.actions: if action.name == "extract-nfsrootfs": extract = action test_dir = overlay.get_namespace_data(action="test", label="results", key="lava_test_results_dir") self.assertIsNotNone(test_dir) self.assertIn("/lava-", test_dir) self.assertIsNotNone(extract) self.assertEqual(extract.timeout.duration, 120) def test_reset_actions(self): job = self.factory.create_job("x86-01.jinja2", "sample_jobs/ipxe.yaml") bootloader_action = None bootloader_retry = None reset_action = None for action in job.pipeline.actions: action.validate() self.assertTrue(action.valid) if action.name == "bootloader-action": bootloader_action = action names = [ r_action.name for r_action in bootloader_action.internal_pipeline.actions ] self.assertIn("connect-device", names) self.assertIn("bootloader-retry", names) for action in bootloader_action.internal_pipeline.actions: if action.name == "bootloader-retry": bootloader_retry = action names = [ r_action.name for r_action in bootloader_retry.internal_pipeline.actions ] self.assertIn("reset-device", names) self.assertIn("bootloader-interrupt", names) self.assertIn("expect-shell-connection", names) self.assertIn("bootloader-commands", names) for action in bootloader_retry.internal_pipeline.actions: if action.name == "reset-device": reset_action = action names = [ r_action.name for r_action in reset_action.internal_pipeline.actions ] self.assertIn("pdu-reboot", names) @unittest.skipIf(infrastructure_error("telnet"), "telnet not installed") def test_prompt_from_job(self): # pylint: disable=too-many-locals """ Support setting the prompt after login via the job Loads a known YAML, adds a prompt to the dict and re-parses the job. Checks that the prompt is available in the expect_shell_connection action. """ job = self.factory.create_job("x86-01.jinja2", "sample_jobs/ipxe-ramdisk.yaml") job.validate() bootloader = [ action for action in job.pipeline.actions if action.name == "bootloader-action" ][0] retry = [ action for action in bootloader.internal_pipeline.actions if action.name == "bootloader-retry" ][0] expect = [ action for action in retry.internal_pipeline.actions if action.name == "expect-shell-connection" ][0] check = expect.parameters (rendered, _) = self.factory.create_device("x86-01.jinja2") device = NewDevice(yaml.safe_load(rendered)) extra_yaml = os.path.join(os.path.dirname(__file__), "sample_jobs/ipxe.yaml") with open(extra_yaml) as data: sample_job_string = data.read() parser = JobParser() sample_job_data = yaml.safe_load(sample_job_string) boot = [ item["boot"] for item in sample_job_data["actions"] if "boot" in item ][0] self.assertIsNotNone(boot) sample_job_string = yaml.dump(sample_job_data) job = parser.parse(sample_job_string, device, 4212, None, "") job.logger = DummyLogger() job.validate() bootloader = [ action for action in job.pipeline.actions if action.name == "bootloader-action" ][0] retry = [ action for action in bootloader.internal_pipeline.actions if action.name == "bootloader-retry" ][0] expect = [ action for action in retry.internal_pipeline.actions if action.name == "expect-shell-connection" ][0] def test_xz_nfs(self): job = self.factory.create_job("x86-01.jinja2", "sample_jobs/ipxe-nfs.yaml") # this job won't validate as the .xz nfsrootfs URL is a fiction self.assertRaises(JobError, job.validate) tftp_deploy = [ action for action in job.pipeline.actions if action.name == "tftp-deploy" ][0] prepare = [ action for action in tftp_deploy.internal_pipeline.actions if action.name == "prepare-tftp-overlay" ][0] nfs = [ action for action in prepare.internal_pipeline.actions if action.name == "extract-nfsrootfs" ][0] self.assertIn("compression", nfs.parameters["nfsrootfs"]) self.assertEqual(nfs.parameters["nfsrootfs"]["compression"], "xz") def test_ipxe_with_monitor(self): job = self.factory.create_job("x86-01.jinja2", "sample_jobs/ipxe-monitor.yaml") job.validate() description_ref = self.pipeline_reference("ipxe-monitor.yaml", job=job) self.assertEqual(description_ref, job.pipeline.describe(False))