service_test.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423
  1. package upgrade
  2. import (
  3. "context"
  4. "io"
  5. "strings"
  6. "testing"
  7. "github.com/Jguer/aur"
  8. "github.com/Jguer/go-alpm/v2"
  9. "github.com/stretchr/testify/assert"
  10. "github.com/stretchr/testify/require"
  11. "github.com/Jguer/yay/v12/pkg/db"
  12. "github.com/Jguer/yay/v12/pkg/db/mock"
  13. "github.com/Jguer/yay/v12/pkg/dep"
  14. "github.com/Jguer/yay/v12/pkg/settings"
  15. "github.com/Jguer/yay/v12/pkg/settings/parser"
  16. "github.com/Jguer/yay/v12/pkg/text"
  17. "github.com/Jguer/yay/v12/pkg/topo"
  18. "github.com/Jguer/yay/v12/pkg/vcs"
  19. mockaur "github.com/Jguer/yay/v12/pkg/dep/mock"
  20. )
  21. func ptrString(s string) *string {
  22. return &s
  23. }
  24. func TestUpgradeService_GraphUpgrades(t *testing.T) {
  25. t.Parallel()
  26. linuxDepInfo := &dep.InstallInfo{
  27. Reason: dep.Explicit,
  28. Source: dep.Sync,
  29. AURBase: nil,
  30. LocalVersion: "4.5.0-1",
  31. Version: "5.0.0-1",
  32. SyncDBName: ptrString("core"),
  33. Upgrade: true,
  34. Devel: false,
  35. }
  36. exampleDepInfoDevel := &dep.InstallInfo{
  37. Source: dep.AUR,
  38. Reason: dep.Dep,
  39. AURBase: ptrString("example"),
  40. LocalVersion: "2.2.1.r32.41baa362-1",
  41. Version: "latest-commit",
  42. Upgrade: true,
  43. Devel: true,
  44. }
  45. exampleDepInfoAUR := &dep.InstallInfo{
  46. Source: dep.AUR,
  47. Reason: dep.Dep,
  48. AURBase: ptrString("example"),
  49. LocalVersion: "2.2.1.r32.41baa362-1",
  50. Version: "2.2.1.r69.g8a10460-1",
  51. Upgrade: true,
  52. Devel: false,
  53. }
  54. yayDepInfo := &dep.InstallInfo{
  55. Reason: dep.Explicit,
  56. Source: dep.AUR,
  57. AURBase: ptrString("yay"),
  58. LocalVersion: "10.2.3",
  59. Version: "10.2.4",
  60. Upgrade: true,
  61. Devel: false,
  62. }
  63. dbExe := &mock.DBExecutor{
  64. InstalledRemotePackageNamesFn: func() []string {
  65. return []string{"yay", "example-git"}
  66. },
  67. InstalledRemotePackagesFn: func() map[string]mock.IPackage {
  68. mapRemote := make(map[string]mock.IPackage)
  69. mapRemote["yay"] = &mock.Package{
  70. PName: "yay",
  71. PBase: "yay",
  72. PVersion: "10.2.3",
  73. PReason: alpm.PkgReasonExplicit,
  74. }
  75. mapRemote["example-git"] = &mock.Package{
  76. PName: "example-git",
  77. PBase: "example",
  78. PVersion: "2.2.1.r32.41baa362-1",
  79. PReason: alpm.PkgReasonDepend,
  80. }
  81. return mapRemote
  82. },
  83. SyncUpgradesFn: func(bool) (map[string]db.SyncUpgrade, error) {
  84. mapUpgrades := make(map[string]db.SyncUpgrade)
  85. coreDB := mock.NewDB("core")
  86. mapUpgrades["linux"] = db.SyncUpgrade{
  87. Package: &mock.Package{
  88. PName: "linux",
  89. PVersion: "5.0.0-1",
  90. PReason: alpm.PkgReasonDepend,
  91. PDB: coreDB,
  92. },
  93. LocalVersion: "4.5.0-1",
  94. Reason: alpm.PkgReasonExplicit,
  95. }
  96. return mapUpgrades, nil
  97. },
  98. ReposFn: func() []string { return []string{"core"} },
  99. }
  100. vcsStore := &vcs.Mock{
  101. ToUpgradeReturn: []string{"example-git"},
  102. }
  103. mockAUR := &mockaur.MockAUR{
  104. GetFn: func(ctx context.Context, query *aur.Query) ([]aur.Pkg, error) {
  105. return []aur.Pkg{
  106. {Name: "yay", Version: "10.2.4", PackageBase: "yay"},
  107. {Name: "example-git", Version: "2.2.1.r69.g8a10460-1", PackageBase: "example"},
  108. }, nil
  109. },
  110. }
  111. type fields struct {
  112. input io.Reader
  113. output io.Writer
  114. noConfirm bool
  115. devel bool
  116. }
  117. type args struct {
  118. graph *topo.Graph[string, *dep.InstallInfo]
  119. enableDowngrade bool
  120. }
  121. tests := []struct {
  122. name string
  123. fields fields
  124. args args
  125. mustExist map[string]*dep.InstallInfo
  126. mustNotExist map[string]bool
  127. wantExclude []string
  128. wantErr bool
  129. }{
  130. {
  131. name: "no input",
  132. fields: fields{
  133. input: strings.NewReader("\n"),
  134. output: io.Discard,
  135. noConfirm: false,
  136. },
  137. args: args{
  138. graph: nil,
  139. enableDowngrade: false,
  140. },
  141. mustExist: map[string]*dep.InstallInfo{
  142. "yay": yayDepInfo,
  143. "linux": linuxDepInfo,
  144. "example-git": exampleDepInfoAUR,
  145. },
  146. mustNotExist: map[string]bool{},
  147. wantErr: false,
  148. wantExclude: []string{},
  149. },
  150. {
  151. name: "no input devel",
  152. fields: fields{
  153. input: strings.NewReader("\n"),
  154. output: io.Discard,
  155. noConfirm: false,
  156. devel: true,
  157. },
  158. args: args{
  159. graph: nil,
  160. enableDowngrade: false,
  161. },
  162. mustExist: map[string]*dep.InstallInfo{
  163. "yay": yayDepInfo,
  164. "linux": linuxDepInfo,
  165. "example-git": exampleDepInfoDevel,
  166. },
  167. mustNotExist: map[string]bool{},
  168. wantErr: false,
  169. wantExclude: []string{},
  170. },
  171. {
  172. name: "exclude yay",
  173. fields: fields{
  174. input: strings.NewReader("1\n"),
  175. output: io.Discard,
  176. noConfirm: false,
  177. },
  178. args: args{
  179. graph: nil,
  180. enableDowngrade: false,
  181. },
  182. mustExist: map[string]*dep.InstallInfo{
  183. "linux": linuxDepInfo,
  184. "example-git": exampleDepInfoAUR,
  185. },
  186. mustNotExist: map[string]bool{"yay": true},
  187. wantErr: false,
  188. wantExclude: []string{"yay"},
  189. },
  190. {
  191. name: "exclude linux",
  192. fields: fields{
  193. input: strings.NewReader("3\n"),
  194. output: io.Discard,
  195. noConfirm: false,
  196. },
  197. args: args{
  198. graph: nil,
  199. enableDowngrade: false,
  200. },
  201. mustExist: map[string]*dep.InstallInfo{
  202. "yay": yayDepInfo,
  203. "example-git": exampleDepInfoAUR,
  204. },
  205. mustNotExist: map[string]bool{"linux": true},
  206. wantErr: false,
  207. wantExclude: []string{"linux"},
  208. },
  209. {
  210. name: "only linux",
  211. fields: fields{
  212. input: strings.NewReader("^3\n"),
  213. output: io.Discard,
  214. noConfirm: false,
  215. },
  216. args: args{
  217. graph: nil,
  218. enableDowngrade: false,
  219. },
  220. mustExist: map[string]*dep.InstallInfo{
  221. "linux": linuxDepInfo,
  222. },
  223. mustNotExist: map[string]bool{"yay": true, "example-git": true},
  224. wantErr: false,
  225. wantExclude: []string{"yay", "example-git"},
  226. },
  227. {
  228. name: "exclude all",
  229. fields: fields{
  230. input: strings.NewReader("1-3\n"),
  231. output: io.Discard,
  232. noConfirm: false,
  233. },
  234. args: args{
  235. graph: nil,
  236. enableDowngrade: false,
  237. },
  238. mustExist: map[string]*dep.InstallInfo{},
  239. mustNotExist: map[string]bool{"yay": true, "example-git": true, "linux": true},
  240. wantErr: false,
  241. wantExclude: []string{"yay", "example-git", "linux"},
  242. },
  243. }
  244. for _, tt := range tests {
  245. t.Run(tt.name, func(t *testing.T) {
  246. grapher := dep.NewGrapher(dbExe, mockAUR,
  247. false, true, false, false, false, text.NewLogger(tt.fields.output,
  248. tt.fields.input, true, "test"))
  249. cfg := &settings.Configuration{
  250. Runtime: &settings.Runtime{Mode: parser.ModeAny},
  251. Devel: tt.fields.devel,
  252. }
  253. u := &UpgradeService{
  254. log: text.NewLogger(tt.fields.output,
  255. tt.fields.input, true, "test"),
  256. grapher: grapher,
  257. aurCache: mockAUR,
  258. dbExecutor: dbExe,
  259. vcsStore: vcsStore,
  260. runtime: cfg.Runtime,
  261. cfg: cfg,
  262. noConfirm: tt.fields.noConfirm,
  263. }
  264. got, err := u.GraphUpgrades(context.Background(), tt.args.graph, tt.args.enableDowngrade, func(*Upgrade) bool { return true })
  265. if (err != nil) != tt.wantErr {
  266. t.Errorf("UpgradeService.GraphUpgrades() error = %v, wantErr %v", err, tt.wantErr)
  267. return
  268. }
  269. excluded, err := u.UserExcludeUpgrades(got)
  270. require.NoError(t, err)
  271. for node, info := range tt.mustExist {
  272. assert.True(t, got.Exists(node), node)
  273. assert.Equal(t, info, got.GetNodeInfo(node).Value)
  274. }
  275. for node := range tt.mustNotExist {
  276. assert.False(t, got.Exists(node), node)
  277. }
  278. assert.ElementsMatch(t, tt.wantExclude, excluded)
  279. })
  280. }
  281. }
  282. func TestUpgradeService_GraphUpgradesNoUpdates(t *testing.T) {
  283. t.Parallel()
  284. dbExe := &mock.DBExecutor{
  285. InstalledRemotePackageNamesFn: func() []string {
  286. return []string{"yay", "example-git"}
  287. },
  288. InstalledRemotePackagesFn: func() map[string]mock.IPackage {
  289. mapRemote := make(map[string]mock.IPackage)
  290. mapRemote["yay"] = &mock.Package{
  291. PName: "yay",
  292. PBase: "yay",
  293. PVersion: "10.2.3",
  294. PReason: alpm.PkgReasonExplicit,
  295. }
  296. mapRemote["example-git"] = &mock.Package{
  297. PName: "example-git",
  298. PBase: "example",
  299. PVersion: "2.2.1.r32.41baa362-1",
  300. PReason: alpm.PkgReasonDepend,
  301. }
  302. return mapRemote
  303. },
  304. SyncUpgradesFn: func(bool) (map[string]db.SyncUpgrade, error) {
  305. mapUpgrades := make(map[string]db.SyncUpgrade)
  306. return mapUpgrades, nil
  307. },
  308. ReposFn: func() []string { return []string{"core"} },
  309. }
  310. vcsStore := &vcs.Mock{
  311. ToUpgradeReturn: []string{},
  312. }
  313. mockAUR := &mockaur.MockAUR{
  314. GetFn: func(ctx context.Context, query *aur.Query) ([]aur.Pkg, error) {
  315. return []aur.Pkg{}, nil
  316. },
  317. }
  318. type fields struct {
  319. input io.Reader
  320. output io.Writer
  321. noConfirm bool
  322. devel bool
  323. }
  324. type args struct {
  325. graph *topo.Graph[string, *dep.InstallInfo]
  326. enableDowngrade bool
  327. }
  328. tests := []struct {
  329. name string
  330. fields fields
  331. args args
  332. mustExist map[string]*dep.InstallInfo
  333. mustNotExist map[string]bool
  334. wantExclude []string
  335. wantErr bool
  336. }{
  337. {
  338. name: "no input",
  339. fields: fields{
  340. input: strings.NewReader(""),
  341. output: io.Discard,
  342. noConfirm: false,
  343. },
  344. args: args{
  345. graph: nil,
  346. enableDowngrade: false,
  347. },
  348. mustExist: map[string]*dep.InstallInfo{},
  349. mustNotExist: map[string]bool{},
  350. wantErr: false,
  351. wantExclude: []string{},
  352. },
  353. }
  354. for _, tt := range tests {
  355. t.Run(tt.name, func(t *testing.T) {
  356. grapher := dep.NewGrapher(dbExe, mockAUR,
  357. false, true, false, false, false, text.NewLogger(tt.fields.output,
  358. tt.fields.input, true, "test"))
  359. cfg := &settings.Configuration{
  360. Runtime: &settings.Runtime{Mode: parser.ModeAny},
  361. Devel: tt.fields.devel,
  362. }
  363. u := &UpgradeService{
  364. log: text.NewLogger(tt.fields.output,
  365. tt.fields.input, true, "test"),
  366. grapher: grapher,
  367. aurCache: mockAUR,
  368. dbExecutor: dbExe,
  369. vcsStore: vcsStore,
  370. runtime: cfg.Runtime,
  371. cfg: cfg,
  372. noConfirm: tt.fields.noConfirm,
  373. }
  374. got, err := u.GraphUpgrades(context.Background(), tt.args.graph, tt.args.enableDowngrade, func(*Upgrade) bool { return true })
  375. if (err != nil) != tt.wantErr {
  376. t.Errorf("UpgradeService.GraphUpgrades() error = %v, wantErr %v", err, tt.wantErr)
  377. return
  378. }
  379. excluded, err := u.UserExcludeUpgrades(got)
  380. require.NoError(t, err)
  381. for node, info := range tt.mustExist {
  382. assert.True(t, got.Exists(node), node)
  383. assert.Equal(t, info, got.GetNodeInfo(node).Value)
  384. }
  385. for node := range tt.mustNotExist {
  386. assert.False(t, got.Exists(node), node)
  387. }
  388. assert.ElementsMatch(t, tt.wantExclude, excluded)
  389. })
  390. }
  391. }