-
Notifications
You must be signed in to change notification settings - Fork 280
[autobackport: sssd-2-11] Tests: Add integration tests validating SSSD socket #8563
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: sssd-2-11
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,185 @@ | ||||||||
| """ | ||||||||
| SSSD Socket Activation Tests. | ||||||||
|
|
||||||||
| :requirement: sssd_socket | ||||||||
| """ | ||||||||
|
|
||||||||
| from __future__ import annotations | ||||||||
|
|
||||||||
| import pytest | ||||||||
| from sssd_test_framework.roles.client import Client | ||||||||
| from sssd_test_framework.roles.generic import GenericProvider | ||||||||
| from sssd_test_framework.roles.nfs import NFS | ||||||||
| from sssd_test_framework.topology import KnownTopology | ||||||||
|
|
||||||||
|
|
||||||||
| @pytest.mark.importance("high") | ||||||||
| @pytest.mark.topology(KnownTopology.LDAP) | ||||||||
| @pytest.mark.parametrize("responder", ["nss", "pam", "ssh"]) | ||||||||
| def test_socket__responders__socket_activation_lifecycle(client: Client, provider: GenericProvider, responder: str): | ||||||||
| """ | ||||||||
| :title: Socket-Activated Responder Lifecycle | ||||||||
| :description: | | ||||||||
| Verify that socket-activated responders: | ||||||||
| 1. Have their socket unit active | ||||||||
| 2. Have their service unit inactive initially | ||||||||
| 3. Start automatically on first client request via systemd socket activation | ||||||||
| :setup: | ||||||||
| 1. Configure SSSD with socket activation enabled | ||||||||
| 2. Add test user to LDAP backend | ||||||||
| :steps: | ||||||||
| 1. Verify socket unit is active and service unit is inactive | ||||||||
| 2. Trigger first request, service unit becomes active | ||||||||
| :expectedresults: | ||||||||
| 1. Service unit is inactive before first request | ||||||||
| 2. Service unit becomes active after first request | ||||||||
| :customerscenario: False | ||||||||
| """ | ||||||||
| u = provider.user("user1").add(password="Secret123") | ||||||||
|
|
||||||||
| if responder in ["pam", "ssh"]: | ||||||||
| client.sssd.sssd["services"] = "nss" | ||||||||
| else: | ||||||||
| client.sssd.sssd["services"] = "" | ||||||||
|
|
||||||||
| client.sssd.restart(clean=True) | ||||||||
| client.sssd.common.socket_responders([responder]) | ||||||||
|
|
||||||||
| socket_unit = f"sssd-{responder}.socket" | ||||||||
| service_unit = f"sssd-{responder}.service" | ||||||||
|
|
||||||||
| assert client.sssd.svc.is_active(socket_unit), f"{responder} socket should be active" | ||||||||
|
|
||||||||
| if responder == "nss": | ||||||||
| entry = client.tools.getent.passwd(u.name) | ||||||||
| assert entry is not None, f"NSS provider failed for {u.name}" | ||||||||
| assert entry.name == u.name, f"Expected user {u.name}, got {entry.name}" | ||||||||
| elif responder == "pam": | ||||||||
| result = client.auth.ssh.password(u.name, "Secret123") | ||||||||
| assert result, f"PAM authentication failed for {u.name}" | ||||||||
| elif responder == "ssh": | ||||||||
| ssh_result = client.host.conn.run(f"sss_ssh_authorizedkeys {u.name}", raise_on_error=False) | ||||||||
| assert ssh_result.rc == 0, f"SSH authorizedkeys lookup failed for {u.name}" | ||||||||
|
|
||||||||
| assert client.sssd.svc.is_active(service_unit), f"{responder} service should be active after request" | ||||||||
|
|
||||||||
|
|
||||||||
| @pytest.mark.importance("low") | ||||||||
| @pytest.mark.topology(KnownTopology.LDAP) | ||||||||
| def test_socket__responders__socket_activation_lifecycle_autofs(client: Client, provider: GenericProvider, nfs: NFS): | ||||||||
| """ | ||||||||
| :title: Socket-Activated Autofs Responder Lifecycle | ||||||||
| :description: | | ||||||||
| Verify that socket-activated autofs responder: | ||||||||
| 1. Have their socket unit active | ||||||||
| 2. Have their service unit inactive initially | ||||||||
| 3. Start automatically on first client request via systemd socket activation | ||||||||
| :setup: | ||||||||
| 1. Configure SSSD with socket activation enabled | ||||||||
| 2. Add test user and autofs maps to LDAP backend | ||||||||
| :steps: | ||||||||
| 1. Verify socket unit is active and service unit is inactive | ||||||||
| 2. Trigger first autofs request, service unit becomes active | ||||||||
| :expectedresults: | ||||||||
| 1. Service unit is inactive before first request | ||||||||
| 2. Service unit becomes active after first request | ||||||||
| :customerscenario: False | ||||||||
| """ | ||||||||
| responder = "autofs" | ||||||||
|
|
||||||||
| nfs_export = nfs.export("export").add() | ||||||||
| auto_master = provider.automount.map("auto.master").add() | ||||||||
| auto_export = provider.automount.map("auto.export").add() | ||||||||
| auto_master.key("/var/export").add(info=auto_export) | ||||||||
| auto_export.key("export").add(info=nfs_export) | ||||||||
|
|
||||||||
| client.sssd.sssd["services"] = "" | ||||||||
| client.sssd.restart(clean=True) | ||||||||
| client.sssd.common.socket_responders([responder]) | ||||||||
|
|
||||||||
| socket_unit = f"sssd-{responder}.socket" | ||||||||
| service_unit = f"sssd-{responder}.service" | ||||||||
|
|
||||||||
| assert client.sssd.svc.is_active(socket_unit), f"{responder} socket should be active" | ||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The test's description and steps state that it should verify that the service unit is inactive initially. This assertion is currently missing. Please add it to ensure the test fully validates the socket activation lifecycle.
Suggested change
|
||||||||
|
|
||||||||
| client.automount.reload() | ||||||||
| result = client.automount.mount("/var/export/export", nfs_export) | ||||||||
| assert result, "AUTOFS mount failed for /var/export/export" | ||||||||
|
|
||||||||
| assert client.sssd.svc.is_active(service_unit), f"{responder} service should be active after request" | ||||||||
|
|
||||||||
|
|
||||||||
| @pytest.mark.importance("low") | ||||||||
| @pytest.mark.topology(KnownTopology.LDAP) | ||||||||
| @pytest.mark.parametrize("socket_responder", ["nss", "ssh"]) | ||||||||
| def test_socket__responders__mixed_socket_and_traditional_services( | ||||||||
| client: Client, provider: GenericProvider, socket_responder: str | ||||||||
| ): | ||||||||
| """ | ||||||||
| :title: Mixed Socket-Activated and Traditional Services (NSS/SSH) | ||||||||
| :description: | | ||||||||
| Verify that some responders can be socket-activated while others run as traditional services | ||||||||
| :setup: | ||||||||
| 1. Configure mixed socket-activated and traditional services | ||||||||
| 2. Add test user to LDAP backend | ||||||||
| :steps: | ||||||||
| 1. Verify socket unit is active and service unit is inactive for socket-activated responder | ||||||||
| 2. Verify traditional responder is configured in services | ||||||||
| 3. Trigger request for socket-activated responder | ||||||||
| 4. Verify its service unit becomes active | ||||||||
| :expectedresults: | ||||||||
| 1. Socket-activated responder is inactive before request | ||||||||
| 2. Traditional responder is configured in traditional mode | ||||||||
| 3. Request triggered for socket-activated responder | ||||||||
| 4. Socket-activated responder starts automatically on first request | ||||||||
| :customerscenario: False | ||||||||
| """ | ||||||||
| u = provider.user("user1").add(password="Secret123") | ||||||||
|
|
||||||||
| if socket_responder == "nss": | ||||||||
| traditional_responder = "ssh" | ||||||||
| else: | ||||||||
| traditional_responder = "nss" | ||||||||
|
|
||||||||
| client.sssd.sssd["services"] = traditional_responder | ||||||||
| client.sssd.restart(clean=True) | ||||||||
|
|
||||||||
| client.sssd.common.socket_responders([socket_responder]) | ||||||||
|
|
||||||||
| socket_unit = f"sssd-{socket_responder}.socket" | ||||||||
| socket_service = f"sssd-{socket_responder}.service" | ||||||||
|
|
||||||||
| assert client.sssd.svc.is_active(socket_unit), f"{socket_responder} socket should be active" | ||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The test's description and steps state that it should verify that the service unit is inactive initially for the socket-activated responder. This assertion is currently missing. Please add it to ensure the test fully validates the socket activation lifecycle.
Suggested change
|
||||||||
|
|
||||||||
| if socket_responder == "nss": | ||||||||
| client.tools.getent.passwd(u.name) | ||||||||
| elif socket_responder == "ssh": | ||||||||
| client.host.conn.run(f"sss_ssh_authorizedkeys {u.name}", raise_on_error=False) | ||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The result of this command is not checked. The test may pass even if the
Suggested change
|
||||||||
|
|
||||||||
| assert client.sssd.svc.is_active(socket_service), f"{socket_responder} service should be active after request" | ||||||||
|
|
||||||||
|
|
||||||||
| @pytest.mark.importance("low") | ||||||||
| @pytest.mark.topology(KnownTopology.Client) | ||||||||
| def test_socket__responders__conflict_socket_and_traditional_config(client: Client): | ||||||||
| """ | ||||||||
| :title: Conflict when responder is both in sssd.conf and socket-activated | ||||||||
| :description: | | ||||||||
| Verify that socket activated 'sssd_nss' refuses to start when a responder is | ||||||||
| configured both in the services line and also enabled for socket activation, as | ||||||||
| this creates a configuration conflict. | ||||||||
| :setup: | ||||||||
| 1. Configure SSSD with NSS responder in services line | ||||||||
| :steps: | ||||||||
| 1. Add NSS to services line in sssd.conf and attempt to enable socket activation for NSS | ||||||||
| :expectedresults: | ||||||||
| 1. socket_responders() raises an exception or logs error | ||||||||
| :customerscenario: False | ||||||||
| """ | ||||||||
| client.sssd.common.local() | ||||||||
|
|
||||||||
| client.sssd.sssd["services"] = "nss" | ||||||||
| client.sssd.restart(clean=True) | ||||||||
|
|
||||||||
| with pytest.raises(Exception, match="Misconfiguration found for the 'nss' responder"): | ||||||||
| client.sssd.common.socket_responders(["nss"]) | ||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This section of the test has two issues:
Test Duplication: The test cases for 'pam' and 'ssh' are testing a mixed-mode scenario where 'nss' runs as a traditional service. This duplicates the scenario tested in
test_socket__responders__mixed_socket_and_traditional_servicesfor the 'ssh' responder. To improve test coverage and avoid duplication, this test should be updated to a 'pure' socket-activation scenario where 'nss' is also socket-activated when testing 'pam' or 'ssh'.Missing Assertion: The test description states that the service unit should be checked for inactivity initially, but this check is missing.
The suggested code refactors the test to address both points. It sets up a pure socket-activation environment and adds the missing check for initial service inactivity. You will also need to update the assertions at the end of the test to verify that all relevant services become active after the request.