local_install_test.go 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. package main
  2. import (
  3. "context"
  4. "fmt"
  5. "os"
  6. "os/exec"
  7. "strings"
  8. "sync"
  9. "testing"
  10. aur "github.com/Jguer/aur"
  11. "github.com/Jguer/aur/metadata"
  12. "github.com/stretchr/testify/assert"
  13. "github.com/stretchr/testify/require"
  14. "github.com/Jguer/yay/v11/pkg/db/mock"
  15. mockaur "github.com/Jguer/yay/v11/pkg/dep/mock"
  16. "github.com/Jguer/yay/v11/pkg/settings"
  17. "github.com/Jguer/yay/v11/pkg/settings/exe"
  18. "github.com/Jguer/yay/v11/pkg/settings/parser"
  19. "github.com/Jguer/yay/v11/pkg/vcs"
  20. )
  21. func TestIntegrationLocalInstall(t *testing.T) {
  22. makepkgBin := t.TempDir() + "/makepkg"
  23. pacmanBin := t.TempDir() + "/pacman"
  24. gitBin := t.TempDir() + "/git"
  25. tmpDir := t.TempDir()
  26. f, err := os.OpenFile(makepkgBin, os.O_RDONLY|os.O_CREATE, 0o755)
  27. require.NoError(t, err)
  28. require.NoError(t, f.Close())
  29. f, err = os.OpenFile(pacmanBin, os.O_RDONLY|os.O_CREATE, 0o755)
  30. require.NoError(t, err)
  31. require.NoError(t, f.Close())
  32. f, err = os.OpenFile(gitBin, os.O_RDONLY|os.O_CREATE, 0o755)
  33. require.NoError(t, err)
  34. require.NoError(t, f.Close())
  35. tars := []string{
  36. tmpDir + "/jellyfin-10.8.4-1-x86_64.pkg.tar.zst",
  37. tmpDir + "/jellyfin-web-10.8.4-1-x86_64.pkg.tar.zst",
  38. tmpDir + "/jellyfin-server-10.8.4-1-x86_64.pkg.tar.zst",
  39. }
  40. wantShow := []string{
  41. "makepkg --verifysource -Ccf",
  42. "pacman -S --config /etc/pacman.conf -- community/dotnet-sdk-6.0 community/dotnet-runtime-6.0",
  43. "pacman -D -q --asdeps --config /etc/pacman.conf -- dotnet-runtime-6.0 dotnet-sdk-6.0",
  44. "makepkg --nobuild -fC --ignorearch",
  45. "makepkg -c --nobuild --noextract --ignorearch",
  46. "makepkg --nobuild -fC --ignorearch",
  47. "makepkg -c --nobuild --noextract --ignorearch",
  48. "makepkg --nobuild -fC --ignorearch",
  49. "makepkg -c --nobuild --noextract --ignorearch",
  50. "pacman -U --config /etc/pacman.conf -- /testdir/jellyfin-server-10.8.4-1-x86_64.pkg.tar.zst /testdir/jellyfin-10.8.4-1-x86_64.pkg.tar.zst /testdir/jellyfin-web-10.8.4-1-x86_64.pkg.tar.zst",
  51. "pacman -D -q --asexplicit --config /etc/pacman.conf -- jellyfin-server jellyfin jellyfin-web",
  52. }
  53. wantCapture := []string{
  54. "makepkg --packagelist",
  55. "git -C testdata/jfin git reset --hard HEAD",
  56. "git -C testdata/jfin git merge --no-edit --ff",
  57. "makepkg --packagelist",
  58. "makepkg --packagelist",
  59. }
  60. captureOverride := func(cmd *exec.Cmd) (stdout string, stderr string, err error) {
  61. return strings.Join(tars, "\n"), "", nil
  62. }
  63. once := sync.Once{}
  64. showOverride := func(cmd *exec.Cmd) error {
  65. once.Do(func() {
  66. for _, tar := range tars {
  67. f, err := os.OpenFile(tar, os.O_RDONLY|os.O_CREATE, 0o666)
  68. require.NoError(t, err)
  69. require.NoError(t, f.Close())
  70. }
  71. })
  72. return nil
  73. }
  74. mockRunner := &exe.MockRunner{CaptureFn: captureOverride, ShowFn: showOverride}
  75. cmdBuilder := &exe.CmdBuilder{
  76. MakepkgBin: makepkgBin,
  77. SudoBin: "su",
  78. PacmanBin: pacmanBin,
  79. PacmanConfigPath: "/etc/pacman.conf",
  80. GitBin: "git",
  81. Runner: mockRunner,
  82. SudoLoopEnabled: false,
  83. }
  84. cmdArgs := parser.MakeArguments()
  85. cmdArgs.AddArg("B")
  86. cmdArgs.AddArg("i")
  87. cmdArgs.AddTarget("testdata/jfin")
  88. settings.NoConfirm = true
  89. defer func() { settings.NoConfirm = false }()
  90. db := &mock.DBExecutor{
  91. AlpmArchitecturesFn: func() ([]string, error) {
  92. return []string{"x86_64"}, nil
  93. },
  94. LocalSatisfierExistsFn: func(s string) bool {
  95. switch s {
  96. case "dotnet-sdk>=6", "dotnet-sdk<7", "dotnet-runtime>=6", "dotnet-runtime<7", "jellyfin-server=10.8.4", "jellyfin-web=10.8.4":
  97. return false
  98. }
  99. return true
  100. },
  101. SyncSatisfierFn: func(s string) mock.IPackage {
  102. switch s {
  103. case "dotnet-runtime>=6", "dotnet-runtime<7":
  104. return &mock.Package{
  105. PName: "dotnet-runtime-6.0",
  106. PBase: "dotnet-runtime-6.0",
  107. PVersion: "6.0.100-1",
  108. PDB: mock.NewDB("community"),
  109. }
  110. case "dotnet-sdk>=6", "dotnet-sdk<7":
  111. return &mock.Package{
  112. PName: "dotnet-sdk-6.0",
  113. PBase: "dotnet-sdk-6.0",
  114. PVersion: "6.0.100-1",
  115. PDB: mock.NewDB("community"),
  116. }
  117. }
  118. return nil
  119. },
  120. }
  121. config := &settings.Configuration{
  122. RemoveMake: "no",
  123. Runtime: &settings.Runtime{
  124. CmdBuilder: cmdBuilder,
  125. VCSStore: &vcs.Mock{},
  126. AURCache: &mockaur.MockAUR{
  127. GetFn: func(ctx context.Context, query *metadata.AURQuery) ([]aur.Pkg, error) {
  128. return []aur.Pkg{}, nil
  129. },
  130. },
  131. },
  132. }
  133. err = handleCmd(context.Background(), config, cmdArgs, db)
  134. require.NoError(t, err)
  135. require.Len(t, mockRunner.ShowCalls, len(wantShow))
  136. require.Len(t, mockRunner.CaptureCalls, len(wantCapture))
  137. for i, call := range mockRunner.ShowCalls {
  138. show := call.Args[0].(*exec.Cmd).String()
  139. show = strings.ReplaceAll(show, tmpDir, "/testdir") // replace the temp dir with a static path
  140. show = strings.ReplaceAll(show, makepkgBin, "makepkg")
  141. show = strings.ReplaceAll(show, pacmanBin, "pacman")
  142. show = strings.ReplaceAll(show, gitBin, "pacman")
  143. // options are in a different order on different systems and on CI root user is used
  144. assert.Subset(t, strings.Split(show, " "), strings.Split(wantShow[i], " "), fmt.Sprintf("%d - %s", i, show))
  145. }
  146. }
  147. func TestIntegrationLocalInstallMissingDep(t *testing.T) {
  148. wantErr := "could not find dotnet-sdk>=6"
  149. makepkgBin := t.TempDir() + "/makepkg"
  150. pacmanBin := t.TempDir() + "/pacman"
  151. gitBin := t.TempDir() + "/git"
  152. tmpDir := t.TempDir()
  153. f, err := os.OpenFile(makepkgBin, os.O_RDONLY|os.O_CREATE, 0o755)
  154. require.NoError(t, err)
  155. require.NoError(t, f.Close())
  156. f, err = os.OpenFile(pacmanBin, os.O_RDONLY|os.O_CREATE, 0o755)
  157. require.NoError(t, err)
  158. require.NoError(t, f.Close())
  159. f, err = os.OpenFile(gitBin, os.O_RDONLY|os.O_CREATE, 0o755)
  160. require.NoError(t, err)
  161. require.NoError(t, f.Close())
  162. tars := []string{
  163. tmpDir + "/jellyfin-10.8.4-1-x86_64.pkg.tar.zst",
  164. tmpDir + "/jellyfin-web-10.8.4-1-x86_64.pkg.tar.zst",
  165. tmpDir + "/jellyfin-server-10.8.4-1-x86_64.pkg.tar.zst",
  166. }
  167. wantShow := []string{}
  168. wantCapture := []string{}
  169. captureOverride := func(cmd *exec.Cmd) (stdout string, stderr string, err error) {
  170. return strings.Join(tars, "\n"), "", nil
  171. }
  172. once := sync.Once{}
  173. showOverride := func(cmd *exec.Cmd) error {
  174. once.Do(func() {
  175. for _, tar := range tars {
  176. f, err := os.OpenFile(tar, os.O_RDONLY|os.O_CREATE, 0o666)
  177. require.NoError(t, err)
  178. require.NoError(t, f.Close())
  179. }
  180. })
  181. return nil
  182. }
  183. mockRunner := &exe.MockRunner{CaptureFn: captureOverride, ShowFn: showOverride}
  184. cmdBuilder := &exe.CmdBuilder{
  185. MakepkgBin: makepkgBin,
  186. SudoBin: "su",
  187. PacmanBin: pacmanBin,
  188. PacmanConfigPath: "/etc/pacman.conf",
  189. GitBin: "git",
  190. Runner: mockRunner,
  191. SudoLoopEnabled: false,
  192. }
  193. cmdArgs := parser.MakeArguments()
  194. cmdArgs.AddArg("B")
  195. cmdArgs.AddArg("i")
  196. cmdArgs.AddTarget("testdata/jfin")
  197. settings.NoConfirm = true
  198. defer func() { settings.NoConfirm = false }()
  199. db := &mock.DBExecutor{
  200. AlpmArchitecturesFn: func() ([]string, error) {
  201. return []string{"x86_64"}, nil
  202. },
  203. LocalSatisfierExistsFn: func(s string) bool {
  204. switch s {
  205. case "dotnet-sdk>=6", "dotnet-sdk<7", "dotnet-runtime>=6", "dotnet-runtime<7", "jellyfin-server=10.8.4", "jellyfin-web=10.8.4":
  206. return false
  207. }
  208. return true
  209. },
  210. SyncSatisfierFn: func(s string) mock.IPackage {
  211. switch s {
  212. case "dotnet-runtime>=6", "dotnet-runtime<7":
  213. return &mock.Package{
  214. PName: "dotnet-runtime-6.0",
  215. PBase: "dotnet-runtime-6.0",
  216. PVersion: "6.0.100-1",
  217. PDB: mock.NewDB("community"),
  218. }
  219. }
  220. return nil
  221. },
  222. }
  223. config := &settings.Configuration{
  224. Runtime: &settings.Runtime{
  225. CmdBuilder: cmdBuilder,
  226. VCSStore: &vcs.Mock{},
  227. AURCache: &mockaur.MockAUR{
  228. GetFn: func(ctx context.Context, query *metadata.AURQuery) ([]aur.Pkg, error) {
  229. return []aur.Pkg{}, nil
  230. },
  231. },
  232. },
  233. }
  234. err = handleCmd(context.Background(), config, cmdArgs, db)
  235. require.Error(t, err)
  236. require.EqualError(t, err, wantErr)
  237. require.Len(t, mockRunner.ShowCalls, len(wantShow))
  238. require.Len(t, mockRunner.CaptureCalls, len(wantCapture))
  239. for i, call := range mockRunner.ShowCalls {
  240. show := call.Args[0].(*exec.Cmd).String()
  241. show = strings.ReplaceAll(show, tmpDir, "/testdir") // replace the temp dir with a static path
  242. show = strings.ReplaceAll(show, makepkgBin, "makepkg")
  243. show = strings.ReplaceAll(show, pacmanBin, "pacman")
  244. show = strings.ReplaceAll(show, gitBin, "pacman")
  245. // options are in a different order on different systems and on CI root user is used
  246. assert.Subset(t, strings.Split(show, " "), strings.Split(wantShow[i], " "), fmt.Sprintf("%d - %s", i, show))
  247. }
  248. }