[kde-linux/os-autoinst-distri-kdelinux] /: Implement secret service credential persistence test
Thomas Duckworth <[email protected]>
| Newsgroups | gmane.comp.kde.cvs |
|---|---|
| Message-ID | <[email protected]> |
Git commit f77f23288c12519f8953cf13d87b9347cffd9ba1 by Thomas Duckworth. Committed on 15/08/2026 at 03:00. Pushed by tduck into branch 'master'. Implement secret service credential persistence test Checks that set secret service credentials persist and are accessible between restarts and upgrades. This splits secret service testing into three tests, so a helper library was created. M +4 -23 extensions/openqa/usr/lib/kde-linux-openqa/tests/secret_service.py A +52 -0 extensions/openqa/usr/lib/kde-linux-openqa/tests/secret_service_persistence_get.py A +44 -0 extensions/openqa/usr/lib/kde-linux-openqa/tests/secret_service_persistence_set.py A +31 -0 lib/sut/secret_service.py M +5 -2 main.pm A +9 -0 tests/kdelinux/desktop/secret_service_persistence_get.py A +9 -0 tests/kdelinux/desktop/secret_service_persistence_set.py https://invent.kde.org/kde-linux/os-autoinst-distri-kdelinux/-/commit/f77f23288c12519f8953cf13d87b9347cffd9ba1 diff --git a/extensions/openqa/usr/lib/kde-linux-openqa/tests/secret_service.py b/extensions/openqa/usr/lib/kde-linux-openqa/tests/secret_service.py index d2c7e9b..541cdcd 100644 --- a/extensions/openqa/usr/lib/kde-linux-openqa/tests/secret_service.py +++ b/extensions/openqa/usr/lib/kde-linux-openqa/tests/secret_service.py @@ -1,7 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL # SPDX-FileCopyrightText: 2026 Thomas Duckworth <[email protected]> -import os import unittest import subprocess from appium import webdriver @@ -13,11 +12,11 @@ from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as ec from lib.sut import openqa_junit_xml from lib.sut import flatpak +from lib.sut import secret_service from lib.common import user_manager # Verifies the Secret Service provider is ksecretd and works through KeepSecret. -SECRETS_BUS_NAME = 'org.freedesktop.secrets' KEEPSECRET_APP_ID = 'org.kde.keepsecret' @@ -41,22 +40,6 @@ class SecretServiceTests(unittest.TestCase): 'user', 'kde-linux-openqa wallet test user'], capture_output=True) - def _activate_secret_service(self): - # The Secret Service is D-Bus activated, bring it up if it isn't already - subprocess.run(['secret-tool', 'lookup', 'kde-linux-openqa', 'probe'], - capture_output=True, text=True) - - def _secret_service_pid(self) -> int: - out = subprocess.check_output( - ['busctl', '--user', 'status', SECRETS_BUS_NAME], text=True) - for line in out.splitlines(): - if line.strip().startswith('PID='): - return int(line.split('=', 1)[1].strip()) - self.fail(f'could not determine PID owning {SECRETS_BUS_NAME}') - - def _process_exe(self, pid: int) -> str: - return os.path.basename(os.readlink(f'/proc/{pid}/exe')) - def _set_text(self, text, element=None, verify=True): # QML text fields seem to not implement AT-SPI EditableText in QT versions older than 6.11 # and synthesised keystrokes get garbled, so we fall back to using the clipboard here. @@ -76,12 +59,11 @@ class SecretServiceTests(unittest.TestCase): def test_1_secret_service_provider_is_ksecretd(self): """Check that the org.freedesktop.secrets provider is ksecretd.""" - self._activate_secret_service() - pid = self._secret_service_pid() - exe = self._process_exe(pid) + secret_service.activate() + exe = secret_service.process_exe() self.assertEqual( exe, 'ksecretd', - f'{SECRETS_BUS_NAME} is provided by {exe!r} (pid {pid}), expected ksecretd' + f'{secret_service.SECRETS_BUS_NAME} is provided by {exe!r} (pid {secret_service.pid()}), expected ksecretd' ) def test_2_keepsecret(self): @@ -138,6 +120,5 @@ class SecretServiceTests(unittest.TestCase): (AppiumBy.XPATH, '//list_item[@name="kde-linux-openqa wallet test"]'))) - if __name__ == "__main__": openqa_junit_xml.run(SecretServiceTests, "secret_service") diff --git a/extensions/openqa/usr/lib/kde-linux-openqa/tests/secret_service_persistence_get.py b/extensions/openqa/usr/lib/kde-linux-openqa/tests/secret_service_persistence_get.py new file mode 100644 index 0000000..ca318a3 --- /dev/null +++ b/extensions/openqa/usr/lib/kde-linux-openqa/tests/secret_service_persistence_get.py @@ -0,0 +1,52 @@ +# SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL +# SPDX-FileCopyrightText: 2026 Thomas Duckworth <[email protected]> + +import unittest +import subprocess +from lib.sut import openqa_junit_xml +from lib.sut import secret_service + +# Looks up credentials set in the secret service before reboot. +# These were set in secret_service_persistence_get.py + + +class SecretServicePersistenceGetTests(unittest.TestCase): + @classmethod + def setUpClass(self): + secret_service.activate() + + def test_1_secret_service_provider_is_ksecretd(self): + """Check that the org.freedesktop.secrets provider is ksecretd.""" + exe = secret_service.process_exe() + self.assertEqual( + exe, + "ksecretd", + f"{secret_service.SECRETS_BUS_NAME} is provided by {exe!r} " + f"(pid {secret_service.pid()}), expected ksecretd", + ) + + def test_2_persistent_credentials(self): + """Check that credentials stored before upgrade persisted.""" + result = subprocess.run( + [ + "secret-tool", + "lookup", + "kde-linux-openqa-secret_service_persistence", + "kde-linux-openqa-secret_service_persistence", + ], + capture_output=True, + text=True, + check=True, + ) + + self.assertEqual( + result.stdout.strip(), + "kde-linux-openqa-secret_service_persistence", + ) + + +if __name__ == "__main__": + openqa_junit_xml.run( + SecretServicePersistenceGetTests, + "secret_service_persistence_get", + ) diff --git a/extensions/openqa/usr/lib/kde-linux-openqa/tests/secret_service_persistence_set.py b/extensions/openqa/usr/lib/kde-linux-openqa/tests/secret_service_persistence_set.py new file mode 100644 index 0000000..8b53128 --- /dev/null +++ b/extensions/openqa/usr/lib/kde-linux-openqa/tests/secret_service_persistence_set.py @@ -0,0 +1,44 @@ +# SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL +# SPDX-FileCopyrightText: 2026 Thomas Duckworth <[email protected]> + +import unittest +import subprocess +from lib.sut import openqa_junit_xml +from lib.sut import secret_service + +# Sets some credentials in the secret service before reboot. +# These are then checked after upgrade in secret_service_persistence_get.py + + +class SecretServicePersistenceSetTests(unittest.TestCase): + @classmethod + def setUpClass(self): + secret_service.activate() + + def test_1_secret_service_provider_is_ksecretd(self): + """Check that the org.freedesktop.secrets provider is ksecretd.""" + exe = secret_service.process_exe() + self.assertEqual( + exe, + "ksecretd", + f"{secret_service.SECRETS_BUS_NAME} is provided by {exe!r} " + f"(pid {secret_service.pid()}), expected ksecretd", + ) + + def test_2_set_persistent_credentials(self): + """Set some credentials in the wallet to check if they persist after reboot.""" + subprocess.run( + [ + "secret-tool", + "store", + "--label='kde-linux-openqa-secret_service_persistence'", + "kde-linux-openqa-secret_service_persistence", + "kde-linux-openqa-secret_service_persistence", + ], + capture_output=True, + check=True, + ) + + +if __name__ == "__main__": + openqa_junit_xml.run(SecretServicePersistenceSetTests, "secret_service_persistence_set") diff --git a/lib/sut/secret_service.py b/lib/sut/secret_service.py new file mode 100644 index 0000000..1a73f23 --- /dev/null +++ b/lib/sut/secret_service.py @@ -0,0 +1,31 @@ +# SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL +# SPDX-FileCopyrightText: 2026 Thomas Duckworth <[email protected]> + +# Helper for interacting with the Secret Service. + +import subprocess +import os + +SECRETS_BUS_NAME = 'org.freedesktop.secrets' + + +class SecretServicePidError(Exception): + """Raised when the Secret Service PID cannot be determined.""" + + +def activate() -> None: + # The Secret Service is D-Bus activated, bring it up if it isn't already + subprocess.run(['secret-tool', 'lookup', 'kde-linux-openqa', 'probe'], capture_output=True, text=True) + + +def pid() -> int: + out = subprocess.check_output( + ['busctl', '--user', 'status', SECRETS_BUS_NAME], text=True) + for line in out.splitlines(): + if line.strip().startswith('PID='): + return int(line.split('=', 1)[1].strip()) + raise SecretServicePidError(f'could not determine PID owning {SECRETS_BUS_NAME}') + + +def process_exe() -> str: + return os.path.basename(os.readlink(f'/proc/{pid()}/exe')) diff --git a/main.pm b/main.pm index 1e27028..7144909 100755 --- a/main.pm +++ b/main.pm @@ -38,6 +38,8 @@ sub test_live_image { loadtest 'kdelinux/desktop/plasma_welcome.py'; # loadtest 'common/system_settings/disable_screen_lock.py'; loadtest 'kdelinux/system_settings/configure_automatic_login.py'; + loadtest 'kdelinux/desktop/secret_service_persistence_set.py'; + loadtest 'kdelinux/desktop/secret_service_persistence_get.py'; loadtest 'kdelinux/system/collect_logs.py'; loadtest 'common/shutdown.py'; } @@ -61,10 +63,11 @@ sub test_kdelinux { loadtest 'kdelinux/app/package_compatibility_helper.py'; loadtest 'kdelinux/app/discover_install.py'; loadtest 'kdelinux/system/system_development.py'; - loadtest 'kdelinux/system/collect_logs.py'; - loadtest 'kdelinux/system/desktop_session_services.py'; loadtest 'kdelinux/system/logout.py'; loadtest 'kdelinux/sddm/sddm_password_login.py'; + loadtest 'kdelinux/desktop/secret_service_persistence_get.py'; + loadtest 'kdelinux/system/desktop_session_services.py'; + loadtest 'kdelinux/system/collect_logs.py'; loadtest 'common/shutdown.py'; } diff --git a/tests/kdelinux/desktop/secret_service_persistence_get.py b/tests/kdelinux/desktop/secret_service_persistence_get.py new file mode 100644 index 0000000..3f22c6d --- /dev/null +++ b/tests/kdelinux/desktop/secret_service_persistence_get.py @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL +# SPDX-FileCopyrightText: 2026 Thomas Duckworth <[email protected]> +from testapi import * +from lib.test import cli_test +from lib.common import user_manager + +def run(self): + test = cli_test.CliTest('secret_service_persistence_set') + test.run_selenium(user=user_manager.installed()) diff --git a/tests/kdelinux/desktop/secret_service_persistence_set.py b/tests/kdelinux/desktop/secret_service_persistence_set.py new file mode 100644 index 0000000..e5619ec --- /dev/null +++ b/tests/kdelinux/desktop/secret_service_persistence_set.py @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL +# SPDX-FileCopyrightText: 2026 Thomas Duckworth <[email protected]> +from testapi import * +from lib.test import cli_test +from lib.common import user_manager + +def run(self): + test = cli_test.CliTest('secret_service_persistence_set') + test.run_python(user=user_manager.installed())