app: Implement API to check if app/component has diagnostics

- Use the API to skip diagnosing apps that don't implement diagnostics.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
Sunil Mohan Adapa 2019-12-27 13:02:27 -08:00 committed by James Valleroy
parent e0dba2cc17
commit 636aa05b66
No known key found for this signature in database
GPG Key ID: 77C0C75E7B650808
3 changed files with 78 additions and 0 deletions

View File

@ -115,6 +115,8 @@ class App:
Results are typically collected by diagnosing each component of the app
and then supplementing the results with any app level diagnostic tests.
Also see :meth:`.has_diagnostics`.
"""
results = []
for component in self.components.values():
@ -122,6 +124,36 @@ class App:
return results
def has_diagnostics(self):
"""Return whether at least one diagnostic test is implemented.
If this method returns True, a button or menu item is shown to the
user to run diagnostics on this app. When the action is selected by the
user, the :meth:`.diagnose` method is called and the results are
presented to the user. Additionally collection of diagnostic results of
all apps can be obtained by the user from the Diagnostics module in
System section.
If a component of this app implements a diagnostic test, this method
returns True.
Further, if a subclass of App overrides the :meth:`.diagnose` method,
it is assumed that it is for implementing diagnostic tests and this
method returns True for such an app. Override this method if this
default behavior does not fit the needs.
"""
# App implements some diagnostics
if self.__class__.diagnose is not App.diagnose:
return True
# Any of the components implement diagnostics
for component in self.components.values():
if component.has_diagnostics():
return True
return False
class Component:
"""Interface for an app component."""
@ -148,9 +180,25 @@ class Component:
result. The test result is a string enumeration from 'failed', 'passed'
and 'error'.
Also see :meth:`.has_diagnostics`.
"""
return []
def has_diagnostics(self):
"""Return whether at least one diagnostic test is implemented.
If this method return True, the :meth:`App.has_diagnostics`. also
returns True.
If a subclass of Component overrides the :meth:`.diagnose` method, it
is assumed that it is for implementing diagnostic tests and this method
returns True for such a component. Override this method if this default
behavior does not fit the needs.
"""
return self.__class__.diagnose is not Component.diagnose
class FollowerComponent(Component):
"""Interface for an app component that follows other components.

View File

@ -112,6 +112,9 @@ def run_on_all_enabled_modules():
if not app.is_enabled():
continue
if not app.has_diagnostics():
continue
apps.append((app.app_id, app))
current_results['results'][app.app_id] = None

View File

@ -19,6 +19,7 @@ Test module for App, base class for all applications.
"""
import collections
from unittest.mock import patch
import pytest
@ -193,6 +194,23 @@ def test_app_diagnose(app_with_components):
('test-result-test-leader-2', 'success')]
def test_app_has_diagnostics(app_with_components):
"""Test checking if app has diagnostics implemented."""
app = app_with_components
# App with components that has diagnostics
assert app.has_diagnostics()
# App with components that don't have diagnostics
app.remove('test-leader-1')
app.remove('test-leader-2')
assert not app.has_diagnostics()
# App with app-level diagnostics
with patch.object(AppTest, 'diagnose', return_value=[('test1', 'passed')]):
assert app.has_diagnostics()
def test_component_initialization():
"""Test that component is initialized properly."""
with pytest.raises(ValueError):
@ -209,6 +227,15 @@ def test_component_diagnose():
assert component.diagnose() == []
def test_component_has_diagnostics():
"""Test checking if component has diagnostics implemented."""
component = LeaderTest('test-leader-1')
assert component.has_diagnostics()
component = FollowerComponent('test-follower-1')
assert not component.has_diagnostics()
def test_follower_component_initialization():
"""Test that follower component is initialized properly."""
component = FollowerComponent('test-follower-1')