def test_no_workspace_needed(self): '''Tests calling JobInterface.validate_connection() without a workspace, but none is needed.''' job_interface_dict = { 'command': 'simple-command', 'command_arguments': '', 'version': '1.0', 'input_data': [{ 'name': 'Input 1', 'type': 'property', }, { 'name': 'Input 2', 'type': 'file', 'media_types': ['text/plain'], }], 'output_data': [], } job_interface = JobInterface(job_interface_dict) job_conn = JobConnection() job_conn.add_property('Input 1') job_conn.add_input_file('Input 2', False, ['text/plain'], False) # No exception is success job_interface.validate_connection(job_conn)
def test_required_workspace_missing(self): '''Tests calling JobInterface.validate_connection() when a required workspace is missing''' job_interface_dict = { 'command': 'simple-command', 'command_arguments': '', 'version': '1.0', 'input_data': [{ 'name': 'Input 1', 'type': 'property', }, { 'name': 'Input 2', 'type': 'file', 'media_types': ['text/plain'], }], 'output_data': [{ 'name': 'Output 1', 'type': 'file', }] } job_interface = JobInterface(job_interface_dict) job_conn = JobConnection() job_conn.add_property('Input 1') job_conn.add_input_file('Input 2', False, ['text/plain'], False) self.assertRaises(InvalidConnection, job_interface.validate_connection, job_conn)
def test_required_missing(self): '''Tests calling JobConnection.validate_input_files() when a required file parameter is missing''' files = {u'Param1': (True, True, ScaleFileDescription()), u'Param2': (True, True, ScaleFileDescription())} conn = JobConnection() conn.add_input_file(u'Param1', True, None, False) self.assertRaises(InvalidConnection, conn.validate_input_files, files)
def test_required_missing(self): """Tests calling JobConnection.validate_properties() when a required property is missing""" property_names = {'Param1': True, 'Param2': True, 'Param3': False} conn = JobConnection() conn.add_property('Param1') self.assertRaises(InvalidConnection, conn.validate_properties, property_names)
def test_jamming_multiple_into_single(self): '''Tests calling JobConnection.validate_input_files() when passing multiple files into a single file''' files = {u'Param1': (True, False, ScaleFileDescription())} conn = JobConnection() conn.add_input_file(u'Param1', True, None, False) self.assertRaises(InvalidConnection, conn.validate_input_files, files)
def test_required_missing(self): """Tests calling JobConnection.validate_input_files() when a required file parameter is missing""" files = {'Param1': (True, True, ScaleFileDescription()), 'Param2': (True, True, ScaleFileDescription())} conn = JobConnection() conn.add_input_file('Param1', True, None, False, False) self.assertRaises(InvalidConnection, conn.validate_input_files, files)
def test_optional_and_required(self): '''Tests calling JobConnection.validate_input_files() when the connection has optional data for required input''' files = {u'Param1': (True, True, ScaleFileDescription())} conn = JobConnection() conn.add_input_file(u'Param1', True, None, True) self.assertRaises(InvalidConnection, conn.validate_input_files, files)
def test_required_missing(self): '''Tests calling JobConnection.validate_properties() when a required property is missing''' property_names = {u'Param1': True, u'Param2': True, u'Param3': False} conn = JobConnection() conn.add_property(u'Param1') self.assertRaises(InvalidConnection, conn.validate_properties, property_names)
def test_optional_and_required(self): '''Tests calling JobConnection.validate_input_files() when the connection has optional data for required input''' files = {u'Param1': (True, True, ScaleFileDescription())} conn = JobConnection() conn.add_input_file(u'Param1', True, None, True, False) self.assertRaises(InvalidConnection, conn.validate_input_files, files)
def test_jamming_multiple_into_single(self): '''Tests calling JobConnection.validate_input_files() when passing multiple files into a single file''' files = {u'Param1': (True, False, ScaleFileDescription())} conn = JobConnection() conn.add_input_file(u'Param1', True, None, False, False) self.assertRaises(InvalidConnection, conn.validate_input_files, files)
def test_successful(self): '''Tests calling JobConnection.validate_properties() successfully''' property_names = {u'Param1': True, u'Param2': False, u'Param3': False} conn = JobConnection() conn.add_property(u'Param1') conn.add_property(u'Param2') # No exception is success warnings = conn.validate_properties(property_names) self.assertFalse(warnings)
def test_bad_media_type(self): '''Tests calling JobConnection.validate_input_files() with a bad media type''' file_desc = ScaleFileDescription() file_desc.add_allowed_media_type(u'application/json') files = {u'Param1': (True, True, file_desc)} conn = JobConnection() conn.add_input_file(u'Param1', True, None, False, False) warnings = conn.validate_input_files(files) self.assertTrue(warnings)
def test_bad_media_type(self): '''Tests calling JobConnection.validate_input_files() with a bad media type''' file_desc = ScaleFileDescription() file_desc.add_allowed_media_type(u'application/json') files = {u'Param1': (True, True, file_desc)} conn = JobConnection() conn.add_input_file(u'Param1', True, None, False) warnings = conn.validate_input_files(files) self.assertTrue(warnings)
def validate_trigger_for_job(self, job_interface): """See :meth:`job.triggers.configuration.trigger_rule.JobTriggerRuleConfiguration.validate_trigger_for_job` """ input_file_name = self.get_input_data_name() media_type = self.get_condition().get_media_type() media_types = [media_type] if media_type else None connection = JobConnection() connection.add_input_file(input_file_name, False, media_types, False, False) connection.add_workspace() return job_interface.validate_connection(connection)
def test_successful(self): """Tests calling JobInterface.validate_connection() successfully.""" job_interface_dict = { 'command': 'simple-command', 'command_arguments': '', 'version': '1.0', 'input_data': [{ 'name': 'Input 1', 'type': 'property', }, { 'name': 'Input 2', 'type': 'file', 'media_types': ['text/plain'] }], 'output_data': [{ 'name': 'Output 1', 'type': 'file', }] } job_interface = JobInterface(job_interface_dict) job_conn = JobConnection() job_conn.add_property('Input 1') job_conn.add_input_file('Input 2', False, ['text/plain'], False, False) job_conn.add_workspace() # No exception is success job_interface.validate_connection(job_conn)
def create(interface): """Instantiate an appropriately typed Job connection based on interface type """ if JobInterfaceSunset.is_seed(interface): return SeedJobConnection() else: return JobConnection()
def _validate_job_interface(self, job_dict, job_types_by_name): """Validates the input connections for the given job in the recipe definition :param job_dict: The job dictionary :type job_dict: dict :param job_types_by_name: Dict mapping all job names in the recipe to their job type models :type job_types_by_name: dict :returns: A list of warnings discovered during validation. :rtype: list[:class:`job.configuration.data.job_data.ValidationWarning`] :raises :class:`recipe.configuration.definition.exceptions.InvalidDefinition`: If there are any invalid job connections in the definition """ # Job connection will represent data to be passed to the job to validate job_conn = JobConnection() # Assume a workspace is provided, this will be verified when validating the recipe data job_conn.add_workspace() # Populate connection with data that will come from recipe inputs self._add_recipe_inputs_to_conn(job_conn, job_dict['recipe_inputs']) # Populate connection with data that will come from job dependencies warnings = [] for dependency_dict in job_dict['dependencies']: dependency_name = dependency_dict['name'] job_type = job_types_by_name[dependency_name] for conn_dict in dependency_dict['connections']: conn_input = conn_dict['input'] job_output = conn_dict['output'] job_type.get_job_interface().add_output_to_connection( job_output, job_conn, conn_input) job_type = job_types_by_name[job_dict['name']] try: warnings.extend( job_type.get_job_interface().validate_connection(job_conn)) except InvalidConnection as ex: raise InvalidDefinition(unicode(ex)) return warnings
def test_no_workspace_needed(self): """Tests calling JobInterface.validate_connection() without a workspace, but none is needed.""" job_interface_dict = { 'command': 'simple-command', 'command_arguments': '', 'version': '1.1', 'input_data': [{ 'name': 'Input 1', 'type': 'property', }, { 'name': 'Input 2', 'type': 'file', 'media_types': ['text/plain'], 'partial': True }], 'output_data': [], } job_interface = JobInterface(job_interface_dict) job_conn = JobConnection() job_conn.add_property('Input 1') job_conn.add_input_file('Input 2', False, ['text/plain'], False, True) # No exception is success job_interface.validate_connection(job_conn)
def test_required_workspace_missing(self): """Tests calling JobInterface.validate_connection() when a required workspace is missing""" job_interface_dict = { 'command': 'simple-command', 'command_arguments': '', 'version': '1.1', 'input_data': [{ 'name': 'Input 1', 'type': 'property', }, { 'name': 'Input 2', 'type': 'file', 'media_types': ['text/plain'], 'partial': True }], 'output_data': [{ 'name': 'Output 1', 'type': 'file', }] } job_interface = JobInterface(job_interface_dict) job_conn = JobConnection() job_conn.add_property('Input 1') job_conn.add_input_file('Input 2', False, ['text/plain'], False, True) self.assertRaises(InvalidConnection, job_interface.validate_connection, job_conn)
def _validate_job_interface(self, job_dict, job_types_by_name): """Validates the input connections for the given job in the recipe definition :param job_dict: The job dictionary :type job_dict: dict :param job_types_by_name: Dict mapping all job names in the recipe to their job type models :type job_types_by_name: dict :returns: A list of warnings discovered during validation. :rtype: list[:class:`job.configuration.data.job_data.ValidationWarning`] :raises :class:`recipe.configuration.definition.exceptions.InvalidDefinition`: If there are any invalid job connections in the definition """ # Job connection will represent data to be passed to the job to validate job_conn = JobConnection() # Assume a workspace is provided, this will be verified when validating the recipe data job_conn.add_workspace() # Populate connection with data that will come from recipe inputs self._add_recipe_inputs_to_conn(job_conn, job_dict['recipe_inputs']) # Populate connection with data that will come from job dependencies warnings = [] for dependency_dict in job_dict['dependencies']: dependency_name = dependency_dict['name'] job_type = job_types_by_name[dependency_name] for conn_dict in dependency_dict['connections']: conn_input = conn_dict['input'] job_output = conn_dict['output'] job_type.get_job_interface().add_output_to_connection(job_output, job_conn, conn_input) job_type = job_types_by_name[job_dict['name']] try: warnings.extend(job_type.get_job_interface().validate_connection(job_conn)) except InvalidConnection as ex: raise InvalidDefinition(unicode(ex)) return warnings
def validate_trigger_for_job(self, job_interface): '''See :meth:`job.triggers.configuration.trigger_rule.JobTriggerRuleConfiguration.validate_trigger_for_job` ''' input_file_name = self.get_input_data_name() media_type = self.get_condition().get_media_type() media_types = [media_type] if media_type else None connection = JobConnection() connection.add_input_file(input_file_name, False, media_types, False, False) connection.add_workspace() return job_interface.validate_connection(connection)
def test_successful(self): """Tests calling JobConnection.validate_input_files() successfully""" file_desc = ScaleFileDescription() file_desc.add_allowed_media_type('application/json') file_desc_2 = ScaleFileDescription() file_desc_2.add_allowed_media_type('application/json') file_desc_2.add_allowed_media_type('text/plain') files = {'Param1': (True, True, file_desc), 'Param2': (True, False, ScaleFileDescription()), 'Param3': (False, True, file_desc_2), 'Param4': (False, True, file_desc_2)} conn = JobConnection() conn.add_input_file('Param1', True, ['application/json'], False, False) conn.add_input_file('Param2', False, ['text/plain'], False, False) conn.add_input_file('Param3', False, ['text/plain'], False, False) # No exception is success warnings = conn.validate_input_files(files) self.assertFalse(warnings)
def test_successful(self): '''Tests calling JobInterface.validate_connection() successfully.''' job_interface_dict = { u'command': u'simple-command', u'command_arguments': u'', u'version': u'1.0', u'input_data': [{u'name': u'Input 1', u'type': u'property'}, {u'name': u'Input 2', u'type': u'file', u'media_types': [u'text/plain']}], u'output_data': [{u'name': u'Output 1', u'type': u'file'}] } job_interface = JobInterface(job_interface_dict) job_conn = JobConnection() job_conn.add_property(u'Input 1') job_conn.add_input_file(u'Input 2', False, [u'text/plain'], False) job_conn.add_workspace() # No exception is success job_interface.validate_connection(job_conn)
def test_successful(self): '''Tests calling JobConnection.validate_input_files() successfully''' file_desc = ScaleFileDescription() file_desc.add_allowed_media_type(u'application/json') file_desc_2 = ScaleFileDescription() file_desc_2.add_allowed_media_type(u'application/json') file_desc_2.add_allowed_media_type(u'text/plain') files = {u'Param1': (True, True, file_desc), u'Param2': (True, False, ScaleFileDescription()), u'Param3': (False, True, file_desc_2), u'Param4': (False, True, file_desc_2)} conn = JobConnection() conn.add_input_file(u'Param1', True, [u'application/json'], False) conn.add_input_file(u'Param2', False, [u'text/plain'], False) conn.add_input_file(u'Param3', False, [u'text/plain'], False) # No exception is success warnings = conn.validate_input_files(files) self.assertFalse(warnings)