返回 DeepSeek-Reasonix
shell_test.go
根目录 / cmd / reasonix-legacy-migrator / shell_test.go
1 package main
2
3 import (
4 "os"
5 "path/filepath"
6 "reasonix/internal/installlayout"
7 "runtime"
8 "testing"
9 )
10
11 func TestInstallerActivationPublishesEntireElectronTree(t *testing.T) {
12 root := t.TempDir()
13 staging := writeInstallerStaging(t, root, "new", true)
14 names := append(installlayout.ShellRequiredNames(runtime.GOOS), "app/locales/en-US.pak", "app/resources/extra.bin")
15 for _, name := range names {
16 p := filepath.Join(staging, filepath.FromSlash(name))
17 if err := os.MkdirAll(filepath.Dir(p), 0755); err != nil {
18 t.Fatal(err)
19 }
20 if err := os.WriteFile(p, []byte(name), 0755); err != nil {
21 t.Fatal(err)
22 }
23 }
24 if err := activateInstallerStaging(root, "v1.39.0", staging); err != nil {
25 t.Fatal(err)
26 }
27 if err := os.RemoveAll(staging); err != nil {
28 t.Fatal(err)
29 }
30 for _, name := range names {
31 data, err := os.ReadFile(filepath.Join(root, "versions", "v1.39.0", filepath.FromSlash(name)))
32 if err != nil || string(data) != name {
33 t.Errorf("%s missing/corrupt after staging cleanup: %v", name, err)
34 }
35 }
36 }
37
38 func TestInstallerRejectsIncompleteShellBeforePointerCommit(t *testing.T) {
39 root := t.TempDir()
40 staging := writeInstallerStaging(t, root, "new", true)
41 if err := os.RemoveAll(filepath.Join(staging, "app")); err != nil {
42 t.Fatal(err)
43 }
44 if err := os.MkdirAll(filepath.Join(staging, "app"), 0755); err != nil {
45 t.Fatal(err)
46 }
47 if err := activateInstallerStaging(root, "v1.39.0", staging); err == nil {
48 t.Fatal("accepted empty shell")
49 }
50 if installlayout.HasCurrent(root) {
51 t.Fatal("committed incomplete shell")
52 }
53 }
54
55 func TestPortableFirstLaunchMigrationCarriesShellIntoActiveVersion(t *testing.T) {
56 root := t.TempDir()
57 writeFlatUnit(t, root, "portable")
58 if err := os.WriteFile(filepath.Join(root, installlayout.LauncherBinaryName()), []byte("launcher"), 0755); err != nil {
59 t.Fatal(err)
60 }
61 names := installlayout.ShellRequiredNames(runtime.GOOS)
62 for _, name := range names {
63 p := filepath.Join(root, filepath.FromSlash(name))
64 if err := os.MkdirAll(filepath.Dir(p), 0755); err != nil {
65 t.Fatal(err)
66 }
67 if err := os.WriteFile(p, []byte(name), 0755); err != nil {
68 t.Fatal(err)
69 }
70 }
71 if err := migrateWithRelaunch(root, "v1.39.0", false); err != nil {
72 t.Fatal(err)
73 }
74 for _, name := range names {
75 p := filepath.Join(root, "versions", "v1.39.0", filepath.FromSlash(name))
76 if data, err := os.ReadFile(p); err != nil || string(data) != name {
77 t.Errorf("portable shell missing %s: %v", name, err)
78 }
79 }
80 // Relaunch must resolve the active service, never the cleaned-up flat entry.
81 if _, err := installlayout.ActiveDesktopPath(root); err != nil {
82 t.Fatal(err)
83 }
84 }
85
86 // The Linux tarball is exactly this member set (desktop/packaging/lib.mjs
87 // linux-tar); its first launch must migrate without a versioned CLI name.
88 func TestPortableUnixArchiveMigratesWithFlatCLIName(t *testing.T) {
89 if runtime.GOOS == "windows" {
90 t.Skip("Unix archive layout")
91 }
92 root := t.TempDir()
93 for _, name := range []string{"reasonix-desktop", "reasonix-launcher", "reasonix-guard", "reasonix"} {
94 if err := os.WriteFile(filepath.Join(root, name), []byte(name), 0755); err != nil {
95 t.Fatal(err)
96 }
97 }
98 for _, name := range installlayout.ShellRequiredNames(runtime.GOOS) {
99 p := filepath.Join(root, filepath.FromSlash(name))
100 if err := os.MkdirAll(filepath.Dir(p), 0755); err != nil {
101 t.Fatal(err)
102 }
103 if err := os.WriteFile(p, []byte(name), 0755); err != nil {
104 t.Fatal(err)
105 }
106 }
107 if err := migrateWithRelaunch(root, "v1.39.0", false); err != nil {
108 t.Fatal(err)
109 }
110 if data, err := os.ReadFile(filepath.Join(root, "versions", "v1.39.0", "reasonix-cli")); err != nil || string(data) != "reasonix" {
111 t.Fatalf("versioned CLI not published from the flat reasonix binary: %v", err)
112 }
113 for _, name := range []string{"reasonix", "reasonix-desktop", "reasonix-guard"} {
114 if _, err := os.Lstat(filepath.Join(root, name)); !os.IsNotExist(err) {
115 t.Errorf("flat %s left behind after migration", name)
116 }
117 }
118 if _, err := os.Lstat(filepath.Join(root, "reasonix-launcher")); err != nil {
119 t.Fatalf("launcher entry must survive migration: %v", err)
120 }
121 }
122
122 lines GO