Ejemplo n.º 1
0
    def test(self):
        filename = os.path.join(self.FIXTURE_DIR, 'LEMS_NML2_Ex5_DetCell.xml')
        errors, warnings, _ = validate_model(filename)
        print(flatten_nested_list_of_strings(errors))
        self.assertEqual(errors, [])
        self.assertEqual(warnings, [])

        filename = os.path.join(self.FIXTURE_DIR, 'no-simulation.xml')
        errors, warnings, _ = validate_model(filename)
        self.assertIn("No component found: sim1", flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])

        filename = os.path.join(self.FIXTURE_DIR, 'undefined-target.xml')
        errors, warnings, _ = validate_model(filename)
        self.assertIn("No component found: net2", flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])

        filename = os.path.join(self.FIXTURE_DIR, 'missing-include.xml')
        errors, warnings, _ = validate_model(filename)
        self.assertIn("Can't find file at path: Cells2.xml", flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])

        filename = os.path.join(self.FIXTURE_DIR, 'invalid.xml')
        errors, warnings, _ = validate_model(filename)
        self.assertIn("Can't read LEMS from XMLElt", flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])
Ejemplo n.º 2
0
    def test(self):
        filename = os.path.join(self.FIXTURE_DIRNAME,
                                'Escherichia-coli-K12-WT.zip')
        errors, warnings, model = validation.validate_model(filename)
        self.assertEqual(errors, [])
        self.assertEqual(warnings, [])
        self.assertIsInstance(model, rba.model.RbaModel)

        filename = None
        errors, warnings, model = validation.validate_model(filename)
        self.assertIn('is not a path', flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])
        self.assertEqual(model, None)

        filename = os.path.join(self.FIXTURE_DIRNAME, 'not exist.zip')
        errors, warnings, model = validation.validate_model(filename)
        self.assertIn('does not exist', flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])
        self.assertEqual(model, None)

        filename = __file__
        errors, warnings, model = validation.validate_model(filename)
        self.assertIn('is not a valid RBA',
                      flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])
        self.assertEqual(model, None)

        filename = os.path.join(self.FIXTURE_DIRNAME,
                                'Escherichia-coli-K12-WT-invalid.zip')
        errors, warnings, model = validation.validate_model(filename)
        self.assertIn('is not a valid RBA',
                      flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])
        self.assertEqual(model, None)
Ejemplo n.º 3
0
    def validate_archive(self, filename):
        reader = CombineArchiveReader()
        name = os.path.relpath(filename, EXAMPLES_DIR)
        temp_dirname = os.path.join(self.temp_dirname, name)
        if not os.path.isdir(temp_dirname):
            os.makedirs(temp_dirname)
        archive = reader.run(filename, temp_dirname)

        config = Config(
            OMEX_METADATA_SCHEMA=OmexMetadataSchema.biosimulations, )

        error_msgs, warning_msgs = validate(
            archive,
            temp_dirname,
            formats_to_validate=list(
                CombineArchiveContentFormat.__members__.values()),
            config=config,
        )

        if warning_msgs:
            msg = 'The COMBINE/OMEX archive may be invalid.\n  {}'.format(
                flatten_nested_list_of_strings(warning_msgs).replace(
                    '\n', '\n  '))
            warnings.warn(msg, BioSimulatorsWarning)

        if error_msgs:
            msg = 'The COMBINE/OMEX archive is not valid.\n  {}'.format(
                flatten_nested_list_of_strings(error_msgs).replace(
                    '\n', '\n  '))
            raise ValueError(msg)
    def test_flatten_nested_list_of_strings(self):
        self.assertEqual(
            utils.flatten_nested_list_of_strings([['A'], ['B'], ['C']],
                                                 prefix='- ',
                                                 indent='  '), '\n'.join([
                                                     '- A',
                                                     '- B',
                                                     '- C',
                                                 ]))

        self.assertEqual(
            utils.flatten_nested_list_of_strings(
                [['A'], [
                    'B',
                    [
                        ['1'],
                        ['2'],
                        ['3'],
                    ],
                ], ['C']],
                prefix='- ',
                indent='  '), '\n'.join([
                    '- A',
                    '- B',
                    '  - 1',
                    '  - 2',
                    '  - 3',
                    '- C',
                ]))

        self.assertEqual(
            utils.flatten_nested_list_of_strings([['A'],
                                                  [
                                                      'B',
                                                      [
                                                          ['1'],
                                                          [
                                                              '2\n3',
                                                              [
                                                                  ['i'],
                                                                  ['ii\niii'],
                                                              ],
                                                          ],
                                                          ['4'],
                                                      ],
                                                  ], ['C']],
                                                 prefix='- ',
                                                 indent='  '), '\n'.join([
                                                     '- A',
                                                     '- B',
                                                     '  - 1',
                                                     '  - 2',
                                                     '    3',
                                                     '    - i',
                                                     '    - ii',
                                                     '      iii',
                                                     '  - 4',
                                                     '- C',
                                                 ]))
    def test_BiosimulationsOmexMetaReader_get_combine_archive_uri_no_root(self):
        rdf, errors, warnings = io.BiosimulationsOmexMetaReader.read_rdf(self.NO_ROOT_FIXTURE)
        triples = io.BiosimulationsOmexMetaReader.get_rdf_triples(rdf)
        root_uri, errors, warnings = io.BiosimulationsOmexMetaReader.get_combine_archive_uri(triples)
        self.assertEqual(root_uri, '.')
        self.assertIn('does not contain metadata', flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])

        _, errors, warnings = io.BiosimulationsOmexMetaReader().run(self.NO_ROOT_FIXTURE)
        self.assertIn('does not contain metadata', flatten_nested_list_of_strings(errors))
    def test_BiosimulationsOmexMetaReader_get_combine_archive_uri_multiple_root(self):
        rdf, errors, warnings = io.BiosimulationsOmexMetaReader.read_rdf(self.MULTIPLE_ROOTS_FIXTURE)
        triples = io.BiosimulationsOmexMetaReader.get_rdf_triples(rdf)
        root_uri, errors, warnings = io.BiosimulationsOmexMetaReader.get_combine_archive_uri(triples)
        self.assertEqual(root_uri, None)
        self.assertIn('metadata about multiple', flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])

        _, errors, warnings = io.BiosimulationsOmexMetaReader().run(self.MULTIPLE_ROOTS_FIXTURE)
        self.assertIn('metadata about multiple OMEX archives', flatten_nested_list_of_strings(errors))
    def test_read_omex_meta_file(self):
        triples, errors, warnings = io.read_omex_meta_file(
            self.FIXTURE,
            config=Config(
                OMEX_METADATA_SCHEMA=data_model.OmexMetadataSchema.rdf_triples,
            ))
        self.assertEqual(errors, [])
        self.assertEqual(warnings, [])

        metadata, errors, warnings = io.read_omex_meta_file(
            self.FIXTURE,
            config=Config(
                OMEX_METADATA_SCHEMA=data_model.OmexMetadataSchema.biosimulations,
            ),
            working_dir=self.dir_name)
        self.assertEqual(errors, [])
        self.assertEqual(warnings, [])

        metadata, errors, warnings = io.read_omex_meta_file(
            self.FIXTURE,
            config=Config(
                OMEX_METADATA_SCHEMA=None,
            ))
        self.assertEqual(metadata, None)
        self.assertIn('is not supported', flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])
    def test_TriplesOmexMetaReader_run(self):
        triples, errors, warnings = io.TriplesOmexMetaReader().run(self.FIXTURE)
        self.assertEqual(errors, [])
        self.assertEqual(warnings, [])

        triples, errors, warnings = io.TriplesOmexMetaReader().run([self.FIXTURE])
        self.assertEqual(errors, [])
        self.assertEqual(warnings, [])

        triples, errors, warnings = io.TriplesOmexMetaReader().run('undefined')
        self.assertIn('is not a file', flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])

        triples, errors, warnings = io.TriplesOmexMetaReader().run(['undefined'])
        self.assertIn('is not a file', flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])
    def test_validate_omex_meta_file(self):
        config = Config(OMEX_METADATA_SCHEMA=OmexMetadataSchema.rdf_triples)

        _, errors, warnings = read_omex_meta_file(os.path.join(
            self.OMEX_META_FIXTURES_DIR, 'libcombine.rdf'),
                                                  working_dir=self.tmp_dir,
                                                  config=config)
        self.assertEqual(errors, [])
        self.assertEqual(warnings, [])

        _, errors, warnings = read_omex_meta_file(os.path.join(
            self.OMEX_META_FIXTURES_DIR, 'biosimulations.rdf'),
                                                  working_dir=self.tmp_dir,
                                                  config=config)
        self.assertEqual(errors, [])
        self.assertEqual(warnings, [])

        _, errors, warnings = read_omex_meta_file(os.path.join(
            self.OMEX_META_FIXTURES_DIR, 'warning.rdf'),
                                                  working_dir=self.tmp_dir,
                                                  config=config)
        self.assertIn("Unsupported version '1.2'",
                      flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])

        _, errors, warnings = read_omex_meta_file(os.path.join(
            self.OMEX_META_FIXTURES_DIR, 'invalid.rdf'),
                                                  working_dir=self.tmp_dir,
                                                  config=config)
        self.assertEqual(len(errors), 4)
        self.assertIn("XML parser error",
                      flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])

        _, errors, warnings = read_omex_meta_file(os.path.join(
            self.OMEX_META_FIXTURES_DIR, 'malformed.rdf'),
                                                  working_dir=self.tmp_dir,
                                                  config=config)
        self.assertEqual(len(errors), 3)
        self.assertIn("Opening and ending tag mismatch",
                      flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])
    def test_manifest_in_manifest(self):
        out_dir = os.path.join(self.tmp_dir, 'out')
        archive = CombineArchiveReader().run(
            os.path.join(os.path.dirname(__file__), '..', 'fixtures',
                         'manifest-in-manifest.omex'), out_dir)
        errors, warnings = validate(archive, out_dir)
        self.assertEqual(errors, [])
        self.assertIn(
            'manifests should not contain content entries for themselves',
            flatten_nested_list_of_strings(warnings))

        out_dir = os.path.join(self.tmp_dir, 'out')
        archive = CombineArchiveReader().run(
            os.path.join(os.path.dirname(__file__), '..', 'fixtures',
                         'multiple-manifests.omex'), out_dir)
        errors, warnings = validate(archive, out_dir)
        self.assertEqual(errors, [])
        self.assertIn(
            'manifests should not contain content entries for themselves',
            flatten_nested_list_of_strings(warnings))
    def test_validate(self):
        os.remove(os.path.join(self.tmp_dir, 'thumbnail.png'))

        archive = CombineArchiveReader().run(self.OMEX_FIXTURE, self.tmp_dir)
        errors, warnings = validate(archive, self.tmp_dir)
        self.assertEqual(errors, [])
        self.assertNotEqual(warnings, [])

        archive2 = copy.deepcopy(archive)
        for content in archive.contents:
            archive2.contents.append(content)
        errors, warnings = validate(archive2, self.tmp_dir)
        self.assertIn('contains repeated content items',
                      flatten_nested_list_of_strings(errors))

        archive2 = copy.deepcopy(archive)
        archive2.contents = []
        errors, warnings = validate(archive2, self.tmp_dir)
        self.assertIn('does not contain content items',
                      flatten_nested_list_of_strings(errors))
    def test_read_rdf(self):
        rdf, errors, warnings = io.OmexMetaReader.read_rdf(self.FIXTURE)
        self.assertIsInstance(rdf, pyomexmeta.RDF)
        self.assertEqual(errors, [])
        self.assertEqual(warnings, [])

        rdf, errors, warnings = io.OmexMetaReader.read_rdf('undefined')
        self.assertEqual(rdf, None)
        self.assertIn('is not a file', flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])

        rdf, errors, warnings = io.OmexMetaReader.read_rdf(self.INVALID_FIXTURE)
        self.assertEqual(rdf, None)
        self.assertIn('XML parser error', flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])

        rdf, errors, warnings = io.OmexMetaReader.read_rdf(self.WARNING_FIXTURE)
        self.assertEqual(rdf, None)
        self.assertIn('Unsupported version', flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])
    def test(self):
        errors, warnings, _ = validate_model(
            os.path.join(self.FIXTURE_DIR, 'bounce1.txt'))
        self.assertEqual(errors, [])
        self.assertEqual(warnings, [])

        errors, warnings, _ = validate_model(
            os.path.join(self.FIXTURE_DIR, 'invalid.txt'))
        self.assertIn("not a valid Smoldyn",
                      flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])

        errors, warnings, _ = validate_model(
            os.path.join(self.FIXTURE_DIR, 'not a file.txt'))
        self.assertIn('is not a file', flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])

        errors, warnings, _ = validate_model(None)
        self.assertIn('must be a path', flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])
Ejemplo n.º 14
0
    def test(self):
        errors, warnings, _ = validate_model(
            os.path.join(self.FIXTURE_DIR, 'valid.bngl'))
        self.assertEqual(errors, [])
        self.assertEqual(warnings, [])

        fid, filename = tempfile.mkstemp()
        os.close(fid)
        shutil.copyfile(os.path.join(self.FIXTURE_DIR, 'valid.bngl'), filename)
        errors, warnings, _ = validate_model(filename)
        self.assertEqual(errors, [])
        self.assertEqual(warnings, [])
        os.remove(filename)

        filename = os.path.join(self.FIXTURE_DIR, 'invalid.bngl2')
        _, errors, _ = read_model(filename, '')
        self.assertIn("not a valid BNGL or BGNL XML file",
                      flatten_nested_list_of_strings(errors))

        filename = os.path.join(self.FIXTURE_DIR, 'invalid.bngl')
        errors, warnings, _ = validate_model(filename)
        self.assertIn("not a valid BNGL",
                      flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])

        filename = os.path.join(self.FIXTURE_DIR, 'does-not-exist')
        errors, warnings, _ = validate_model(filename)
        self.assertIn('is not a file', flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])

        filename = None
        errors, warnings, _ = validate_model(filename)
        self.assertIn('must be a path', flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])

        filename = os.path.join(self.FIXTURE_DIR, '..', 'BIOMD0000000075.xml')
        errors, warnings, _ = validate_model(filename)
        self.assertIn('does not appear to a valid',
                      flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])
    def test_validate_biosimulations_metadata_for_uri(self):
        config = Config(
            OMEX_METADATA_SCHEMA=data_model.OmexMetadataSchema.biosimulations)
        md, errors, _ = read_omex_meta_file(
            [self.FIXTURE_THIRD_A, self.FIXTURE_THIRD_B, self.FIXTURE_THIRD_C],
            config=config)
        self.assertEqual(errors, [])
        self.assertEqual(len(md), 2)

        md, errors, _ = read_omex_meta_file(
            [self.FIXTURE_THIRD_A, self.FIXTURE_THIRD_B], config=config)
        self.assertEqual(errors, [])
        self.assertEqual(len(md), 1)

        md, errors, _ = read_omex_meta_file(
            [self.FIXTURE_THIRD_A, self.FIXTURE_THIRD_C], config=config)
        self.assertEqual(errors, [])
        self.assertEqual(len(md), 2)

        md, errors, _ = read_omex_meta_file(
            [self.FIXTURE_THIRD_B, self.FIXTURE_THIRD_C], config=config)
        self.assertIn('is required', flatten_nested_list_of_strings(errors))
        self.assertEqual(len(md), 2)

        md, errors, _ = read_omex_meta_file([self.FIXTURE_THIRD_A],
                                            config=config)
        self.assertEqual(errors, [])
        self.assertEqual(len(md), 1)

        md, errors, _ = read_omex_meta_file([self.FIXTURE_THIRD_B],
                                            config=config)
        self.assertIn('is required', flatten_nested_list_of_strings(errors))
        self.assertEqual(len(md), 1)

        md, errors, _ = read_omex_meta_file([self.FIXTURE_THIRD_C],
                                            config=config)
        self.assertIn('does not contain information',
                      flatten_nested_list_of_strings(errors))
        self.assertEqual(len(md), 1)
    def test_read_omex_meta_files_for_archive(self):
        shutil.copyfile(os.path.join(self.FIXTURE_DIR, 'biosimulations.rdf'),
                        os.path.join(self.dir_name, 'biosimulations.rdf'))
        shutil.copyfile(os.path.join(self.FIXTURE_DIR, 'biosimulations-with-file-annotations.rdf'),
                        os.path.join(self.dir_name, 'biosimulations-with-file-annotations.rdf'))

        archive = CombineArchive()
        archive.contents = [
            CombineArchiveContent(
                location='biosimulations.rdf',
                format=CombineArchiveContentFormat.OMEX_METADATA,
            ),
            CombineArchiveContent(
                location='biosimulations-with-file-annotations.rdf',
                format=CombineArchiveContentFormat.OMEX_METADATA,
            ),
        ]

        config = Config(
            OMEX_METADATA_SCHEMA=data_model.OmexMetadataSchema.biosimulations,
        )
        md, errors, warnings = io.read_omex_meta_files_for_archive(
            archive, self.dir_name, config=config)
        self.assertIn('The COMBINE archive should only contain one instance of predicate', flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])
        self.assertEqual(len(md), 2)
        self.assertEqual(sorted(m['uri'] for m in md), sorted(['.', './sim.sedml/figure1']))

        md, errors, warnings = io.read_omex_meta_files_for_archive(archive, self.dir_name)
        self.assertIn('The COMBINE archive should only contain one instance of predicate', flatten_nested_list_of_strings(errors))

        shutil.copyfile(os.path.join(self.FIXTURE_DIR, 'biosimulations-abbrev-third-a.rdf'),
                        os.path.join(self.dir_name, 'biosimulations-abbrev-third-a.rdf'))
        shutil.copyfile(os.path.join(self.FIXTURE_DIR, 'biosimulations-abbrev-third-b.rdf'),
                        os.path.join(self.dir_name, 'biosimulations-abbrev-third-b.rdf'))
        shutil.copyfile(os.path.join(self.FIXTURE_DIR, 'biosimulations-abbrev-third-c.rdf'),
                        os.path.join(self.dir_name, 'biosimulations-abbrev-third-c.rdf'))

        archive = CombineArchive()
        archive.contents = [
            CombineArchiveContent(
                location='biosimulations-abbrev-third-a.rdf',
                format=CombineArchiveContentFormat.OMEX_METADATA,
            ),
            CombineArchiveContent(
                location='biosimulations-abbrev-third-b.rdf',
                format=CombineArchiveContentFormat.OMEX_METADATA,
            ),
            CombineArchiveContent(
                location='biosimulations-abbrev-third-c.rdf',
                format=CombineArchiveContentFormat.OMEX_METADATA,
            ),
        ]

        config = Config(
            OMEX_METADATA_SCHEMA=data_model.OmexMetadataSchema.biosimulations,
        )
        md, errors, warnings = io.read_omex_meta_files_for_archive(
            archive, self.dir_name, config=config)
        self.assertEqual(errors, [])
        self.assertEqual(warnings, [])
        self.assertEqual(len(md), 2)
        self.assertEqual(sorted(m['uri'] for m in md), sorted(['.', './sim.sedml/figure1']))
    def test_no_validation(self):
        archive_dirname = os.path.join(self.tmp_dir, 'archive')
        os.mkdir(archive_dirname)

        # OMEX manifests
        archive = CombineArchive()

        errors, warnings = validate(archive, archive_dirname)
        self.assertIn('must have at least one content',
                      flatten_nested_list_of_strings(errors))
        self.assertNotEqual(warnings, [])

        with mock.patch.dict('os.environ', {'VALIDATE_OMEX_MANIFESTS': '0'}):
            errors, warnings = validate(archive, archive_dirname)
        self.assertEqual(errors, [])
        self.assertEqual(warnings, [])

        # SED-ML
        archive = CombineArchive()
        archive.contents.append(
            CombineArchiveContent(
                location='simulation.sedml',
                format=CombineArchiveContentFormat.SED_ML.value,
            ))

        sedml_filename = os.path.join(archive_dirname, 'simulation.sedml')
        with open(sedml_filename, 'w') as file:
            file.write('invalid')

        errors, warnings = validate(archive, archive_dirname)
        self.assertIn('Missing XML declaration',
                      flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])

        with mock.patch.dict('os.environ', {
                'VALIDATE_OMEX_MANIFESTS': '0',
                'VALIDATE_SEDML': '0',
        }):
            errors, warnings = validate(archive, archive_dirname)
        self.assertEqual(errors, [])
        self.assertEqual(warnings, [])

        os.remove(sedml_filename)

        # models
        archive = CombineArchive()
        archive.contents.append(
            CombineArchiveContent(
                location='simulation.sedml',
                format=CombineArchiveContentFormat.SED_ML.value,
            ))

        model_filename = os.path.join(archive_dirname, 'model.xml')
        shutil.copyfile(
            os.path.join(os.path.dirname(__file__), '..', 'fixtures',
                         'BIOMD0000000297.xml'), model_filename)

        sed_doc = SedDocument()
        sed_doc.models.append(
            Model(id='model',
                  source=model_filename,
                  language=ModelLanguage.SBML.value))

        sedml_filename = os.path.join(archive_dirname, 'simulation.sedml')
        SedmlSimulationWriter().run(sed_doc, sedml_filename)

        with open(model_filename, 'w') as file:
            file.write('invalid')

        errors, warnings = validate(archive, archive_dirname)
        self.assertIn('Missing XML declaration',
                      flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])

        with mock.patch.dict('os.environ', {
                'VALIDATE_OMEX_MANIFESTS': '0',
                'VALIDATE_SEDML_MODELS': '0',
        }):
            errors, warnings = validate(archive, archive_dirname)
        self.assertEqual(errors, [])
        self.assertEqual(warnings, [])

        os.remove(sedml_filename)
        os.remove(model_filename)

        # images
        archive = CombineArchive()
        archive.contents.append(
            CombineArchiveContent(
                location='image.png',
                format=CombineArchiveContentFormat.PNG.value,
            ))

        errors, warnings = validate(
            archive,
            archive_dirname,
            formats_to_validate=[CombineArchiveContentFormat.PNG])
        self.assertIn('The PNG file at location `image.png` is invalid.',
                      flatten_nested_list_of_strings(errors))
        self.assertNotEqual(warnings, [])

        with mock.patch.dict('os.environ', {
                'VALIDATE_OMEX_MANIFESTS': '0',
                'VALIDATE_IMAGES': '0',
        }):
            errors, warnings = validate(
                archive,
                archive_dirname,
                formats_to_validate=[CombineArchiveContentFormat.PNG])
        self.assertEqual(errors, [])
        self.assertEqual(warnings, [])

        # OMEX metadata
        archive = CombineArchive()
        archive.contents.append(
            CombineArchiveContent(
                location='metadata.rdf',
                format=CombineArchiveContentFormat.OMEX_METADATA.value,
            ))

        metadata_file = os.path.join(archive_dirname, 'metadata.rdf')
        shutil.copyfile(
            os.path.join(os.path.dirname(__file__), '..', 'fixtures',
                         'omex-metadata', 'invalid.rdf'), metadata_file)

        errors, warnings = validate(
            archive,
            archive_dirname,
            formats_to_validate=[CombineArchiveContentFormat.OMEX_METADATA])
        self.assertIn(
            'The OMEX Metadata file at location `metadata.rdf` is invalid.',
            flatten_nested_list_of_strings(errors))
        self.assertNotEqual(warnings, [])

        with mock.patch.dict('os.environ', {
                'VALIDATE_OMEX_MANIFESTS': '0',
                'VALIDATE_OMEX_METADATA': '0',
        }):
            errors, warnings = validate(
                archive,
                archive_dirname,
                formats_to_validate=[
                    CombineArchiveContentFormat.OMEX_METADATA
                ])
        self.assertEqual(errors, [])
        self.assertEqual(warnings, [])

        os.remove(metadata_file)
 def test_read_omex_meta_file_no_root(self):
     filename = self.NO_ROOT_FIXTURE
     metadata, errors, warnings = io.BiosimulationsOmexMetaReader().run(filename, working_dir=self.dir_name)
     self.assertEqual(metadata, None)
     self.assertIn('does not contain metadata', flatten_nested_list_of_strings(errors))
     self.assertEqual(warnings, [])
    def test_BiosimulationsOmexMetaReader_run(self):
        metadata, errors, warnings = io.BiosimulationsOmexMetaReader().run(self.FIXTURE, working_dir=self.dir_name)
        expected = [{
            'uri': '.',
            'combine_archive_uri': 'http://omex-library.org/BioSim0001.omex',
            'title': 'Name',
            'abstract': 'Short summary',
            'keywords': ['tag 1', 'tag 2'],
            'thumbnails': ['./thumbnail.png'],
            'description': 'Description',
            'taxa': [
                {
                    'uri': 'http://identifiers.org/taxonomy/9606',
                    'label': 'H**o sapiens',
                }
            ],
            'encodes': [
                {
                    'uri': 'http://identifiers.org/CL:0001057',
                    'label': 'myeloid dendritic cell, human',
                }
            ],
            'sources': [
                {
                    'uri': 'http://identifiers.org/github:lab/project',
                    'label': 'Tsur 2019 model source code',
                }
            ],
            'predecessors': [
                {
                    'uri': 'http://identifiers.org/biomodels.db:BIOMD0000000837',
                    'label': 'Hanson2016 - Toxicity Management in CAR T cell therapy for B-ALL',
                }
            ],
            'references': [
                {
                    'uri': 'http://identifiers.org/pubmed:1234',
                    'label': 'D Nadeau, C Marchand. Change in the kinetics of sulphacetamide tissue distribution in Walker tumor-bearing rats. Drug Metab Dispos 3(6): 565-76 (1975).',
                },
            ],
            'successors': [
                {
                    'uri': 'http://identifiers.org/biomodels.db:BIOMD0000000839',
                    'label': 'Almeida2019 - Transcription-based circadian ...',
                }
            ],
            'see_also': [
                {
                    'uri': 'http://identifiers.org/biomodels.db:BIOMD0000000836',
                    'label': 'Radosavljevic2009_BioterroristAttack_PanicProtection_1',
                }
            ],
            'identifiers': [
                {
                    'uri': 'http://identifiers.org/biomodels.db:BIOMD0000000838',
                    'label': 'biomodels.db:BIOMD0000000838',
                }
            ],
            'citations': [
                {
                    'uri': 'http://identifiers.org/doi:10.1016/j.copbio.2017.12.013',
                    'label': (
                        'Goldberg AP, Szigeti B, Chew YH, Sekar JA, Roth YD & Karr JR. '
                        'Emerging whole-cell modeling principles and methods. '
                        'Curr Opin Biotechnol 2018, 51:97-102.'
                    ),
                },
                {
                    'uri': 'http://identifiers.org/pubmed:29275251',
                    'label': (
                        'Goldberg AP, Szigeti B, Chew YH, Sekar JA, Roth YD & Karr JR. '
                        'Emerging whole-cell modeling principles and methods. '
                        'Curr Opin Biotechnol 2018, 51:97-102.'
                    ),
                }
            ],
            'creators': [
                {
                    'uri': 'http://identifiers.org/orcid:0000-0001-8254-4958',
                    'label': 'Jonathan Karr',
                }
            ],
            'contributors': [
                {
                    'uri': None,
                    'label': 'Name of person with no ORCID account',
                }
            ],
            'license': {
                'uri': 'http://identifiers.org/spdx:MIT',
                'label': 'MIT',
            },
            'funders': [
                {
                    'uri': 'http://identifiers.org/doi:10.13039/100000001',
                    'label': 'National Science Foundation',
                },
            ],
            'created': '2020-06-18',
            'modified': ['2021-06-18'],
            'other': [
                {
                    'attribute': {
                        'uri': 'http://ontology.eil.utoronto.ca/icity/OM/temporalUnit',
                        'label': 'Temporal unit',
                    },
                    'value': {
                        'uri': 'http://www.w3.org/2006/time#second',
                        'label': 'second',
                    },
                },
            ],
        }]
        for key in expected[0].keys():
            self.assertEqual(metadata[0][key], expected[0][key], key)
        self.assertEqual(metadata, expected)
        self.assertEqual(errors, [])
        self.assertEqual(warnings, [])

        filename = os.path.join(self.FIXTURE_DIR, 'biosimulations-abbrev.rdf')
        metadata2, errors, warnings = io.BiosimulationsOmexMetaReader().run(filename, working_dir=self.dir_name)
        self.assertEqual(metadata2, metadata)

        filename = os.path.join(self.FIXTURE_DIR, 'abbrev.rdf')
        metadata, errors, warnings = io.BiosimulationsOmexMetaReader().run(filename, working_dir=self.dir_name)
        self.assertEqual(metadata[0]['title'], 'Name')
        self.assertEqual(metadata[0]['funders'], [
            {
                'uri': 'http://identifiers.org/doi:10.13039/100000001',
                'label': 'National Science Foundation',
            },
        ])
        self.assertEqual(errors, [])
        self.assertEqual(warnings, [])

        md, errors, warnings = io.BiosimulationsOmexMetaReader().run(
            os.path.join(self.FIXTURE_DIR, 'biosimulations-with-file-annotations.rdf'),
            working_dir=self.dir_name)
        self.assertEqual(errors, [])
        self.assertEqual(warnings, [])
        self.assertEqual(len(md), 2)
        self.assertEqual(set(m['uri'] for m in md), set(['.', './sim.sedml/figure1']))
        m = next(m for m in md if m['uri'] == './sim.sedml/figure1')
        self.assertEqual(m, {
            'uri': './sim.sedml/figure1',
            'combine_archive_uri': 'http://omex-library.org/BioSim0001.omex',
            'title': None,
            'abstract': None,
            'keywords': [],
            'thumbnails': [],
            'description': None,
            'taxa': [],
            'encodes': [],
            'sources': [],
            'predecessors': [],
            'references': [],
            'successors': [],
            'see_also': [],
            'identifiers': [{
                'uri': 'http://identifiers.org/doi:10.1371/journal.pcbi.1008379.g001',
                'label': 'Figure 1a',
            }],
            'citations': [],
            'creators': [],
            'contributors': [],
            'license': None,
            'funders': [],
            'created': None,
            'modified': [],
            'other': [
            ],
        })

        filename = os.path.join(self.FIXTURE_DIR, 'missing-required.rdf')
        metadata, errors, warnings = io.BiosimulationsOmexMetaReader().run(filename, working_dir=self.dir_name)
        self.assertIn('is required', flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])

        filename = os.path.join(self.FIXTURE_DIR, 'missing-label.rdf')
        metadata, errors, warnings = io.BiosimulationsOmexMetaReader().run(filename, working_dir=self.dir_name)
        self.assertEqual(errors, [])
        self.assertIn('does not contain an rdf:label', flatten_nested_list_of_strings(warnings))

        filename = os.path.join(self.FIXTURE_DIR, 'invalid-thumbnail-uri.rdf')
        metadata, errors, warnings = io.BiosimulationsOmexMetaReader().run(filename, working_dir=self.dir_name)
        self.assertIn('must begin with the URI', flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])

        filename = os.path.join(self.FIXTURE_DIR, 'missing-thumbnail-uri.rdf')
        metadata, errors, warnings = io.BiosimulationsOmexMetaReader().run(filename, working_dir=self.dir_name)
        self.assertEqual(errors, [])
        self.assertIn('does not contain an URI', flatten_nested_list_of_strings(warnings))

        filename = os.path.join(self.FIXTURE_DIR, 'missing-uri.rdf')
        metadata, errors, warnings = io.BiosimulationsOmexMetaReader().run(filename, working_dir=self.dir_name)
        self.assertEqual(errors, [])
        self.assertEqual(warnings, [])

        filename = os.path.join(self.FIXTURE_DIR, 'missing-label-2.rdf')
        metadata, errors, warnings = io.BiosimulationsOmexMetaReader().run(filename, working_dir=self.dir_name)
        self.assertEqual(errors, [])
        self.assertIn('does not contain an rdf:label', flatten_nested_list_of_strings(warnings))

        filename = os.path.join(self.FIXTURE_DIR, 'too-many-objects.rdf')
        metadata, errors, warnings = io.BiosimulationsOmexMetaReader().run(filename, working_dir=self.dir_name)
        self.assertIn('should only contain one instance of predicate', flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])

        filename = 'does not exist'
        metadata, errors, warnings = io.BiosimulationsOmexMetaReader().run(filename, working_dir=self.dir_name)
        self.assertEqual(metadata, None)
        self.assertIn('is not a file', flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])

        filename = self.NO_ROOT_FIXTURE
        metadata, errors, warnings = io.BiosimulationsOmexMetaReader().run(filename, working_dir=self.dir_name)
        self.assertNotEqual(metadata, None)
        self.assertIn('Thumbnail URIs must begin with', flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])
    def test_validate_biosimulations_metadata_for_uri(self):
        config = Config(
            OMEX_METADATA_SCHEMA=data_model.OmexMetadataSchema.biosimulations)
        md, _, _ = read_omex_meta_file(self.FIXTURE, config=config)
        md = md[0]

        errors, warnings = validate_biosimulations_metadata_for_uri(md)
        self.assertEqual(errors, [])
        self.assertIn('thumbnails could not be validated',
                      flatten_nested_list_of_strings(warnings))

        errors, warnings = validate_biosimulations_metadata_for_uri(
            md, working_dir=self.dir_name)
        self.assertIn('is not a file', flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])

        shutil.copyfile(
            os.path.join(self.FIXTURES_DIR, 'images',
                         'PNG_transparency_demonstration_1.png'),
            os.path.join(self.dir_name, 'thumbnail.png'))
        errors, warnings = validate_biosimulations_metadata_for_uri(
            md, working_dir=self.dir_name)
        self.assertEqual(errors, [])
        self.assertEqual(warnings, [])

        shutil.copyfile(
            os.path.join(self.FIXTURES_DIR, 'images',
                         'PNG_transparency_demonstration_1.png'),
            os.path.join(self.dir_name, 'thumbnail.png'))
        archive = CombineArchive(contents=[
            CombineArchiveContent(
                location='thumbnail.png',
                format=CombineArchiveContentFormat.PNG.value,
            ),
        ])
        errors, warnings = validate_biosimulations_metadata_for_uri(
            md,
            validate_minimal_metadata=True,
            archive=archive,
            working_dir=self.dir_name)
        self.assertEqual(errors, [])
        self.assertEqual(warnings, [])

        archive.contents[0].format = CombineArchiveContentFormat.PDF.value
        errors, warnings = validate_biosimulations_metadata_for_uri(
            md,
            validate_minimal_metadata=True,
            archive=archive,
            working_dir=self.dir_name)
        self.assertNotEqual(errors, [])
        self.assertEqual(warnings, [])

        md2 = copy.deepcopy(md)
        md2['title'] = None
        errors, warnings = validate_biosimulations_metadata_for_uri(
            md2, validate_minimal_metadata=True, working_dir=self.dir_name)
        self.assertIn('is required', flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])

        md2 = copy.deepcopy(md)
        md2['creators'][0]['uri'] = 'xyz'
        errors, warnings = validate_biosimulations_metadata_for_uri(
            md2, validate_minimal_metadata=True, working_dir=self.dir_name)
        self.assertIn('is not a valid URI',
                      flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])

        md2 = copy.deepcopy(md)
        md2['created'] = 'xyz'
        errors, warnings = validate_biosimulations_metadata_for_uri(
            md2, validate_minimal_metadata=True, working_dir=self.dir_name)
        self.assertIn('is not a valid date',
                      flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])

        md2 = copy.deepcopy(md)
        md2['modified'].append('xyz')
        errors, warnings = validate_biosimulations_metadata_for_uri(
            md2, validate_minimal_metadata=True, working_dir=self.dir_name)
        self.assertIn('is not a valid date',
                      flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])

        md2 = copy.deepcopy(md)
        md2['creators'][0]['uri'] = 'http://identifiers.org/pubmed:1234'
        errors, warnings = validate_biosimulations_metadata_for_uri(
            md2, validate_minimal_metadata=True, working_dir=self.dir_name)
        self.assertEqual(errors, [])
        self.assertEqual(warnings, [])

        md2 = copy.deepcopy(md)
        md2['creators'][0]['uri'] = 'http://identifiers.org/pubmed/1234'
        errors, warnings = validate_biosimulations_metadata_for_uri(
            md2, validate_minimal_metadata=True, working_dir=self.dir_name)
        self.assertEqual(errors, [])
        self.assertEqual(warnings, [])

        md2 = copy.deepcopy(md)
        md2['creators'][0]['uri'] = 'http://identifiers.org/PubMed:1234'
        errors, warnings = validate_biosimulations_metadata_for_uri(
            md2, validate_minimal_metadata=True, working_dir=self.dir_name)
        self.assertEqual(errors, [])
        self.assertEqual(warnings, [])

        md2 = copy.deepcopy(md)
        md2['creators'][0]['uri'] = 'http://identifiers.org/ncbi/pubmed:1234'
        errors, warnings = validate_biosimulations_metadata_for_uri(
            md2, validate_minimal_metadata=True, working_dir=self.dir_name)
        self.assertEqual(errors, [])
        self.assertEqual(warnings, [])

        md2 = copy.deepcopy(md)
        md2['creators'][0]['uri'] = 'http://identifiers.org/NCBI/pubmed:1234'
        errors, warnings = validate_biosimulations_metadata_for_uri(
            md2, validate_minimal_metadata=True, working_dir=self.dir_name)
        self.assertEqual(errors, [])
        self.assertEqual(warnings, [])

        md2 = copy.deepcopy(md)
        md2['creators'][0][
            'uri'] = 'http://identifiers.org/not-a-namespace:invalid'
        errors, warnings = validate_biosimulations_metadata_for_uri(
            md2, validate_minimal_metadata=True, working_dir=self.dir_name)
        self.assertIn('is not a valid prefix',
                      flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])

        md2 = copy.deepcopy(md)
        md2['creators'][0]['uri'] = 'http://identifiers.org/pubmed:invalid'
        errors, warnings = validate_biosimulations_metadata_for_uri(
            md2, validate_minimal_metadata=True, working_dir=self.dir_name)
        self.assertIn('is not valid for',
                      flatten_nested_list_of_strings(errors))
        self.assertIn('not a valid Identifiers.org identifier',
                      flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])

        md2 = copy.deepcopy(md)
        md2['creators'][0]['uri'] = 'http://identifiers.org/ncbi:pubmed:1234'
        errors, warnings = validate_biosimulations_metadata_for_uri(
            md2, validate_minimal_metadata=True, working_dir=self.dir_name)
        self.assertIn('is not a valid prefix',
                      flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])

        md2 = copy.deepcopy(md)
        md2['thumbnails'][0] = 'x'
        errors, warnings = validate_biosimulations_metadata_for_uri(
            md2, validate_minimal_metadata=True, working_dir=self.dir_name)
        self.assertIn('is not a file', flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])

        md2 = copy.deepcopy(md)
        errors, warnings = validate_biosimulations_metadata_for_uri(
            md2,
            validate_minimal_metadata=True,
            working_dir=self.dir_name,
            archive=CombineArchive(contents=[
                CombineArchiveContent(
                    location=os.path.relpath(md2['thumbnails'][0], '.'),
                    format=CombineArchiveContentFormat.TEXT.value,
                )
            ]))
        self.assertIn('must be one of the following',
                      flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])

        md2 = copy.deepcopy(md)
        md2['created'] = 'x'
        errors, warnings = validate_biosimulations_metadata_for_uri(
            md2, validate_minimal_metadata=True, working_dir=self.dir_name)
        self.assertIn('not a valid date',
                      flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])

        md2 = copy.deepcopy(md)
        md2['modified'][0] = 'x'
        errors, warnings = validate_biosimulations_metadata_for_uri(
            md2, validate_minimal_metadata=True, working_dir=self.dir_name)
        self.assertIn('not a valid date',
                      flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])
Ejemplo n.º 21
0
def handler(body, file=None):
    ''' Get the manifest of a COMBINE/OMEX archive

    Args:
        body (:obj:`dict`): dictionary with keys

            * ``url`` whose value has schema ``Url`` with the
              URL for a COMBINE/OMEX archive or a manifest for a COMBINE/OMEX archive

        file (:obj:`werkzeug.datastructures.FileStorage`, optional): COMBINE/OMEX archive or OMEX manifest file

    Returns:
        ``CombineArchive``: manifest of the COMBINE/OMEX archive
    '''
    archive_or_manifest_file = file
    archive_or_manifest_url = body.get('url', None)
    if archive_or_manifest_url and archive_or_manifest_file:
        raise BadRequestException(
            title='Only one of `file` or `url` can be used at a time.',
            instance=ValueError(),
        )
    if not archive_or_manifest_url and not archive_or_manifest_file:
        raise BadRequestException(
            title='One of `file` or `url` must be used.',
            instance=ValueError(),
        )

    # create temporary working directory
    temp_dirname = get_temp_dir()
    archive_or_manifest_filename = os.path.join(temp_dirname, 'archive.omex')
    manifest_filename = os.path.join(temp_dirname, 'manifest.xml')

    # get COMBINE/OMEX archive or manifest
    if archive_or_manifest_file:
        archive_or_manifest_file.save(archive_or_manifest_filename)

    else:
        try:
            response = requests.get(archive_or_manifest_url)
            response.raise_for_status()
        except requests.exceptions.RequestException as exception:
            title = 'File could not be loaded from `{}`'.format(
                archive_or_manifest_url)
            raise BadRequestException(
                title=title,
                instance=exception,
            )

        # save archive to local temporary file
        with open(archive_or_manifest_filename, 'wb') as file:
            file.write(response.content)

    # read archive
    is_archive = False
    try:
        with zipfile.ZipFile(archive_or_manifest_filename, 'r') as zip_file:
            is_archive = True
            zip_file.extract('manifest.xml', temp_dirname)
    except zipfile.BadZipFile:
        pass
    except KeyError as exception:
        raise BadRequestException(
            title='COMBINE/OMEX archive does not contain a manifest.',
            instance=exception)

    if not is_archive:
        manifest_filename = archive_or_manifest_filename

    reader = CombineArchiveReader()
    contents = reader.read_manifest(manifest_filename,
                                    archive_or_manifest_filename)
    if reader.errors:
        raise BadRequestException(
            title=
            'File is not a valid manifest or a COMBINE/OMEX which contains a valid manifest.\n  {}'
            .format(
                flatten_nested_list_of_strings(reader.errors).replace(
                    '\n', '\n  ')),
            instance=ValueError())

    contents_specs = []
    for content in contents:
        content_specs = {
            '_type': 'CombineArchiveManifestContent',
            'location': {
                '_type': 'CombineArchiveManifestLocation',
                'path': content.location,
                'value': {
                    '_type': 'CombineArchiveContentFile',
                    'filename': os.path.relpath(content.location, '.'),
                },
            },
            'format': content.format,
            'master': content.master,
        }
        contents_specs.append(content_specs)

    # format response
    response = {'_type': 'CombineArchiveManifest', 'contents': contents_specs}

    # return reponse
    return response
    def test(self):
        filename = os.path.join(self.FIXTURE_DIRNAME, 'wilson-cowan.ode')
        errors, warnings, model = validation.validate_model(filename)
        self.assertEqual(errors, [])
        self.assertEqual(warnings, [])
        parameters = collections.OrderedDict([
            ('aee', 10),
            ('aie', 8),
            ('aei', 12),
            ('aii', 3),
            ('ze', .2),
            ('zi', 4),
            ('tau', 1),
            ('ie0', 0.0),
            ('ie1', 0.0),
            ('w', 0.25),
            ('ii0', 0.0),
            ('ii1', 0.0),
        ])
        initial_conditions = collections.OrderedDict([
            ('U', .1),
            ('V', .05),
        ])
        simulation_method = {
            'total': '40',
        }
        plot = {
            'elements': {
                1: {
                    'x': 'U',
                    'y': 'V',
                },
            },
            'xlo': -.1,
            'xhi': 1.,
            'ylo': -.1,
            'yhi': 1.,
        }
        self.assertEqual(list(model['parameters'].keys()),
                         list(parameters.keys()))
        self.assertEqual(model['parameters'], parameters)
        self.assertEqual(model['simulation_method'], simulation_method)
        self.assertEqual(model['plot'], plot)
        self.assertEqual(
            model, {
                'parameters': parameters,
                'initial_conditions': initial_conditions,
                'sets': {},
                'auxiliary_variables': collections.OrderedDict(),
                'simulation_method': simulation_method,
                'range': None,
                'plot': plot,
            })
        self.assertEqual(model['initial_conditions'], initial_conditions)

        filename = os.path.join(self.FIXTURE_DIRNAME,
                                'wilson-cowan-modified.ode')
        errors, warnings, model = validation.validate_model(filename)
        self.assertEqual(errors, [])
        self.assertEqual(warnings, [])
        self.assertEqual(model['simulation_method'], {
            'total': '130',
            'njmp': '20',
        })
        self.assertEqual(
            model['plot'], {
                'elements': {
                    1: {
                        'x': 'U',
                        'y': 'V',
                    },
                },
                'xlo': -.1,
                'xhi': 1.,
                'ylo': -.1,
                'yhi': 1.,
                'axes': 2,
            })

        filename = os.path.join(self.FIXTURE_DIRNAME,
                                'wilson-cowan-auxiliary-variables.ode')
        errors, warnings, model = validation.validate_model(filename)
        self.assertEqual(errors, [])
        self.assertEqual(warnings, [])
        self.assertEqual(
            model['auxiliary_variables'],
            collections.OrderedDict({
                'DV': "-u+f(aee*u-aie*v-ze+i_e(t))",
            }))

        filename = None
        errors, warnings, model = validation.validate_model(filename)
        self.assertIn('is not a path', flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])
        self.assertEqual(model, None)

        filename = os.path.join(self.FIXTURE_DIRNAME, 'not exist.ode')
        errors, warnings, model = validation.validate_model(filename)
        self.assertIn('does not exist', flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])
        self.assertEqual(model, None)

        filename = os.path.join(self.FIXTURE_DIRNAME,
                                'wilson-cowan-invalid.ode')
        errors, warnings, model = validation.validate_model(filename)
        self.assertIn('is not a valid XPP',
                      flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])
        self.assertEqual(model, None)

        filename = os.path.join(self.FIXTURE_DIRNAME,
                                'wilson-cowan-invalid.ode')
        return_value_1 = mock.Mock(
            returncode=1,
            stdout=mock.Mock(decode=lambda errors: 'Error message', ),
        )
        with mock.patch('subprocess.run', return_value=return_value_1):
            errors, warnings, model = validation.validate_model(filename)
        self.assertIn('is not a valid XPP file',
                      flatten_nested_list_of_strings(errors))
        self.assertIn('Error message', flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])
        self.assertEqual(model, None)

        filename = os.path.join(self.FIXTURE_DIRNAME,
                                'wilson-cowan-modified-3.ode')
        errors, warnings, model = validation.validate_model(filename)
        self.assertIn('T0 must be a float',
                      flatten_nested_list_of_strings(errors))
        self.assertIn('TOTAL must be a float',
                      flatten_nested_list_of_strings(errors))
        self.assertIn('DT must be a float',
                      flatten_nested_list_of_strings(errors))
        self.assertIn('NJMP must be a positive integer',
                      flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])
        self.assertNotEqual(model, None)

        filename = os.path.join(self.FIXTURE_DIRNAME,
                                'wilson-cowan-modified-4.ode')
        errors, warnings, model = validation.validate_model(filename)
        self.assertIn('T0 must be a float',
                      flatten_nested_list_of_strings(errors))
        self.assertIn('TOTAL must be a float',
                      flatten_nested_list_of_strings(errors))
        self.assertIn('DT must be a float',
                      flatten_nested_list_of_strings(errors))
        self.assertIn('NJMP must be a positive integer',
                      flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])
        self.assertNotEqual(model, None)

        filename = os.path.join(self.FIXTURE_DIRNAME,
                                'wilson-cowan-modified-5.ode')
        errors, warnings, model = validation.validate_model(filename)
        self.assertIn('Number of steps must be an integer',
                      flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])
        self.assertNotEqual(model, None)

        filename = os.path.join(self.FIXTURE_DIRNAME, 'BIOMD0000000001.ode')
        errors, warnings, model = validation.validate_model(filename)
        self.assertEqual(errors, [])
        self.assertIn("I' is a duplicate name",
                      flatten_nested_list_of_strings(warnings))
        self.assertEqual(
            model['simulation_method'], {
                'delay': '50',
                'meth': 'cvode',
                'tol': '1e-6',
                'atol': '1e-8',
                'bound': '40000',
                'total': '200',
            })
Ejemplo n.º 23
0
    def test(self):
        # 1 model
        errors, warnings, _ = validate_model(
            os.path.join(self.FIXTURE_DIR,
                         'albrecht_colegrove_friel_2002.xml'))
        self.assertEqual(errors, [])
        self.assertEqual(warnings, [])

        errors, warnings, _ = validate_model(
            os.path.join(self.FIXTURE_DIR,
                         'albrecht_colegrove_friel_2002-error.xml'))
        self.assertIn("has extra content: units2",
                      flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])

        # 1.1 model
        errors, warnings, _ = validate_model(
            os.path.join(self.FIXTURE_DIR, 'parameters-1.1.cellml'))
        self.assertEqual(errors, [])
        self.assertIn("not available for CellML 1.1",
                      flatten_nested_list_of_strings(warnings))

        # 2.0 model
        errors, warnings, _ = validate_model(
            os.path.join(self.FIXTURE_DIR, 'version2.xml'))
        self.assertEqual(errors, [])
        self.assertEqual(warnings, [])

        errors, warnings, _ = validate_model(
            os.path.join(self.FIXTURE_DIR, 'version2-with-imports.xml'))
        self.assertEqual(errors, [])
        self.assertEqual(warnings, [])

        errors, warnings, _ = validate_model(
            os.path.join(self.FIXTURE_DIR, 'version2-missing-imports.xml'))
        self.assertIn("the file could not be opened",
                      flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])

        # 2.0 error: invalid namespace
        errors, warnings, _ = validate_model(
            os.path.join(self.FIXTURE_DIR, 'invalid_namespace.xml'))
        self.assertIn("default namespace must be",
                      flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])

        errors, warnings, _ = validate_model(
            os.path.join(self.FIXTURE_DIR, 'not_a_path.xml'))
        self.assertIn("is not a file", flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])

        errors, warnings, _ = validate_model(
            os.path.join(self.FIXTURE_DIR, 'invalid_cellml_2.0.xml'))
        self.assertIn("Start tag expected",
                      flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])

        return_value = mock.Mock(getroot=lambda: mock.Mock(nsmap=mock.Mock(
            get=lambda x, y: 'http://www.cellml.org/cellml/2.0#')))
        with mock.patch('lxml.etree.parse', return_value=return_value):
            errors, warnings, _ = validate_model(
                os.path.join(self.FIXTURE_DIR, 'invalid_cellml_2.0.xml'))
            self.assertIn("Start tag expected",
                          flatten_nested_list_of_strings(errors))
            self.assertEqual(warnings, [])

        errors, warnings, _ = validate_model(
            os.path.join(self.FIXTURE_DIR, 'missing-attribute.xml'))
        self.assertIn("does not have a valid name attribute",
                      flatten_nested_list_of_strings(errors))
        self.assertEqual(warnings, [])
    def test_error_handling(self):
        os.remove(os.path.join(self.tmp_dir, 'thumbnail.png'))

        archive = CombineArchive()
        errors, warnings = validate(archive, self.tmp_dir)
        self.assertEqual(len(errors), 1)
        self.assertEqual(len(errors[0]), 1)
        self.assertIn('must have at least one content element', errors[0][0])
        self.assertEqual(len(warnings), 1)
        self.assertEqual(len(warnings[0]), 1)
        self.assertIn('does not contain any SED-ML files', warnings[0][0])

        archive = CombineArchive(contents=[
            None,
        ])
        errors, warnings = validate(archive, self.tmp_dir)
        self.assertEqual(len(errors), 1)
        self.assertEqual(len(warnings), 1)
        self.assertIn('must be an instance of',
                      flatten_nested_list_of_strings(errors))
        self.assertIn('does not contain any SED-ML files',
                      flatten_nested_list_of_strings(warnings))

        archive = CombineArchive(contents=[
            CombineArchiveContent(),
        ])
        errors, warnings = validate(archive, self.tmp_dir)
        self.assertEqual(len(errors), 1)
        self.assertEqual(len(warnings), 1)
        self.assertIn('must have a location',
                      flatten_nested_list_of_strings(errors))
        self.assertIn('must have a format',
                      flatten_nested_list_of_strings(errors))
        self.assertIn('does not contain any SED-ML files',
                      flatten_nested_list_of_strings(warnings))

        archive = CombineArchive(contents=[
            CombineArchiveContent(
                location='plain.txt',
                format='plain/text',
            ),
        ])
        errors, warnings = validate(archive, self.tmp_dir)
        self.assertEqual(len(errors), 1)
        self.assertEqual(len(warnings), 1)
        self.assertIn('is not a file', flatten_nested_list_of_strings(errors))
        self.assertIn('does not contain any SED-ML files',
                      flatten_nested_list_of_strings(warnings))

        with open(os.path.join(self.tmp_dir, 'sim.sedml'), 'w') as file:
            pass

        archive = CombineArchive(contents=[
            CombineArchiveContent(
                location='sim.sedml',
                format=CombineArchiveContentFormat.SED_ML,
            ),
        ])
        errors, warnings = validate(archive, self.tmp_dir)
        self.assertEqual(len(errors), 1)
        self.assertEqual(warnings, [])
        self.assertIn('is invalid', flatten_nested_list_of_strings(errors))

        archive = CombineArchive(contents=[
            CombineArchiveContent(
                location='sim.sedml',
                format=CombineArchiveContentFormat.SED_ML,
            ),
        ])
        with mock.patch.object(SedmlSimulationReader,
                               'run',
                               side_effect=ValueError('other error')):
            with self.assertRaisesRegex(ValueError, 'other error'):
                validate(archive, self.tmp_dir)

        def side_effect(self,
                        filename,
                        validate_models_with_languages=False,
                        config=None):
            self.warnings = [['my warning']]

        with mock.patch.object(SedmlSimulationReader, 'run', side_effect):
            errors, warnings = validate(archive, self.tmp_dir)
        self.assertEqual(errors, [])
        self.assertEqual(len(warnings), 1)
        self.assertIn('may be invalid',
                      flatten_nested_list_of_strings(warnings))
        self.assertIn('my warning', flatten_nested_list_of_strings(warnings))