def test_create_internal_pipeline(self): action = Action() action.name = "internal_pipe" action.description = "test action only" action.summary = "starter" pipe = Pipeline() pipe.add_action(action) self.assertEqual(len(pipe.actions), 1) self.assertEqual(action.level, "1") action = Action() action.name = "child_action" action.summary = "child" action.description = "action implementing an internal pipe" with self.assertRaises(LAVABug): Pipeline(action) pipe.add_action(action) self.assertEqual(action.level, "2") self.assertEqual(len(pipe.actions), 2) # a formal RetryAction would contain a pre-built pipeline which can be inserted directly retry_pipe = Pipeline(action) action = Action() action.name = "inside_action" action.description = "action inside the internal pipe" action.summary = "child" retry_pipe.add_action(action) self.assertEqual(len(retry_pipe.actions), 1) self.assertEqual(action.level, "2.1")
def test_create_internal_pipeline(self): action = Action() action.name = "internal_pipe" action.description = "test action only" action.summary = "starter" pipe = Pipeline() pipe.add_action(action) self.assertEqual(len(pipe.children[pipe]), 1) self.assertEqual(action.level, "1") action = Action() action.name = "child_action" action.summary = "child" action.description = "action implementing an internal pipe" with self.assertRaises(RuntimeError): Pipeline(action) pipe.add_action(action) self.assertEqual(action.level, "2") self.assertEqual(len(pipe.children[pipe]), 2) # a formal RetryAction would contain a pre-built pipeline which can be inserted directly retry_pipe = Pipeline(action) action = Action() action.name = "inside_action" action.description = "action inside the internal pipe" action.summary = "child" retry_pipe.add_action(action) self.assertEqual(len(retry_pipe.children[retry_pipe]), 1) self.assertEqual(action.level, "2.1")
def test_composite_action_aggregates_errors_from_sub_actions(self): # pylint: disable=invalid-name # Unable to call Action.validate() as there is no job in this unit test sub1 = Action() sub1.__errors__ = [1] sub2 = Action() sub2.name = "sub2" sub2.__errors__ = [2] pipe = Pipeline() sub1.name = "sub1" pipe.add_action(sub1) pipe.add_action(sub2) self.assertEqual([1, 2], pipe.errors)
def test_add_action_to_pipeline(self): action = Action() action.name = "test-action" action.description = "test action only" action.summary = "starter" self.assertEqual(action.description, "test action only") self.assertEqual(action.summary, "starter") # action needs to be added to a top level pipe first with self.assertRaises(LAVABug): Pipeline(action) pipe = Pipeline() with self.assertRaises(LAVABug): pipe.add_action(None) with self.assertRaises(LAVABug): pipe.add_action(pipe) pipe.add_action(action) self.assertEqual(pipe.actions, [action]) self.assertEqual(action.level, "1") try: description = pipe.describe() except Exception as exc: # pylint: disable=broad-except self.fail(exc) self.assertIsNotNone(description) self.assertIsInstance(description, list) self.assertIn('description', description[0]) self.assertIn('level', description[0]) self.assertIn('summary', description[0]) self.assertIn('max_retries', description[0]) self.assertIn('timeout', description[0])
def test_complex_pipeline(self): # pylint: disable=too-many-statements action = Action() action.name = "starter_action" action.description = "test action only" action.summary = "starter" pipe = Pipeline() pipe.add_action(action) self.assertEqual(action.level, "1") action = Action() action.name = "pipe_action" action.description = "action implementing an internal pipe" action.summary = "child" pipe.add_action(action) self.assertEqual(action.level, "2") # a formal RetryAction would contain a pre-built pipeline which can be inserted directly retry_pipe = Pipeline(action) action = Action() action.name = "child_action" action.description = "action inside the internal pipe" action.summary = "child" retry_pipe.add_action(action) self.assertEqual(action.level, "2.1") action = Action() action.name = "second-child-action" action.description = "second action inside the internal pipe" action.summary = "child2" retry_pipe.add_action(action) self.assertEqual(action.level, "2.2") action = Action() action.name = "baby_action" action.description = "action implementing an internal pipe" action.summary = "baby" retry_pipe.add_action(action) self.assertEqual(action.level, "2.3") inner_pipe = Pipeline(action) action = Action() action.name = "single_action" action.description = "single line action" action.summary = "single" inner_pipe.add_action(action) self.assertEqual(action.level, "2.3.1") action = Action() action.name = "step_out" action.description = "step out of inner pipe" action.summary = "brother" retry_pipe.add_action(action) self.assertEqual(action.level, "2.4") action = Action() action.name = "top-level" action.description = "top level" action.summary = "action" pipe.add_action(action) self.assertEqual(action.level, "3") self.assertEqual(len(pipe.describe()), 3)
def test_add_action_to_pipeline(self): action = Action() action.name = "test-action" action.description = "test action only" action.summary = "starter" self.assertEqual(action.description, "test action only") self.assertEqual(action.summary, "starter") # action needs to be added to a top level pipe first with self.assertRaises(RuntimeError): Pipeline(action) pipe = Pipeline() with self.assertRaises(RuntimeError): pipe.add_action(None) with self.assertRaises(RuntimeError): pipe.add_action(pipe) pipe.add_action(action) self.assertNotEqual(pipe.children, {pipe: []}) self.assertEqual(pipe.children, {pipe: [action]}) self.assertEqual(action.level, "1") try: simplejson.loads(pipe.describe()) except: # pylint: disable=bare-except self.assertFalse(0)
def test_kvm_simulation(self): # pylint: disable=too-many-statements """ Build a pipeline which simulates a KVM LAVA job without using the formal objects (to avoid validating data known to be broken). The details are entirely arbitrary. """ factory = Factory() job = factory.create_kvm_job('sample_jobs/kvm.yaml') pipe = Pipeline() action = Action() action.name = "deploy_linaro_image" action.description = "deploy action using preset subactions in an internal pipe" action.summary = "deploy_linaro_image" action.job = job # deliberately unlikely location # a successful validation would need to use the cwd action.parameters = {"image": "file:///none/images/bad-kvm-debian-wheezy.img"} pipe.add_action(action) self.assertEqual(action.level, "1") deploy_pipe = Pipeline(action) action = Action() action.name = "downloader" action.description = "download image wrapper, including an internal retry pipe" action.summary = "downloader" action.job = job deploy_pipe.add_action(action) self.assertEqual(action.level, "1.1") # a formal RetryAction would contain a pre-built pipeline which can be inserted directly retry_pipe = Pipeline(action) action = Action() action.name = "wget" action.description = "do the download with retries" action.summary = "wget" action.job = job retry_pipe.add_action(action) self.assertEqual(action.level, "1.1.1") action = Action() action.name = "checksum" action.description = "checksum the downloaded file" action.summary = "md5sum" action.job = job deploy_pipe.add_action(action) self.assertEqual(action.level, "1.2") action = Action() action.name = "overlay" action.description = "apply lava overlay" action.summary = "overlay" action.job = job deploy_pipe.add_action(action) self.assertEqual(action.level, "1.3") action = Action() action.name = "boot" action.description = "boot image" action.summary = "qemu" action.job = job # cmd_line built from device configuration action.parameters = { 'cmd_line': [ 'qemu-system-x86_64', '-machine accel=kvm:tcg', '-hda' '%s' % "tbd", '-nographic', '-net', 'nic,model=virtio' '-net user' ] } pipe.add_action(action) self.assertEqual(action.level, "2") action = Action() action.name = "simulated" action.description = "lava test shell" action.summary = "simulated" action.job = job # a formal lava test shell action would include an internal pipe # which would handle the run.sh pipe.add_action(action) self.assertEqual(action.level, "3") # just a fake action action = Action() action.name = "fake" action.description = "faking results" action.summary = "fake action" action.job = job pipe.add_action(action) self.assertEqual(action.level, "4") self.assertEqual(len(pipe.describe()), 4)
def test_kvm_simulation(self): # pylint: disable=too-many-statements """ Build a pipeline which simulates a KVM LAVA job without using the formal objects (to avoid validating data known to be broken). The details are entirely arbitrary. """ factory = Factory() job = factory.create_kvm_job('sample_jobs/kvm.yaml') pipe = Pipeline() action = Action() action.name = "deploy_linaro_image" action.description = "deploy action using preset subactions in an internal pipe" action.summary = "deploy_linaro_image" action.job = job # deliberately unlikely location # a successful validation would need to use the cwd action.parameters = { "image": "file:///none/images/bad-kvm-debian-wheezy.img" } pipe.add_action(action) self.assertEqual(action.level, "1") deploy_pipe = Pipeline(action) action = Action() action.name = "downloader" action.description = "download image wrapper, including an internal retry pipe" action.summary = "downloader" action.job = job deploy_pipe.add_action(action) self.assertEqual(action.level, "1.1") # a formal RetryAction would contain a pre-built pipeline which can be inserted directly retry_pipe = Pipeline(action) action = Action() action.name = "wget" action.description = "do the download with retries" action.summary = "wget" action.job = job retry_pipe.add_action(action) self.assertEqual(action.level, "1.1.1") action = Action() action.name = "checksum" action.description = "checksum the downloaded file" action.summary = "md5sum" action.job = job deploy_pipe.add_action(action) self.assertEqual(action.level, "1.2") action = Action() action.name = "overlay" action.description = "apply lava overlay" action.summary = "overlay" action.job = job deploy_pipe.add_action(action) self.assertEqual(action.level, "1.3") action = Action() action.name = "boot" action.description = "boot image" action.summary = "qemu" action.job = job # cmd_line built from device configuration action.parameters = { 'cmd_line': [ 'qemu-system-x86_64', '-machine accel=kvm:tcg', '-hda' '%s' % "tbd", '-nographic', '-net', 'nic,model=virtio' '-net user' ] } pipe.add_action(action) self.assertEqual(action.level, "2") action = Action() action.name = "simulated" action.description = "lava test shell" action.summary = "simulated" action.job = job # a formal lava test shell action would include an internal pipe # which would handle the run.sh pipe.add_action(action) self.assertEqual(action.level, "3") # just a fake action action = Action() action.name = "fake" action.description = "faking results" action.summary = "fake action" action.job = job pipe.add_action(action) self.assertEqual(action.level, "4") self.assertEqual(len(pipe.describe()), 4)