def create_kvm_job(self, filename, validate_job=False): """ Custom function to allow for extra exception handling. """ job_ctx = { "arch": "amd64", "no_kvm": True, } # override to allow unit tests on all types of systems (data, device_dict) = self.create_device("kvm01.jinja2", job_ctx) device = NewDevice(yaml.safe_load(data)) if self.debug: print("####### Device configuration #######") print(data) print("#######") self.validate_data("hi6220-hikey-01", device_dict) kvm_yaml = os.path.join(os.path.dirname(__file__), filename) parser = JobParser() job_data = "" with open(kvm_yaml) as sample_job_data: job_data = yaml.safe_load(sample_job_data.read()) if self.debug: print("########## Test Job Submission validation #######") if validate_job: validate_submission(job_data) try: job = parser.parse(yaml.dump(job_data), device, 4212, None, "") job.logger = DummyLogger() except LAVAError as exc: print(exc) # some deployments listed in basics.yaml are not implemented yet return None return job
def test_compression_change(self): bad_submission = """ job_name: bbb-ramdisk visibility: public timeouts: job: minutes: 15 action: minutes: 5 actions: - deploy: to: tftp kernel: url: http://test.com/foo ramdisk: url: http://test.com/bar header: u-boot add-header: u-boot compression: gz os: oe # breakage at the dtb block of a tftp deploy dtb: location: http://test.com/baz """ try: validate_submission(yaml.safe_load(bad_submission)) except SubmissionException as exc: self.assertIn('required key not provided', str(exc)) self.assertIn('dtb', str(exc)) self.assertIn('url', str(exc)) bad_submission = """ job_name: bbb-ramdisk visibility: public timeouts: job: minutes: 15 action: minutes: 5 actions: - deploy: to: tftp kernel: url: http://test.com/foo ramdisk: url: http://test.com/bar header: u-boot add-header: u-boot compression: gz os: oe # breakage using the original syntax dtb: http://test.com/baz """ try: validate_submission(yaml.safe_load(bad_submission)) except SubmissionException as exc: self.assertIn('expected a dictionary for dictionary value', str(exc)) self.assertIn('dtb', str(exc)) self.assertNotIn('url', str(exc))
def validate_yaml(self, yaml_string): """ Name ---- validate_yaml (yaml_job_data) Description ----------- Validate the supplied pipeline YAML against the submission schema. Note: this does not validate the job itself, just the YAML against the submission schema. A job which validates against the schema can still be an invalid job for the dispatcher and such jobs will be accepted as Submitted, scheduled and then marked as Incomplete with a failure comment. Full validation only happens after a device has been assigned to the Submitted job. Arguments --------- 'yaml_job_data': string Return value ------------ Raises an Exception if the yaml_job_data is invalid. """ try: # YAML can parse JSON as YAML, JSON cannot parse YAML at all yaml_data = yaml.load(yaml_string) except yaml.YAMLError as exc: raise xmlrpclib.Fault(400, "Decoding job submission failed: %s." % exc) try: # validate against the submission schema. validate_submission(yaml_data) # raises SubmissionException if invalid. except SubmissionException as exc: raise xmlrpclib.Fault(400, "Invalid YAML submission: %s" % exc)
def create_custom_job(self, template, job_data, job_ctx=None, validate_job=True): if validate_job: validate_submission(job_data) if job_ctx: job_data["context"] = job_ctx else: job_ctx = job_data.get("context") (data, device_dict) = self.create_device(template, job_ctx) device = NewDevice(yaml.safe_load(data)) if self.debug: print("####### Device configuration #######") print(data) print("#######") try: parser = JobParser() job = parser.parse(yaml.dump(job_data), device, 4999, None, "") except (ConfigurationError, TypeError) as exc: print("####### Parser exception ########") print(device) print("#######") raise ConfigurationError("Invalid device: %s" % exc) job.logger = DummyLogger() return job
def validate_yaml(self, yaml_string): """ Name ---- validate_yaml (yaml_job_data) Description ----------- Validate the supplied pipeline YAML against the submission schema. Note: this does not validate the job itself, just the YAML against the submission schema. A job which validates against the schema can still be an invalid job for the dispatcher and such jobs will be accepted as Submitted, scheduled and then marked as Incomplete with a failure comment. Full validation only happens after a device has been assigned to the Submitted job. Arguments --------- 'yaml_job_data': string Return value ------------ Raises an Exception if the yaml_job_data is invalid. """ try: # YAML can parse JSON as YAML, JSON cannot parse YAML at all yaml_data = yaml.safe_load(yaml_string) except yaml.YAMLError as exc: raise xmlrpc.client.Fault(400, "Decoding job submission failed: %s." % exc) try: # validate against the submission schema. validate_submission(yaml_data) # raises SubmissionException if invalid. except SubmissionException as exc: raise xmlrpc.client.Fault(400, "Invalid YAML submission: %s" % exc)
def test_compression_change(self): bad_submission = """ job_name: bbb-ramdisk visibility: public timeouts: job: minutes: 15 action: minutes: 5 actions: - deploy: to: tftp kernel: url: http://test.com/foo ramdisk: url: http://test.com/bar header: u-boot add-header: u-boot compression: gz os: oe # breakage at the dtb block of a tftp deploy dtb: location: http://test.com/baz """ try: validate_submission(yaml.load(bad_submission)) except SubmissionException as exc: self.assertIn('required key not provided', str(exc)) self.assertIn('dtb', str(exc)) self.assertIn('url', str(exc)) bad_submission = """ job_name: bbb-ramdisk visibility: public timeouts: job: minutes: 15 action: minutes: 5 actions: - deploy: to: tftp kernel: url: http://test.com/foo ramdisk: url: http://test.com/bar header: u-boot add-header: u-boot compression: gz os: oe # breakage using the original syntax dtb: http://test.com/baz """ try: validate_submission(yaml.load(bad_submission)) except SubmissionException as exc: self.assertIn('expected a dictionary for dictionary value', str(exc)) self.assertIn('dtb', str(exc)) self.assertNotIn('url', str(exc))
def create_kvm_job(self, filename, check_job=False): # pylint: disable=no-self-use """ Custom function to allow for extra exception handling. """ job_ctx = { 'arch': 'amd64', 'no_kvm': True } # override to allow unit tests on all types of systems (data, device_dict) = self.create_device('kvm01.jinja2', job_ctx) device = NewDevice(yaml.safe_load(data)) if self.debug: print('####### Device configuration #######') print(data) print('#######') self.validate_data('hi6220-hikey-01', device_dict) kvm_yaml = os.path.join(os.path.dirname(__file__), filename) parser = JobParser() job_data = '' with open(kvm_yaml) as sample_job_data: job_data = yaml.safe_load(sample_job_data.read()) if self.debug: print('########## Test Job Submission validation #######') if check_job: # FIXME: all submissions should validate. validate_submission(job_data) try: job = parser.parse(yaml.dump(job_data), device, 4212, None, "") job.logger = DummyLogger() except LAVAError as exc: print(exc) # some deployments listed in basics.yaml are not implemented yet return None return job
def test_breakage_detection(self): bad_submission = """ timeouts: job: minutes: 15 action: minutes: 5 """ self.assertRaises(SubmissionException, validate_submission, yaml.load(bad_submission)) try: validate_submission(yaml.load(bad_submission)) except SubmissionException as exc: # with more than one omission, which one gets mentioned is undefined self.assertIn('required key not provided', str(exc)) bad_submission += """ actions: - deploy: to: tmpfs """ self.assertRaises(SubmissionException, validate_submission, yaml.load(bad_submission)) try: validate_submission(yaml.load(bad_submission)) except SubmissionException as exc: self.assertIn('required key not provided', str(exc)) # with more than one omission, which one gets mentioned is undefined self.assertTrue('visibility' in str(exc) or 'job_name' in str(exc)) bad_submission += """ visibility: public """ self.assertRaises(SubmissionException, validate_submission, yaml.load(bad_submission)) try: validate_submission(yaml.load(bad_submission)) except SubmissionException as exc: self.assertIn('required key not provided', str(exc)) self.assertIn('job_name', str(exc)) bad_submission += """ job_name: qemu-pipeline """ self.assertTrue(validate_submission(yaml.load(bad_submission))) bad_yaml = yaml.load(bad_submission) del bad_yaml['timeouts']['job'] try: validate_submission(yaml.load(bad_submission)) except SubmissionException as exc: self.assertIn('required key not provided', str(exc)) self.assertIn('job', str(exc)) self.assertIn('timeouts', str(exc)) bad_submission += """ notify: criteria: status: complete """ self.assertTrue(validate_submission(yaml.load(bad_submission))) bad_submission += """ compare: query: entity: testrunfilter """ self.assertRaises(SubmissionException, validate_yaml, yaml.load(bad_submission))
def validate_job(data): try: yaml_data = yaml_safe_load(data) except yaml.YAMLError as exc: raise SubmissionException("Loading job submission failed: %s." % exc) # validate against the submission schema. validate_submission(yaml_data) # raises SubmissionException if invalid. validate_yaml(yaml_data) # raises SubmissionException if invalid.
def test_submission_schema(self): files = [] path = os.path.normpath(os.path.dirname(__file__)) for name in os.listdir(path): if name.endswith('.yaml'): files.append(name) # these files have already been split by utils as multinode sub_id jobs. # FIXME: validate the schema of split files using lava-dispatcher. split_files = [ 'kvm-multinode-client.yaml', 'kvm-multinode-server.yaml', 'qemu-ssh-guest-1.yaml', 'qemu-ssh-guest-2.yaml', 'qemu-ssh-parent.yaml' ] for filename in files: # some files are dispatcher-level test files, e.g. after the multinode split try: yaml_data = yaml.load(open(os.path.join(path, filename), 'r')) except yaml.YAMLError as exc: raise RuntimeError("Decoding YAML job submission failed: %s." % exc) if filename in split_files: self.assertRaises(SubmissionException, validate_submission, yaml_data) else: self.assertTrue(validate_submission(yaml_data))
def test_secrets(self): secrets = """ job_name: kvm-test visibility: personal timeouts: job: minutes: 10 action: minutes: 5 actions: - deploy: to: tmpfs images: rootfs: url: //images.validation.linaro.org/kvm-debian-wheezy.img.gz compression: gz os: debian secrets: foo: bar username: secret """ self.assertTrue(validate_submission(yaml.load(secrets))) secrets = """ job_name: kvm-test visibility: public timeouts: job: minutes: 10 action: minutes: 5 actions: - deploy: to: tmpfs images: rootfs: url: //images.validation.linaro.org/kvm-debian-wheezy.img.gz compression: gz os: debian secrets: foo: bar username: secret """ self.assertRaises(SubmissionException, validate_submission, yaml.load(secrets))
def test_submission_schema(self): files = [] path = os.path.normpath(os.path.dirname(__file__)) for name in os.listdir(path): if name.endswith('.yaml'): files.append(name) device_files = [ # device files supporting unit tests 'bbb-01.yaml' ] # these files have already been split by utils as multinode sub_id jobs. # FIXME: validate the schema of split files using lava-dispatcher. split_files = [ 'kvm-multinode-client.yaml', 'kvm-multinode-server.yaml', 'qemu-ssh-guest-1.yaml', 'qemu-ssh-guest-2.yaml', 'qemu-ssh-parent.yaml' ] for filename in files: # some files are dispatcher-level test files, e.g. after the multinode split try: yaml_data = yaml.load(open(os.path.join(path, filename), 'r')) except yaml.YAMLError as exc: raise RuntimeError("Decoding YAML job submission failed: %s." % exc) if filename in device_files: validate_device(yaml_data) continue if filename in split_files: self.assertRaises(SubmissionException, validate_submission, yaml_data) else: try: ret = validate_submission(yaml_data) self.assertTrue(ret) except SubmissionException as exc: msg = '########## %s ###########\n%s' % (filename, exc) self.fail(msg)
def test_breakage_detection(self): bad_submission = """ timeouts: job: minutes: 15 action: minutes: 5 """ self.assertRaises(SubmissionException, validate_submission, yaml.load(bad_submission)) try: validate_submission(yaml.load(bad_submission)) except SubmissionException as exc: # with more than one omission, which one gets mentioned is undefined self.assertIn('required key not provided', str(exc)) bad_submission += """ actions: - deploy: to: tmpfs """ self.assertRaises(SubmissionException, validate_submission, yaml.load(bad_submission)) try: validate_submission(yaml.load(bad_submission)) except SubmissionException as exc: self.assertIn('required key not provided', str(exc)) self.assertIn('job_name', str(exc)) bad_submission += """ job_name: qemu-pipeline """ self.assertTrue(validate_submission(yaml.load(bad_submission))) bad_yaml = yaml.load(bad_submission) del bad_yaml['timeouts']['job'] try: validate_submission(yaml.load(bad_submission)) except SubmissionException as exc: self.assertIn('required key not provided', str(exc)) self.assertIn('job', str(exc)) self.assertIn('timeouts', str(exc))
def submit_job(self, job_data): """ Name ---- `submit_job` (`job_data`) Description ----------- Submit the given job data which is in LAVA job JSON format as a new job to LAVA scheduler. Arguments --------- `job_data`: string Job JSON string. Return value ------------ This function returns an XML-RPC integer which is the newly created job's id, provided the user is authenticated with an username and token. """ self._authenticate() if not self.user.has_perm('lava_scheduler_app.add_testjob'): raise xmlrpclib.Fault( 403, "Permission denied. User %r does not have the " "'lava_scheduler_app.add_testjob' permission. Contact " "the administrators." % self.user.username) is_json = True is_yaml = False try: json.loads(job_data) except (AttributeError, JSONDecodeError, ValueError) as exc: is_json = False try: # only try YAML if this is not JSON # YAML can parse JSON as YAML, JSON cannot parse YAML at all yaml_data = yaml.load(job_data) except yaml.YAMLError as exc: # neither yaml nor json loaders were able to process the submission. raise xmlrpclib.Fault( 400, "Loading job submission failed: %s." % exc) # validate against the submission schema. is_yaml = validate_submission( yaml_data) # raises SubmissionException if invalid. try: if is_json: job = TestJob.from_json_and_user(job_data, self.user) elif is_yaml: job = TestJob.from_yaml_and_user(job_data, self.user) else: raise xmlrpclib.Fault( 400, "Unable to determine whether job is JSON or YAML.") except (JSONDataError, JSONDecodeError, ValueError) as exc: raise xmlrpclib.Fault(400, "Decoding job submission failed: %s." % exc) except Device.DoesNotExist: raise xmlrpclib.Fault(404, "Specified device not found.") except DeviceType.DoesNotExist: raise xmlrpclib.Fault(404, "Specified device type not found.") except DevicesUnavailableException as e: raise xmlrpclib.Fault(400, str(e)) if isinstance(job, type(list())): return [j.sub_id for j in job] else: return job.id
def test_breakage_detection(self): bad_submission = """ timeouts: job: minutes: 15 action: minutes: 5 """ self.assertRaises(SubmissionException, validate_submission, yaml.load(bad_submission)) try: validate_submission(yaml.load(bad_submission)) except SubmissionException as exc: # with more than one omission, which one gets mentioned is undefined self.assertIn('required key not provided', str(exc)) bad_submission += """ actions: - deploy: to: tmpfs """ self.assertRaises(SubmissionException, validate_submission, yaml.load(bad_submission)) try: validate_submission(yaml.load(bad_submission)) except SubmissionException as exc: self.assertIn('required key not provided', str(exc)) # with more than one omission, which one gets mentioned is undefined self.assertTrue('visibility' in str(exc) or 'job_name' in str(exc)) bad_submission += """ visibility: public """ self.assertRaises(SubmissionException, validate_submission, yaml.load(bad_submission)) try: validate_submission(yaml.load(bad_submission)) except SubmissionException as exc: self.assertIn('required key not provided', str(exc)) self.assertIn('job_name', str(exc)) bad_submission += """ job_name: qemu-pipeline """ self.assertTrue(validate_submission(yaml.load(bad_submission))) bad_yaml = yaml.load(bad_submission) del bad_yaml['timeouts']['job'] try: validate_submission(yaml.load(bad_submission)) except SubmissionException as exc: self.assertIn('required key not provided', str(exc)) self.assertIn('job', str(exc)) self.assertIn('timeouts', str(exc)) bad_submission += """ notify: criteria: status: complete """ self.assertTrue(validate_submission(yaml.load(bad_submission))) bad_submission += """ compare: query: entity: testrunfilter """ self.assertRaises(SubmissionException, validate_yaml, yaml.load(bad_submission)) invalid_monitors_name_char_yaml_def = """ # Zephyr JOB definition device_type: 'arduino101' job_name: 'zephyr-upstream master drivers/spi/spi_basic_api/test_spi' timeouts: job: minutes: 6 action: minutes: 2 actions: wait-usb-device: seconds: 40 priority: medium visibility: public actions: - deploy: timeout: minutes: 3 to: tmpfs type: monitor images: app: image_arg: --alt x86_app --download {app} url: 'https://snapshots.linaro.org/components/kernel/zephyr/master/zephyr/arduino_101/722/tests/drivers/spi/spi_basic_api/test_spi/zephyr.bin' - boot: method: dfu timeout: minutes: 10 - test: monitors: - name: drivers/spi/spi_basic_api/test_spi start: tc_start() end: PROJECT EXECUTION pattern: (?P<result>(PASS|FAIL))\s-\s(?P<test_case_id>\w+)\. fixupdict: PASS: pass FAIL: fail """ self.assertRaises(SubmissionException, validate_submission, yaml.load(invalid_monitors_name_char_yaml_def))
def test_breakage_detection(self): bad_submission = """ timeouts: job: minutes: 15 action: minutes: 5 """ self.assertRaises(SubmissionException, validate_submission, yaml.load(bad_submission)) try: validate_submission(yaml.load(bad_submission)) except SubmissionException as exc: # with more than one omission, which one gets mentioned is undefined self.assertIn('required key not provided', str(exc)) bad_submission += """ actions: - deploy: to: tmpfs """ self.assertRaises(SubmissionException, validate_submission, yaml.load(bad_submission)) try: validate_submission(yaml.load(bad_submission)) except SubmissionException as exc: self.assertIn('required key not provided', str(exc)) # with more than one omission, which one gets mentioned is undefined self.assertTrue('visibility' in str(exc) or 'job_name' in str(exc)) bad_submission += """ visibility: public """ self.assertRaises(SubmissionException, validate_submission, yaml.load(bad_submission)) try: validate_submission(yaml.load(bad_submission)) except SubmissionException as exc: self.assertIn('required key not provided', str(exc)) self.assertIn('job_name', str(exc)) bad_submission += """ job_name: qemu-pipeline """ self.assertTrue(validate_submission(yaml.load(bad_submission))) bad_yaml = yaml.load(bad_submission) del bad_yaml['timeouts']['job'] try: validate_submission(yaml.load(bad_submission)) except SubmissionException as exc: self.assertIn('required key not provided', str(exc)) self.assertIn('job', str(exc)) self.assertIn('timeouts', str(exc)) bad_submission += """ notify: criteria: status: complete """ self.assertTrue(validate_submission(yaml.load(bad_submission))) bad_submission += """ compare: query: entity: testrunfilter """ self.assertRaises(SubmissionException, validate_yaml, yaml.load(bad_submission)) invalid_test_name_char_yaml_def = """ # Sample JOB definition for a KVM device_type: qemu job_name: kvm-pipeline timeouts: job: minutes: 15 action: minutes: 5 priority: medium visibility: public actions: - deploy: to: tmpfs image: http://images.validation.linaro.org/kvm-debian-wheezy.img.gz compression: gz os: debian - boot: method: qemu media: tmpfs failure_retry: 2 - test: name: kvm-advanced-singlenode definitions: - repository: git://git.linaro.org/qa/test-definitions.git from: git path: ubuntu/smoke-tests-basic.yaml name: smoke/tests """ self.assertRaises(SubmissionException, validate_submission, yaml.load(invalid_test_name_char_yaml_def)) invalid_monitors_name_char_yaml_def = """ # Zephyr JOB definition device_type: 'arduino101' job_name: 'zephyr-upstream master drivers/spi/spi_basic_api/test_spi' timeouts: job: minutes: 6 action: minutes: 2 actions: wait-usb-device: seconds: 40 priority: medium visibility: public actions: - deploy: timeout: minutes: 3 to: tmpfs type: monitor images: app: image_arg: --alt x86_app --download {app} url: 'https://snapshots.linaro.org/components/kernel/zephyr/master/zephyr/arduino_101/722/tests/drivers/spi/spi_basic_api/test_spi/zephyr.bin' - boot: method: dfu timeout: minutes: 10 - test: monitors: - name: drivers/spi/spi_basic_api/test_spi start: tc_start() end: PROJECT EXECUTION pattern: (?P<result>(PASS|FAIL))\s-\s(?P<test_case_id>\w+)\. fixupdict: PASS: pass FAIL: fail """ self.assertRaises(SubmissionException, validate_submission, yaml.load(invalid_monitors_name_char_yaml_def))
def test_json_vs_yaml(self): """ Test that invalid JSON gets rejected but valid YAML is accepted as pipeline """ user = self.factory.ensure_user('test', '*****@*****.**', 'test') user.user_permissions.add( Permission.objects.get(codename='add_testjob')) user.save() job = self.factory.make_testjob(submitter=user) self.assertFalse(job.is_pipeline) # "break" the JSON by dropping the closing } as JSON needs the complete file to validate invalid_def = job.definition[:-2] self.assertRaises(ValueError, json.loads, invalid_def) server = self.server_proxy('test', 'test') self.assertRaises(xmlrpclib.Fault, server.scheduler.submit_job, invalid_def) invalid_yaml_def = """ # Sample JOB definition for a KVM device_type: qemu job_name: kvm-pipeline priority: medium """ self.assertRaises(ValueError, json.loads, invalid_yaml_def) self.assertRaises(xmlrpclib.Fault, server.scheduler.submit_job, invalid_yaml_def) yaml_def = """ # Sample JOB definition for a KVM device_type: qemu job_name: kvm-pipeline timeouts: job: minutes: 15 action: minutes: 5 priority: medium visibility: public actions: - deploy: to: tmpfs image: http://images.validation.linaro.org/kvm-debian-wheezy.img.gz compression: gz os: debian - boot: method: qemu media: tmpfs failure_retry: 2 - test: name: kvm-basic-singlenode definitions: - repository: git://git.linaro.org/qa/test-definitions.git from: git path: ubuntu/smoke-tests-basic.yaml # name: if not present, use the name from the YAML. The name can # also be overriden from the actual commands being run by # calling the lava-test-suite-name API call (e.g. # `lava-test-suite-name FOO`). name: smoke-tests """ yaml_data = yaml.load(yaml_def) validate_submission(yaml_data) self.assertRaises(xmlrpclib.Fault, server.scheduler.submit_job, yaml_def) device_type = self.factory.make_device_type('qemu') device = self.factory.make_device(device_type=device_type, hostname="qemu1") device.save() self.assertFalse(device.is_pipeline) self.assertRaises(xmlrpclib.Fault, server.scheduler.submit_job, yaml_def) device = self.factory.make_device(device_type=device_type, hostname="qemu2", is_pipeline=True) device.save() self.assertTrue(device.is_pipeline) job_id = server.scheduler.submit_job(yaml_def) job = TestJob.objects.get(id=job_id) self.assertTrue(job.is_pipeline)
def submit_job(self, job_data): """ Name ---- `submit_job` (`job_data`) Description ----------- Submit the given job data which is in LAVA job JSON format as a new job to LAVA scheduler. Arguments --------- `job_data`: string Job JSON string. Return value ------------ This function returns an XML-RPC integer which is the newly created job's id, provided the user is authenticated with an username and token. """ self._authenticate() if not self.user.has_perm('lava_scheduler_app.add_testjob'): raise xmlrpclib.Fault( 403, "Permission denied. User %r does not have the " "'lava_scheduler_app.add_testjob' permission. Contact " "the administrators." % self.user.username) is_json = True is_yaml = False try: json.loads(job_data) except (AttributeError, JSONDecodeError, ValueError) as exc: is_json = False try: # only try YAML if this is not JSON # YAML can parse JSON as YAML, JSON cannot parse YAML at all yaml_data = yaml.load(job_data) except yaml.YAMLError as exc: # neither yaml nor json loaders were able to process the submission. raise xmlrpclib.Fault(400, "Loading job submission failed: %s." % exc) # validate against the submission schema. is_yaml = validate_submission(yaml_data) # raises SubmissionException if invalid. try: if is_json: job = TestJob.from_json_and_user(job_data, self.user) elif is_yaml: job = TestJob.from_yaml_and_user(job_data, self.user) else: raise xmlrpclib.Fault(400, "Unable to determine whether job is JSON or YAML.") except (JSONDataError, JSONDecodeError, ValueError) as exc: raise xmlrpclib.Fault(400, "Decoding job submission failed: %s." % exc) except Device.DoesNotExist: raise xmlrpclib.Fault(404, "Specified device not found.") except DeviceType.DoesNotExist: raise xmlrpclib.Fault(404, "Specified device type not found.") except DevicesUnavailableException as exc: raise xmlrpclib.Fault(400, str(exc)) if isinstance(job, type(list())): return [j.sub_id for j in job] else: return job.id
def test_multinode(self): # Without protocols data = """ job_name: test visibility: public timeouts: job: minutes: 10 action: minutes: 5 actions: [] """ self.assertTrue(validate_submission(yaml.load(data))) data = """ job_name: test visibility: public timeouts: job: minutes: 10 action: minutes: 5 actions: [] protocols: {} """ self.assertTrue(validate_submission(yaml.load(data))) # With a valid multinode protocol data = """ job_name: test visibility: public timeouts: job: minutes: 10 action: minutes: 5 actions: [] protocols: lava-multinode: roles: guest: {} host: {} """ self.assertTrue(validate_submission(yaml.load(data))) data = """ job_name: test visibility: public timeouts: job: minutes: 10 action: minutes: 5 actions: [] protocols: lava-multinode: roles: guest: host_role: host expect_role: host host: {} """ self.assertTrue(validate_submission(yaml.load(data))) # invalid host_role or expect_role data = """ job_name: test visibility: public timeouts: job: minutes: 10 action: minutes: 5 actions: [] protocols: lava-multinode: roles: guest: host_role: server host: {} """ self.assertRaises(SubmissionException, validate_submission, yaml.load(data)) data = """ job_name: test visibility: public timeouts: job: minutes: 10 action: minutes: 5 actions: [] protocols: lava-multinode: roles: guest: host_role: host expect_role: server host: {} """ self.assertRaises(SubmissionException, validate_submission, yaml.load(data)) # host_role without expect_role data = """ job_name: test visibility: public timeouts: job: minutes: 10 action: minutes: 5 actions: [] protocols: lava-multinode: roles: guest: host_role: host host: {} """ self.assertRaises(SubmissionException, validate_submission, yaml.load(data)) # expect_role without host_role data = """ job_name: test visibility: public timeouts: job: minutes: 10 action: minutes: 5 actions: [] protocols: lava-multinode: roles: guest: expect_role: host host: {} """ self.assertRaises(SubmissionException, validate_submission, yaml.load(data))