From bd38123d242b4abef617ee89523059098b2f8476 Mon Sep 17 00:00:00 2001 From: Juho Inkinen Date: Fri, 12 Jul 2019 11:29:27 +0300 Subject: [PATCH 1/6] Test for ConfigurationException for missing backend entry in project --- tests/projects.cfg | 6 ++++++ tests/test_project.py | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/tests/projects.cfg b/tests/projects.cfg index 8185205b8..eaccea36f 100644 --- a/tests/projects.cfg +++ b/tests/projects.cfg @@ -44,6 +44,12 @@ language=en backend=tfidf analyzer=snowball(english) +[nobackend] +name=Dummy with no backend +language=en +vocab=dummy +analyzer=snowball(english) + [pav] name=PAV Ensemble Finnish language=fi diff --git a/tests/test_project.py b/tests/test_project.py index b70a41af4..3fb1c1a6b 100644 --- a/tests/test_project.py +++ b/tests/test_project.py @@ -75,6 +75,13 @@ def test_get_project_novocab(app): vocab = project.vocab +def test_get_project_nobackend(app): + with app.app_context(): + project = annif.project.get_project('nobackend') + with pytest.raises(ConfigurationException): + backend = project.backend + + def test_project_load_vocabulary_tfidf(app, vocabulary, testdatadir): with app.app_context(): project = annif.project.get_project('tfidf-fi') From 9d5a248562a71d2900f30c25f937c452251701f7 Mon Sep 17 00:00:00 2001 From: Juho Inkinen Date: Fri, 12 Jul 2019 15:08:31 +0300 Subject: [PATCH 2/6] Raise ConfigurationException for missing backend entry in project --- annif/project.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/annif/project.py b/annif/project.py index 5bd03d0b3..7b852cb5d 100644 --- a/annif/project.py +++ b/annif/project.py @@ -87,10 +87,10 @@ def _initialize_vectorizer(self): def _initialize_backend(self): logger.debug("Project '%s': initializing backend", self.project_id) - if not self.backend: - logger.debug("Cannot initialize backend: does not exist") - return try: + if not self.backend: + logger.debug("Cannot initialize backend: does not exist") + return self.backend.initialize() except AnnifException as err: logger.warning(err.format_message()) @@ -127,6 +127,9 @@ def analyzer(self): @property def backend(self): if self._backend is None: + if 'backend' not in self.config: + raise ConfigurationException( + "backend setting is missing", project_id=self.project_id) backend_id = self.config['backend'] try: backend_class = annif.backend.get_backend(backend_id) @@ -214,7 +217,7 @@ def dump(self): return {'project_id': self.project_id, 'name': self.name, 'language': self.language, - 'backend': {'backend_id': self.config['backend']} + 'backend': {'backend_id': self.config.get('backend')} } From ab6003c33ab1767ca6e6ab2f7133989e27839000 Mon Sep 17 00:00:00 2001 From: Juho Inkinen Date: Fri, 12 Jul 2019 16:07:00 +0300 Subject: [PATCH 3/6] Test for ConfigurationException for invalid project.cfg (duplications) --- annif/default_config.py | 4 ++++ tests/projects_invalid.cfg | 23 +++++++++++++++++++++++ tests/test_project.py | 8 ++++++++ 3 files changed, 35 insertions(+) create mode 100644 tests/projects_invalid.cfg diff --git a/annif/default_config.py b/annif/default_config.py index 133225c14..cf310a289 100644 --- a/annif/default_config.py +++ b/annif/default_config.py @@ -36,3 +36,7 @@ class TestingInitializeConfig(TestingConfig): class TestingNoProjectsConfig(TestingConfig): PROJECTS_FILE = 'tests/notfound.cfg' + + +class TestingInvalidProjectsConfig(TestingConfig): + PROJECTS_FILE = 'tests/projects_invalid.cfg' diff --git a/tests/projects_invalid.cfg b/tests/projects_invalid.cfg new file mode 100644 index 000000000..67b91cb9e --- /dev/null +++ b/tests/projects_invalid.cfg @@ -0,0 +1,23 @@ +# Project configuration for Annif unit tests + +[duplicatedproject] +name=Dummy with no backend +language=en +backend=dummy +vocab=dummy +analyzer=snowball(english) + +[duplicatedproject] +name=Dummy with no backend +language=en +backend=dummy +vocab=dummy +analyzer=snowball(english) + +[duplicatedvocab] +name=Dummy with no backend +language=en +backend=dummy +vocab=dummy +vocab=dummy +analyzer=snowball(english) diff --git a/tests/test_project.py b/tests/test_project.py index 3fb1c1a6b..4c477f300 100644 --- a/tests/test_project.py +++ b/tests/test_project.py @@ -82,6 +82,14 @@ def test_get_project_nobackend(app): backend = project.backend +def test_get_project_invalid_config_file(app): + app = annif.create_app( + config_name='annif.default_config.TestingInvalidProjectsConfig') + with app.app_context(): + with pytest.raises(ConfigurationException): + project = annif.project.get_project('duplicatedvocab') + + def test_project_load_vocabulary_tfidf(app, vocabulary, testdatadir): with app.app_context(): project = annif.project.get_project('tfidf-fi') From 863a574e9defcfb234b105a31d392cd4c3af383a Mon Sep 17 00:00:00 2001 From: Juho Inkinen Date: Fri, 12 Jul 2019 16:08:32 +0300 Subject: [PATCH 4/6] Raise ConfigurationException for duplications in project.cfg --- annif/project.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/annif/project.py b/annif/project.py index 7b852cb5d..549f54b8c 100644 --- a/annif/project.py +++ b/annif/project.py @@ -233,7 +233,11 @@ def _create_projects(projects_file, datadir, init_projects): config = configparser.ConfigParser() config.optionxform = lambda option: option with open(projects_file, encoding='utf-8') as projf: - config.read_file(projf) + try: + config.read_file(projf) + except (configparser.DuplicateOptionError, + configparser.DuplicateSectionError) as err: + raise ConfigurationException(err) # create AnnifProject objects from the configuration file projects = collections.OrderedDict() From f03c320435fb1d460e99bd36144a4ac78a43e734 Mon Sep 17 00:00:00 2001 From: Juho Inkinen Date: Thu, 15 Aug 2019 10:46:01 +0300 Subject: [PATCH 5/6] Raise ConfigurationError for unspecifed analyzer but needed by backend --- annif/project.py | 21 +++++++++++++++------ tests/projects.cfg | 4 ++-- tests/test_project.py | 7 +++++++ 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/annif/project.py b/annif/project.py index 549f54b8c..4d5796baa 100644 --- a/annif/project.py +++ b/annif/project.py @@ -62,10 +62,13 @@ def _init_access(self): project_id=self.project_id) def _initialize_analyzer(self): - analyzer = self.analyzer - logger.debug("Project '%s': initialized analyzer: %s", - self.project_id, - str(analyzer)) + try: + analyzer = self.analyzer + logger.debug("Project '%s': initialized analyzer: %s", + self.project_id, + str(analyzer)) + except AnnifException as err: + logger.warning(err.format_message()) def _initialize_subjects(self): try: @@ -120,8 +123,14 @@ def _suggest_with_backend(self, text, backend_params): @property def analyzer(self): - if self._analyzer is None and self.analyzer_spec: - self._analyzer = annif.analyzer.get_analyzer(self.analyzer_spec) + if self._analyzer is None: + if self.analyzer_spec: + self._analyzer = annif.analyzer.get_analyzer( + self.analyzer_spec) + elif self.backend.needs_subject_vectorizer: + raise ConfigurationException( + "analyzer setting is missing (and needed by the backend)", + project_id=self.project_id) return self._analyzer @property diff --git a/tests/projects.cfg b/tests/projects.cfg index eaccea36f..952fe8be3 100644 --- a/tests/projects.cfg +++ b/tests/projects.cfg @@ -33,9 +33,9 @@ sources=dummy-en,dummydummy vocab=dummy [noanalyzer] -name=Dummy with no analyzer +name=TFIDF with no analyzer language=en -backend=dummy +backend=tfidf vocab=dummy [novocab] diff --git a/tests/test_project.py b/tests/test_project.py index 4c477f300..331aedf7f 100644 --- a/tests/test_project.py +++ b/tests/test_project.py @@ -68,6 +68,13 @@ def test_get_project_nonexistent(app): annif.project.get_project('nonexistent') +def test_get_project_noanalyzer(app): + with app.app_context(): + project = annif.project.get_project('noanalyzer') + with pytest.raises(ConfigurationException): + analyzer = project.analyzer + + def test_get_project_novocab(app): with app.app_context(): project = annif.project.get_project('novocab') From 47d4f2af086b49ccde39036e65b7460d2cd23267 Mon Sep 17 00:00:00 2001 From: Juho Inkinen Date: Fri, 23 Aug 2019 13:22:47 +0300 Subject: [PATCH 6/6] Ignore needs_subject_vectorizer; error if analyzer field is accessed but missing --- annif/project.py | 2 +- tests/projects.cfg | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/annif/project.py b/annif/project.py index 4d5796baa..1454c76e7 100644 --- a/annif/project.py +++ b/annif/project.py @@ -127,7 +127,7 @@ def analyzer(self): if self.analyzer_spec: self._analyzer = annif.analyzer.get_analyzer( self.analyzer_spec) - elif self.backend.needs_subject_vectorizer: + else: raise ConfigurationException( "analyzer setting is missing (and needed by the backend)", project_id=self.project_id) diff --git a/tests/projects.cfg b/tests/projects.cfg index 952fe8be3..eaccea36f 100644 --- a/tests/projects.cfg +++ b/tests/projects.cfg @@ -33,9 +33,9 @@ sources=dummy-en,dummydummy vocab=dummy [noanalyzer] -name=TFIDF with no analyzer +name=Dummy with no analyzer language=en -backend=tfidf +backend=dummy vocab=dummy [novocab]