Files
DroidDeck/tools/tests/test_seed_redists.py
K11MCH1 b7b08a40e8 Steam: EA games install the EA app (#2036)
The redistributable seeder marks every process in a game's install scripts
as already run, except Vulkan runtime and Ubisoft Connect installers. EA
games on Steam list the EA app installer (EADesktopSetup) there and start
through steam2ea://, which only the EA app handles. With the installer
skipped, Proton could not open that link (ret 31) and the game closed
without a window (Burnout Paradise Remastered). The EA app installer is
now left to run like Ubisoft Connect's, and a marker an earlier seeding
wrote is taken back out, so an existing prefix installs it on its next
launch.
2026-11-03 07:41:01 -05:00

455 lines
22 KiB
Python

import os
import shutil
import subprocess
import tempfile
import unittest
from pathlib import Path
SCRIPT = Path(__file__).resolve().parents[1] / "linuxfs/overlay/usr/local/bin/droiddeck-seed-redists"
GAME_SCRIPT = r'''"InstallScript"
{
"Run Process"
{
"VCRedist2022"
{
"HasRunKey" "HKEY_LOCAL_MACHINE\\Software\\Valve\\Steam\\Apps\\CommonRedist\\vcredist\\2022"
"process 1" "%INSTALLDIR%\\_CommonRedist\\vcredist\\2022\\VC_redist.x64.exe"
"command 1" "/q /norestart"
"NoCleanUp" "1"
}
}
}
'''
VULKAN_SCRIPT = r'''"InstallScript"
{
"Run Process"
{
"Vulkan111080"
{
"HasRunKey" "HKEY_LOCAL_MACHINE\\Software\\Valve\\Steam\\Apps\\1174180"
"process 1" "%INSTALLDIR%\\Redistributables\\VulkanRT-1.1.108.0-Installer.exe"
"command 1" "/S"
"NoCleanUp" "0"
}
"RockstarLauncher"
{
"HasRunKey" "HKEY_LOCAL_MACHINE\\Software\\Rockstar Games\\Steam\\Launcher"
"process 1" "%INSTALLDIR%\\Redistributables\\Rockstar-Games-Launcher.exe"
"command 1" "/s /t"
"NoCleanUp" "0"
}
}
}
'''
UBISOFT_SCRIPT = r'''"installscript"
{
"Run Process"
{
"Ubisoft Connect PC Client"
{
"process 1" "%INSTALLDIR%\\UbisoftConnectInstaller.exe"
"command 1" "/S"
}
"easyanticheat"
{
"HasRunKey" "HKEY_CURRENT_USER\\SOFTWARE\\Ubisoft\\WatchDogs2EAC"
"process 1" "%INSTALLDIR%\\EasyAntiCheat\\InstallWD2EAC.cmd"
"command 1" ""
}
}
}
'''
EA_SCRIPT = r'''"installscript"
{
"Run Process"
{
"EADesktopSetup"
{
"process 1" "%INSTALLDIR%\\__Installer\\Origin\\redist\\internal\\EAappInstaller.exe"
"command 1" "EAX_LAUNCH_CLIENT=0 IGNORE_INSTALLED=1"
"HasRunStringKey" "HKEY_LOCAL_MACHINE\\SOFTWARE\\Electronic Arts\\EA Desktop\\InstallSuccessful"
"HasRunStringValue" "true"
"RunType" "1"
}
"Windows6.1-KB2670838-x64.msu"
{
"process 1" "%INSTALLDIR%\\__Installer\\customcomponent\\patch_KB2670838_x64\\Windows6.1-KB2670838-x64.msu"
"command 1" "/quiet"
"Requirement_OS"
{
"OSType" "Windows 7"
}
}
}
}
'''
class SeedRedistsTest(unittest.TestCase):
def setUp(self):
self.tmp = Path(tempfile.mkdtemp())
self.addCleanup(shutil.rmtree, self.tmp, True)
self.steam = self.tmp / "Steam"
self.reg = self.steam / "steamapps/compatdata/1234/pfx/system.reg"
self.reg.parent.mkdir(parents=True)
self.reg.write_text("WINE REGISTRY Version 2\n")
self.user = self.reg.with_name("user.reg")
self.user.write_text('WINE REGISTRY Version 2\n\n[Software\\\\Unrelated] 1\n"Keep"="untouched"\n')
def game(self, name="Some Game", script=GAME_SCRIPT, library=None):
root = Path(library or self.steam)
path = root / "steamapps/common" / name / "_CommonRedist/vcredist/2022/installscript.vdf"
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(script)
manifest = root / "steamapps" / ("appmanifest_%d.acf" % (abs(hash(name)) % 100000))
manifest.write_text('"AppState" { "installdir" "%s" }' % name)
return path
def run_seed(self, libraries=""):
env = dict(os.environ, DROIDDECK_LIBRARIES=libraries)
return subprocess.run(["bash", str(SCRIPT), str(self.steam)], env=env, capture_output=True, text=True, check=True)
def test_a_games_own_install_script_is_marked_as_run(self):
self.game()
self.run_seed()
reg = self.reg.read_text()
self.assertIn("[Software\\\\Valve\\\\Steam\\\\Apps\\\\CommonRedist\\\\vcredist\\\\2022]", reg)
self.assertIn("[Software\\\\Wow6432Node\\\\Valve\\\\Steam\\\\Apps\\\\CommonRedist\\\\vcredist\\\\2022]", reg)
self.assertIn('"VCRedist2022"=dword:00000001', reg)
def test_games_in_other_libraries_are_read(self):
sd = self.tmp / "sd"
self.game(library=sd)
self.run_seed(str(sd))
self.assertIn('"VCRedist2022"=dword:00000001', self.reg.read_text())
def test_current_user_and_machine_markers_go_to_their_own_registries(self):
self.game(script=GAME_SCRIPT + GAME_SCRIPT.replace("HKEY_LOCAL_MACHINE", "HKEY_CURRENT_USER").replace("VCRedist2022", "UserRedist"))
with self.reg.open("a") as out:
out.write('\n[Software\\\\Unrelated] 1\n"Keep"="machine"\n')
for reg in (self.reg, self.user):
os.utime(reg, ns=(1_000_000_000_123456789, 1_000_000_000_123456789))
self.run_seed()
system, user = self.reg.read_text(), self.user.read_text()
self.assertEqual(system.count('"VCRedist2022"=dword:00000001'), 2)
self.assertNotIn("UserRedist", system)
self.assertEqual(user.count('"UserRedist"=dword:00000001'), 1)
self.assertNotIn("Wow6432Node", user)
self.assertNotIn("VCRedist2022", user)
self.assertIn('"Keep"="machine"', system)
self.assertIn('"Keep"="untouched"', user)
self.run_seed()
self.assertEqual(system, self.reg.read_text())
self.assertEqual(user, self.user.read_text())
for reg in (self.reg, self.user):
self.assertEqual(reg.stat().st_mtime_ns, 1_000_000_000_123456789)
def test_a_user_marker_with_the_same_machine_path_and_value_is_separate(self):
self.game(script=GAME_SCRIPT + GAME_SCRIPT.replace("HKEY_LOCAL_MACHINE", "HKEY_CURRENT_USER"))
self.run_seed()
system = self.reg.read_text()
self.assertEqual(self.user.read_text().count('"VCRedist2022"=dword:00000001'), 1)
self.user.write_text("WINE REGISTRY Version 2\n")
self.run_seed()
self.assertEqual(self.user.read_text().count('"VCRedist2022"=dword:00000001'), 1)
self.assertEqual(system, self.reg.read_text())
def test_a_legacy_user_ledger_entry_is_checked_in_user_reg(self):
self.game(script=GAME_SCRIPT.replace("HKEY_LOCAL_MACHINE", "HKEY_CURRENT_USER"))
self.run_seed()
system = self.reg.read_bytes()
self.user.write_text("WINE REGISTRY Version 2\n")
(self.reg.parent / ".droiddeck-redists-checked").write_text(subprocess.check_output(["stat", "-c", "%i %s %.9Y", str(self.reg)], text=True))
self.run_seed()
self.assertEqual(self.user.read_text().count('"VCRedist2022"=dword:00000001'), 1)
self.assertEqual(system, self.reg.read_bytes())
def test_an_absent_user_registry_is_not_created_or_claimed(self):
self.game(script=GAME_SCRIPT + GAME_SCRIPT.replace("HKEY_LOCAL_MACHINE", "HKEY_CURRENT_USER").replace("VCRedist2022", "UserRedist"))
self.user.unlink()
self.run_seed()
self.assertFalse(self.user.exists())
self.assertNotIn("UserRedist", (self.reg.parent / ".droiddeck-redists").read_text())
self.assertEqual(self.reg.read_text().count('"VCRedist2022"=dword:00000001'), 2)
system = self.reg.read_bytes()
self.user.write_text("WINE REGISTRY Version 2\n")
self.run_seed()
self.assertIn('"UserRedist"=dword:00000001', self.user.read_text())
self.run_seed()
self.user.unlink()
self.run_seed()
self.assertFalse(self.user.exists())
self.assertNotIn("UserRedist", (self.reg.parent / ".droiddeck-redists").read_text())
self.assertEqual(system, self.reg.read_bytes())
@unittest.skipIf(os.name == "posix" and os.geteuid() == 0, "root can write through read-only mode bits")
def test_an_unwritable_user_registry_does_not_claim_a_missing_marker(self):
self.game(script=GAME_SCRIPT + GAME_SCRIPT.replace("HKEY_LOCAL_MACHINE", "HKEY_CURRENT_USER").replace("VCRedist2022", "UserRedist"))
ledger = self.reg.parent / ".droiddeck-redists"
ledger.write_text("HKEY_CURRENT_USER\\\\Software\\\\Valve\\\\Steam\\\\Apps\\\\CommonRedist\\\\vcredist\\\\2022\tUserRedist\n")
user = self.user.read_bytes()
self.user.chmod(0o444)
try:
self.run_seed()
self.assertEqual(user, self.user.read_bytes())
self.assertEqual(self.user.stat().st_mode & 0o777, 0o444)
self.assertNotIn("UserRedist", ledger.read_text())
self.assertEqual(self.reg.read_text().count('"VCRedist2022"=dword:00000001'), 2)
finally:
self.user.chmod(0o644)
def test_user_markers_in_a_default_prefix_and_another_library_are_seeded(self):
default = self.steam / "steamapps/common/Proton Test/files/share/default_pfx"
default.mkdir(parents=True)
for name in ("system.reg", "user.reg"):
(default / name).write_text("WINE REGISTRY Version 2\n")
sd = self.tmp / "sd"
self.game(library=sd, script=GAME_SCRIPT.replace("HKEY_LOCAL_MACHINE", "HKEY_CURRENT_USER"))
self.run_seed(str(sd))
self.assertIn('"VCRedist2022"=dword:00000001', (default / "user.reg").read_text())
self.assertNotIn('"VCRedist2022"', (default / "system.reg").read_text())
self.assertIn('"VCRedist2022"=dword:00000001', self.user.read_text())
def test_the_vc_runtime_is_recorded_for_every_architecture_and_view(self):
self.run_seed()
reg = self.reg.read_text()
for view in ("Software", "Software\\\\Wow6432Node"):
for arch in ("x86", "x64", "arm64"):
self.assertIn("[%s\\\\Microsoft\\\\VisualStudio\\\\14.0\\\\VC\\\\Runtimes\\\\%s]" % (view, arch), reg)
self.assertIn('"Installed"=dword:00000001', reg)
self.assertIn('"Major"=dword:0000000e', reg)
self.assertIn('"Version"="v14.51.36247.00"', reg)
def test_a_seeded_prefix_is_left_alone_until_a_game_changes(self):
self.run_seed()
once = self.reg.read_text()
self.run_seed()
self.assertEqual(once, self.reg.read_text())
self.game()
self.run_seed()
self.assertIn('"VCRedist2022"=dword:00000001', self.reg.read_text())
def test_markers_a_replaced_registry_lost_are_seeded_again(self):
self.game()
stock = self.reg.read_text()
self.run_seed()
ledger = (self.reg.parent / ".droiddeck-redists").read_text()
self.assertIn("VCRedist2022", ledger)
self.reg.write_text(stock)
self.run_seed()
reg = self.reg.read_text()
self.assertEqual(reg.count('"VCRedist2022"=dword:00000001'), 2, "both views again")
self.assertIn("[Software\\\\Microsoft\\\\VisualStudio\\\\14.0\\\\VC\\\\Runtimes\\\\x86]", reg)
self.assertEqual(sorted((self.reg.parent / ".droiddeck-redists").read_text().splitlines()), sorted(ledger.splitlines()))
self.run_seed()
self.assertEqual(reg, self.reg.read_text())
def test_a_marker_kept_in_only_one_view_is_seeded_again(self):
self.game()
self.run_seed()
wow = "[Software\\\\Wow6432Node\\\\Valve\\\\Steam\\\\Apps\\\\CommonRedist\\\\vcredist\\\\2022]"
blocks = self.reg.read_text().split("\n\n")
self.reg.write_text("\n\n".join(b for b in blocks if not (b.startswith(wow) and '"VCRedist2022"' in b)))
self.assertEqual(self.reg.read_text().count('"VCRedist2022"'), 1)
self.run_seed()
reg = self.reg.read_text()
self.assertEqual(reg.count('"VCRedist2022"'), 3, "the one left plus both views again")
self.assertTrue(any(b.startswith(wow) and '"VCRedist2022"' in b for b in reg.split("\n\n")))
def test_a_vc_runtime_another_architecture_lost_is_seeded_again(self):
self.run_seed()
arm64 = "[Software\\\\Wow6432Node\\\\Microsoft\\\\VisualStudio\\\\14.0\\\\VC\\\\Runtimes\\\\arm64]"
blocks = self.reg.read_text().split("\n\n")
self.reg.write_text("\n\n".join(b for b in blocks if not b.startswith(arm64)))
self.assertNotIn(arm64, self.reg.read_text())
self.run_seed()
reg = self.reg.read_text()
self.assertIn(arm64, reg)
self.assertEqual(reg.count("[Software\\\\Microsoft\\\\VisualStudio\\\\14.0\\\\VC\\\\Runtimes\\\\x86]"), 2)
def test_a_marker_written_in_one_view_only_is_kept_as_it_is(self):
self.game(script=GAME_SCRIPT.replace("Software\\\\Valve\\\\Steam\\\\Apps\\\\CommonRedist\\\\vcredist\\\\2022", "SOFTWARE\\\\AGEIA Technologies").replace("VCRedist2022", "PhysX Version"))
self.run_seed()
once = self.reg.read_text()
self.assertEqual(once.count('"PhysX Version"=dword:00000001'), 1)
result = self.run_seed()
self.assertEqual(once, self.reg.read_text())
self.assertNotIn("gone", result.stdout)
def test_an_evaluator_script_nested_deeper_is_read(self):
script = self.tmp / "legacycompat/evaluatorscript_409710.vdf"
script.parent.mkdir(parents=True)
script.write_text('"evaluatorscript"\n{\n\t"1"\n' + "\n".join("\t" + line for line in GAME_SCRIPT.replace("VCRedist2022", "x64 14.99.1.0").splitlines()) + "\n}\n")
env = dict(os.environ, DROIDDECK_LIBRARIES="", DROIDDECK_SEED_SCRIPTS=str(script))
subprocess.run(["bash", str(SCRIPT), str(self.steam)], env=env, capture_output=True, text=True, check=True)
self.assertIn('"x64 14.99.1.0"=dword:00000001', self.reg.read_text())
def test_an_unchanged_registry_is_not_read_again(self):
self.game(script=GAME_SCRIPT + GAME_SCRIPT.replace("HKEY_LOCAL_MACHINE", "HKEY_CURRENT_USER").replace("VCRedist2022", "UserRedist"))
self.run_seed()
self.run_seed()
shim = self.tmp / "bin"
shim.mkdir()
log = self.tmp / "awk.log"
(shim / "awk").write_text('#!/bin/sh\nprintf "%%s\\n" "$*" >> "%s"\nexec %s "$@"\n' % (log, shutil.which("awk")))
(shim / "awk").chmod(0o755)
env = dict(os.environ, DROIDDECK_LIBRARIES="", PATH="%s:%s" % (shim, os.environ["PATH"]))
once = self.reg.read_text()
user = self.user.read_text()
subprocess.run(["bash", str(SCRIPT), str(self.steam)], env=env, capture_output=True, text=True, check=True)
self.assertEqual(once, self.reg.read_text())
self.assertEqual(user, self.user.read_text())
self.assertNotIn(str(self.reg), log.read_text() if log.exists() else "")
self.assertNotIn(str(self.user), log.read_text() if log.exists() else "")
replaced = self.user.with_name("user.reg.new")
replaced.write_text(user.replace('"UserRedist"', '"OtherValue"'))
os.utime(replaced, ns=(self.user.stat().st_atime_ns, self.user.stat().st_mtime_ns))
self.assertEqual(replaced.stat().st_size, self.user.stat().st_size)
os.replace(replaced, self.user)
subprocess.run(["bash", str(SCRIPT), str(self.steam)], env=env, capture_output=True, text=True, check=True)
self.assertEqual(self.user.read_text().count('"UserRedist"=dword:00000001'), 1)
self.assertIn('"OtherValue"=dword:00000001', self.user.read_text())
self.assertEqual(once, self.reg.read_text())
replaced = self.reg.with_name("system.reg.new")
replaced.write_text("WINE REGISTRY Version 2\n")
os.replace(replaced, self.reg)
subprocess.run(["bash", str(SCRIPT), str(self.steam)], env=env, capture_output=True, text=True, check=True)
self.assertEqual(self.reg.read_text().count('"VCRedist2022"=dword:00000001'), 2)
def test_the_prefix_date_is_kept(self):
os.utime(self.reg, (1_000_000_000, 1_000_000_000))
self.run_seed()
self.assertEqual(int(self.reg.stat().st_mtime), 1_000_000_000)
def rdr2(self):
path = self.steam / "steamapps/common/Red Dead Redemption 2/installscript.vdf"
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(VULKAN_SCRIPT)
(self.steam / "steamapps/appmanifest_1174180.acf").write_text('"AppState" { "installdir" "Red Dead Redemption 2" }')
def test_a_vulkan_runtime_installer_is_left_to_run(self):
self.rdr2()
self.run_seed()
reg = self.reg.read_text()
self.assertNotIn("Vulkan111080", reg)
self.assertIn('"RockstarLauncher"=dword:00000001', reg)
self.assertNotIn("Vulkan111080", (self.reg.parent / ".droiddeck-redists").read_text())
def test_a_current_user_vulkan_installer_is_left_to_run(self):
self.game(script=VULKAN_SCRIPT.replace("HKEY_LOCAL_MACHINE", "HKEY_CURRENT_USER"))
self.run_seed()
self.assertIn('"RockstarLauncher"=dword:00000001', self.user.read_text())
self.assertNotIn("Vulkan111080", self.user.read_text())
self.assertNotIn("Vulkan111080", self.reg.read_text())
self.assertNotIn("Vulkan111080", (self.reg.parent / ".droiddeck-redists").read_text())
def test_a_current_user_vulkan_marker_comes_out_of_only_its_own_hive(self):
self.game(script=VULKAN_SCRIPT.replace("HKEY_LOCAL_MACHINE", "HKEY_CURRENT_USER"))
self.run_seed()
system = self.reg.read_bytes() + b'\n[Software\\\\Valve\\\\Steam\\\\Apps\\\\1174180] 1\n"Vulkan111080"=dword:00000001\n'
self.reg.write_bytes(system)
with self.user.open("a") as out:
out.write('\n[Software\\\\Valve\\\\Steam\\\\Apps\\\\1174180] 1\n"Other"="keep"\n"Vulkan111080"=dword:00000001\n'
'\n[Software\\\\Wow6432Node\\\\Valve\\\\Steam\\\\Apps\\\\1174180] 1\n"Vulkan111080"=dword:00000001\n'
'\n[Software\\\\Valve\\\\Steam\\\\Apps\\\\22380] 1\n"Vulkan111080"=dword:00000001\n')
with (self.reg.parent / ".droiddeck-redists").open("a") as out:
out.write("HKEY_CURRENT_USER\\\\Software\\\\Valve\\\\Steam\\\\Apps\\\\1174180\tVulkan111080\n")
os.utime(self.user, ns=(1_000_000_000_123456789, 1_000_000_000_123456789))
self.run_seed()
user = self.user.read_text()
self.assertEqual(user.count('"Vulkan111080"'), 2, "the other path and the unseeded user view stay")
self.assertIn('"Other"="keep"', user)
self.assertEqual(system, self.reg.read_bytes())
self.assertNotIn("Vulkan111080", (self.reg.parent / ".droiddeck-redists").read_text())
self.assertEqual(self.user.stat().st_mtime_ns, 1_000_000_000_123456789)
with self.user.open("a") as out:
out.write('\n[Software\\\\Valve\\\\Steam\\\\Apps\\\\1174180] 1\n"Vulkan111080"=dword:00000001\n')
user = self.user.read_bytes()
self.run_seed()
self.assertEqual(user, self.user.read_bytes())
def test_a_vulkan_marker_an_earlier_seeding_wrote_comes_out_once(self):
self.rdr2()
marker = "HKEY_LOCAL_MACHINE\\\\Software\\\\Valve\\\\Steam\\\\Apps\\\\1174180\tVulkan111080"
self.reg.write_text(
"WINE REGISTRY Version 2\n"
"\n[Software\\\\Valve\\\\Steam\\\\Apps\\\\1174180] 1791729070\n#time=1dd598d29161f72\n"
'"Other"=dword:00000001\n"Vulkan111080"=dword:00000001\n'
"\n[Software\\\\Wow6432Node\\\\Valve\\\\Steam\\\\Apps\\\\1174180] 1791729070\n"
'"Vulkan111080"=dword:00000001\n'
"\n[Software\\\\Valve\\\\Steam\\\\Apps\\\\22380] 1791311644\n"
'"Vulkan111080"=dword:00000001\n')
(self.reg.parent / ".droiddeck-redists").write_text(marker + "\n")
os.utime(self.reg, (1_000_000_000, 1_000_000_000))
self.run_seed()
reg = self.reg.read_text()
self.assertEqual(reg.count('"Vulkan111080"'), 1, "only the other app's value stays")
self.assertIn('"Other"=dword:00000001', reg)
self.assertNotIn("Vulkan111080", (self.reg.parent / ".droiddeck-redists").read_text())
self.assertEqual(int(self.reg.stat().st_mtime), 1_000_000_000)
with self.reg.open("a") as out:
out.write('\n[Software\\\\Valve\\\\Steam\\\\Apps\\\\1174180] 1791730000\n"Vulkan111080"=dword:00000001\n')
self.run_seed()
self.assertEqual(self.reg.read_text().count('"Vulkan111080"'), 2)
def evaluator(self, appid, install_script):
script = self.tmp / ("legacycompat/evaluatorscript_%s.vdf" % appid)
script.parent.mkdir(parents=True)
script.write_text('"evaluatorscript"\n{\n\t"appid"\t\t"%s"\n\t"1"\n' % appid
+ "\n".join("\t" + line for line in install_script.splitlines()) + "\n}\n")
env = dict(os.environ, DROIDDECK_LIBRARIES="", DROIDDECK_SEED_SCRIPTS=str(script))
return subprocess.run(["bash", str(SCRIPT), str(self.steam)], env=env, capture_output=True, text=True, check=True)
def ubisoft(self):
return self.evaluator("447040", UBISOFT_SCRIPT)
def test_the_ubisoft_connect_installer_is_left_to_run(self):
self.ubisoft()
self.assertIn('"easyanticheat"=dword:00000001', self.user.read_text())
self.assertNotIn("Ubisoft Connect PC Client", self.reg.read_text())
self.assertNotIn("Ubisoft Connect PC Client", (self.reg.parent / ".droiddeck-redists").read_text())
def test_a_ubisoft_connect_marker_an_earlier_seeding_wrote_comes_out(self):
marker = "HKEY_LOCAL_MACHINE\\\\Software\\\\Valve\\\\Steam\\\\Apps\\\\447040\tUbisoft Connect PC Client"
self.reg.write_text(
"WINE REGISTRY Version 2\n"
"\n[Software\\\\Valve\\\\Steam\\\\Apps\\\\447040] 1791729070\n"
'"Ubisoft Connect PC Client"=dword:00000001\n'
"\n[Software\\\\Wow6432Node\\\\Valve\\\\Steam\\\\Apps\\\\447040] 1791729070\n"
'"Ubisoft Connect PC Client"=dword:00000001\n')
(self.reg.parent / ".droiddeck-redists").write_text(marker + "\n")
result = self.ubisoft()
self.assertNotIn("Ubisoft Connect PC Client", self.reg.read_text())
self.assertNotIn("Ubisoft Connect PC Client", (self.reg.parent / ".droiddeck-redists").read_text())
self.assertIn("Ubisoft Connect and EA app markers out", result.stdout)
def test_the_ea_app_installer_is_left_to_run(self):
self.evaluator("1238080", EA_SCRIPT)
reg = self.reg.read_text()
self.assertNotIn("EADesktopSetup", reg)
self.assertEqual(reg.count('"Windows6.1-KB2670838-x64.msu"=dword:00000001'), 2)
self.assertNotIn("EADesktopSetup", (self.reg.parent / ".droiddeck-redists").read_text())
def test_an_ea_app_marker_an_earlier_seeding_wrote_comes_out(self):
marker = "HKEY_LOCAL_MACHINE\\\\Software\\\\Valve\\\\Steam\\\\Apps\\\\1238080\tEADesktopSetup"
self.reg.write_text(
"WINE REGISTRY Version 2\n"
"\n[Software\\\\Valve\\\\Steam\\\\Apps\\\\1238080] 1793680524\n"
'"EADesktopSetup"=dword:00000001\n'
"\n[Software\\\\Wow6432Node\\\\Valve\\\\Steam\\\\Apps\\\\1238080] 1793680524\n"
'"EADesktopSetup"=dword:00000001\n')
(self.reg.parent / ".droiddeck-redists").write_text(marker + "\n")
result = self.evaluator("1238080", EA_SCRIPT)
self.assertNotIn("EADesktopSetup", self.reg.read_text())
self.assertNotIn("EADesktopSetup", (self.reg.parent / ".droiddeck-redists").read_text())
self.assertIn("EA app markers out", result.stdout)
if __name__ == "__main__":
unittest.main()