From 2dbb121e354c1dc3af6492f71db4dea5a2c2237e Mon Sep 17 00:00:00 2001 From: Adrien Ferrand Date: Thu, 13 Feb 2020 17:02:38 +0100 Subject: [PATCH] Finish integration tests --- .../test_main.py | 108 ++++++++++-------- windows-installer/auto-update.ps1 | 4 +- windows-installer/tasks-up.ps1 | 2 +- windows-installer/template-nsi.patch | Bin 0 -> 9628 bytes windows-installer/template.nsi | 89 +++------------ 5 files changed, 79 insertions(+), 124 deletions(-) create mode 100644 windows-installer/template-nsi.patch diff --git a/certbot-ci/windows_installer_integration_tests/test_main.py b/certbot-ci/windows_installer_integration_tests/test_main.py index ab08d07f8..d2258b027 100644 --- a/certbot-ci/windows_installer_integration_tests/test_main.py +++ b/certbot-ci/windows_installer_integration_tests/test_main.py @@ -55,8 +55,8 @@ def github_mock(installer): pass class GitHubMock(BaseHTTPRequestHandler): - # def log_message(self, log_format, *args): - # pass + def log_message(self, log_format, *args): + pass def do_GET(self): if re.match(r'^.*/releases/latest$', self.path): @@ -95,8 +95,8 @@ def github_mock(installer): server.server_close() -@pytest.fixture(autouse=True) -def registry_config(signing_cert, github_mock): +@pytest.fixture +def upgrade_env(signing_cert, github_mock): try: _ps('New-Item -Path HKLM:\\Software -Name Certbot -ErrorAction SilentlyContinue | Out-Null; exit 0') _ps('New-ItemProperty -Path HKLM:\\Software\\Certbot -Name CertbotUpgradeApiURL -Value {} ' @@ -105,62 +105,76 @@ def registry_config(signing_cert, github_mock): '([Convert]::ToBase64String((Get-PfxCertificate -FilePath {0}).GetPublicKey())) ' '| Out-Null'.format(signing_cert)) - yield + yield True finally: _ps('Remove-ItemProperty -Path HKLM:\\Software\\Certbot -Name CertbotUpgradeApiURL') _ps('Remove-ItemProperty -Path HKLM:\\Software\\Certbot -Name CertbotSigningPubKey') @unittest.skipIf(os.name != 'nt', reason='Windows installer tests must be run on Windows.') -def test_it(installer): +def test_base(installer): + _assert_certbot_is_broken() + + # Install certbot + subprocess.check_output([installer, '/S']) + + # Assert certbot is installed and runnable + output = subprocess.check_output('certbot --version', shell=True, universal_newlines=True) + assert re.match(r'^certbot \d+\.\d+\.\d+.*$', output), 'Flag --version does not output a version.' + + # Assert the renew + auto-upgrade task is installed and ready + output = _ps('(Get-ScheduledTask -TaskName "{}").State'.format(SCHEDULED_TASK_NAME), capture_stdout=True) + assert output.strip() == 'Ready' + + # Trigger the renew + auto-upgrade task, expecting Certbot to check for certificate renewals. + now = time.time() + _ps('Start-ScheduledTask -TaskName "{}"'.format(SCHEDULED_TASK_NAME)) + _wait_for_task_completion() + + log_path = os.path.join('C:\\', 'Certbot', 'log', 'letsencrypt.log') + + modification_time = os.path.getmtime(log_path) + assert now < modification_time, 'Certbot log file has not been modified by the renew task.' + + with open(log_path) as file_h: + data = file_h.read() + assert 'no renewal failures' in data, 'Renew task did not execute properly.' + + +# NB: This test must sit after test_base, because it needs to have +# a working installation of Certbot, and test_base does that. +@unittest.skipIf(os.name != 'nt', reason='Windows installer tests must be run on Windows.') +def test_upgrade(upgrade_env): + assert upgrade_env + subprocess.check_output(['certbot', '--version']) + + # Break on purpose certbot + _ps('Remove-Item "${env:ProgramFiles(x86)}\\Certbot\\bin\\certbot.exe" -Confirm:$false') + _assert_certbot_is_broken() + + # Trigger the renew + auto-upgrade task, expecting Certbot to be reinstalled and functional again. + now = time.time() + _ps('Start-ScheduledTask -TaskName "{}"'.format(SCHEDULED_TASK_NAME)) + _wait_for_task_completion() + + subprocess.check_output(['certbot', '--version']) + + +def _assert_certbot_is_broken(): try: - subprocess.check_call('certbot --version', shell=True) + subprocess.check_output(['certbot', '--version']) except (subprocess.CalledProcessError, OSError): pass else: raise AssertionError('Expect certbot to not be available in the PATH.') - try: - # Install certbot - subprocess.check_call([installer, '/S']) - # Assert certbot is installed and runnable - output = subprocess.check_output('certbot --version', shell=True, universal_newlines=True) - assert re.match(r'^certbot \d+\.\d+\.\d+.*$', output), 'Flag --version does not output a version.' - - # Assert renew task is installed and ready - output = _ps('(Get-ScheduledTask -TaskName "{}").State'.format(SCHEDULED_TASK_NAME), capture_stdout=True) - assert output.strip() == 'Ready' - - # Assert renew task is working - now = time.time() - _ps('Start-ScheduledTask -TaskName "{}"'.format(SCHEDULED_TASK_NAME)) - - status = 'Running' - while status != 'Ready': - status = _ps('(Get-ScheduledTask -TaskName "{}").State' - .format(SCHEDULED_TASK_NAME), capture_stdout=True).strip() - time.sleep(1) - - log_path = os.path.join('C:\\', 'Certbot', 'log', 'letsencrypt.log') - - modification_time = os.path.getmtime(log_path) - assert now < modification_time, 'Certbot log file has not been modified by the renew task.' - - with open(log_path) as file_h: - data = file_h.read() - assert 'no renewal failures' in data, 'Renew task did not execute properly.' - - finally: - # Sadly this command cannot work in non interactive mode: uninstaller will ask explicitly permission in an UAC prompt - # print('Uninstalling Certbot ...') - # uninstall_path = _ps('(gci "HKLM:\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall"' - # ' | foreach { gp $_.PSPath }' - # ' | ? { $_ -match "Certbot" }' - # ' | select UninstallString)' - # '.UninstallString', capture_stdout=True) - # subprocess.check_call([uninstall_path, '/S']) - pass +def _wait_for_task_completion(): + status = 'Running' + while status != 'Ready': + status = _ps('(Get-ScheduledTask -TaskName "{}").State' + .format(SCHEDULED_TASK_NAME), capture_stdout=True).strip() + time.sleep(1) def _ps(powershell_str, capture_stdout=False): diff --git a/windows-installer/auto-update.ps1 b/windows-installer/auto-update.ps1 index a47f8b13b..4df728cb0 100644 --- a/windows-installer/auto-update.ps1 +++ b/windows-installer/auto-update.ps1 @@ -112,11 +112,11 @@ Aborting auto-upgrade process. if (Test-Path $installDir\uninstall.exe) { # Uninstall old Certbot first Write-Message "Running the uninstaller for old version (install dir: $installDir) ..." - Start-Process -FilePath $installDir\uninstall.exe -ArgumentList "/S _?=$installDir" + Start-Process -FilePath $installDir\uninstall.exe -ArgumentList "/S" -Wait } # Install new version of Certbot Write-Message "Running the installer for new version (install dir: $installDir) ..." - Start-Process -FilePath $installerPath -ArgumentList "/S /D=$installDir" + Start-Process -FilePath $installerPath -ArgumentList "/S /D=$installDir" -Wait Write-Message "Certbot $latestVersion is installed." } catch { diff --git a/windows-installer/tasks-up.ps1 b/windows-installer/tasks-up.ps1 index b669a7cc1..2d1ad54f5 100644 --- a/windows-installer/tasks-up.ps1 +++ b/windows-installer/tasks-up.ps1 @@ -11,7 +11,7 @@ $down = Join-Path (Get-ScriptDirectory) 'tasks-down.ps1' $taskName = "Certbot Renew & Auto-Update Task" $taskDescription = "Execute twice a day the 'certbot renew' command, to renew managed certificates if needed, and upgrade Certbot is a new version is available." -$actionRenew = New-ScheduledTaskAction -Execute 'Powershell.exe' -Argument '-NoProfile -WindowStyle Hidden -Command "certbot renew"' +$actionRenew = New-ScheduledTaskAction -Execute 'Powershell.exe' -Argument "-NoProfile -WindowStyle Hidden -Command ""& '$InstallDir\bin\certbot.exe' renew""" $actionUpgrade = New-ScheduledTaskAction -Execute 'Powershell.exe' -Argument "-NoProfile -WindowStyle Hidden -File ""$InstallDir\auto-update.ps1""" $delay = New-TimeSpan -Hours 12 diff --git a/windows-installer/template-nsi.patch b/windows-installer/template-nsi.patch new file mode 100644 index 0000000000000000000000000000000000000000..fbff996512d338c97682d3ae49c0d625852c445b GIT binary patch literal 9628 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