255 lines
8.3 KiB
NSIS
255 lines
8.3 KiB
NSIS
Unicode true
|
|
|
|
; Tests use the silent install feature to bypass message box prompts.
|
|
SilentInstall silent
|
|
|
|
; This is the executable that will be run by an xpcshell test
|
|
OutFile "test_stub_installer.exe"
|
|
|
|
|
|
; The executable will write output to this file, and the xpcshell test
|
|
; will read the contents of the file to determine whether the tests passed
|
|
!define TEST_OUTPUT_FILENAME .\test_installer_output.txt
|
|
|
|
|
|
!include "stub_shared_defs.nsh"
|
|
|
|
; Some variables used only by tests and mocks
|
|
Var Stdout
|
|
Var FailureMessage
|
|
Var TestBreakpointNumber
|
|
|
|
; For building the test exectuable, this version of the IsTestBreakpointSet macro
|
|
; checks the value of the TestBreakpointNumber. For real installer executables,
|
|
; this macro is empty, and does nothing. (See stub.nsi for the that version.)
|
|
!macro IsTestBreakpointSet breakpointNumber
|
|
${If} ${breakpointNumber} == $TestBreakpointNumber
|
|
Return
|
|
${EndIf}
|
|
!macroend
|
|
|
|
!include "LogicLib.nsh"
|
|
!include "FileFunc.nsh"
|
|
!include "TextFunc.nsh"
|
|
!include "WinVer.nsh"
|
|
!include "WordFunc.nsh"
|
|
|
|
|
|
Function ExitProcess
|
|
FunctionEnd
|
|
|
|
Function AttachConsole
|
|
; NSIS doesn't attach a console to the installer, so we'll do that now
|
|
System::Call 'kernel32::AttachConsole(i -1)i.r0'
|
|
${If} $0 != 0
|
|
; Windows STD_OUTPUT_HANDLE is defined as -11
|
|
System::Call 'kernel32::GetStdHandle(i -11)i.r0'
|
|
Push $0
|
|
${Else}
|
|
; If there's no console, exit with a nonzero exit code
|
|
System::Call 'kernel32::ExitProcess(i 65536)'
|
|
${EndIf}
|
|
FunctionEnd
|
|
|
|
; ${AtLeastWin10} is a macro provided by WinVer.nsh that can act as the predicate of a LogicLib
|
|
; control statement. This macro redefinition makes this test mockable
|
|
Var MockAtLeastWin10
|
|
!define /redef AtLeastWin10 `$MockAtLeastWin10 IsMockedAsTrue ""`
|
|
|
|
; See stub.nsi for the real version of CheckCpuSupportsSSE
|
|
Var MockCpuHasSSE
|
|
Function CheckCpuSupportsSSE
|
|
StrCpy $CpuSupportsSSE "$MockCpuHasSSE"
|
|
FunctionEnd
|
|
|
|
; See stub.nsi for the real version of CanWrite
|
|
Var MockCanWrite
|
|
Function CanWrite
|
|
StrCpy $CanWriteToInstallDir $MockCanWrite
|
|
FunctionEnd
|
|
|
|
!macro _IsMockedAsTrue _v _b _t _f
|
|
; If the mock value is the same as 'true', jump to the label specified in $_t
|
|
; Otherwise, jump to the label specified in $_f
|
|
; (This is compatible with LogicLib ${If} and similar tests)
|
|
StrCmp `${_v}` 'true' `${_t}` `${_f}`
|
|
!macroend
|
|
|
|
; A helpful macro for testing that a variable is equal to a value.
|
|
; Provide the variable name (bare, without $ prefix) and the expected value.
|
|
; For example, to test that $MyVariable is equal to "hello there", you would write:
|
|
; !insertmacro AssertEqual MyVariable "hello there"
|
|
!macro AssertEqual _variableName _expectedValue
|
|
${If} $${_variableName} != ${_expectedValue}
|
|
StrCpy $FailureMessage "At Line ${__LINE__}: Expected ${_variableName} of ${_expectedValue} , got $${_variableName}"
|
|
SetErrors
|
|
Return
|
|
${EndIf}
|
|
!macroend
|
|
|
|
Var TestFailureCount
|
|
|
|
!macro UnitTest _testFunctionName
|
|
Call ${_testFunctionName}
|
|
IfErrors 0 +3
|
|
IntOp $TestFailureCount $TestFailureCount + 1
|
|
FileWrite $Stdout "FAILURE: $FailureMessage; "
|
|
ClearErrors
|
|
!macroend
|
|
|
|
; Redefine ElevateUAC as a no-op in this test exectuable
|
|
!define /redef ElevateUAC ``
|
|
|
|
!include stub.nsh
|
|
|
|
|
|
; .onInit is responsible for running the tests
|
|
Function .onInit
|
|
Call AttachConsole
|
|
Pop $Stdout
|
|
IntOp $TestFailureCount 0 + 0
|
|
!insertmacro UnitTest TestDontInstallOnOldWindows
|
|
|
|
!insertmacro UnitTest TestDontInstallOnNewWindowsWithoutSSE
|
|
|
|
!insertmacro UnitTest TestDontInstallOnOldWindowsWithoutSSE
|
|
|
|
!insertmacro UnitTest TestGetArchToInstall
|
|
|
|
!insertmacro UnitTest TestMaintServiceCfg
|
|
|
|
!insertmacro UnitTest TestCanWriteToDirSuccess
|
|
|
|
!insertmacro UnitTest TestCanWriteToDirFail
|
|
|
|
${If} $TestFailureCount = 0
|
|
; On success, write the success metric and jump to the end
|
|
FileWrite $Stdout "All stub installer tests passed"
|
|
${Else}
|
|
FileWrite $Stdout "$TestFailureCount stub installer tests failed"
|
|
${EndIf}
|
|
FileClose $Stdout
|
|
Return
|
|
OnError:
|
|
Abort "Failed to run tests."
|
|
FunctionEnd
|
|
|
|
; Expect installation to abort if windows version < 10
|
|
Function TestDontInstallOnOldWindows
|
|
StrCpy $MockAtLeastWin10 'false'
|
|
StrCpy $MockCpuHasSSE '1'
|
|
StrCpy $AbortInstallation ''
|
|
StrCpy $ExitCode "Unknown"
|
|
Call CommonOnInit
|
|
!insertmacro AssertEqual ExitCode "${ERR_PREINSTALL_SYS_OS_REQ}"
|
|
!insertmacro AssertEqual AbortInstallation "true"
|
|
!insertmacro AssertEqual R7 "$(WARN_MIN_SUPPORTED_OSVER_MSG)"
|
|
FunctionEnd
|
|
|
|
|
|
; Expect installation to abort on processor without SSE, WIndows 10+ version
|
|
Function TestDontInstallOnNewWindowsWithoutSSE
|
|
StrCpy $MockAtLeastWin10 'true'
|
|
StrCpy $MockCpuHasSSE '0'
|
|
StrCpy $AbortInstallation ''
|
|
StrCpy $ExitCode "Unknown"
|
|
Call CommonOnInit
|
|
!insertmacro AssertEqual ExitCode "${ERR_PREINSTALL_SYS_HW_REQ}"
|
|
!insertmacro AssertEqual AbortInstallation "true"
|
|
FunctionEnd
|
|
|
|
; Expect installation to abort on processor without SSE, Windows <10 version
|
|
Function TestDontInstallOnOldWindowsWithoutSSE
|
|
StrCpy $MockAtLeastWin10 'false'
|
|
StrCpy $MockCpuHasSSE '0'
|
|
StrCpy $AbortInstallation ''
|
|
StrCpy $ExitCode "Unknown"
|
|
Call CommonOnInit
|
|
!insertmacro AssertEqual ExitCode "${ERR_PREINSTALL_SYS_OS_REQ}"
|
|
!insertmacro AssertEqual AbortInstallation "true"
|
|
!insertmacro AssertEqual R7 "$(WARN_MIN_SUPPORTED_OSVER_CPU_MSG)"
|
|
FunctionEnd
|
|
|
|
; Expect to find a known supported architecture for Windows
|
|
Function TestGetArchToInstall
|
|
StrCpy $TestBreakpointNumber "${TestBreakpointArchToInstall}"
|
|
StrCpy $MockAtLeastWin10 'true'
|
|
StrCpy $MockCpuHasSSE '1'
|
|
StrCpy $INSTDIR "Unknown"
|
|
StrCpy $ArchToInstall "Unknown"
|
|
|
|
Call CommonOnInit
|
|
${Switch} $ArchToInstall
|
|
${Case} "${ARCH_X86}"
|
|
; OK, fall through
|
|
${Case} "${ARCH_AMD64}"
|
|
; OK, fall through
|
|
${Case} "${ARCH_AARCH64}"
|
|
; OK
|
|
${Break}
|
|
${Default}
|
|
StrCpy $FailureMessage "Unexpected value for ArchToInstall: $ArchToInstall"
|
|
SetErrors
|
|
Return
|
|
${EndSwitch}
|
|
|
|
${Switch} $INSTDIR
|
|
${Case} "${DefaultInstDir64bit}"
|
|
; OK, fall through
|
|
${Case} "${DefaultInstDir32bit}"
|
|
; OK
|
|
${Break}
|
|
${Default}
|
|
StrCpy $FailureMessage "Unexpected value for INSTDIR: $INSTDIR"
|
|
SetErrors
|
|
Return
|
|
${EndSwitch}
|
|
FunctionEnd
|
|
|
|
; Since we're not actually elevating permissions, expect not to enable installing maintenance service
|
|
Function TestMaintServiceCfg
|
|
StrCpy $TestBreakpointNumber "${TestBreakpointMaintService}"
|
|
StrCpy $CheckboxInstallMaintSvc 'Unknown'
|
|
StrCpy $MockAtLeastWin10 'true'
|
|
StrCpy $MockCpuHasSSE '1'
|
|
|
|
Call CommonOnInit
|
|
|
|
!insertmacro AssertEqual CheckboxInstallMaintSvc "0"
|
|
FunctionEnd
|
|
|
|
; Expect success if we can write to installation directory
|
|
Function TestCanWriteToDirSuccess
|
|
StrCpy $TestBreakpointNumber "${TestBreakpointCanWriteToDir}"
|
|
StrCpy $MockCanWrite 'true'
|
|
StrCpy $MockAtLeastWin10 'true'
|
|
StrCpy $MockCpuHasSSE '1'
|
|
StrCpy $CanWriteToInstallDir "Unknown"
|
|
StrCpy $AbortInstallation "false"
|
|
|
|
Call CommonOnInit
|
|
|
|
; Since we're not running as admin, expect directory to be under user's own home directory, so it should be writable
|
|
!insertmacro AssertEqual CanWriteToInstallDir "true"
|
|
!insertmacro AssertEqual AbortInstallation "false"
|
|
FunctionEnd
|
|
|
|
; Expect failure if we can't write to installation directory
|
|
Function TestCanWriteToDirFail
|
|
StrCpy $TestBreakpointNumber "${TestBreakpointCanWriteToDir}"
|
|
StrCpy $MockCanWrite 'false'
|
|
StrCpy $MockAtLeastWin10 'true'
|
|
StrCpy $MockCpuHasSSE '1'
|
|
StrCpy $CanWriteToInstallDir "Unknown"
|
|
StrCpy $AbortInstallation "false"
|
|
|
|
Call CommonOnInit
|
|
|
|
; Since we're not running as admin, expect directory to be under user's own home directory, so it should be writable
|
|
!insertmacro AssertEqual CanWriteToInstallDir "false"
|
|
!insertmacro AssertEqual ExitCode "${ERR_PREINSTALL_NOT_WRITABLE}"
|
|
!insertmacro AssertEqual AbortInstallation "true"
|
|
FunctionEnd
|
|
|
|
Section
|
|
SectionEnd
|