mirror of
https://github.com/esengine/DeepSeek-Reasonix.git
synced 2026-11-07 10:45:59 -10:00
A release that turns out to be bad currently leaves the user hunting for an old installer. The version panel lists what has been published and installs any of them — the same code path forward or back, because a rollback that took its own path would be the less-tested one. The chosen version is pinned before the download starts: if the machine dies mid-install, the next launch must not helpfully update past what the user picked. The update core moves out of the old shell into desktop/internal/update so both shells share it. Beyond deduplication that finally makes it compile on every platform — updater_mac.go could not even be type-checked from Windows, so the macOS half was only ever verified by CI. Publishing writes a per-tag index alongside the artifacts, so the catalog the panel reads is produced by the release itself rather than maintained by hand. Two things the transport learned the hard way, now covered by tests: a 404 is not transient and must not burn the full retry budget, and a resumed download has to verify the range it was actually given — a middle box that answers `bytes 0-` to a range request will otherwise append the whole file to what is already on disk.
104 lines
3.6 KiB
Go
104 lines
3.6 KiB
Go
package update
|
|
|
|
import (
|
|
"os"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestInstallerCommandLineUsesVisibleUpdateModeAndKeepsDFlagLast(t *testing.T) {
|
|
got := installerCommandLine(`C:\Temp\Reasonix Installer.exe`, `D:\Tools\Reasonix App`)
|
|
want := `"C:\Temp\Reasonix Installer.exe" /REASONIXUPDATE=1 /REASONIXSTAGE=1 /D=D:\Tools\Reasonix App`
|
|
if got != want {
|
|
t.Fatalf("installerCommandLine = %q, want %q", got, want)
|
|
}
|
|
if strings.Contains(got, " /S") {
|
|
t.Fatalf("auto-update must expose progress instead of using silent mode, got %q", got)
|
|
}
|
|
if !strings.HasSuffix(got, `/D=D:\Tools\Reasonix App`) {
|
|
t.Fatalf("/D= must be the final unquoted NSIS token, got %q", got)
|
|
}
|
|
}
|
|
|
|
func TestWindowsUpdateHandoffArgsCarryParentInstallAndRelaunch(t *testing.T) {
|
|
got := windowsUpdateHandoffArgs(
|
|
4242,
|
|
`C:\Users\Jane Doe\AppData\Local\Reasonix\updates\Reasonix-windows-amd64-installer.exe`,
|
|
strings.Repeat("a", 64),
|
|
`D:\Tools\Reasonix App`,
|
|
`D:\Tools\Reasonix App\reasonix-desktop.exe`,
|
|
"v1.6.0",
|
|
"2026-07-29T00:00:00Z",
|
|
"transaction-1",
|
|
)
|
|
want := []string{
|
|
"--parent-pid", "4242",
|
|
"--installer", `C:\Users\Jane Doe\AppData\Local\Reasonix\updates\Reasonix-windows-amd64-installer.exe`,
|
|
"--installer-sha256", strings.Repeat("a", 64),
|
|
"--to-version", "v1.6.0",
|
|
"--created-at", "2026-07-29T00:00:00Z",
|
|
"--transaction-id", "transaction-1",
|
|
"--install-dir", `D:\Tools\Reasonix App`,
|
|
"--relaunch", `D:\Tools\Reasonix App\reasonix-desktop.exe`,
|
|
}
|
|
if strings.Join(got, "\x00") != strings.Join(want, "\x00") {
|
|
t.Fatalf("args = %#v, want %#v", got, want)
|
|
}
|
|
}
|
|
|
|
func TestWindowsVersionedUpdateHandoffArgsDoNotRequireLegacyPendingIdentity(t *testing.T) {
|
|
got := windowsVersionedUpdateHandoffArgs(
|
|
4242,
|
|
`C:\Temp\Reasonix-installer.exe`,
|
|
strings.Repeat("b", 64),
|
|
`D:\Tools\Reasonix`,
|
|
`D:\Tools\Reasonix\reasonix-launcher.exe`,
|
|
"v1.20.0",
|
|
)
|
|
want := []string{
|
|
"--parent-pid", "4242",
|
|
"--installer", `C:\Temp\Reasonix-installer.exe`,
|
|
"--installer-sha256", strings.Repeat("b", 64),
|
|
"--to-version", "v1.20.0",
|
|
"--install-layout", "versioned-v1",
|
|
"--install-dir", `D:\Tools\Reasonix`,
|
|
"--relaunch", `D:\Tools\Reasonix\reasonix-launcher.exe`,
|
|
}
|
|
if strings.Join(got, "\x00") != strings.Join(want, "\x00") {
|
|
t.Fatalf("args = %#v, want %#v", got, want)
|
|
}
|
|
for _, legacy := range []string{"--created-at", "--transaction-id"} {
|
|
if strings.Contains(strings.Join(got, " "), legacy) {
|
|
t.Fatalf("versioned handoff must not carry legacy field %s", legacy)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestWindowsUpdateRequiresObservedHelperHandoff(t *testing.T) {
|
|
data, err := os.ReadFile("install_windows.go")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
source := string(data)
|
|
if !strings.Contains(source, "return startWindowsUpdateHelper(") {
|
|
t.Fatal("Windows update handoff does not require the observed helper path")
|
|
}
|
|
if strings.Contains(source, "return installerCommand(") {
|
|
t.Fatal("Windows update silently falls back to an unobserved installer")
|
|
}
|
|
if !strings.Contains(source, "cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}") {
|
|
t.Fatal("Windows handoff helper should stay hidden while NSIS shows update progress")
|
|
}
|
|
helperData, err := os.ReadFile("../../cmd/update-helper/main_windows.go")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
helperSource := string(helperData)
|
|
if !strings.Contains(helperSource, "reconcileWindowsUninstallRegistrationFn(installDir, toVersion)") {
|
|
t.Fatal("versioned Windows activation must refresh its managed uninstall registration")
|
|
}
|
|
if strings.Contains(helperSource, "installerCommandLine(installer, installDir), HideWindow: true") {
|
|
t.Fatal("update helper still hides the NSIS progress window")
|
|
}
|
|
}
|