service_test.go 20 KB

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