query_test.go 7.3 KB

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