query_test.go 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  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/settings"
  17. "github.com/Jguer/yay/v12/pkg/settings/exe"
  18. "github.com/Jguer/yay/v12/pkg/settings/parser"
  19. "github.com/Jguer/aur"
  20. "github.com/stretchr/testify/assert"
  21. "github.com/stretchr/testify/require"
  22. )
  23. func getFromFile(t *testing.T, filePath string) mockaur.GetFunc {
  24. f, err := os.Open(filePath)
  25. require.NoError(t, err)
  26. fBytes, err := io.ReadAll(f)
  27. require.NoError(t, err)
  28. pkgs := []aur.Pkg{}
  29. err = json.Unmarshal(fBytes, &pkgs)
  30. require.NoError(t, err)
  31. return func(ctx context.Context, query *aur.Query) ([]aur.Pkg, error) {
  32. return pkgs, nil
  33. }
  34. }
  35. func TestSyncInfo(t *testing.T) {
  36. t.Parallel()
  37. pacmanBin := t.TempDir() + "/pacman"
  38. testCases := []struct {
  39. name string
  40. args []string
  41. targets []string
  42. wantShow []string
  43. wantErr bool
  44. }{
  45. {
  46. name: "Si linux",
  47. args: []string{"S", "i"},
  48. targets: []string{"linux"},
  49. wantShow: []string{"pacman", "-S", "-i", "--config", "/etc/pacman.conf", "--", "linux"},
  50. },
  51. {
  52. name: "Si jellyfin",
  53. args: []string{"S", "i"},
  54. targets: []string{"jellyfin"},
  55. wantShow: []string{},
  56. },
  57. {
  58. name: "Si linux jellyfin",
  59. args: []string{"S", "i"},
  60. targets: []string{"linux", "jellyfin"},
  61. wantShow: []string{"pacman", "-S", "-i", "--config", "/etc/pacman.conf", "--", "linux"},
  62. },
  63. {
  64. name: "Si jellyfin",
  65. args: []string{"S", "i"},
  66. targets: []string{"jellyfin"},
  67. wantShow: []string{},
  68. },
  69. {
  70. name: "Si missing",
  71. args: []string{"S", "i"},
  72. targets: []string{"missing"},
  73. wantShow: []string{},
  74. wantErr: true,
  75. },
  76. }
  77. dbExc := &mock.DBExecutor{
  78. SyncSatisfierFn: func(s string) mock.IPackage {
  79. if s == "linux" {
  80. return &mock.Package{
  81. PName: "linux",
  82. PBase: "linux",
  83. }
  84. }
  85. return nil
  86. },
  87. PackagesFromGroupFn: func(s string) []mock.IPackage {
  88. return nil
  89. },
  90. }
  91. mockAUR := &mockaur.MockAUR{GetFn: func(ctx context.Context, query *aur.Query) ([]aur.Pkg, error) {
  92. if query.Needles[0] == "jellyfin" {
  93. jfinFn := getFromFile(t, "pkg/dep/testdata/jellyfin.json")
  94. return jfinFn(ctx, query)
  95. }
  96. return nil, fmt.Errorf("not found")
  97. }}
  98. for _, tc := range testCases {
  99. t.Run(tc.name, func(t *testing.T) {
  100. mockRunner := &exe.MockRunner{
  101. CaptureFn: func(cmd *exec.Cmd) (stdout string, stderr string, err error) {
  102. return "", "", nil
  103. },
  104. ShowFn: func(cmd *exec.Cmd) error { return nil },
  105. }
  106. cmdBuilder := &exe.CmdBuilder{
  107. SudoBin: "su",
  108. PacmanBin: pacmanBin,
  109. PacmanConfigPath: "/etc/pacman.conf",
  110. GitBin: "git",
  111. Runner: mockRunner,
  112. SudoLoopEnabled: false,
  113. }
  114. cfg := &settings.Configuration{
  115. Runtime: &settings.Runtime{
  116. CmdBuilder: cmdBuilder,
  117. AURCache: mockAUR,
  118. Logger: NewTestLogger(),
  119. },
  120. }
  121. cmdArgs := parser.MakeArguments()
  122. cmdArgs.AddArg(tc.args...)
  123. cmdArgs.AddTarget(tc.targets...)
  124. err := handleCmd(context.Background(),
  125. cfg, 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. cfg := &settings.Configuration{
  246. Runtime: &settings.Runtime{
  247. CmdBuilder: cmdBuilder,
  248. AURCache: mockAUR,
  249. QueryBuilder: query.NewSourceQueryBuilder(mockAUR, NewTestLogger(), "votes", parser.ModeAny, "name",
  250. tc.bottomUp, tc.singleLine, tc.mixed),
  251. Logger: NewTestLogger(),
  252. },
  253. }
  254. cmdArgs := parser.MakeArguments()
  255. cmdArgs.AddArg(tc.args...)
  256. cmdArgs.AddTarget(tc.targets...)
  257. err := handleCmd(context.Background(),
  258. cfg, cmdArgs, dbExc,
  259. )
  260. if tc.wantErr {
  261. require.Error(t, err)
  262. assert.EqualError(t, err, "")
  263. } else {
  264. require.NoError(t, err)
  265. }
  266. if len(tc.wantShow) == 0 {
  267. assert.Empty(t, mockRunner.ShowCalls)
  268. return
  269. }
  270. for i, call := range mockRunner.ShowCalls {
  271. show := call.Args[0].(*exec.Cmd).String()
  272. show = strings.ReplaceAll(show, pacmanBin, "pacman")
  273. // options are in a different order on different systems and on CI root user is used
  274. assert.Subset(t, strings.Split(show, " "),
  275. strings.Split(tc.wantShow[i], " "),
  276. fmt.Sprintf("%d - %s", i, show))
  277. }
  278. })
  279. }
  280. }