query_test.go 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. //go:build !integration
  2. // +build !integration
  3. package main
  4. import (
  5. "context"
  6. "encoding/json"
  7. "fmt"
  8. "io"
  9. "os"
  10. "os/exec"
  11. "strings"
  12. "testing"
  13. "github.com/Jguer/yay/v12/pkg/db/mock"
  14. mockaur "github.com/Jguer/yay/v12/pkg/dep/mock"
  15. "github.com/Jguer/yay/v12/pkg/query"
  16. "github.com/Jguer/yay/v12/pkg/runtime"
  17. "github.com/Jguer/yay/v12/pkg/settings"
  18. "github.com/Jguer/yay/v12/pkg/settings/exe"
  19. "github.com/Jguer/yay/v12/pkg/settings/parser"
  20. "github.com/Jguer/aur"
  21. "github.com/stretchr/testify/assert"
  22. "github.com/stretchr/testify/require"
  23. )
  24. func getFromFile(t *testing.T, filePath string) mockaur.GetFunc {
  25. f, err := os.Open(filePath)
  26. require.NoError(t, err)
  27. fBytes, err := io.ReadAll(f)
  28. require.NoError(t, err)
  29. pkgs := []aur.Pkg{}
  30. err = json.Unmarshal(fBytes, &pkgs)
  31. require.NoError(t, err)
  32. return func(ctx context.Context, query *aur.Query) ([]aur.Pkg, error) {
  33. return pkgs, nil
  34. }
  35. }
  36. func TestSyncInfo(t *testing.T) {
  37. t.Parallel()
  38. pacmanBin := t.TempDir() + "/pacman"
  39. testCases := []struct {
  40. name string
  41. args []string
  42. targets []string
  43. wantShow []string
  44. wantErr bool
  45. }{
  46. {
  47. name: "Si linux",
  48. args: []string{"S", "i"},
  49. targets: []string{"linux"},
  50. wantShow: []string{"pacman", "-S", "-i", "--config", "/etc/pacman.conf", "--", "linux"},
  51. },
  52. {
  53. name: "Si jellyfin",
  54. args: []string{"S", "i"},
  55. targets: []string{"jellyfin"},
  56. wantShow: []string{},
  57. },
  58. {
  59. name: "Si linux jellyfin",
  60. args: []string{"S", "i"},
  61. targets: []string{"linux", "jellyfin"},
  62. wantShow: []string{"pacman", "-S", "-i", "--config", "/etc/pacman.conf", "--", "linux"},
  63. },
  64. {
  65. name: "Si jellyfin",
  66. args: []string{"S", "i"},
  67. targets: []string{"jellyfin"},
  68. wantShow: []string{},
  69. },
  70. {
  71. name: "Si missing",
  72. args: []string{"S", "i"},
  73. targets: []string{"missing"},
  74. wantShow: []string{},
  75. wantErr: true,
  76. },
  77. }
  78. dbExc := &mock.DBExecutor{
  79. SyncSatisfierFn: func(s string) mock.IPackage {
  80. if s == "linux" {
  81. return &mock.Package{
  82. PName: "linux",
  83. PBase: "linux",
  84. }
  85. }
  86. return nil
  87. },
  88. PackagesFromGroupFn: func(s string) []mock.IPackage {
  89. return nil
  90. },
  91. }
  92. mockAUR := &mockaur.MockAUR{GetFn: func(ctx context.Context, query *aur.Query) ([]aur.Pkg, error) {
  93. if query.Needles[0] == "jellyfin" {
  94. jfinFn := getFromFile(t, "pkg/dep/testdata/jellyfin.json")
  95. return jfinFn(ctx, query)
  96. }
  97. return nil, fmt.Errorf("not found")
  98. }}
  99. for _, tc := range testCases {
  100. t.Run(tc.name, func(t *testing.T) {
  101. mockRunner := &exe.MockRunner{
  102. CaptureFn: func(cmd *exec.Cmd) (stdout string, stderr string, err error) {
  103. return "", "", nil
  104. },
  105. ShowFn: func(cmd *exec.Cmd) error { return nil },
  106. }
  107. cmdBuilder := &exe.CmdBuilder{
  108. SudoBin: "su",
  109. PacmanBin: pacmanBin,
  110. PacmanConfigPath: "/etc/pacman.conf",
  111. GitBin: "git",
  112. Runner: mockRunner,
  113. SudoLoopEnabled: false,
  114. }
  115. run := &runtime.Runtime{
  116. CmdBuilder: cmdBuilder,
  117. AURClient: mockAUR,
  118. Logger: newTestLogger(),
  119. Cfg: &settings.Configuration{},
  120. }
  121. cmdArgs := parser.MakeArguments()
  122. cmdArgs.AddArg(tc.args...)
  123. cmdArgs.AddTarget(tc.targets...)
  124. err := handleCmd(context.Background(),
  125. run, cmdArgs, dbExc,
  126. )
  127. if tc.wantErr {
  128. require.Error(t, err)
  129. assert.EqualError(t, err, "")
  130. } else {
  131. require.NoError(t, err)
  132. }
  133. if len(tc.wantShow) == 0 {
  134. assert.Empty(t, mockRunner.ShowCalls)
  135. return
  136. }
  137. for i, call := range mockRunner.ShowCalls {
  138. show := call.Args[0].(*exec.Cmd).String()
  139. show = strings.ReplaceAll(show, pacmanBin, "pacman")
  140. // options are in a different order on different systems and on CI root user is used
  141. assert.Subset(t, strings.Split(show, " "),
  142. strings.Split(tc.wantShow[i], " "),
  143. fmt.Sprintf("%d - %s", i, show))
  144. }
  145. })
  146. }
  147. }
  148. // Should not error when there is a DB called aur
  149. func TestSyncSearchAURDB(t *testing.T) {
  150. t.Parallel()
  151. pacmanBin := t.TempDir() + "/pacman"
  152. testCases := []struct {
  153. name string
  154. args []string
  155. targets []string
  156. wantShow []string
  157. wantErr bool
  158. bottomUp bool
  159. singleLine bool
  160. mixed bool
  161. }{
  162. {
  163. name: "Ss jellyfin false false",
  164. args: []string{"S", "s"},
  165. targets: []string{"jellyfin"},
  166. wantShow: []string{},
  167. },
  168. {
  169. name: "Ss jellyfin true false",
  170. args: []string{"S", "s"},
  171. targets: []string{"jellyfin"},
  172. wantShow: []string{},
  173. singleLine: true,
  174. },
  175. {
  176. name: "Ss jellyfin true true",
  177. args: []string{"S", "s"},
  178. targets: []string{"jellyfin"},
  179. wantShow: []string{},
  180. singleLine: true,
  181. mixed: true,
  182. },
  183. {
  184. name: "Ss jellyfin false true",
  185. args: []string{"S", "s"},
  186. targets: []string{"jellyfin"},
  187. wantShow: []string{},
  188. singleLine: false,
  189. mixed: true,
  190. },
  191. {
  192. name: "Ss jellyfin true true - bottomup",
  193. args: []string{"S", "s"},
  194. targets: []string{"jellyfin"},
  195. wantShow: []string{},
  196. singleLine: true,
  197. mixed: true,
  198. bottomUp: true,
  199. },
  200. }
  201. dbExc := &mock.DBExecutor{
  202. SyncPackagesFn: func(s ...string) []mock.IPackage {
  203. return []mock.IPackage{
  204. &mock.Package{
  205. PName: "jellyfin",
  206. PBase: "jellyfin",
  207. PDB: mock.NewDB("aur"),
  208. },
  209. }
  210. },
  211. LocalPackageFn: func(s string) mock.IPackage {
  212. return &mock.Package{
  213. PName: "jellyfin",
  214. PBase: "jellyfin",
  215. PDB: mock.NewDB("aur"),
  216. }
  217. },
  218. PackagesFromGroupFn: func(s string) []mock.IPackage {
  219. return nil
  220. },
  221. }
  222. mockAUR := &mockaur.MockAUR{GetFn: func(ctx context.Context, query *aur.Query) ([]aur.Pkg, error) {
  223. if query.Needles[0] == "jellyfin" {
  224. jfinFn := getFromFile(t, "pkg/dep/testdata/jellyfin.json")
  225. return jfinFn(ctx, query)
  226. }
  227. return nil, fmt.Errorf("not found")
  228. }}
  229. for _, tc := range testCases {
  230. t.Run(tc.name, func(t *testing.T) {
  231. mockRunner := &exe.MockRunner{
  232. CaptureFn: func(cmd *exec.Cmd) (stdout string, stderr string, err error) {
  233. return "", "", nil
  234. },
  235. ShowFn: func(cmd *exec.Cmd) error { return nil },
  236. }
  237. cmdBuilder := &exe.CmdBuilder{
  238. SudoBin: "su",
  239. PacmanBin: pacmanBin,
  240. PacmanConfigPath: "/etc/pacman.conf",
  241. GitBin: "git",
  242. Runner: mockRunner,
  243. SudoLoopEnabled: false,
  244. }
  245. run := &runtime.Runtime{
  246. CmdBuilder: cmdBuilder,
  247. AURClient: mockAUR,
  248. QueryBuilder: query.NewSourceQueryBuilder(mockAUR, newTestLogger(), "votes", parser.ModeAny, "name",
  249. tc.bottomUp, tc.singleLine, tc.mixed),
  250. Logger: newTestLogger(),
  251. Cfg: &settings.Configuration{},
  252. }
  253. cmdArgs := parser.MakeArguments()
  254. cmdArgs.AddArg(tc.args...)
  255. cmdArgs.AddTarget(tc.targets...)
  256. err := handleCmd(context.Background(),
  257. run, cmdArgs, dbExc,
  258. )
  259. if tc.wantErr {
  260. require.Error(t, err)
  261. assert.EqualError(t, err, "")
  262. } else {
  263. require.NoError(t, err)
  264. }
  265. if len(tc.wantShow) == 0 {
  266. assert.Empty(t, mockRunner.ShowCalls)
  267. return
  268. }
  269. for i, call := range mockRunner.ShowCalls {
  270. show := call.Args[0].(*exec.Cmd).String()
  271. show = strings.ReplaceAll(show, pacmanBin, "pacman")
  272. // options are in a different order on different systems and on CI root user is used
  273. assert.Subset(t, strings.Split(show, " "),
  274. strings.Split(tc.wantShow[i], " "),
  275. fmt.Sprintf("%d - %s", i, show))
  276. }
  277. })
  278. }
  279. }