Skip to content

Commit 531cd25

Browse files
committed
tests: Add an environment sync test to TC_20_NonAudio
Multiple bugs in Qubes have been the result of the either the user session or the systemd user manager missing environment variables that were set in /etc/profile.d (see Qubes issues #10299, #10712, #10759). We now have code that syncs the environment from the systemd user manager into a user session, and vice versa. Add tests that ensure environment variables are being synced both ways without clobbering values that are supposed to be augmented.
1 parent 2488f2b commit 531cd25

1 file changed

Lines changed: 109 additions & 0 deletions

File tree

qubes/tests/integ/vm_qrexec_gui.py

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import qubes.tests
3333
import qubes.vm.appvm
3434
import qubes.vm.templatevm
35+
import qubes.vm.standalonevm
3536

3637
in_qemu = os.path.exists("/sys/firmware/qemu_fw_cfg")
3738

@@ -930,6 +931,114 @@ async def _test_400_long_window_title(self, utf8=False):
930931
except ProcessLookupError: # already dead
931932
pass
932933

934+
def test_500_gui_agent_env_sync(self):
935+
# Create a StandaloneVM so changes made to it will survive a reboot
936+
self.env_sync_vm = self.app.add_new_vm(
937+
qubes.vm.standalonevm.StandaloneVM,
938+
label="red",
939+
name=self.make_vm_name("envsync"),
940+
)
941+
self.env_sync_vm.clone_properties(self.app.domains[self.template])
942+
self.env_sync_vm.features.update(
943+
self.app.domains[self.template].features
944+
)
945+
self.loop.run_until_complete(
946+
self.env_sync_vm.clone_disk_files(self.app.domains[self.template])
947+
)
948+
self.env_sync_vm.provides_network = True
949+
self.app.save()
950+
951+
# Create a user environment generator and profile script that will
952+
# both modify the same environment variable
953+
self.loop.run_until_complete(self.env_sync_vm.start())
954+
self.assertEqual(self.env_sync_vm.get_power_state(), "Running")
955+
self.loop.run_until_complete(self.wait_for_session(self.env_sync_vm))
956+
957+
try:
958+
self.loop.run_until_complete(
959+
self.env_sync_vm.run_for_stdio(
960+
"printf '%s\\n' "
961+
+ "'#!/bin/bash' "
962+
+ "'echo QUBES_ENV_TEST=first' "
963+
+ "| sudo tee "
964+
+ "/usr/lib/systemd/user-environment-generators/90-test"
965+
)
966+
)
967+
except subprocess.CalledProcessError:
968+
self.fail("cannot create user environment generator")
969+
970+
try:
971+
self.loop.run_until_complete(
972+
self.env_sync_vm.run_for_stdio(
973+
"printf '%s\\n' "
974+
+ "'#!/bin/bash' "
975+
+ "'QUBES_ENV_TEST=\"${QUBES_ENV_TEST}:second\"' "
976+
+ "'export QUBES_ENV_TEST' "
977+
+ "| sudo tee /etc/profile.d/ztest.sh"
978+
)
979+
)
980+
except subprocess.CalledProcessError:
981+
self.fail("cannot create profile.d script")
982+
983+
try:
984+
self.loop.run_until_complete(
985+
self.env_sync_vm.run_for_stdio(
986+
"sudo chmod +x "
987+
+ "/usr/lib/systemd/user-environment-generators/90-test "
988+
+ "/etc/profile.d/ztest.sh"
989+
)
990+
)
991+
except subprocess.CalledProcessError:
992+
self.fail("cannot mark scripts executable")
993+
994+
self.loop.run_until_complete(self.env_sync_vm.shutdown(wait=True))
995+
self.assertEqual(self.env_sync_vm.get_power_state(), "Halted")
996+
997+
# Get the value of QUBES_ENV_TEST from a user session and ensure it is
998+
# equal to 'first:second', indicating that the environment has been
999+
# synced from systemd into the session
1000+
self.loop.run_until_complete(self.env_sync_vm.start())
1001+
self.assertEqual(self.env_sync_vm.get_power_state(), "Running")
1002+
self.loop.run_until_complete(self.wait_for_session(self.env_sync_vm))
1003+
1004+
try:
1005+
stdout, _ = self.loop.run_until_complete(
1006+
self.env_sync_vm.run_for_stdio(
1007+
'printf "%s\\n" "$QUBES_ENV_TEST"'
1008+
)
1009+
)
1010+
except subprocess.CalledProcessError as e:
1011+
self.fail(
1012+
"could not get value of QUBES_ENV_TEST variable: {}".format(
1013+
e.stderr
1014+
)
1015+
)
1016+
if stdout != "first:second":
1017+
self.fail(
1018+
"unexpected QUBES_ENV_TEST value from session, "
1019+
+ "got '{}', expected 'first:second'".format(stdout)
1020+
)
1021+
1022+
## Make sure the systemd user manager has the variable set properly too
1023+
try:
1024+
stdout, _ = self.loop.run_until_complete(
1025+
self.env_sync_vm.run_for_stdio(
1026+
"systemctl --user show-environment "
1027+
+ "| grep '^QUBES_ENV_TEST=' "
1028+
+ "| cut -d'=' -f2"
1029+
)
1030+
)
1031+
except subprocess.CalledProcessError as e:
1032+
self.fail(
1033+
"could not get value of QUBES_ENV_TEST from systemd user "
1034+
+ "manager: {}".format(e.stderr)
1035+
)
1036+
if stdout != "first:second":
1037+
self.fail(
1038+
"unexpected QUBES_ENV_TEST value from systemd user manager, "
1039+
+ "got '{}', expected 'first:second'".format(stdout)
1040+
)
1041+
9331042

9341043
class TC_10_Generic(qubes.tests.SystemTestCase):
9351044
def setUp(self):

0 commit comments

Comments
 (0)