diagnostics: Translate descriptions only in view

Tests:

- Enable all apps, and run diagnostics. Diagnostic descriptions are formatted
  as expected.

- Change the language to Spanish, and view the diagnostic results. Diagnostic
  descriptions are translated as expected.

Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
This commit is contained in:
James Valleroy 2023-11-17 16:45:11 -05:00 committed by Sunil Mohan Adapa
parent a5820bc36d
commit 3fcd6b9e58
No known key found for this signature in database
GPG Key ID: 43EA1CFF0AA7C5F2
18 changed files with 101 additions and 89 deletions

View File

@ -3,8 +3,7 @@
import logging import logging
import pathlib import pathlib
from django.utils.text import format_lazy from django.utils.translation import gettext_noop
from django.utils.translation import gettext_lazy as _
from plinth.privileged import config as privileged from plinth.privileged import config as privileged
@ -117,8 +116,8 @@ class DropinConfigs(app_module.FollowerComponent):
check_id = f'dropin-config-{etc_path}' check_id = f'dropin-config-{etc_path}'
result_string = Result.PASSED if result else Result.FAILED result_string = Result.PASSED if result else Result.FAILED
template = _('Static configuration {etc_path} is setup properly') description = gettext_noop(
description = format_lazy(template, etc_path=str(etc_path)) 'Static configuration {etc_path} is setup properly')
parameters = {'etc_path': str(etc_path)} parameters = {'etc_path': str(etc_path)}
results.append( results.append(
DiagnosticCheck(check_id, description, result_string, DiagnosticCheck(check_id, description, result_string,

View File

@ -5,9 +5,7 @@ import socket
import subprocess import subprocess
import psutil import psutil
from django.utils.text import format_lazy from django.utils.translation import gettext_noop
from django.utils.translation import gettext as _
from django.utils.translation import gettext_lazy
from plinth import action_utils, app from plinth import action_utils, app
@ -104,8 +102,7 @@ class Daemon(app.LeaderComponent):
check_id = f'daemon-running-{self.unit}' check_id = f'daemon-running-{self.unit}'
result = Result.PASSED if self.is_running() else Result.FAILED result = Result.PASSED if self.is_running() else Result.FAILED
template = gettext_lazy('Service {service_name} is running') description = gettext_noop('Service {service_name} is running')
description = format_lazy(template, service_name=self.unit)
parameters = {'service_name': self.unit} parameters = {'service_name': self.unit}
return DiagnosticCheck(check_id, description, result, parameters) return DiagnosticCheck(check_id, description, result, parameters)
@ -163,14 +160,11 @@ def diagnose_port_listening(port, kind='tcp', listen_address=None):
if listen_address: if listen_address:
parameters['listen_address'] = listen_address parameters['listen_address'] = listen_address
check_id = f'daemon-listening-address-{kind}-{port}-{listen_address}' check_id = f'daemon-listening-address-{kind}-{port}-{listen_address}'
template = gettext_lazy( description = gettext_noop(
'Listening on {kind} port {listen_address}:{port}') 'Listening on {kind} port {listen_address}:{port}')
description = format_lazy(template, kind=kind,
listen_address=listen_address, port=port)
else: else:
check_id = f'daemon-listening-{kind}-{port}' check_id = f'daemon-listening-{kind}-{port}'
template = gettext_lazy('Listening on {kind} port {port}') description = gettext_noop('Listening on {kind} port {port}')
description = format_lazy(template, kind=kind, port=port)
return DiagnosticCheck(check_id, description, return DiagnosticCheck(check_id, description,
Result.PASSED if result else Result.FAILED, Result.PASSED if result else Result.FAILED,
@ -239,11 +233,11 @@ def diagnose_netcat(host, port, input='', negate=False):
result = Result.FAILED result = Result.FAILED
check_id = f'daemon-netcat-{host}-{port}' check_id = f'daemon-netcat-{host}-{port}'
description = _('Connect to {host}:{port}') description = gettext_noop('Connect to {host}:{port}')
parameters = {'host': host, 'port': port, 'negate': negate} parameters = {'host': host, 'port': port, 'negate': negate}
if negate: if negate:
check_id = f'daemon-netcat-negate-{host}-{port}' check_id = f'daemon-netcat-negate-{host}-{port}'
description = _('Cannot connect to {host}:{port}') description = gettext_noop('Cannot connect to {host}:{port}')
return DiagnosticCheck(check_id, description.format(host=host, port=port), return DiagnosticCheck(check_id, description.format(host=host, port=port),
result, parameters) result, parameters)

View File

@ -4,8 +4,7 @@
import re import re
import subprocess import subprocess
from django.utils.text import format_lazy from django.utils.translation import gettext_noop
from django.utils.translation import gettext_lazy
from plinth import action_utils, app from plinth import action_utils, app
from plinth.modules.diagnostics.check import DiagnosticCheck, Result from plinth.modules.diagnostics.check import DiagnosticCheck, Result
@ -149,16 +148,13 @@ def diagnose_url(url, kind=None, env=None, check_certificate=True,
except FileNotFoundError: except FileNotFoundError:
result = Result.ERROR result = Result.ERROR
parameters = {'url': url} parameters = {'url': url, 'kind': kind}
if kind: if kind:
parameters['kind'] = kind
check_id = f'apache-url-kind-{url}-{kind}' check_id = f'apache-url-kind-{url}-{kind}'
template = gettext_lazy('Access URL {url} on tcp{kind}') description = gettext_noop('Access URL {url} on tcp{kind}')
description = format_lazy(template, url=url, kind=kind)
else: else:
check_id = f'apache-url-{url}' check_id = f'apache-url-{url}'
template = gettext_lazy('Access URL {url}') description = gettext_noop('Access URL {url}')
description = format_lazy(template, url=url)
return DiagnosticCheck(check_id, description, result, parameters) return DiagnosticCheck(check_id, description, result, parameters)

View File

@ -12,7 +12,8 @@ from plinth import app
from plinth.modules.apache.components import (Uwsgi, Webserver, check_url, from plinth.modules.apache.components import (Uwsgi, Webserver, check_url,
diagnose_url, diagnose_url,
diagnose_url_on_all) diagnose_url_on_all)
from plinth.modules.diagnostics.check import DiagnosticCheck, Result from plinth.modules.diagnostics.check import (DiagnosticCheck, Result,
translate, translate_checks)
def test_webserver_init(): def test_webserver_init():
@ -248,13 +249,13 @@ def test_diagnose_url(get_addresses, check):
} }
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 = translate(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 https://localhost/test on tcp4', Result.PASSED, parameters) 'Access URL https://localhost/test on tcp4', Result.PASSED, parameters)
check.return_value = False check.return_value = False
result = diagnose_url(**args) result = translate(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 https://localhost/test on tcp4', Result.FAILED, parameters) 'Access URL https://localhost/test on tcp4', Result.FAILED, parameters)
@ -283,7 +284,7 @@ def test_diagnose_url(get_addresses, check):
'kind': '6' 'kind': '6'
}, },
] ]
results = diagnose_url_on_all(**args) results = translate_checks(diagnose_url_on_all(**args))
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 https://test-host-1/test on tcp4', 'Access URL https://test-host-1/test on tcp4',

View File

@ -6,6 +6,7 @@ FreedomBox app to configure system date and time.
import subprocess import subprocess
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.utils.translation import gettext_noop
from plinth import app as app_module from plinth import app as app_module
from plinth import menu from plinth import menu
@ -118,4 +119,5 @@ def _diagnose_time_synchronized():
pass pass
return DiagnosticCheck('datetime-ntp-sync', return DiagnosticCheck('datetime-ntp-sync',
_('Time synchronized to NTP server'), result) gettext_noop('Time synchronized to NTP server'),
result)

View File

@ -3,6 +3,7 @@
FreedomBox app for running diagnostics. FreedomBox app for running diagnostics.
""" """
from copy import deepcopy
import logging import logging
from django.http import Http404, HttpResponseRedirect from django.http import Http404, HttpResponseRedirect
@ -17,7 +18,7 @@ from plinth.app import App
from plinth.modules import diagnostics from plinth.modules import diagnostics
from plinth.views import AppView from plinth.views import AppView
from .check import Result from .check import Result, translate_checks
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -62,7 +63,14 @@ class DiagnosticsFullView(TemplateView):
is_task_running = False is_task_running = False
with diagnostics.results_lock: with diagnostics.results_lock:
results = diagnostics.current_results results = deepcopy(diagnostics.current_results)
# Translate and format diagnostic check descriptions for each app
for app_id in results['results']:
if 'diagnosis' in results['results'][app_id]:
diagnosis = results['results'][app_id]['diagnosis']
results['results'][app_id]['diagnosis'] = translate_checks(
diagnosis)
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
context['is_task_running'] = is_task_running context['is_task_running'] = is_task_running
@ -89,6 +97,8 @@ def diagnose_app(request, app_id):
exception) exception)
diagnosis_exception = str(exception) diagnosis_exception = str(exception)
# Translate and format diagnostic check descriptions
diagnosis = translate_checks(diagnosis)
show_rerun_setup = False show_rerun_setup = False
for check in diagnosis: for check in diagnosis:
if check.result in [Result.FAILED, Result.WARNING]: if check.result in [Result.FAILED, Result.WARNING]:

View File

@ -4,8 +4,8 @@
import contextlib import contextlib
import logging import logging
from django.utils.translation import gettext
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.utils.translation import gettext_noop
from plinth import app as app_module from plinth import app as app_module
from plinth import cfg, menu from plinth import cfg, menu
@ -268,7 +268,7 @@ def remove_passthrough(ipv, *args):
def _diagnose_default_zone(config): def _diagnose_default_zone(config):
"""Diagnose whether the default zone is external.""" """Diagnose whether the default zone is external."""
check_id = 'firewall-default-zone' check_id = 'firewall-default-zone'
description = gettext('Default zone is external') description = gettext_noop('Default zone is external')
result = Result.PASSED if config[ result = Result.PASSED if config[
'default_zone'] == 'external' else Result.FAILED 'default_zone'] == 'external' else Result.FAILED
return DiagnosticCheck(check_id, description, result) return DiagnosticCheck(check_id, description, result)
@ -277,7 +277,7 @@ def _diagnose_default_zone(config):
def _diagnose_firewall_backend(config): def _diagnose_firewall_backend(config):
"""Diagnose whether the firewall backend is nftables.""" """Diagnose whether the firewall backend is nftables."""
check_id = 'firewall-backend' check_id = 'firewall-backend'
description = gettext('Firewall backend is nftables') description = gettext_noop('Firewall backend is nftables')
result = Result.PASSED if config['backend'] == 'nftables' \ result = Result.PASSED if config['backend'] == 'nftables' \
else Result.FAILED else Result.FAILED
return DiagnosticCheck(check_id, description, result) return DiagnosticCheck(check_id, description, result)
@ -290,7 +290,7 @@ def _diagnose_direct_passthroughs(config):
which are the number that are added by firewall's setup. which are the number that are added by firewall's setup.
""" """
check_id = 'firewall-direct-passthroughs' check_id = 'firewall-direct-passthroughs'
description = gettext('Direct passthrough rules exist') description = gettext_noop('Direct passthrough rules exist')
result = Result.PASSED if len( result = Result.PASSED if len(
config['passthroughs']) >= 12 else Result.FAILED config['passthroughs']) >= 12 else Result.FAILED
return DiagnosticCheck(check_id, description, result) return DiagnosticCheck(check_id, description, result)

View File

@ -7,8 +7,7 @@ import logging
import re import re
from typing import ClassVar from typing import ClassVar
from django.utils.text import format_lazy from django.utils.translation import gettext_noop
from django.utils.translation import gettext_lazy as _
from plinth import app from plinth import app
from plinth.modules import firewall from plinth.modules import firewall
@ -133,9 +132,8 @@ class Firewall(app.FollowerComponent):
# Internal zone # Internal zone
check_id = f'firewall-port-internal-{port}' check_id = f'firewall-port-internal-{port}'
result = Result.PASSED if port in internal_ports else Result.FAILED result = Result.PASSED if port in internal_ports else Result.FAILED
template = _( description = gettext_noop(
'Port {name} ({details}) available for internal networks') 'Port {name} ({details}) available for internal networks')
description = format_lazy(template, name=port, details=details)
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))
@ -145,17 +143,15 @@ class Firewall(app.FollowerComponent):
check_id = f'firewall-port-external-available-{port}' check_id = f'firewall-port-external-available-{port}'
result = Result.PASSED \ result = Result.PASSED \
if port in external_ports else Result.FAILED if port in external_ports else Result.FAILED
template = _( description = gettext_noop(
'Port {name} ({details}) available for external networks') 'Port {name} ({details}) available for external networks')
description = format_lazy(template, name=port, details=details)
else: else:
check_id = f'firewall-port-external-unavailable-{port}' check_id = f'firewall-port-external-unavailable-{port}'
result = Result.PASSED \ result = Result.PASSED \
if port not in external_ports else Result.FAILED if port not in external_ports else Result.FAILED
template = _( description = gettext_noop(
'Port {name} ({details}) unavailable for external networks' 'Port {name} ({details}) unavailable for external networks'
) )
description = format_lazy(template, name=port, details=details)
parameters = {'name': port, 'details': details} parameters = {'name': port, 'details': details}
results.append( results.append(

View File

@ -8,7 +8,8 @@ from unittest.mock import call, patch
import pytest import pytest
from plinth.app import App from plinth.app import App
from plinth.modules.diagnostics.check import DiagnosticCheck, Result from plinth.modules.diagnostics.check import (DiagnosticCheck, Result,
translate_checks)
from plinth.modules.firewall.components import (Firewall, from plinth.modules.firewall.components import (Firewall,
FirewallLocalProtection) FirewallLocalProtection)
@ -153,7 +154,7 @@ def test_diagnose(get_enabled_services, get_port_details):
get_port_details.side_effect = get_port_details_side_effect get_port_details.side_effect = get_port_details_side_effect
firewall = Firewall('test-firewall-1', ports=['test-port1', 'test-port2'], firewall = Firewall('test-firewall-1', ports=['test-port1', 'test-port2'],
is_external=False) is_external=False)
results = firewall.diagnose() results = translate_checks(firewall.diagnose())
assert results == [ assert results == [
DiagnosticCheck( DiagnosticCheck(
'firewall-port-internal-test-port1', 'firewall-port-internal-test-port1',
@ -187,7 +188,7 @@ def test_diagnose(get_enabled_services, get_port_details):
firewall = Firewall('test-firewall-1', ports=['test-port3', 'test-port4'], firewall = Firewall('test-firewall-1', ports=['test-port3', 'test-port4'],
is_external=True) is_external=True)
results = firewall.diagnose() results = translate_checks(firewall.diagnose())
assert results == [ assert results == [
DiagnosticCheck( DiagnosticCheck(
'firewall-port-internal-test-port3', 'firewall-port-internal-test-port3',

View File

@ -6,6 +6,7 @@ import logging
import pathlib import pathlib
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.utils.translation import gettext_noop
from plinth import app as app_module from plinth import app as app_module
from plinth import cfg, menu from plinth import cfg, menu
@ -13,6 +14,7 @@ from plinth.config import DropinConfigs
from plinth.modules import names from plinth.modules import names
from plinth.modules.apache.components import diagnose_url from plinth.modules.apache.components import diagnose_url
from plinth.modules.backups.components import BackupRestore from plinth.modules.backups.components import BackupRestore
from plinth.modules.diagnostics.check import DiagnosticCheck, Result
from plinth.modules.names.components import DomainType from plinth.modules.names.components import DomainType
from plinth.package import Packages from plinth.package import Packages
from plinth.signals import domain_added, domain_removed, post_app_loading from plinth.signals import domain_added, domain_removed, post_app_loading
@ -97,7 +99,10 @@ class LetsEncryptApp(app_module.App):
if not results: if not results:
results.append( results.append(
(_('Cannot test: No domains are configured.'), 'warning')) DiagnosticCheck(
'letsencrypt-cannot-test',
gettext_noop('Cannot test: No domains are configured.'),
Result.WARNING))
return results return results

View File

@ -5,6 +5,7 @@ FreedomBox app to configure Privoxy.
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.utils.translation import gettext_noop
from plinth import action_utils from plinth import action_utils
from plinth import app as app_module from plinth import app as app_module
@ -112,9 +113,9 @@ def diagnose_url_with_proxy():
result = diagnose_url(url, kind=address['kind'], env=env) result = diagnose_url(url, kind=address['kind'], env=env)
result.check_id = f'privoxy-url-proxy-kind-{url}-{address["kind"]}' result.check_id = f'privoxy-url-proxy-kind-{url}-{address["kind"]}'
result.description = _( result.description = gettext_noop(
'Access {url} with proxy {proxy} on tcp{kind}') \ 'Access {url} with proxy {proxy} on tcp{kind}')
.format(url=url, proxy=proxy, kind=address['kind']) result.parameters['proxy'] = proxy
results.append(result) results.append(result)
return results return results

View File

@ -5,6 +5,7 @@ import json
import logging import logging
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.utils.translation import gettext_noop
from plinth import action_utils from plinth import action_utils
from plinth import app as app_module from plinth import app as app_module
@ -134,7 +135,7 @@ class TorApp(app_module.App):
if status['relay_enabled']: if status['relay_enabled']:
results.append( results.append(
DiagnosticCheck( DiagnosticCheck(
'tor-port-relay', _('Tor relay port available'), 'tor-port-relay', gettext_noop('Tor relay port available'),
Result.PASSED if 'orport' in ports else Result.FAILED)) Result.PASSED if 'orport' in ports else Result.FAILED))
if 'orport' in ports: if 'orport' in ports:
results.append( results.append(
@ -145,7 +146,8 @@ class TorApp(app_module.App):
if status['bridge_relay_enabled']: if status['bridge_relay_enabled']:
results.append( results.append(
DiagnosticCheck( DiagnosticCheck(
'tor-port-obfs3', _('Obfs3 transport registered'), 'tor-port-obfs3',
gettext_noop('Obfs3 transport registered'),
Result.PASSED if 'obfs3' in ports else Result.FAILED)) Result.PASSED if 'obfs3' in ports else Result.FAILED))
if 'obfs3' in ports: if 'obfs3' in ports:
results.append( results.append(
@ -155,7 +157,8 @@ class TorApp(app_module.App):
results.append( results.append(
DiagnosticCheck( DiagnosticCheck(
'tor-port-obfs4', _('Obfs4 transport registered'), 'tor-port-obfs4',
gettext_noop('Obfs4 transport registered'),
Result.PASSED if 'obfs4' in ports else Result.FAILED)) Result.PASSED if 'obfs4' in ports else Result.FAILED))
if 'obfs4' in ports: if 'obfs4' in ports:
results.append( results.append(
@ -167,8 +170,8 @@ class TorApp(app_module.App):
hs_hostname = status['hs_hostname'].split('.onion')[0] hs_hostname = status['hs_hostname'].split('.onion')[0]
results.append( results.append(
DiagnosticCheck( DiagnosticCheck(
'tor-onion-version', _('Onion service is version 3'), 'tor-onion-version',
Result.PASSED gettext_noop('Onion service is version 3'), Result.PASSED
if len(hs_hostname) == 56 else Result.FAILED)) if len(hs_hostname) == 56 else Result.FAILED))
return results return results

View File

@ -6,6 +6,7 @@ import logging
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.utils.translation import gettext_noop
from plinth import app as app_module from plinth import app as app_module
from plinth import cfg, frontpage, kvstore, menu from plinth import cfg, frontpage, kvstore, menu
@ -136,8 +137,7 @@ def _diagnose_url_via_tor(url, kind=None):
"""Diagnose whether a URL is reachable via Tor.""" """Diagnose whether a URL is reachable via Tor."""
result = diagnose_url(url, kind=kind, wrapper='torsocks') result = diagnose_url(url, kind=kind, wrapper='torsocks')
result.check_id = 'torproxy-url' result.check_id = 'torproxy-url'
result.description = _('Access URL {url} on tcp{kind} via Tor') \ result.description = gettext_noop('Access URL {url} on tcp{kind} via Tor')
.format(url=url, kind=kind)
return result return result
@ -148,7 +148,7 @@ def _diagnose_tor_use(url, kind=None):
result = diagnose_url(url, kind=kind, wrapper='torsocks', result = diagnose_url(url, kind=kind, wrapper='torsocks',
expected_output=expected_output) expected_output=expected_output)
result.check_id = 'torproxy-using-tor' result.check_id = 'torproxy-using-tor'
result.description = _('Confirm Tor usage at {url} on tcp{kind}') \ result.description = gettext_noop(
.format(url=url, kind=kind) 'Confirm Tor usage at {url} on tcp{kind}')
return result return result

View File

@ -7,6 +7,7 @@ import subprocess
import augeas import augeas
from django.utils.text import format_lazy from django.utils.text import format_lazy
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.utils.translation import gettext_noop
from plinth import app as app_module from plinth import app as app_module
from plinth import cfg, menu from plinth import cfg, menu
@ -123,8 +124,7 @@ def _diagnose_ldap_entry(search_item):
except subprocess.CalledProcessError: except subprocess.CalledProcessError:
pass pass
template = _('Check LDAP entry "{search_item}"') description = gettext_noop('Check LDAP entry "{search_item}"')
description = format_lazy(template, search_item=search_item)
parameters = {'search_item': search_item} parameters = {'search_item': search_item}
return DiagnosticCheck(check_id, description, result, parameters) return DiagnosticCheck(check_id, description, result, parameters)
@ -138,8 +138,7 @@ def _diagnose_nslcd_config(config, key, value):
except KeyError: except KeyError:
result = Result.FAILED result = Result.FAILED
template = _('Check nslcd config "{key} {value}"') description = gettext_noop('Check nslcd config "{key} {value}"')
description = format_lazy(template, key=key, value=value)
parameters = {'key': key, 'value': value} parameters = {'key': key, 'value': value}
return DiagnosticCheck(check_id, description, result, parameters) return DiagnosticCheck(check_id, description, result, parameters)
@ -169,8 +168,7 @@ def _diagnose_nsswitch_config():
break break
template = _('Check nsswitch config "{database}"') description = gettext_noop('Check nsswitch config "{database}"')
description = format_lazy(template, database=database)
parameters = {'database': database} parameters = {'database': database}
results.append( results.append(

View File

@ -8,7 +8,7 @@ import time
import apt.cache import apt.cache
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from django.utils.translation import gettext_lazy from django.utils.translation import gettext_lazy, gettext_noop
import plinth.privileged.packages as privileged import plinth.privileged.packages as privileged
from plinth import app as app_module from plinth import app as app_module
@ -211,9 +211,8 @@ class Packages(app_module.FollowerComponent):
package_name = package_expression.actual() package_name = package_expression.actual()
except MissingPackageError: except MissingPackageError:
check_id = f'package-available-{package_expression}' check_id = f'package-available-{package_expression}'
description = _( description = gettext_noop('Package {package_expression} is '
'Package {expression} is not available for ' 'not available for install')
'install').format(expression=package_expression)
parameters = {'package_expression': str(package_expression)} parameters = {'package_expression': str(package_expression)}
results.append( results.append(
DiagnosticCheck(check_id, description, Result.FAILED, DiagnosticCheck(check_id, description, Result.FAILED,
@ -229,10 +228,8 @@ class Packages(app_module.FollowerComponent):
result = Result.PASSED result = Result.PASSED
check_id = f'package-latest-{package_name}' check_id = f'package-latest-{package_name}'
description = _('Package {package_name} is the latest version ' description = gettext_noop('Package {package_name} is the latest '
'({latest_version})').format( 'version ({latest_version})')
package_name=package_name,
latest_version=latest_version)
parameters = { parameters = {
'package_name': package_name, 'package_name': package_name,
'latest_version': latest_version, 'latest_version': latest_version,

View File

@ -9,7 +9,8 @@ import pytest
from plinth.app import App from plinth.app import App
from plinth.config import DropinConfigs from plinth.config import DropinConfigs
from plinth.modules.diagnostics.check import DiagnosticCheck, Result from plinth.modules.diagnostics.check import (DiagnosticCheck, Result,
translate_checks)
pytestmark = pytest.mark.usefixtures('mock_privileged') pytestmark = pytest.mark.usefixtures('mock_privileged')
privileged_modules_to_mock = ['plinth.privileged.config'] privileged_modules_to_mock = ['plinth.privileged.config']
@ -160,7 +161,7 @@ def test_dropin_config_diagnose_symlinks(dropin_configs, tmp_path):
"""Test diagnosing dropin configs for symlinks.""" """Test diagnosing dropin configs for symlinks."""
with patch('plinth.config.DropinConfigs.ROOT', new=tmp_path): with patch('plinth.config.DropinConfigs.ROOT', new=tmp_path):
# Nothing exists # Nothing exists
results = dropin_configs.diagnose() results = translate_checks(dropin_configs.diagnose())
assert results == [ assert results == [
DiagnosticCheck( DiagnosticCheck(
f'dropin-config-{tmp_path}/etc/test/path1', f'dropin-config-{tmp_path}/etc/test/path1',

View File

@ -12,7 +12,8 @@ import pytest
from plinth.app import App, FollowerComponent, Info from plinth.app import App, FollowerComponent, Info
from plinth.daemon import (Daemon, RelatedDaemon, app_is_running, from plinth.daemon import (Daemon, RelatedDaemon, app_is_running,
diagnose_netcat, diagnose_port_listening) diagnose_netcat, diagnose_port_listening)
from plinth.modules.diagnostics.check import DiagnosticCheck, Result from plinth.modules.diagnostics.check import (DiagnosticCheck, Result,
translate, translate_checks)
privileged_modules_to_mock = ['plinth.privileged.service'] privileged_modules_to_mock = ['plinth.privileged.service']
@ -148,7 +149,7 @@ def test_diagnose(port_listening, service_is_running, daemon):
(345, 'udp')]) (345, 'udp')])
port_listening.side_effect = side_effect port_listening.side_effect = side_effect
service_is_running.return_value = True service_is_running.return_value = True
results = daemon.diagnose() results = translate_checks(daemon.diagnose())
assert results == [ assert results == [
DiagnosticCheck('daemon-running-test-unit', DiagnosticCheck('daemon-running-test-unit',
'Service test-unit is running', Result.PASSED, 'Service test-unit is running', Result.PASSED,
@ -214,14 +215,14 @@ def test_diagnose_port_listening(connections):
] ]
# Check that message is correct # Check that message is correct
results = diagnose_port_listening(1234) results = translate(diagnose_port_listening(1234))
assert results == DiagnosticCheck('daemon-listening-tcp-1234', assert results == DiagnosticCheck('daemon-listening-tcp-1234',
'Listening on tcp port 1234', 'Listening on tcp port 1234',
Result.PASSED, { Result.PASSED, {
'kind': 'tcp', 'kind': 'tcp',
'port': 1234 'port': 1234
}) })
results = diagnose_port_listening(1234, 'tcp', '0.0.0.0') results = translate(diagnose_port_listening(1234, 'tcp', '0.0.0.0'))
assert results == DiagnosticCheck( assert results == DiagnosticCheck(
'daemon-listening-address-tcp-1234-0.0.0.0', 'daemon-listening-address-tcp-1234-0.0.0.0',
'Listening on tcp port 0.0.0.0:1234', Result.PASSED, { 'Listening on tcp port 0.0.0.0:1234', Result.PASSED, {
@ -231,14 +232,14 @@ def test_diagnose_port_listening(connections):
}) })
# Failed results # Failed results
results = diagnose_port_listening(4321) results = translate(diagnose_port_listening(4321))
assert results == DiagnosticCheck('daemon-listening-tcp-4321', assert results == DiagnosticCheck('daemon-listening-tcp-4321',
'Listening on tcp port 4321', 'Listening on tcp port 4321',
Result.FAILED, { Result.FAILED, {
'kind': 'tcp', 'kind': 'tcp',
'port': 4321 'port': 4321
}) })
results = diagnose_port_listening(4321, 'tcp', '0.0.0.0') results = translate(diagnose_port_listening(4321, 'tcp', '0.0.0.0'))
assert results == DiagnosticCheck( assert results == DiagnosticCheck(
'daemon-listening-address-tcp-4321-0.0.0.0', 'daemon-listening-address-tcp-4321-0.0.0.0',
'Listening on tcp port 0.0.0.0:4321', Result.FAILED, { 'Listening on tcp port 0.0.0.0:4321', Result.FAILED, {

View File

@ -10,7 +10,8 @@ import pytest
from plinth.app import App from plinth.app import App
from plinth.errors import MissingPackageError from plinth.errors import MissingPackageError
from plinth.modules.diagnostics.check import DiagnosticCheck, Result from plinth.modules.diagnostics.check import (DiagnosticCheck, Result,
translate_checks)
from plinth.package import Package, Packages, packages_installed from plinth.package import Package, Packages, packages_installed
@ -238,27 +239,33 @@ def test_diagnose(cache):
Package('package4') | Package('package5'), Package('package4') | Package('package5'),
Package('package6') | Package('package7') Package('package6') | Package('package7')
]) ])
results = component.diagnose() results = translate_checks(component.diagnose())
assert results == [ assert results == [
DiagnosticCheck('package-available-package1', DiagnosticCheck('package-available-package1',
'Package package1 is not available for install', 'Package package1 is not available for install',
Result.FAILED, {'package_expression': 'package1'}), Result.FAILED, {'package_expression': 'package1'}),
DiagnosticCheck('package-latest-package2', DiagnosticCheck('package-latest-package2',
'Package package2 is the latest version (2.0)', 'Package package2 is the latest version (2.0)',
Result.PASSED, Result.PASSED, {
{'package_name': 'package2', 'latest_version': '2.0'}), 'package_name': 'package2',
'latest_version': '2.0'
}),
DiagnosticCheck('package-latest-package3', DiagnosticCheck('package-latest-package3',
'Package package3 is the latest version (3.0)', 'Package package3 is the latest version (3.0)',
Result.WARNING, Result.WARNING, {
{'package_name': 'package3', 'latest_version': '3.0'}), 'package_name': 'package3',
'latest_version': '3.0'
}),
DiagnosticCheck( DiagnosticCheck(
'package-available-package4 | package5', 'package-available-package4 | package5',
'Package package4 | package5 is not available for install', 'Package package4 | package5 is not available for install',
Result.FAILED, {'package_expression': 'package4 | package5'}), Result.FAILED, {'package_expression': 'package4 | package5'}),
DiagnosticCheck('package-latest-package7', DiagnosticCheck('package-latest-package7',
'Package package7 is the latest version (4.0)', 'Package package7 is the latest version (4.0)',
Result.PASSED, Result.PASSED, {
{'package_name': 'package7', 'latest_version': '4.0'}), 'package_name': 'package7',
'latest_version': '4.0'
}),
] ]