service_test.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786
  1. //go:build !integration
  2. // +build !integration
  3. package upgrade
  4. import (
  5. "context"
  6. "io"
  7. "os"
  8. "strings"
  9. "testing"
  10. "github.com/Jguer/aur"
  11. "github.com/Jguer/go-alpm/v2"
  12. "github.com/stretchr/testify/assert"
  13. "github.com/stretchr/testify/require"
  14. "github.com/Jguer/yay/v12/pkg/db"
  15. "github.com/Jguer/yay/v12/pkg/db/mock"
  16. "github.com/Jguer/yay/v12/pkg/dep"
  17. "github.com/Jguer/yay/v12/pkg/query"
  18. "github.com/Jguer/yay/v12/pkg/settings"
  19. "github.com/Jguer/yay/v12/pkg/settings/parser"
  20. "github.com/Jguer/yay/v12/pkg/text"
  21. "github.com/Jguer/yay/v12/pkg/topo"
  22. "github.com/Jguer/yay/v12/pkg/vcs"
  23. mockaur "github.com/Jguer/yay/v12/pkg/dep/mock"
  24. )
  25. func ptrString(s string) *string {
  26. return &s
  27. }
  28. func TestUpgradeService_GraphUpgrades(t *testing.T) {
  29. t.Parallel()
  30. linuxDepInfo := &dep.InstallInfo{
  31. Reason: dep.Explicit,
  32. Source: dep.Sync,
  33. AURBase: nil,
  34. LocalVersion: "4.5.0-1",
  35. Version: "5.0.0-1",
  36. SyncDBName: ptrString("core"),
  37. Upgrade: true,
  38. Devel: false,
  39. }
  40. exampleDepInfoDevel := &dep.InstallInfo{
  41. Source: dep.AUR,
  42. Reason: dep.Dep,
  43. AURBase: ptrString("example"),
  44. LocalVersion: "2.2.1.r32.41baa362-1",
  45. Version: "latest-commit",
  46. Upgrade: true,
  47. Devel: true,
  48. }
  49. newDepInfo := &dep.InstallInfo{
  50. Source: dep.Sync,
  51. Reason: dep.Dep,
  52. SyncDBName: ptrString("core"),
  53. Version: "3.0.1-2",
  54. LocalVersion: "",
  55. Upgrade: true,
  56. Devel: false,
  57. }
  58. exampleDepInfoAUR := &dep.InstallInfo{
  59. Source: dep.AUR,
  60. Reason: dep.Dep,
  61. AURBase: ptrString("example"),
  62. LocalVersion: "2.2.1.r32.41baa362-1",
  63. Version: "2.2.1.r69.g8a10460-1",
  64. Upgrade: true,
  65. Devel: false,
  66. }
  67. yayDepInfo := &dep.InstallInfo{
  68. Reason: dep.Explicit,
  69. Source: dep.AUR,
  70. AURBase: ptrString("yay"),
  71. LocalVersion: "10.2.3",
  72. Version: "10.2.4",
  73. Upgrade: true,
  74. Devel: false,
  75. }
  76. coreDB := mock.NewDB("core")
  77. dbExe := &mock.DBExecutor{
  78. InstalledRemotePackageNamesFn: func() []string {
  79. return []string{"yay", "example-git"}
  80. },
  81. InstalledRemotePackagesFn: func() map[string]mock.IPackage {
  82. mapRemote := make(map[string]mock.IPackage)
  83. mapRemote["yay"] = &mock.Package{
  84. PName: "yay",
  85. PBase: "yay",
  86. PVersion: "10.2.3",
  87. PReason: alpm.PkgReasonExplicit,
  88. }
  89. mapRemote["example-git"] = &mock.Package{
  90. PName: "example-git",
  91. PBase: "example",
  92. PVersion: "2.2.1.r32.41baa362-1",
  93. PReason: alpm.PkgReasonDepend,
  94. }
  95. return mapRemote
  96. },
  97. LocalSatisfierExistsFn: func(string) bool { return false },
  98. SyncSatisfierFn: func(s string) mock.IPackage {
  99. return &mock.Package{
  100. PName: "new-dep",
  101. PVersion: "3.0.1-2",
  102. PDB: coreDB,
  103. }
  104. },
  105. SyncUpgradesFn: func(bool) (map[string]db.SyncUpgrade, error) {
  106. mapUpgrades := make(map[string]db.SyncUpgrade)
  107. mapUpgrades["linux"] = db.SyncUpgrade{
  108. Package: &mock.Package{
  109. PName: "linux",
  110. PVersion: "5.0.0-1",
  111. PReason: alpm.PkgReasonDepend,
  112. PDB: coreDB,
  113. PDepends: mock.DependList{Depends: []alpm.Depend{
  114. {Name: "new-dep", Version: "3.0.1"},
  115. }},
  116. },
  117. LocalVersion: "4.5.0-1",
  118. Reason: alpm.PkgReasonExplicit,
  119. }
  120. mapUpgrades["new-dep"] = db.SyncUpgrade{
  121. Package: &mock.Package{
  122. PName: "new-dep",
  123. PVersion: "3.0.1-2",
  124. PReason: alpm.PkgReasonDepend,
  125. PDB: coreDB,
  126. },
  127. LocalVersion: "",
  128. Reason: alpm.PkgReasonDepend,
  129. }
  130. return mapUpgrades, nil
  131. },
  132. ReposFn: func() []string { return []string{"core"} },
  133. }
  134. vcsStore := &vcs.Mock{
  135. ToUpgradeReturn: []string{"example-git"},
  136. }
  137. mockAUR := &mockaur.MockAUR{
  138. GetFn: func(ctx context.Context, query *aur.Query) ([]aur.Pkg, error) {
  139. return []aur.Pkg{
  140. {Name: "yay", Version: "10.2.4", PackageBase: "yay"},
  141. {
  142. Name: "example-git", Version: "2.2.1.r69.g8a10460-1",
  143. PackageBase: "example", Depends: []string{"new-dep"},
  144. },
  145. }, nil
  146. },
  147. }
  148. type fields struct {
  149. input io.Reader
  150. output io.Writer
  151. noConfirm bool
  152. devel bool
  153. }
  154. type args struct {
  155. graph *topo.Graph[string, *dep.InstallInfo]
  156. enableDowngrade bool
  157. }
  158. tests := []struct {
  159. name string
  160. fields fields
  161. args args
  162. mustExist map[string]*dep.InstallInfo
  163. mustNotExist map[string]bool
  164. wantExclude []string
  165. wantErr bool
  166. }{
  167. {
  168. name: "no input",
  169. fields: fields{
  170. input: strings.NewReader("\n"),
  171. output: io.Discard,
  172. noConfirm: false,
  173. },
  174. args: args{
  175. graph: nil,
  176. enableDowngrade: false,
  177. },
  178. mustExist: map[string]*dep.InstallInfo{
  179. "yay": yayDepInfo,
  180. "linux": linuxDepInfo,
  181. "example-git": exampleDepInfoAUR,
  182. "new-dep": newDepInfo,
  183. },
  184. mustNotExist: map[string]bool{},
  185. wantErr: false,
  186. wantExclude: []string{},
  187. },
  188. {
  189. name: "no input devel",
  190. fields: fields{
  191. input: strings.NewReader("\n"),
  192. output: io.Discard,
  193. noConfirm: false,
  194. devel: true,
  195. },
  196. args: args{
  197. graph: nil,
  198. enableDowngrade: false,
  199. },
  200. mustExist: map[string]*dep.InstallInfo{
  201. "yay": yayDepInfo,
  202. "linux": linuxDepInfo,
  203. "example-git": exampleDepInfoDevel,
  204. },
  205. mustNotExist: map[string]bool{},
  206. wantErr: false,
  207. wantExclude: []string{},
  208. },
  209. {
  210. name: "exclude example-git",
  211. fields: fields{
  212. input: strings.NewReader("2\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. "yay": yayDepInfo,
  222. "linux": linuxDepInfo,
  223. },
  224. mustNotExist: map[string]bool{"example-git": true, "new-dep": true},
  225. wantErr: false,
  226. wantExclude: []string{"example-git", "new-dep"},
  227. },
  228. {
  229. name: "exclude new-dep should have no effect",
  230. fields: fields{
  231. input: strings.NewReader("1 3 4\n"),
  232. output: io.Discard,
  233. noConfirm: false,
  234. },
  235. args: args{
  236. graph: nil,
  237. enableDowngrade: false,
  238. },
  239. mustExist: map[string]*dep.InstallInfo{
  240. "example-git": exampleDepInfoAUR,
  241. "new-dep": newDepInfo,
  242. },
  243. mustNotExist: map[string]bool{"linux": true, "yay": true},
  244. wantErr: false,
  245. wantExclude: []string{"linux", "yay"},
  246. },
  247. {
  248. name: "exclude yay",
  249. fields: fields{
  250. input: strings.NewReader("1\n"),
  251. output: io.Discard,
  252. noConfirm: false,
  253. },
  254. args: args{
  255. graph: nil,
  256. enableDowngrade: false,
  257. },
  258. mustExist: map[string]*dep.InstallInfo{
  259. "linux": linuxDepInfo,
  260. "example-git": exampleDepInfoAUR,
  261. },
  262. mustNotExist: map[string]bool{"yay": true},
  263. wantErr: false,
  264. wantExclude: []string{"yay"},
  265. },
  266. {
  267. name: "exclude linux",
  268. fields: fields{
  269. input: strings.NewReader("3\n"),
  270. output: io.Discard,
  271. noConfirm: false,
  272. },
  273. args: args{
  274. graph: nil,
  275. enableDowngrade: false,
  276. },
  277. mustExist: map[string]*dep.InstallInfo{
  278. "yay": yayDepInfo,
  279. "example-git": exampleDepInfoAUR,
  280. "new-dep": newDepInfo,
  281. },
  282. mustNotExist: map[string]bool{"linux": true},
  283. wantErr: false,
  284. wantExclude: []string{"linux"},
  285. },
  286. {
  287. name: "only linux",
  288. fields: fields{
  289. input: strings.NewReader("^3\n"),
  290. output: io.Discard,
  291. noConfirm: false,
  292. },
  293. args: args{
  294. graph: nil,
  295. enableDowngrade: false,
  296. },
  297. mustExist: map[string]*dep.InstallInfo{
  298. "linux": linuxDepInfo,
  299. },
  300. mustNotExist: map[string]bool{"yay": true, "example-git": true},
  301. wantErr: false,
  302. wantExclude: []string{"yay", "example-git", "new-dep"},
  303. },
  304. {
  305. name: "exclude all",
  306. fields: fields{
  307. input: strings.NewReader("1-4\n"),
  308. output: io.Discard,
  309. noConfirm: false,
  310. },
  311. args: args{
  312. graph: nil,
  313. enableDowngrade: false,
  314. },
  315. mustExist: map[string]*dep.InstallInfo{},
  316. mustNotExist: map[string]bool{"yay": true, "example-git": true, "linux": true},
  317. wantErr: false,
  318. wantExclude: []string{"yay", "example-git", "linux", "new-dep"},
  319. },
  320. }
  321. for _, tt := range tests {
  322. t.Run(tt.name, func(t *testing.T) {
  323. grapher := dep.NewGrapher(dbExe, mockAUR,
  324. false, true, false, false, false, text.NewLogger(tt.fields.output, os.Stderr,
  325. tt.fields.input, true, "test"))
  326. cfg := &settings.Configuration{
  327. Devel: tt.fields.devel, Mode: parser.ModeAny,
  328. }
  329. logger := text.NewLogger(tt.fields.output, os.Stderr,
  330. tt.fields.input, true, "test")
  331. u := &UpgradeService{
  332. log: logger,
  333. grapher: grapher,
  334. aurCache: mockAUR,
  335. dbExecutor: dbExe,
  336. vcsStore: vcsStore,
  337. cfg: cfg,
  338. noConfirm: tt.fields.noConfirm,
  339. AURWarnings: query.NewWarnings(logger),
  340. }
  341. got, err := u.GraphUpgrades(context.Background(), tt.args.graph, tt.args.enableDowngrade, func(*Upgrade) bool { return true })
  342. if (err != nil) != tt.wantErr {
  343. t.Errorf("UpgradeService.GraphUpgrades() error = %v, wantErr %v", err, tt.wantErr)
  344. return
  345. }
  346. excluded, err := u.UserExcludeUpgrades(got)
  347. require.NoError(t, err)
  348. for node, info := range tt.mustExist {
  349. assert.True(t, got.Exists(node), node)
  350. assert.Equal(t, info, got.GetNodeInfo(node).Value)
  351. }
  352. for node := range tt.mustNotExist {
  353. assert.False(t, got.Exists(node), node)
  354. }
  355. assert.ElementsMatch(t, tt.wantExclude, excluded)
  356. })
  357. }
  358. }
  359. func TestUpgradeService_GraphUpgradesNoUpdates(t *testing.T) {
  360. t.Parallel()
  361. dbExe := &mock.DBExecutor{
  362. InstalledRemotePackageNamesFn: func() []string {
  363. return []string{"yay", "example-git"}
  364. },
  365. InstalledRemotePackagesFn: func() map[string]mock.IPackage {
  366. mapRemote := make(map[string]mock.IPackage)
  367. mapRemote["yay"] = &mock.Package{
  368. PName: "yay",
  369. PBase: "yay",
  370. PVersion: "10.2.3",
  371. PReason: alpm.PkgReasonExplicit,
  372. }
  373. mapRemote["example-git"] = &mock.Package{
  374. PName: "example-git",
  375. PBase: "example",
  376. PVersion: "2.2.1.r32.41baa362-1",
  377. PReason: alpm.PkgReasonDepend,
  378. }
  379. return mapRemote
  380. },
  381. SyncUpgradesFn: func(bool) (map[string]db.SyncUpgrade, error) {
  382. mapUpgrades := make(map[string]db.SyncUpgrade)
  383. return mapUpgrades, nil
  384. },
  385. ReposFn: func() []string { return []string{"core"} },
  386. }
  387. vcsStore := &vcs.Mock{
  388. ToUpgradeReturn: []string{},
  389. }
  390. mockAUR := &mockaur.MockAUR{
  391. GetFn: func(ctx context.Context, query *aur.Query) ([]aur.Pkg, error) {
  392. return []aur.Pkg{}, nil
  393. },
  394. }
  395. type fields struct {
  396. input io.Reader
  397. output io.Writer
  398. noConfirm bool
  399. devel bool
  400. }
  401. type args struct {
  402. graph *topo.Graph[string, *dep.InstallInfo]
  403. enableDowngrade bool
  404. }
  405. tests := []struct {
  406. name string
  407. fields fields
  408. args args
  409. mustExist map[string]*dep.InstallInfo
  410. mustNotExist map[string]bool
  411. wantExclude []string
  412. wantErr bool
  413. }{
  414. {
  415. name: "no input",
  416. fields: fields{
  417. input: strings.NewReader(""),
  418. output: io.Discard,
  419. noConfirm: false,
  420. },
  421. args: args{
  422. graph: nil,
  423. enableDowngrade: false,
  424. },
  425. mustExist: map[string]*dep.InstallInfo{},
  426. mustNotExist: map[string]bool{},
  427. wantErr: false,
  428. wantExclude: []string{},
  429. },
  430. }
  431. for _, tt := range tests {
  432. t.Run(tt.name, func(t *testing.T) {
  433. grapher := dep.NewGrapher(dbExe, mockAUR,
  434. false, true, false, false, false, text.NewLogger(tt.fields.output, os.Stderr,
  435. tt.fields.input, true, "test"))
  436. cfg := &settings.Configuration{
  437. Devel: tt.fields.devel,
  438. Mode: parser.ModeAny,
  439. }
  440. logger := text.NewLogger(tt.fields.output, os.Stderr,
  441. tt.fields.input, true, "test")
  442. u := &UpgradeService{
  443. log: logger,
  444. grapher: grapher,
  445. aurCache: mockAUR,
  446. dbExecutor: dbExe,
  447. vcsStore: vcsStore,
  448. cfg: cfg,
  449. noConfirm: tt.fields.noConfirm,
  450. AURWarnings: query.NewWarnings(logger),
  451. }
  452. got, err := u.GraphUpgrades(context.Background(), tt.args.graph, tt.args.enableDowngrade, func(*Upgrade) bool { return true })
  453. if (err != nil) != tt.wantErr {
  454. t.Errorf("UpgradeService.GraphUpgrades() error = %v, wantErr %v", err, tt.wantErr)
  455. return
  456. }
  457. excluded, err := u.UserExcludeUpgrades(got)
  458. require.NoError(t, err)
  459. for node, info := range tt.mustExist {
  460. assert.True(t, got.Exists(node), node)
  461. assert.Equal(t, info, got.GetNodeInfo(node).Value)
  462. }
  463. for node := range tt.mustNotExist {
  464. assert.False(t, got.Exists(node), node)
  465. }
  466. assert.ElementsMatch(t, tt.wantExclude, excluded)
  467. })
  468. }
  469. }
  470. func TestUpgradeService_Warnings(t *testing.T) {
  471. t.Parallel()
  472. dbExe := &mock.DBExecutor{
  473. InstalledRemotePackageNamesFn: func() []string {
  474. return []string{"orphan", "outdated", "missing", "orphan-ignored"}
  475. },
  476. InstalledRemotePackagesFn: func() map[string]mock.IPackage {
  477. mapRemote := make(map[string]mock.IPackage)
  478. mapRemote["orphan"] = &mock.Package{
  479. PName: "orphan",
  480. PBase: "orphan",
  481. PVersion: "10.2.3",
  482. PReason: alpm.PkgReasonExplicit,
  483. }
  484. mapRemote["outdated"] = &mock.Package{
  485. PName: "outdated",
  486. PBase: "outdated",
  487. PVersion: "10.2.3",
  488. PReason: alpm.PkgReasonExplicit,
  489. }
  490. mapRemote["missing"] = &mock.Package{
  491. PName: "missing",
  492. PBase: "missing",
  493. PVersion: "10.2.3",
  494. PReason: alpm.PkgReasonExplicit,
  495. }
  496. mapRemote["orphan-ignored"] = &mock.Package{
  497. PName: "orphan-ignored",
  498. PBase: "orphan-ignored",
  499. PVersion: "10.2.3",
  500. PReason: alpm.PkgReasonExplicit,
  501. PShouldIgnore: true,
  502. }
  503. return mapRemote
  504. },
  505. LocalSatisfierExistsFn: func(string) bool { return false },
  506. SyncSatisfierFn: func(s string) mock.IPackage {
  507. return nil
  508. },
  509. SyncUpgradesFn: func(bool) (map[string]db.SyncUpgrade, error) {
  510. mapUpgrades := make(map[string]db.SyncUpgrade)
  511. return mapUpgrades, nil
  512. },
  513. ReposFn: func() []string { return []string{"core"} },
  514. }
  515. vcsStore := &vcs.Mock{
  516. ToUpgradeReturn: []string{},
  517. }
  518. mockAUR := &mockaur.MockAUR{
  519. GetFn: func(ctx context.Context, query *aur.Query) ([]aur.Pkg, error) {
  520. return []aur.Pkg{
  521. {
  522. Name: "outdated", Version: "10.2.4", PackageBase: "orphan",
  523. OutOfDate: 100, Maintainer: "bob",
  524. },
  525. {
  526. Name: "orphan", Version: "10.2.4", PackageBase: "orphan",
  527. Maintainer: "",
  528. },
  529. }, nil
  530. },
  531. }
  532. logger := text.NewLogger(io.Discard, os.Stderr,
  533. strings.NewReader("\n"), true, "test")
  534. grapher := dep.NewGrapher(dbExe, mockAUR,
  535. false, true, false, false, false, logger)
  536. cfg := &settings.Configuration{
  537. Devel: false, Mode: parser.ModeAUR,
  538. }
  539. u := &UpgradeService{
  540. log: logger,
  541. grapher: grapher,
  542. aurCache: mockAUR,
  543. dbExecutor: dbExe,
  544. vcsStore: vcsStore,
  545. cfg: cfg,
  546. noConfirm: true,
  547. AURWarnings: query.NewWarnings(logger),
  548. }
  549. _, err := u.GraphUpgrades(context.Background(), nil, false, func(*Upgrade) bool { return true })
  550. require.NoError(t, err)
  551. assert.Equal(t, []string{"missing"}, u.AURWarnings.Missing)
  552. assert.Equal(t, []string{"outdated"}, u.AURWarnings.OutOfDate)
  553. assert.Equal(t, []string{"orphan"}, u.AURWarnings.Orphans)
  554. }
  555. func TestUpgradeService_GraphUpgrades_zfs_dkms(t *testing.T) {
  556. t.Parallel()
  557. zfsDKMSInfo := &dep.InstallInfo{
  558. Reason: dep.Explicit,
  559. Source: dep.AUR,
  560. AURBase: ptrString("zfs-dkms"),
  561. LocalVersion: "2.1.10-1",
  562. Version: "2.1.11-1",
  563. Upgrade: true,
  564. Devel: false,
  565. }
  566. zfsUtilsInfo := &dep.InstallInfo{
  567. Reason: dep.Dep,
  568. Source: dep.AUR,
  569. AURBase: ptrString("zfs-utils"),
  570. LocalVersion: "2.1.10-1",
  571. Version: "2.1.11-1",
  572. Upgrade: true,
  573. Devel: false,
  574. }
  575. vcsStore := &vcs.Mock{ToUpgradeReturn: []string{}}
  576. mockAUR := &mockaur.MockAUR{
  577. GetFn: func(ctx context.Context, query *aur.Query) ([]aur.Pkg, error) {
  578. if len(query.Needles) == 2 {
  579. return []aur.Pkg{
  580. {
  581. Name: "zfs-dkms", Version: "2.1.11-1",
  582. PackageBase: "zfs-dkms", Depends: []string{"zfs-utils=2.1.11"},
  583. },
  584. {Name: "zfs-utils", Version: "2.1.11-1", PackageBase: "zfs-utils"},
  585. }, nil
  586. }
  587. if len(query.Needles) == 1 {
  588. return []aur.Pkg{
  589. {Name: "zfs-utils", Version: "2.1.11-1", PackageBase: "zfs-utils"},
  590. }, nil
  591. }
  592. panic("not implemented")
  593. },
  594. }
  595. type fields struct {
  596. input io.Reader
  597. noConfirm bool
  598. devel bool
  599. }
  600. type args struct {
  601. graph *topo.Graph[string, *dep.InstallInfo]
  602. enableDowngrade bool
  603. }
  604. tests := []struct {
  605. name string
  606. fields fields
  607. args args
  608. mustExist map[string]*dep.InstallInfo
  609. mustNotExist map[string]bool
  610. wantExclude []string
  611. wantErr bool
  612. remotePackages []string
  613. }{
  614. {
  615. name: "no input",
  616. fields: fields{
  617. input: strings.NewReader("\n"),
  618. noConfirm: false,
  619. },
  620. args: args{
  621. graph: nil,
  622. enableDowngrade: false,
  623. },
  624. mustExist: map[string]*dep.InstallInfo{
  625. "zfs-dkms": zfsDKMSInfo,
  626. "zfs-utils": zfsUtilsInfo,
  627. },
  628. remotePackages: []string{"zfs-utils", "zfs-dkms"},
  629. mustNotExist: map[string]bool{},
  630. wantErr: false,
  631. wantExclude: []string{},
  632. },
  633. {
  634. name: "no input - inverted order",
  635. fields: fields{
  636. input: strings.NewReader("\n"),
  637. noConfirm: false,
  638. },
  639. args: args{
  640. graph: nil,
  641. enableDowngrade: false,
  642. },
  643. mustExist: map[string]*dep.InstallInfo{
  644. "zfs-dkms": zfsDKMSInfo,
  645. "zfs-utils": zfsUtilsInfo,
  646. },
  647. remotePackages: []string{"zfs-dkms", "zfs-utils"},
  648. mustNotExist: map[string]bool{},
  649. wantErr: false,
  650. wantExclude: []string{},
  651. },
  652. }
  653. for _, tt := range tests {
  654. tt := tt
  655. t.Run(tt.name, func(t *testing.T) {
  656. t.Parallel()
  657. dbExe := &mock.DBExecutor{
  658. InstalledRemotePackageNamesFn: func() []string {
  659. return tt.remotePackages
  660. },
  661. InstalledRemotePackagesFn: func() map[string]mock.IPackage {
  662. mapRemote := make(map[string]mock.IPackage)
  663. mapRemote["zfs-dkms"] = &mock.Package{
  664. PName: "zfs-dkms",
  665. PBase: "zfs-dkms",
  666. PVersion: "2.1.10-1",
  667. PReason: alpm.PkgReasonExplicit,
  668. PDepends: mock.DependList{Depends: []alpm.Depend{
  669. {Name: "zfs-utils", Version: "2.1.10-1"},
  670. }},
  671. }
  672. mapRemote["zfs-utils"] = &mock.Package{
  673. PName: "zfs-utils",
  674. PBase: "zfs-utils",
  675. PVersion: "2.1.10-1",
  676. PReason: alpm.PkgReasonDepend,
  677. }
  678. return mapRemote
  679. },
  680. LocalSatisfierExistsFn: func(string) bool { return false },
  681. SyncSatisfierFn: func(s string) mock.IPackage {
  682. return nil
  683. },
  684. SyncUpgradesFn: func(bool) (map[string]db.SyncUpgrade, error) {
  685. mapUpgrades := make(map[string]db.SyncUpgrade)
  686. return mapUpgrades, nil
  687. },
  688. ReposFn: func() []string { return []string{"core"} },
  689. }
  690. logger := text.NewLogger(io.Discard, os.Stderr,
  691. tt.fields.input, true, "test")
  692. grapher := dep.NewGrapher(dbExe, mockAUR,
  693. false, true, false, false, false, logger)
  694. cfg := &settings.Configuration{
  695. Devel: tt.fields.devel, Mode: parser.ModeAny,
  696. }
  697. u := &UpgradeService{
  698. log: logger,
  699. grapher: grapher,
  700. aurCache: mockAUR,
  701. dbExecutor: dbExe,
  702. vcsStore: vcsStore,
  703. cfg: cfg,
  704. noConfirm: tt.fields.noConfirm,
  705. AURWarnings: query.NewWarnings(logger),
  706. }
  707. got, err := u.GraphUpgrades(context.Background(), tt.args.graph, tt.args.enableDowngrade, func(*Upgrade) bool { return true })
  708. if (err != nil) != tt.wantErr {
  709. t.Errorf("UpgradeService.GraphUpgrades() error = %v, wantErr %v", err, tt.wantErr)
  710. return
  711. }
  712. excluded, err := u.UserExcludeUpgrades(got)
  713. require.NoError(t, err)
  714. for node, info := range tt.mustExist {
  715. assert.True(t, got.Exists(node), node)
  716. assert.Equal(t, info, got.GetNodeInfo(node).Value)
  717. }
  718. for node := range tt.mustNotExist {
  719. assert.False(t, got.Exists(node), node)
  720. }
  721. assert.ElementsMatch(t, tt.wantExclude, excluded)
  722. })
  723. }
  724. }