diff options
-rw-r--r-- | lava_scheduler_app/tests/device-types/mustang-grub-efi.jinja2 | 9 | ||||
-rw-r--r-- | lava_scheduler_app/tests/mustang-ssh-multinode.yaml | 138 | ||||
-rw-r--r-- | lava_scheduler_app/tests/test_pipeline.py | 68 |
3 files changed, 212 insertions, 3 deletions
diff --git a/lava_scheduler_app/tests/device-types/mustang-grub-efi.jinja2 b/lava_scheduler_app/tests/device-types/mustang-grub-efi.jinja2 index 9429216eb..023904e76 100644 --- a/lava_scheduler_app/tests/device-types/mustang-grub-efi.jinja2 +++ b/lava_scheduler_app/tests/device-types/mustang-grub-efi.jinja2 @@ -61,7 +61,8 @@ actions: - insmod efinet - net_bootp {% endif %} - - linux (tftp,{SERVER_IP})/{KERNEL} console={{ console_device }},{{ baud_rate }}n8 debug root=/dev/ram0 rw {{ base_ip_args }} + - linux (tftp,{SERVER_IP})/{KERNEL} console={{ console_device }},{{ baud_rate }}n8 debug + root=/dev/ram0 rw {{ base_ip_args }} {{ extra_kernel_args }} - initrd (tftp,{SERVER_IP})/{RAMDISK} - boot installed: @@ -71,7 +72,8 @@ actions: - insmod efinet - net_bootp {% endif %} - - linux (tftp,{SERVER_IP})/{KERNEL} console={{ console_device }},{{ baud_rate }}n8 debug root=/dev/sda2 rw {{ base_ip_args }} + - linux (tftp,{SERVER_IP})/{KERNEL} console={{ console_device }},{{ baud_rate }}n8 debug + root=/dev/sda2 rw {{ base_ip_args }} {{ extra_kernel_args }} - initrd (tftp,{SERVER_IP})/{RAMDISK} - boot nfs: @@ -81,7 +83,8 @@ actions: - insmod efinet - net_bootp {% endif %} - - 'linux (tftp,{SERVER_IP})/{KERNEL} console={{ console_device }},{{ baud_rate }}n8 debug root=/dev/nfs rw {{ base_nfsroot_args }} {{ base_ip_args }}' + - 'linux (tftp,{SERVER_IP})/{KERNEL} console={{ console_device }},{{ baud_rate }}n8 debug + root=/dev/nfs rw {{ base_nfsroot_args }} {{ base_ip_args }} {{ extra_kernel_args }}' - initrd (tftp,{SERVER_IP})/{RAMDISK} - boot uefi-menu: diff --git a/lava_scheduler_app/tests/mustang-ssh-multinode.yaml b/lava_scheduler_app/tests/mustang-ssh-multinode.yaml new file mode 100644 index 000000000..750f39766 --- /dev/null +++ b/lava_scheduler_app/tests/mustang-ssh-multinode.yaml @@ -0,0 +1,138 @@ +device_type: mustang +job_name: KVM pipeline test + +timeouts: + job: + minutes: 60 + action: + minutes: 20 + connection: + minutes: 2 + +priority: medium +visibility: public + +protocols: + lava-multinode: + roles: + guest: + connection: ssh + count: 1 + expect_role: host + host_role: host + request: lava-start + timeout: + minutes: 15 + host: + count: 1 + device_type: mustang + timeout: + minutes: 10 + +actions: +- deploy: + role: + - host + authorize: ssh + dtb: + url: https://storage.kernelci.org/mainline/v4.11-rc2/arm64-defconfig/dtbs/apm/apm-mustang.dtb + kernel: + url: https://storage.kernelci.org/mainline/v4.11-rc2/arm64-defconfig/Image + type: image + modules: + url: https://storage.kernelci.org/mainline/v4.11-rc2/arm64-defconfig/modules.tar.xz + compression: xz + nfsrootfs: + url: http://releases.linaro.org/debian/images/developer-arm64/16.07/linaro-jessie-developer-20160722-88.tar.gz + compression: gz + prefix: binary/ + ramdisk: + url: http://people.linaro.org/~riku.voipio/initramfs.arm64.cpio.gz + compression: gz + os: debian + timeout: + minutes: 12 + to: tftp + +# wait for the guest IP to deploy lava overlay on it +- deploy: + role: + - guest + connection: ssh + os: ubuntu + protocols: + lava-multinode: + - action: prepare-scp-overlay + request: lava-wait + # messageID matches hostID + messageID: ipv4 + message: + ipaddr: $ipaddr + timeout: # delay_start timeout + minutes: 21 + timeout: + minutes: 22 + to: ssh + +- boot: + role: + - host + commands: nfs + method: grub-efi + type: uimage + prompts: + - 'root@linaro-developer:' + timeout: + minutes: 5 + +# run tests on guest over ssh +- boot: + role: + - guest + method: ssh + prompts: + - 'root@linaro-developer:' + parameters: + hostID: ipv4 # messageID + host_key: ipaddr # message key + timeout: + minutes: 23 + +# host tests +- test: + role: + - host + definitions: + - from: git + name: hackbench-host + path: automated/linux/hackbench/hackbench.yaml + repository: https://git.linaro.org/qa/test-definitions.git + - from: git + name: kvm-guest + path: ubuntu/start-kvm.yaml + parameters: + GUEST_ARCH: aarch64 + GUEST_CORES: 4 + GUEST_IMAGE: https://cloud-images.ubuntu.com/xenial/current/xenial-server-cloudimg-arm64-uefi1.img + repository: https://git.linaro.org/qa/test-definitions.git + timeout: + minutes: 40 + +- test: + role: + - guest + definitions: + - from: git + name: hackbench-guest + path: automated/linux/hackbench/hackbench.yaml + repository: https://git.linaro.org/qa/test-definitions.git + - from: git + name: guest-complete + path: ubuntu/stop-guest.yaml + repository: https://git.linaro.org/qa/test-definitions.git + timeout: + minutes: 41 + +context: + kernel_loglevel: "" + diff --git a/lava_scheduler_app/tests/test_pipeline.py b/lava_scheduler_app/tests/test_pipeline.py index 2179ae608..17763247f 100644 --- a/lava_scheduler_app/tests/test_pipeline.py +++ b/lava_scheduler_app/tests/test_pipeline.py @@ -843,6 +843,74 @@ class TestYamlMultinode(TestCaseWithFactory): if role == 'server': self.assertEqual(job, yaml.load(open(server_check, 'r'))) + def test_secondary_connection(self): + user = self.factory.make_user() + device_type = self.factory.make_device_type(name='mustang') + device = self.factory.make_device(device_type, 'mustang1') + mustang = DeviceDictionary(hostname=device.hostname) + mustang.parameters = { + 'connection_command': 'telnet serial4 7012', + 'extends': 'mustang-grub-efi.jinja2', + } + mustang.save() + submission = yaml.load(open( + os.path.join(os.path.dirname(__file__), 'mustang-ssh-multinode.yaml'), 'r')) + target_group = 'arbitrary-group-id' # for unit tests only + jobs_dict = split_multinode_yaml(submission, target_group) + self.assertIsNotNone(jobs_dict) + jobs = TestJob.from_yaml_and_user(yaml.dump(submission), user) + self.assertIsNotNone(jobs) + host_job = None + guest_job = None + for job in jobs: + if job.device_role == 'host': + host_job = job + if job.device_role == 'guest': + guest_job = job + self.assertIsNotNone(host_job) + self.assertIsNotNone(guest_job) + self.assertTrue(guest_job.dynamic_connection) + parser = JobParser() + job_ctx = {} + host_job.actual_device = device + + try: + device_config = device.load_device_configuration(job_ctx, system=False) # raw dict + except (jinja2.TemplateError, yaml.YAMLError, IOError) as exc: + # FIXME: report the exceptions as useful user messages + self.fail("[%d] jinja2 error: %s" % (host_job.id, exc)) + if not device_config or not isinstance(device_config, dict): + # it is an error to have a pipeline device without a device dictionary as it will never get any jobs. + msg = "Administrative error. Device '%s' has no device dictionary." % device.hostname + self.fail('[%d] device-dictionary error: %s' % (host_job.id, msg)) + + device_object = PipelineDevice(device_config, device.hostname) # equivalent of the NewDevice in lava-dispatcher, without .yaml file. + # FIXME: drop this nasty hack once 'target' is dropped as a parameter + if 'target' not in device_object: + device_object.target = device.hostname + device_object['hostname'] = device.hostname + self.assertIsNotNone(device_object) + parser_device = device_object + try: + # pass (unused) output_dir just for validation as there is no zmq socket either. + pipeline_job = parser.parse( + host_job.definition, parser_device, + host_job.id, None, "", output_dir=host_job.output_dir) + except (AttributeError, JobError, NotImplementedError, KeyError, TypeError) as exc: + self.fail('[%s] parser error: %s' % (host_job.sub_id, exc)) + pipeline_job._validate(False) + self.assertEqual([], pipeline_job.pipeline.errors) + + try: + # pass (unused) output_dir just for validation as there is no zmq socket either. + pipeline_job = parser.parse( + guest_job.definition, parser_device, + guest_job.id, None, "", output_dir=guest_job.output_dir) + except (AttributeError, JobError, NotImplementedError, KeyError, TypeError) as exc: + self.fail('[%s] parser error: %s' % (guest_job.sub_id, exc)) + pipeline_job._validate(False) + self.assertEqual([], pipeline_job.pipeline.errors) + def test_multinode_tags(self): Tag.objects.all().delete() self.factory.ensure_tag('tap'), |