mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-09-19 04:59:01 +00:00
diagnostics: Add optional component_id to DiagnosticCheck
Signed-off-by: James Valleroy <jvalleroy@mailbox.org> Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
This commit is contained in:
parent
9fa45b4239
commit
ddc9b434a7
@ -222,9 +222,9 @@ class App:
|
|||||||
|
|
||||||
Return value must be a list of results. Each result is a
|
Return value must be a list of results. Each result is a
|
||||||
:class:`~plinth.diagnostic_check.DiagnosticCheck` with a
|
:class:`~plinth.diagnostic_check.DiagnosticCheck` with a
|
||||||
unique check_id, a user visible description of the test, and the
|
unique check_id, a user visible description of the test, the result,
|
||||||
result. The test result is a string enumeration from 'failed',
|
test parameters, and the component ID. The test result is a string
|
||||||
'passed', 'error', 'warning' and 'not_done'.
|
enumeration from 'failed', 'passed', 'error', 'warning' and 'not_done'.
|
||||||
|
|
||||||
Results are typically collected by diagnosing each component of the app
|
Results are typically collected by diagnosing each component of the app
|
||||||
and then supplementing the results with any app level diagnostic tests.
|
and then supplementing the results with any app level diagnostic tests.
|
||||||
@ -314,9 +314,9 @@ class Component:
|
|||||||
|
|
||||||
Return value must be a list of results. Each result is a
|
Return value must be a list of results. Each result is a
|
||||||
:class:`~plinth.diagnostic_check.DiagnosticCheck` with a
|
:class:`~plinth.diagnostic_check.DiagnosticCheck` with a
|
||||||
unique check_id, a user visible description of the test, and the
|
unique check_id, a user visible description of the test, the result,
|
||||||
result. The test result is a string enumeration from 'failed',
|
test parameters, and the component ID. The test result is a string
|
||||||
'passed', 'error', 'warning' and 'not_done'.
|
enumeration from 'failed', 'passed', 'error', 'warning' and 'not_done'.
|
||||||
|
|
||||||
Also see :meth:`.has_diagnostics`.
|
Also see :meth:`.has_diagnostics`.
|
||||||
|
|
||||||
|
|||||||
@ -104,7 +104,7 @@ class DropinConfigs(app_module.FollowerComponent):
|
|||||||
parameters: DiagnosticCheckParameters = {'etc_path': str(etc_path)}
|
parameters: DiagnosticCheckParameters = {'etc_path': str(etc_path)}
|
||||||
results.append(
|
results.append(
|
||||||
DiagnosticCheck(check_id, description, result_string,
|
DiagnosticCheck(check_id, description, result_string,
|
||||||
parameters))
|
parameters, self.component_id))
|
||||||
|
|
||||||
return results
|
return results
|
||||||
|
|
||||||
|
|||||||
@ -110,7 +110,9 @@ class Daemon(app.LeaderComponent):
|
|||||||
results = []
|
results = []
|
||||||
results.append(self._diagnose_unit_is_running())
|
results.append(self._diagnose_unit_is_running())
|
||||||
for port in self.listen_ports:
|
for port in self.listen_ports:
|
||||||
results.append(diagnose_port_listening(port[0], port[1]))
|
results.append(
|
||||||
|
diagnose_port_listening(port[0], port[1], None,
|
||||||
|
self.component_id))
|
||||||
|
|
||||||
return results
|
return results
|
||||||
|
|
||||||
@ -124,7 +126,8 @@ class Daemon(app.LeaderComponent):
|
|||||||
'service_name': str(self.unit)
|
'service_name': str(self.unit)
|
||||||
}
|
}
|
||||||
|
|
||||||
return DiagnosticCheck(check_id, description, result, parameters)
|
return DiagnosticCheck(check_id, description, result, parameters,
|
||||||
|
self.component_id)
|
||||||
|
|
||||||
|
|
||||||
class RelatedDaemon(app.FollowerComponent):
|
class RelatedDaemon(app.FollowerComponent):
|
||||||
@ -200,7 +203,8 @@ def app_is_running(app_):
|
|||||||
|
|
||||||
def diagnose_port_listening(
|
def diagnose_port_listening(
|
||||||
port: int, kind: str = 'tcp',
|
port: int, kind: str = 'tcp',
|
||||||
listen_address: str | None = None) -> DiagnosticCheck:
|
listen_address: str | None = None,
|
||||||
|
component_id: str | None = None) -> DiagnosticCheck:
|
||||||
"""Run a diagnostic on whether a port is being listened on.
|
"""Run a diagnostic on whether a port is being listened on.
|
||||||
|
|
||||||
Kind must be one of inet, inet4, inet6, tcp, tcp4, tcp6, udp,
|
Kind must be one of inet, inet4, inet6, tcp, tcp4, tcp6, udp,
|
||||||
@ -222,7 +226,7 @@ def diagnose_port_listening(
|
|||||||
|
|
||||||
return DiagnosticCheck(check_id, description,
|
return DiagnosticCheck(check_id, description,
|
||||||
Result.PASSED if result else Result.FAILED,
|
Result.PASSED if result else Result.FAILED,
|
||||||
parameters)
|
parameters, component_id)
|
||||||
|
|
||||||
|
|
||||||
def _check_port(port: int, kind: str = 'tcp',
|
def _check_port(port: int, kind: str = 'tcp',
|
||||||
@ -272,7 +276,8 @@ def _check_port(port: int, kind: str = 'tcp',
|
|||||||
|
|
||||||
|
|
||||||
def diagnose_netcat(host: str, port: int, remote_input: str = '',
|
def diagnose_netcat(host: str, port: int, remote_input: str = '',
|
||||||
negate: bool = False) -> DiagnosticCheck:
|
negate: bool = False,
|
||||||
|
component_id: str | None = None) -> DiagnosticCheck:
|
||||||
"""Run a diagnostic using netcat."""
|
"""Run a diagnostic using netcat."""
|
||||||
try:
|
try:
|
||||||
process = subprocess.Popen(['nc', host, str(port)],
|
process = subprocess.Popen(['nc', host, str(port)],
|
||||||
@ -298,4 +303,5 @@ def diagnose_netcat(host: str, port: int, remote_input: str = '',
|
|||||||
check_id = f'daemon-netcat-negate-{host}-{port}'
|
check_id = f'daemon-netcat-negate-{host}-{port}'
|
||||||
description = gettext_noop('Cannot connect to {host}:{port}')
|
description = gettext_noop('Cannot connect to {host}:{port}')
|
||||||
|
|
||||||
return DiagnosticCheck(check_id, description, result, parameters)
|
return DiagnosticCheck(check_id, description, result, parameters,
|
||||||
|
component_id)
|
||||||
|
|||||||
@ -30,6 +30,7 @@ class DiagnosticCheck:
|
|||||||
description: str
|
description: str
|
||||||
result: Result = Result.NOT_DONE
|
result: Result = Result.NOT_DONE
|
||||||
parameters: DiagnosticCheckParameters = field(default_factory=dict)
|
parameters: DiagnosticCheckParameters = field(default_factory=dict)
|
||||||
|
component_id: str | None = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def translated_description(self):
|
def translated_description(self):
|
||||||
@ -65,6 +66,7 @@ class CheckJSONDecoder(json.JSONDecoder):
|
|||||||
"""Convert tagged data to DiagnosticCheck."""
|
"""Convert tagged data to DiagnosticCheck."""
|
||||||
if data.get('__class__') == 'DiagnosticCheck':
|
if data.get('__class__') == 'DiagnosticCheck':
|
||||||
return DiagnosticCheck(data['check_id'], data['description'],
|
return DiagnosticCheck(data['check_id'], data['description'],
|
||||||
data['result'], data['parameters'])
|
data['result'], data['parameters'],
|
||||||
|
data.get('component_id'))
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|||||||
@ -69,11 +69,13 @@ class Webserver(app.LeaderComponent):
|
|||||||
for url in self.urls:
|
for url in self.urls:
|
||||||
if '{host}' in url:
|
if '{host}' in url:
|
||||||
results.extend(
|
results.extend(
|
||||||
diagnose_url_on_all(
|
diagnose_url_on_all(url, check_certificate=False,
|
||||||
url, check_certificate=False,
|
expect_redirects=self.expect_redirects,
|
||||||
expect_redirects=self.expect_redirects))
|
component_id=self.component_id))
|
||||||
else:
|
else:
|
||||||
results.append(diagnose_url(url, check_certificate=False))
|
results.append(
|
||||||
|
diagnose_url(url, check_certificate=False,
|
||||||
|
component_id=self.component_id))
|
||||||
|
|
||||||
return results
|
return results
|
||||||
|
|
||||||
@ -141,7 +143,8 @@ def diagnose_url(url: str, kind: str | None = None,
|
|||||||
check_certificate: bool = True,
|
check_certificate: bool = True,
|
||||||
extra_options: list[str] | None = None,
|
extra_options: list[str] | None = None,
|
||||||
wrapper: str | None = None,
|
wrapper: str | None = None,
|
||||||
expected_output: str | None = None) -> DiagnosticCheck:
|
expected_output: str | None = None,
|
||||||
|
component_id: str | None = None) -> DiagnosticCheck:
|
||||||
"""Run a diagnostic on whether a URL is accessible.
|
"""Run a diagnostic on whether a URL is accessible.
|
||||||
|
|
||||||
Kind can be '4' for IPv4 or '6' for IPv6.
|
Kind can be '4' for IPv4 or '6' for IPv6.
|
||||||
@ -161,10 +164,12 @@ def diagnose_url(url: str, kind: str | None = None,
|
|||||||
check_id = f'apache-url-{url}'
|
check_id = f'apache-url-{url}'
|
||||||
description = gettext_noop('Access URL {url}')
|
description = gettext_noop('Access URL {url}')
|
||||||
|
|
||||||
return DiagnosticCheck(check_id, description, result, parameters)
|
return DiagnosticCheck(check_id, description, result, parameters,
|
||||||
|
component_id)
|
||||||
|
|
||||||
|
|
||||||
def diagnose_url_on_all(url: str, expect_redirects: bool = False,
|
def diagnose_url_on_all(url: str, expect_redirects: bool = False,
|
||||||
|
component_id: str | None = None,
|
||||||
**kwargs) -> list[DiagnosticCheck]:
|
**kwargs) -> list[DiagnosticCheck]:
|
||||||
"""Run a diagnostic on whether a URL is accessible."""
|
"""Run a diagnostic on whether a URL is accessible."""
|
||||||
results = []
|
results = []
|
||||||
@ -174,7 +179,9 @@ def diagnose_url_on_all(url: str, expect_redirects: bool = False,
|
|||||||
if not expect_redirects:
|
if not expect_redirects:
|
||||||
diagnose_kwargs.setdefault('kind', address['kind'])
|
diagnose_kwargs.setdefault('kind', address['kind'])
|
||||||
|
|
||||||
results.append(diagnose_url(current_url, **diagnose_kwargs))
|
results.append(
|
||||||
|
diagnose_url(current_url, component_id=component_id,
|
||||||
|
**diagnose_kwargs))
|
||||||
|
|
||||||
return results
|
return results
|
||||||
|
|
||||||
|
|||||||
@ -72,13 +72,16 @@ def test_webserver_disable(disable):
|
|||||||
def test_webserver_diagnose(diagnose_url_on_all, diagnose_url):
|
def test_webserver_diagnose(diagnose_url_on_all, diagnose_url):
|
||||||
"""Test running diagnostics."""
|
"""Test running diagnostics."""
|
||||||
|
|
||||||
def on_all_side_effect(url, check_certificate, expect_redirects):
|
def on_all_side_effect(url, check_certificate, expect_redirects,
|
||||||
|
component_id):
|
||||||
return [
|
return [
|
||||||
DiagnosticCheck('test-all-id', 'test-result-' + url, 'success')
|
DiagnosticCheck('test-all-id', 'test-result-' + url, 'success', {},
|
||||||
|
component_id)
|
||||||
]
|
]
|
||||||
|
|
||||||
def side_effect(url, check_certificate):
|
def side_effect(url, check_certificate, component_id):
|
||||||
return DiagnosticCheck('test-id', 'test-result-' + url, 'success')
|
return DiagnosticCheck('test-id', 'test-result-' + url, 'success', {},
|
||||||
|
component_id)
|
||||||
|
|
||||||
diagnose_url_on_all.side_effect = on_all_side_effect
|
diagnose_url_on_all.side_effect = on_all_side_effect
|
||||||
diagnose_url.side_effect = side_effect
|
diagnose_url.side_effect = side_effect
|
||||||
@ -86,19 +89,26 @@ def test_webserver_diagnose(diagnose_url_on_all, diagnose_url):
|
|||||||
urls=['{host}url1', 'url2'], expect_redirects=True)
|
urls=['{host}url1', 'url2'], expect_redirects=True)
|
||||||
results = webserver1.diagnose()
|
results = webserver1.diagnose()
|
||||||
assert results == [
|
assert results == [
|
||||||
DiagnosticCheck('test-all-id', 'test-result-{host}url1', 'success'),
|
DiagnosticCheck('test-all-id', 'test-result-{host}url1', 'success', {},
|
||||||
DiagnosticCheck('test-id', 'test-result-url2', 'success')
|
'test-webserver'),
|
||||||
|
DiagnosticCheck('test-id', 'test-result-url2', 'success', {},
|
||||||
|
'test-webserver')
|
||||||
]
|
]
|
||||||
diagnose_url_on_all.assert_has_calls(
|
diagnose_url_on_all.assert_has_calls([
|
||||||
[call('{host}url1', check_certificate=False, expect_redirects=True)])
|
call('{host}url1', check_certificate=False, expect_redirects=True,
|
||||||
diagnose_url.assert_has_calls([call('url2', check_certificate=False)])
|
component_id='test-webserver')
|
||||||
|
])
|
||||||
|
diagnose_url.assert_has_calls(
|
||||||
|
[call('url2', check_certificate=False, component_id='test-webserver')])
|
||||||
|
|
||||||
diagnose_url_on_all.reset_mock()
|
diagnose_url_on_all.reset_mock()
|
||||||
webserver2 = Webserver('test-webserver', 'test-config',
|
webserver2 = Webserver('test-webserver', 'test-config',
|
||||||
urls=['{host}url1', 'url2'], expect_redirects=False)
|
urls=['{host}url1', 'url2'], expect_redirects=False)
|
||||||
results = webserver2.diagnose()
|
results = webserver2.diagnose()
|
||||||
diagnose_url_on_all.assert_has_calls(
|
diagnose_url_on_all.assert_has_calls([
|
||||||
[call('{host}url1', check_certificate=False, expect_redirects=False)])
|
call('{host}url1', check_certificate=False, expect_redirects=False,
|
||||||
|
component_id='test-webserver')
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
@patch('plinth.privileged.service.restart')
|
@patch('plinth.privileged.service.restart')
|
||||||
@ -244,20 +254,23 @@ def test_diagnose_url(get_addresses, check):
|
|||||||
'test-1': 'value-1'
|
'test-1': 'value-1'
|
||||||
},
|
},
|
||||||
'wrapper': 'test-wrapper',
|
'wrapper': 'test-wrapper',
|
||||||
'expected_output': 'test-expected'
|
'expected_output': 'test-expected',
|
||||||
|
'component_id': 'test-component',
|
||||||
}
|
}
|
||||||
parameters = {key: args[key] for key in ['url', 'kind']}
|
parameters = {key: args[key] for key in ['url', 'kind']}
|
||||||
check.return_value = True
|
check.return_value = True
|
||||||
result = diagnose_url(**args)
|
result = diagnose_url(**args)
|
||||||
assert result == DiagnosticCheck(
|
assert result == DiagnosticCheck(
|
||||||
'apache-url-kind-https://localhost/test-4',
|
'apache-url-kind-https://localhost/test-4',
|
||||||
'Access URL {url} on tcp{kind}', Result.PASSED, parameters)
|
'Access URL {url} on tcp{kind}', Result.PASSED, parameters,
|
||||||
|
'test-component')
|
||||||
|
|
||||||
check.return_value = False
|
check.return_value = False
|
||||||
result = diagnose_url(**args)
|
result = diagnose_url(**args)
|
||||||
assert result == DiagnosticCheck(
|
assert result == DiagnosticCheck(
|
||||||
'apache-url-kind-https://localhost/test-4',
|
'apache-url-kind-https://localhost/test-4',
|
||||||
'Access URL {url} on tcp{kind}', Result.FAILED, parameters)
|
'Access URL {url} on tcp{kind}', Result.FAILED, parameters,
|
||||||
|
'test-component')
|
||||||
|
|
||||||
del args['kind']
|
del args['kind']
|
||||||
args['url'] = 'https://{host}/test'
|
args['url'] = 'https://{host}/test'
|
||||||
@ -287,10 +300,10 @@ def test_diagnose_url(get_addresses, check):
|
|||||||
assert results == [
|
assert results == [
|
||||||
DiagnosticCheck('apache-url-kind-https://test-host-1/test-4',
|
DiagnosticCheck('apache-url-kind-https://test-host-1/test-4',
|
||||||
'Access URL {url} on tcp{kind}', Result.PASSED,
|
'Access URL {url} on tcp{kind}', Result.PASSED,
|
||||||
parameters[0]),
|
parameters[0], 'test-component'),
|
||||||
DiagnosticCheck('apache-url-kind-https://test-host-2/test-6',
|
DiagnosticCheck('apache-url-kind-https://test-host-2/test-6',
|
||||||
'Access URL {url} on tcp{kind}', Result.PASSED,
|
'Access URL {url} on tcp{kind}', Result.PASSED,
|
||||||
parameters[1]),
|
parameters[1], 'test-component'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -142,7 +142,8 @@ class Firewall(app.FollowerComponent):
|
|||||||
'details': details
|
'details': details
|
||||||
}
|
}
|
||||||
results.append(
|
results.append(
|
||||||
DiagnosticCheck(check_id, description, result, parameters))
|
DiagnosticCheck(check_id, description, result, parameters,
|
||||||
|
self.component_id))
|
||||||
|
|
||||||
# External zone
|
# External zone
|
||||||
if self.is_external:
|
if self.is_external:
|
||||||
@ -161,7 +162,8 @@ class Firewall(app.FollowerComponent):
|
|||||||
|
|
||||||
parameters = {'name': port, 'details': details}
|
parameters = {'name': port, 'details': details}
|
||||||
results.append(
|
results.append(
|
||||||
DiagnosticCheck(check_id, description, result, parameters))
|
DiagnosticCheck(check_id, description, result, parameters,
|
||||||
|
self.component_id))
|
||||||
|
|
||||||
return results
|
return results
|
||||||
|
|
||||||
|
|||||||
@ -161,28 +161,28 @@ def test_diagnose(get_enabled_services, get_port_details):
|
|||||||
'networks', Result.PASSED, {
|
'networks', Result.PASSED, {
|
||||||
'name': 'test-port1',
|
'name': 'test-port1',
|
||||||
'details': '1234/tcp, 1234/udp'
|
'details': '1234/tcp, 1234/udp'
|
||||||
}),
|
}, 'test-firewall-1'),
|
||||||
DiagnosticCheck(
|
DiagnosticCheck(
|
||||||
'firewall-port-external-unavailable-test-port1',
|
'firewall-port-external-unavailable-test-port1',
|
||||||
'Port {name} ({details}) unavailable for external '
|
'Port {name} ({details}) unavailable for external '
|
||||||
'networks', Result.PASSED, {
|
'networks', Result.PASSED, {
|
||||||
'name': 'test-port1',
|
'name': 'test-port1',
|
||||||
'details': '1234/tcp, 1234/udp'
|
'details': '1234/tcp, 1234/udp'
|
||||||
}),
|
}, 'test-firewall-1'),
|
||||||
DiagnosticCheck(
|
DiagnosticCheck(
|
||||||
'firewall-port-internal-test-port2',
|
'firewall-port-internal-test-port2',
|
||||||
'Port {name} ({details}) available for internal networks',
|
'Port {name} ({details}) available for internal networks',
|
||||||
Result.FAILED, {
|
Result.FAILED, {
|
||||||
'name': 'test-port2',
|
'name': 'test-port2',
|
||||||
'details': '2345/udp'
|
'details': '2345/udp'
|
||||||
}),
|
}, 'test-firewall-1'),
|
||||||
DiagnosticCheck(
|
DiagnosticCheck(
|
||||||
'firewall-port-external-unavailable-test-port2',
|
'firewall-port-external-unavailable-test-port2',
|
||||||
'Port {name} ({details}) unavailable for external networks',
|
'Port {name} ({details}) unavailable for external networks',
|
||||||
Result.FAILED, {
|
Result.FAILED, {
|
||||||
'name': 'test-port2',
|
'name': 'test-port2',
|
||||||
'details': '2345/udp'
|
'details': '2345/udp'
|
||||||
}),
|
}, 'test-firewall-1'),
|
||||||
]
|
]
|
||||||
|
|
||||||
firewall = Firewall('test-firewall-1', ports=['test-port3', 'test-port4'],
|
firewall = Firewall('test-firewall-1', ports=['test-port3', 'test-port4'],
|
||||||
@ -195,28 +195,28 @@ def test_diagnose(get_enabled_services, get_port_details):
|
|||||||
Result.PASSED, {
|
Result.PASSED, {
|
||||||
'name': 'test-port3',
|
'name': 'test-port3',
|
||||||
'details': '3456/tcp'
|
'details': '3456/tcp'
|
||||||
}),
|
}, 'test-firewall-1'),
|
||||||
DiagnosticCheck(
|
DiagnosticCheck(
|
||||||
'firewall-port-external-available-test-port3',
|
'firewall-port-external-available-test-port3',
|
||||||
'Port {name} ({details}) available for external networks',
|
'Port {name} ({details}) available for external networks',
|
||||||
Result.PASSED, {
|
Result.PASSED, {
|
||||||
'name': 'test-port3',
|
'name': 'test-port3',
|
||||||
'details': '3456/tcp'
|
'details': '3456/tcp'
|
||||||
}),
|
}, 'test-firewall-1'),
|
||||||
DiagnosticCheck(
|
DiagnosticCheck(
|
||||||
'firewall-port-internal-test-port4',
|
'firewall-port-internal-test-port4',
|
||||||
'Port {name} ({details}) available for internal networks',
|
'Port {name} ({details}) available for internal networks',
|
||||||
Result.FAILED, {
|
Result.FAILED, {
|
||||||
'name': 'test-port4',
|
'name': 'test-port4',
|
||||||
'details': '4567/udp'
|
'details': '4567/udp'
|
||||||
}),
|
}, 'test-firewall-1'),
|
||||||
DiagnosticCheck(
|
DiagnosticCheck(
|
||||||
'firewall-port-external-available-test-port4',
|
'firewall-port-external-available-test-port4',
|
||||||
'Port {name} ({details}) available for external networks',
|
'Port {name} ({details}) available for external networks',
|
||||||
Result.FAILED, {
|
Result.FAILED, {
|
||||||
'name': 'test-port4',
|
'name': 'test-port4',
|
||||||
'details': '4567/udp'
|
'details': '4567/udp'
|
||||||
}),
|
}, 'test-firewall-1'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -210,7 +210,7 @@ class Packages(app_module.FollowerComponent):
|
|||||||
}
|
}
|
||||||
results.append(
|
results.append(
|
||||||
DiagnosticCheck(check_id, description, Result.FAILED,
|
DiagnosticCheck(check_id, description, Result.FAILED,
|
||||||
parameters))
|
parameters, self.component_id))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
result = Result.WARNING
|
result = Result.WARNING
|
||||||
@ -230,7 +230,8 @@ class Packages(app_module.FollowerComponent):
|
|||||||
'latest_version': str(latest_version)
|
'latest_version': str(latest_version)
|
||||||
}
|
}
|
||||||
results.append(
|
results.append(
|
||||||
DiagnosticCheck(check_id, description, result, parameters))
|
DiagnosticCheck(check_id, description, result, parameters,
|
||||||
|
self.component_id))
|
||||||
|
|
||||||
return results
|
return results
|
||||||
|
|
||||||
|
|||||||
@ -165,11 +165,13 @@ def test_dropin_config_diagnose_symlinks(dropin_configs, tmp_path):
|
|||||||
DiagnosticCheck(
|
DiagnosticCheck(
|
||||||
f'dropin-config-{tmp_path}/etc/test/path1',
|
f'dropin-config-{tmp_path}/etc/test/path1',
|
||||||
'Static configuration {etc_path} is setup properly',
|
'Static configuration {etc_path} is setup properly',
|
||||||
Result.FAILED, {'etc_path': f'{tmp_path}/etc/test/path1'}),
|
Result.FAILED, {'etc_path': f'{tmp_path}/etc/test/path1'},
|
||||||
|
'test-component'),
|
||||||
DiagnosticCheck(
|
DiagnosticCheck(
|
||||||
f'dropin-config-{tmp_path}/etc/path2',
|
f'dropin-config-{tmp_path}/etc/path2',
|
||||||
'Static configuration {etc_path} is setup properly',
|
'Static configuration {etc_path} is setup properly',
|
||||||
Result.FAILED, {'etc_path': f'{tmp_path}/etc/path2'}),
|
Result.FAILED, {'etc_path': f'{tmp_path}/etc/path2'},
|
||||||
|
'test-component'),
|
||||||
]
|
]
|
||||||
|
|
||||||
# Proper symlinks exist
|
# Proper symlinks exist
|
||||||
|
|||||||
@ -181,9 +181,9 @@ def test_ensure_running(subprocess_call, subprocess_run, service_is_running,
|
|||||||
def test_diagnose(port_listening, service_is_running, daemon):
|
def test_diagnose(port_listening, service_is_running, daemon):
|
||||||
"""Test running diagnostics."""
|
"""Test running diagnostics."""
|
||||||
|
|
||||||
def side_effect(port, kind):
|
def side_effect(port, kind, _listen_address, component_id):
|
||||||
name = f'test-result-{port}-{kind}'
|
name = f'test-result-{port}-{kind}'
|
||||||
return DiagnosticCheck(name, name, Result.PASSED)
|
return DiagnosticCheck(name, name, Result.PASSED, {}, component_id)
|
||||||
|
|
||||||
daemon = Daemon('test-daemon', 'test-unit', listen_ports=[(8273, 'tcp4'),
|
daemon = Daemon('test-daemon', 'test-unit', listen_ports=[(8273, 'tcp4'),
|
||||||
(345, 'udp')])
|
(345, 'udp')])
|
||||||
@ -193,13 +193,16 @@ def test_diagnose(port_listening, service_is_running, daemon):
|
|||||||
assert results == [
|
assert results == [
|
||||||
DiagnosticCheck('daemon-running-test-unit',
|
DiagnosticCheck('daemon-running-test-unit',
|
||||||
'Service {service_name} is running', Result.PASSED,
|
'Service {service_name} is running', Result.PASSED,
|
||||||
{'service_name': 'test-unit'}),
|
{'service_name': 'test-unit'}, 'test-daemon'),
|
||||||
DiagnosticCheck('test-result-8273-tcp4', 'test-result-8273-tcp4',
|
DiagnosticCheck('test-result-8273-tcp4', 'test-result-8273-tcp4',
|
||||||
Result.PASSED),
|
Result.PASSED, {}, 'test-daemon'),
|
||||||
DiagnosticCheck('test-result-345-udp', 'test-result-345-udp',
|
DiagnosticCheck('test-result-345-udp', 'test-result-345-udp',
|
||||||
Result.PASSED)
|
Result.PASSED, {}, 'test-daemon')
|
||||||
]
|
]
|
||||||
port_listening.assert_has_calls([call(8273, 'tcp4'), call(345, 'udp')])
|
port_listening.assert_has_calls([
|
||||||
|
call(8273, 'tcp4', None, 'test-daemon'),
|
||||||
|
call(345, 'udp', None, 'test-daemon')
|
||||||
|
])
|
||||||
service_is_running.assert_has_calls([call('test-unit')])
|
service_is_running.assert_has_calls([call('test-unit')])
|
||||||
|
|
||||||
service_is_running.return_value = False
|
service_is_running.return_value = False
|
||||||
@ -342,12 +345,13 @@ def test_diagnose_netcat(popen):
|
|||||||
assert popen.mock_calls[2] == call().communicate(input=b'test-input')
|
assert popen.mock_calls[2] == call().communicate(input=b'test-input')
|
||||||
|
|
||||||
result = diagnose_netcat('test-host', 3300, remote_input='test-input',
|
result = diagnose_netcat('test-host', 3300, remote_input='test-input',
|
||||||
negate=True)
|
negate=True, component_id='test-component')
|
||||||
parameters2 = parameters.copy()
|
parameters2 = parameters.copy()
|
||||||
parameters2['negate'] = True
|
parameters2['negate'] = True
|
||||||
assert result == DiagnosticCheck('daemon-netcat-negate-test-host-3300',
|
assert result == DiagnosticCheck('daemon-netcat-negate-test-host-3300',
|
||||||
'Cannot connect to {host}:{port}',
|
'Cannot connect to {host}:{port}',
|
||||||
Result.FAILED, parameters2)
|
Result.FAILED, parameters2,
|
||||||
|
'test-component')
|
||||||
|
|
||||||
popen().returncode = 1
|
popen().returncode = 1
|
||||||
result = diagnose_netcat('test-host', 3300, remote_input='test-input')
|
result = diagnose_netcat('test-host', 3300, remote_input='test-input')
|
||||||
|
|||||||
@ -23,13 +23,14 @@ def test_result():
|
|||||||
def test_diagnostic_check():
|
def test_diagnostic_check():
|
||||||
"""Test the diagnostic check data class."""
|
"""Test the diagnostic check data class."""
|
||||||
with pytest.raises(TypeError):
|
with pytest.raises(TypeError):
|
||||||
DiagnosticCheck()
|
DiagnosticCheck() # pylint: disable=E1120
|
||||||
|
|
||||||
check = DiagnosticCheck('some-check-id', 'sample check')
|
check = DiagnosticCheck('some-check-id', 'sample check')
|
||||||
assert check.check_id == 'some-check-id'
|
assert check.check_id == 'some-check-id'
|
||||||
assert check.description == 'sample check'
|
assert check.description == 'sample check'
|
||||||
assert check.translated_description == 'sample check'
|
assert check.translated_description == 'sample check'
|
||||||
assert check.result == Result.NOT_DONE
|
assert check.result == Result.NOT_DONE
|
||||||
|
assert check.component_id is None
|
||||||
assert not check.parameters
|
assert not check.parameters
|
||||||
|
|
||||||
check = DiagnosticCheck('some-check-id', 'sample check', Result.PASSED)
|
check = DiagnosticCheck('some-check-id', 'sample check', Result.PASSED)
|
||||||
@ -40,6 +41,10 @@ def test_diagnostic_check():
|
|||||||
{'key': 'value'})
|
{'key': 'value'})
|
||||||
assert check.parameters['key'] == 'value'
|
assert check.parameters['key'] == 'value'
|
||||||
|
|
||||||
|
check = DiagnosticCheck('some-check-id', 'sample check', Result.FAILED, {},
|
||||||
|
'some-component')
|
||||||
|
assert check.component_id == 'some-component'
|
||||||
|
|
||||||
|
|
||||||
def test_translate():
|
def test_translate():
|
||||||
"""Test formatting the translated description."""
|
"""Test formatting the translated description."""
|
||||||
@ -58,7 +63,7 @@ def test_json_encoder_decoder():
|
|||||||
check_json = json.dumps(check, cls=CheckJSONEncoder)
|
check_json = json.dumps(check, cls=CheckJSONEncoder)
|
||||||
for string in [
|
for string in [
|
||||||
'"check_id": "some-check-id"', '"description": "sample check"',
|
'"check_id": "some-check-id"', '"description": "sample check"',
|
||||||
'"result": "passed"', '"parameters": {}',
|
'"result": "passed"', '"parameters": {}', '"component_id": null',
|
||||||
'"__class__": "DiagnosticCheck"'
|
'"__class__": "DiagnosticCheck"'
|
||||||
]:
|
]:
|
||||||
assert string in check_json
|
assert string in check_json
|
||||||
|
|||||||
@ -284,32 +284,34 @@ def test_diagnose(cache):
|
|||||||
DiagnosticCheck(
|
DiagnosticCheck(
|
||||||
'package-available-package1',
|
'package-available-package1',
|
||||||
'Package {package_expression} is not available for install',
|
'Package {package_expression} is not available for install',
|
||||||
Result.FAILED, {'package_expression': 'package1'}),
|
Result.FAILED, {'package_expression': 'package1'},
|
||||||
|
'test-component'),
|
||||||
DiagnosticCheck(
|
DiagnosticCheck(
|
||||||
'package-latest-package2',
|
'package-latest-package2',
|
||||||
'Package {package_name} is the latest version ({latest_version})',
|
'Package {package_name} is the latest version ({latest_version})',
|
||||||
Result.PASSED, {
|
Result.PASSED, {
|
||||||
'package_name': 'package2',
|
'package_name': 'package2',
|
||||||
'latest_version': '2.0'
|
'latest_version': '2.0'
|
||||||
}),
|
}, 'test-component'),
|
||||||
DiagnosticCheck(
|
DiagnosticCheck(
|
||||||
'package-latest-package3',
|
'package-latest-package3',
|
||||||
'Package {package_name} is the latest version ({latest_version})',
|
'Package {package_name} is the latest version ({latest_version})',
|
||||||
Result.WARNING, {
|
Result.WARNING, {
|
||||||
'package_name': 'package3',
|
'package_name': 'package3',
|
||||||
'latest_version': '3.0'
|
'latest_version': '3.0'
|
||||||
}),
|
}, 'test-component'),
|
||||||
DiagnosticCheck(
|
DiagnosticCheck(
|
||||||
'package-available-package4 | package5',
|
'package-available-package4 | package5',
|
||||||
'Package {package_expression} is not available for install',
|
'Package {package_expression} is not available for install',
|
||||||
Result.FAILED, {'package_expression': 'package4 | package5'}),
|
Result.FAILED, {'package_expression': 'package4 | package5'},
|
||||||
|
'test-component'),
|
||||||
DiagnosticCheck(
|
DiagnosticCheck(
|
||||||
'package-latest-package7',
|
'package-latest-package7',
|
||||||
'Package {package_name} is the latest version ({latest_version})',
|
'Package {package_name} is the latest version ({latest_version})',
|
||||||
Result.PASSED, {
|
Result.PASSED, {
|
||||||
'package_name': 'package7',
|
'package_name': 'package7',
|
||||||
'latest_version': '4.0'
|
'latest_version': '4.0'
|
||||||
}),
|
}, 'test-component'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user