mirror of
https://github.com/mudler/luet.git
synced 2025-09-01 23:37:07 +00:00
Make solver consume databases instead of world lists
first step - it is slower in the implementation for now, but all cases seems to be sorted out. Drop Flagged() and IsSet() from solver. the solver wont care, and only the assertion value does matter (exception for uninstall)
This commit is contained in:
@@ -22,7 +22,7 @@ import (
|
|||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
pkg "github.com/mudler/luet/pkg/package"
|
pkg "github.com/mudler/luet/pkg/package"
|
||||||
"github.com/philopon/go-toposort"
|
toposort "github.com/philopon/go-toposort"
|
||||||
"github.com/stevenle/topsort"
|
"github.com/stevenle/topsort"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -88,7 +88,7 @@ func (assertions PackagesAssertions) EnsureOrder() PackagesAssertions {
|
|||||||
fingerprints = append(fingerprints, a.Package.GetFingerPrint())
|
fingerprints = append(fingerprints, a.Package.GetFingerPrint())
|
||||||
unorderedAssertions = append(unorderedAssertions, a) // Build a list of the ones that must be ordered
|
unorderedAssertions = append(unorderedAssertions, a) // Build a list of the ones that must be ordered
|
||||||
|
|
||||||
if a.Package.Flagged() && a.Value {
|
if a.Value {
|
||||||
unorderedAssertions = append(unorderedAssertions, a) // Build a list of the ones that must be ordered
|
unorderedAssertions = append(unorderedAssertions, a) // Build a list of the ones that must be ordered
|
||||||
} else {
|
} else {
|
||||||
orderedAssertions = append(orderedAssertions, a) // Keep last the ones which are not meant to be installed
|
orderedAssertions = append(orderedAssertions, a) // Keep last the ones which are not meant to be installed
|
||||||
@@ -137,7 +137,7 @@ func (assertions PackagesAssertions) Order(fingerprint string) PackagesAssertion
|
|||||||
fingerprints = append(fingerprints, a.Package.GetFingerPrint())
|
fingerprints = append(fingerprints, a.Package.GetFingerPrint())
|
||||||
unorderedAssertions = append(unorderedAssertions, a) // Build a list of the ones that must be ordered
|
unorderedAssertions = append(unorderedAssertions, a) // Build a list of the ones that must be ordered
|
||||||
|
|
||||||
if a.Package.Flagged() && a.Value {
|
if a.Value {
|
||||||
unorderedAssertions = append(unorderedAssertions, a) // Build a list of the ones that must be ordered
|
unorderedAssertions = append(unorderedAssertions, a) // Build a list of the ones that must be ordered
|
||||||
} else {
|
} else {
|
||||||
orderedAssertions = append(orderedAssertions, a) // Keep last the ones which are not meant to be installed
|
orderedAssertions = append(orderedAssertions, a) // Keep last the ones which are not meant to be installed
|
||||||
@@ -215,7 +215,7 @@ func (a PackagesAssertions) Less(i, j int) bool {
|
|||||||
func (assertions PackagesAssertions) AssertionHash() string {
|
func (assertions PackagesAssertions) AssertionHash() string {
|
||||||
var fingerprint string
|
var fingerprint string
|
||||||
for _, assertion := range assertions { // Note: Always order them first!
|
for _, assertion := range assertions { // Note: Always order them first!
|
||||||
if assertion.Value && assertion.Package.Flagged() { // Tke into account only dependencies installed (get fingerprint of subgraph)
|
if assertion.Value { // Tke into account only dependencies installed (get fingerprint of subgraph)
|
||||||
fingerprint += assertion.ToString() + "\n"
|
fingerprint += assertion.ToString() + "\n"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -26,11 +26,22 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var _ = Describe("Decoder", func() {
|
var _ = Describe("Decoder", func() {
|
||||||
|
db := pkg.NewInMemoryDatabase(false)
|
||||||
|
dbInstalled := pkg.NewInMemoryDatabase(false)
|
||||||
|
dbDefinitions := pkg.NewInMemoryDatabase(false)
|
||||||
|
s := NewSolver(dbInstalled, dbDefinitions, db)
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
db = pkg.NewInMemoryDatabase(false)
|
||||||
|
dbInstalled = pkg.NewInMemoryDatabase(false)
|
||||||
|
dbDefinitions = pkg.NewInMemoryDatabase(false)
|
||||||
|
s = NewSolver(dbInstalled, dbDefinitions, db)
|
||||||
|
})
|
||||||
|
|
||||||
Context("Assertion ordering", func() {
|
Context("Assertion ordering", func() {
|
||||||
eq := 0
|
eq := 0
|
||||||
for index := 0; index < 300; index++ { // Just to make sure we don't have false positives
|
for index := 0; index < 300; index++ { // Just to make sure we don't have false positives
|
||||||
It("Orders them correctly #"+strconv.Itoa(index), func() {
|
It("Orders them correctly #"+strconv.Itoa(index), func() {
|
||||||
db := pkg.NewInMemoryDatabase(false)
|
|
||||||
|
|
||||||
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
E := pkg.NewPackage("E", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
E := pkg.NewPackage("E", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
@@ -41,15 +52,23 @@ var _ = Describe("Decoder", func() {
|
|||||||
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{D}, []*pkg.DefaultPackage{})
|
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{D}, []*pkg.DefaultPackage{})
|
||||||
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{B}, []*pkg.DefaultPackage{})
|
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{B}, []*pkg.DefaultPackage{})
|
||||||
|
|
||||||
s := NewSolver([]pkg.Package{C}, []pkg.Package{A, B, C, D, E, F, G}, db)
|
for _, p := range []pkg.Package{A, B, C, D, E, F, G} {
|
||||||
|
_, err := dbDefinitions.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range []pkg.Package{C} {
|
||||||
|
_, err := dbInstalled.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
solution, err := s.Install([]pkg.Package{A})
|
solution, err := s.Install([]pkg.Package{A})
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: A.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: A, Value: true}))
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: B.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: B, Value: true}))
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: D.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: D, Value: true}))
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: C.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: C, Value: true}))
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: H.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: H, Value: true}))
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: G.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: G, Value: true}))
|
||||||
|
|
||||||
Expect(len(solution)).To(Equal(6))
|
Expect(len(solution)).To(Equal(6))
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
@@ -73,7 +92,6 @@ var _ = Describe("Decoder", func() {
|
|||||||
equality := 0
|
equality := 0
|
||||||
for index := 0; index < 300; index++ { // Just to make sure we don't have false positives
|
for index := 0; index < 300; index++ { // Just to make sure we don't have false positives
|
||||||
It("Doesn't order them correctly otherwise #"+strconv.Itoa(index), func() {
|
It("Doesn't order them correctly otherwise #"+strconv.Itoa(index), func() {
|
||||||
db := pkg.NewInMemoryDatabase(false)
|
|
||||||
|
|
||||||
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
E := pkg.NewPackage("E", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
E := pkg.NewPackage("E", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
@@ -84,15 +102,23 @@ var _ = Describe("Decoder", func() {
|
|||||||
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{D}, []*pkg.DefaultPackage{})
|
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{D}, []*pkg.DefaultPackage{})
|
||||||
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{B}, []*pkg.DefaultPackage{})
|
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{B}, []*pkg.DefaultPackage{})
|
||||||
|
|
||||||
s := NewSolver([]pkg.Package{C}, []pkg.Package{A, B, C, D, E, F, G}, db)
|
for _, p := range []pkg.Package{A, B, C, D, E, F, G} {
|
||||||
|
_, err := dbDefinitions.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range []pkg.Package{C} {
|
||||||
|
_, err := dbInstalled.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
solution, err := s.Install([]pkg.Package{A})
|
solution, err := s.Install([]pkg.Package{A})
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: A.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: A, Value: true}))
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: B.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: B, Value: true}))
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: D.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: D, Value: true}))
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: C.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: C, Value: true}))
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: H.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: H, Value: true}))
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: G.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: G, Value: true}))
|
||||||
|
|
||||||
Expect(len(solution)).To(Equal(6))
|
Expect(len(solution)).To(Equal(6))
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
@@ -132,7 +158,6 @@ var _ = Describe("Decoder", func() {
|
|||||||
|
|
||||||
Context("Assertion hashing", func() {
|
Context("Assertion hashing", func() {
|
||||||
It("Hashes them, and could be used for comparison", func() {
|
It("Hashes them, and could be used for comparison", func() {
|
||||||
db := pkg.NewInMemoryDatabase(false)
|
|
||||||
|
|
||||||
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
E := pkg.NewPackage("E", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
E := pkg.NewPackage("E", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
@@ -143,15 +168,23 @@ var _ = Describe("Decoder", func() {
|
|||||||
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{D}, []*pkg.DefaultPackage{})
|
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{D}, []*pkg.DefaultPackage{})
|
||||||
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{B}, []*pkg.DefaultPackage{})
|
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{B}, []*pkg.DefaultPackage{})
|
||||||
|
|
||||||
s := NewSolver([]pkg.Package{C}, []pkg.Package{A, B, C, D, E, F, G}, db)
|
for _, p := range []pkg.Package{A, B, C, D, E, F, G} {
|
||||||
|
_, err := dbDefinitions.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range []pkg.Package{C} {
|
||||||
|
_, err := dbInstalled.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
solution, err := s.Install([]pkg.Package{A})
|
solution, err := s.Install([]pkg.Package{A})
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: A.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: A, Value: true}))
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: B.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: B, Value: true}))
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: D.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: D, Value: true}))
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: C.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: C, Value: true}))
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: H.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: H, Value: true}))
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: G.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: G, Value: true}))
|
||||||
|
|
||||||
Expect(len(solution)).To(Equal(6))
|
Expect(len(solution)).To(Equal(6))
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
@@ -165,11 +198,11 @@ var _ = Describe("Decoder", func() {
|
|||||||
hash := solution.AssertionHash()
|
hash := solution.AssertionHash()
|
||||||
|
|
||||||
solution, err = s.Install([]pkg.Package{B})
|
solution, err = s.Install([]pkg.Package{B})
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: B.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: B, Value: true}))
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: D.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: D, Value: true}))
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: C.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: C, Value: true}))
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: H.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: H, Value: true}))
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: G.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: G, Value: true}))
|
||||||
|
|
||||||
Expect(len(solution)).To(Equal(6))
|
Expect(len(solution)).To(Equal(6))
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
@@ -183,18 +216,29 @@ var _ = Describe("Decoder", func() {
|
|||||||
Expect(solution[3].Package.GetName()).To(Equal("D"))
|
Expect(solution[3].Package.GetName()).To(Equal("D"))
|
||||||
Expect(solution[4].Package.GetName()).To(Equal("B"))
|
Expect(solution[4].Package.GetName()).To(Equal("B"))
|
||||||
Expect(solution[0].Value).ToNot(BeTrue())
|
Expect(solution[0].Value).ToNot(BeTrue())
|
||||||
Expect(solution[0].Package.Flagged()).To(BeTrue())
|
|
||||||
|
|
||||||
Expect(hash).ToNot(Equal(""))
|
Expect(hash).ToNot(Equal(""))
|
||||||
Expect(hash2).ToNot(Equal(""))
|
Expect(hash2).ToNot(Equal(""))
|
||||||
Expect(hash != hash2).To(BeTrue())
|
Expect(hash != hash2).To(BeTrue())
|
||||||
db2 := pkg.NewInMemoryDatabase(false)
|
|
||||||
|
})
|
||||||
|
It("Hashes them, and could be used for comparison", func() {
|
||||||
|
|
||||||
X := pkg.NewPackage("X", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
X := pkg.NewPackage("X", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
Y := pkg.NewPackage("Y", "", []*pkg.DefaultPackage{X}, []*pkg.DefaultPackage{})
|
Y := pkg.NewPackage("Y", "", []*pkg.DefaultPackage{X}, []*pkg.DefaultPackage{})
|
||||||
Z := pkg.NewPackage("Z", "", []*pkg.DefaultPackage{X}, []*pkg.DefaultPackage{})
|
Z := pkg.NewPackage("Z", "", []*pkg.DefaultPackage{X}, []*pkg.DefaultPackage{})
|
||||||
s = NewSolver([]pkg.Package{}, []pkg.Package{X, Y, Z}, db2)
|
|
||||||
solution, err = s.Install([]pkg.Package{Y})
|
for _, p := range []pkg.Package{X, Y, Z} {
|
||||||
|
_, err := dbDefinitions.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range []pkg.Package{} {
|
||||||
|
_, err := dbInstalled.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
solution, err := s.Install([]pkg.Package{Y})
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
solution2, err := s.Install([]pkg.Package{Z})
|
solution2, err := s.Install([]pkg.Package{Z})
|
||||||
|
@@ -16,9 +16,11 @@
|
|||||||
package solver
|
package solver
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
|
//. "github.com/mudler/luet/pkg/logger"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"github.com/crillab/gophersat/bf"
|
"github.com/crillab/gophersat/bf"
|
||||||
version "github.com/hashicorp/go-version"
|
version "github.com/hashicorp/go-version"
|
||||||
pkg "github.com/mudler/luet/pkg/package"
|
pkg "github.com/mudler/luet/pkg/package"
|
||||||
@@ -26,32 +28,57 @@ import (
|
|||||||
|
|
||||||
// PackageSolver is an interface to a generic package solving algorithm
|
// PackageSolver is an interface to a generic package solving algorithm
|
||||||
type PackageSolver interface {
|
type PackageSolver interface {
|
||||||
SetWorld(p []pkg.Package)
|
SetDefinitionDatabase(pkg.PackageDatabase)
|
||||||
Install(p []pkg.Package) (PackagesAssertions, error)
|
Install(p []pkg.Package) (PackagesAssertions, error)
|
||||||
Uninstall(candidate pkg.Package) ([]pkg.Package, error)
|
Uninstall(candidate pkg.Package) ([]pkg.Package, error)
|
||||||
ConflictsWithInstalled(p pkg.Package) (bool, error)
|
ConflictsWithInstalled(p pkg.Package) (bool, error)
|
||||||
ConflictsWith(p pkg.Package, ls []pkg.Package) (bool, error)
|
ConflictsWith(p pkg.Package, ls []pkg.Package) (bool, error)
|
||||||
Best([]pkg.Package) pkg.Package
|
Best([]pkg.Package) pkg.Package
|
||||||
|
World() []pkg.Package
|
||||||
}
|
}
|
||||||
|
|
||||||
// Solver is the default solver for luet
|
// Solver is the default solver for luet
|
||||||
type Solver struct {
|
type Solver struct {
|
||||||
|
DefinitionDatabase pkg.PackageDatabase
|
||||||
SolverDatabase pkg.PackageDatabase
|
SolverDatabase pkg.PackageDatabase
|
||||||
Wanted []pkg.Package
|
Wanted []pkg.Package
|
||||||
Installed []pkg.Package
|
InstalledDatabase pkg.PackageDatabase
|
||||||
World []pkg.Package
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSolver accepts as argument two lists of packages, the first is the initial set,
|
// NewSolver accepts as argument two lists of packages, the first is the initial set,
|
||||||
// the second represent all the known packages.
|
// the second represent all the known packages.
|
||||||
func NewSolver(init []pkg.Package, w []pkg.Package, solverdb pkg.PackageDatabase) PackageSolver {
|
func NewSolver(installed pkg.PackageDatabase, definitiondb pkg.PackageDatabase, solverdb pkg.PackageDatabase) PackageSolver {
|
||||||
for _, v := range init {
|
// inst := pkg.NewInMemoryDatabase(false)
|
||||||
pkg.NormalizeFlagged(v)
|
// def := pkg.NewInMemoryDatabase(false)
|
||||||
}
|
// // // FIXME: This should all be locked in the db - for now forbid the solver to be run in threads.
|
||||||
for _, v := range w {
|
// for _, k := range installed.GetPackages() {
|
||||||
pkg.NormalizeFlagged(v)
|
// pack, err := installed.GetPackage(k)
|
||||||
}
|
// if err == nil {
|
||||||
return &Solver{Installed: init, World: w, SolverDatabase: solverdb}
|
// inst.CreatePackage(pack)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// for _, k := range definitiondb.GetPackages() {
|
||||||
|
// pack, err := definitiondb.GetPackage(k)
|
||||||
|
// if err == nil {
|
||||||
|
// def.CreatePackage(pack)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// // FIXME:
|
||||||
|
// for _, k := range inst.GetPackages() {
|
||||||
|
// pack, err := inst.GetPackage(k)
|
||||||
|
// if err == nil {
|
||||||
|
|
||||||
|
// pkg.NormalizeFlagged(inst, pack)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// for _, k := range def.GetPackages() {
|
||||||
|
// pack, err := def.GetPackage(k)
|
||||||
|
// if err == nil {
|
||||||
|
|
||||||
|
// pkg.NormalizeFlagged(def, pack)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
return &Solver{InstalledDatabase: installed, DefinitionDatabase: definitiondb, SolverDatabase: solverdb}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: []pkg.Package should have its own type with this kind of methods in (+Unique, sort, etc.)
|
// TODO: []pkg.Package should have its own type with this kind of methods in (+Unique, sort, etc.)
|
||||||
@@ -81,12 +108,36 @@ func (s *Solver) Best(set []pkg.Package) pkg.Package {
|
|||||||
|
|
||||||
// SetWorld is a setter for the list of all known packages to the solver
|
// SetWorld is a setter for the list of all known packages to the solver
|
||||||
|
|
||||||
func (s *Solver) SetWorld(p []pkg.Package) {
|
func (s *Solver) SetDefinitionDatabase(db pkg.PackageDatabase) {
|
||||||
s.World = p
|
s.DefinitionDatabase = db
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Solver) World() []pkg.Package {
|
||||||
|
var all []pkg.Package
|
||||||
|
// FIXME: This should all be locked in the db - for now forbid the solver to be run in threads.
|
||||||
|
for _, k := range s.DefinitionDatabase.GetPackages() {
|
||||||
|
pack, err := s.DefinitionDatabase.GetPackage(k)
|
||||||
|
if err == nil {
|
||||||
|
all = append(all, pack)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return all
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Solver) Installed() []pkg.Package {
|
||||||
|
var all []pkg.Package
|
||||||
|
// FIXME: This should all be locked in the db - for now forbid the solver to be run in threads.
|
||||||
|
for _, k := range s.InstalledDatabase.GetPackages() {
|
||||||
|
pack, err := s.InstalledDatabase.GetPackage(k)
|
||||||
|
if err == nil {
|
||||||
|
all = append(all, pack)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return all
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Solver) noRulesWorld() bool {
|
func (s *Solver) noRulesWorld() bool {
|
||||||
for _, p := range s.World {
|
for _, p := range s.World() {
|
||||||
if len(p.GetConflicts()) != 0 || len(p.GetRequires()) != 0 {
|
if len(p.GetConflicts()) != 0 || len(p.GetRequires()) != 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -97,8 +148,8 @@ func (s *Solver) noRulesWorld() bool {
|
|||||||
|
|
||||||
func (s *Solver) BuildInstalled() (bf.Formula, error) {
|
func (s *Solver) BuildInstalled() (bf.Formula, error) {
|
||||||
var formulas []bf.Formula
|
var formulas []bf.Formula
|
||||||
for _, p := range s.Installed {
|
for _, p := range s.Installed() {
|
||||||
solvable, err := p.BuildFormula(s.SolverDatabase)
|
solvable, err := p.BuildFormula(s.DefinitionDatabase, s.SolverDatabase)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -124,8 +175,8 @@ func (s *Solver) BuildWorld(includeInstalled bool) (bf.Formula, error) {
|
|||||||
formulas = append(formulas, solvable)
|
formulas = append(formulas, solvable)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, p := range s.World {
|
for _, p := range s.World() {
|
||||||
solvable, err := p.BuildFormula(s.SolverDatabase)
|
solvable, err := p.BuildFormula(s.DefinitionDatabase, s.SolverDatabase)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -134,15 +185,42 @@ func (s *Solver) BuildWorld(includeInstalled bool) (bf.Formula, error) {
|
|||||||
return bf.And(formulas...), nil
|
return bf.And(formulas...), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Solver) ConflictsWith(p pkg.Package, ls []pkg.Package) (bool, error) {
|
func (s *Solver) getList(db pkg.PackageDatabase, lsp []pkg.Package) ([]pkg.Package, error) {
|
||||||
pkg.NormalizeFlagged(p)
|
var ls []pkg.Package
|
||||||
|
for _, pp := range lsp {
|
||||||
|
cp, err := db.FindPackage(pp)
|
||||||
|
if err != nil {
|
||||||
|
cp = pp //Relax search, otherwise we cannot compute solutions for packages not in definitions
|
||||||
|
|
||||||
|
//return nil, errors.Wrap(err, "Package not found in db")
|
||||||
|
}
|
||||||
|
ls = append(ls, cp)
|
||||||
|
}
|
||||||
|
return ls, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Solver) ConflictsWith(pack pkg.Package, lsp []pkg.Package) (bool, error) {
|
||||||
|
p, err := s.DefinitionDatabase.FindPackage(pack)
|
||||||
|
if err != nil {
|
||||||
|
p = pack //Relax search, otherwise we cannot compute solutions for packages not in definitions
|
||||||
|
|
||||||
|
// return false, errors.Wrap(err, "Package not found in definition db")
|
||||||
|
}
|
||||||
|
|
||||||
|
ls, err := s.getList(s.DefinitionDatabase, lsp)
|
||||||
|
if err != nil {
|
||||||
|
return false, errors.Wrap(err, "Package not found in definition db")
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Needs to be find in package def before encoding!
|
||||||
|
// pkg.NormalizeFlagged(s.DefinitionDatabase, p)
|
||||||
var formulas []bf.Formula
|
var formulas []bf.Formula
|
||||||
|
|
||||||
if s.noRulesWorld() {
|
if s.noRulesWorld() {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
encodedP, err := p.IsFlagged(true).Encode(s.SolverDatabase)
|
encodedP, err := p.Encode(s.SolverDatabase)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
@@ -181,33 +259,45 @@ func (s *Solver) ConflictsWith(p pkg.Package, ls []pkg.Package) (bool, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Solver) ConflictsWithInstalled(p pkg.Package) (bool, error) {
|
func (s *Solver) ConflictsWithInstalled(p pkg.Package) (bool, error) {
|
||||||
return s.ConflictsWith(p, s.Installed)
|
return s.ConflictsWith(p, s.Installed())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uninstall takes a candidate package and return a list of packages that would be removed
|
// Uninstall takes a candidate package and return a list of packages that would be removed
|
||||||
// in order to purge the candidate. Returns error if unsat.
|
// in order to purge the candidate. Returns error if unsat.
|
||||||
func (s *Solver) Uninstall(candidate pkg.Package) ([]pkg.Package, error) {
|
func (s *Solver) Uninstall(c pkg.Package) ([]pkg.Package, error) {
|
||||||
var res []pkg.Package
|
var res []pkg.Package
|
||||||
|
candidate, err := s.InstalledDatabase.FindPackage(c)
|
||||||
|
if err != nil {
|
||||||
|
candidate = c //Relax search, otherwise we cannot compute solutions for packages not in definitions
|
||||||
|
// return nil, errors.Wrap(err, "Package not found between installed")
|
||||||
|
}
|
||||||
// Build a fake "Installed" - Candidate and its requires tree
|
// Build a fake "Installed" - Candidate and its requires tree
|
||||||
var InstalledMinusCandidate []pkg.Package
|
var InstalledMinusCandidate []pkg.Package
|
||||||
for _, i := range s.Installed {
|
|
||||||
if !i.Matches(candidate) && !candidate.RequiresContains(i) {
|
// TODO: Can be optimized
|
||||||
|
for _, i := range s.Installed() {
|
||||||
|
if !i.Matches(candidate) {
|
||||||
|
contains, err := candidate.RequiresContains(s.SolverDatabase, i)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "Failed getting installed list")
|
||||||
|
}
|
||||||
|
if !contains {
|
||||||
InstalledMinusCandidate = append(InstalledMinusCandidate, i)
|
InstalledMinusCandidate = append(InstalledMinusCandidate, i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Get the requirements to install the candidate
|
// Get the requirements to install the candidate
|
||||||
saved := s.Installed
|
saved := s.InstalledDatabase
|
||||||
s.Installed = []pkg.Package{}
|
s.InstalledDatabase = pkg.NewInMemoryDatabase(false)
|
||||||
asserts, err := s.Install([]pkg.Package{candidate})
|
asserts, err := s.Install([]pkg.Package{candidate})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
s.Installed = saved
|
s.InstalledDatabase = saved
|
||||||
|
|
||||||
for _, a := range asserts {
|
for _, a := range asserts {
|
||||||
if a.Value && a.Package.Flagged() {
|
if a.Value {
|
||||||
|
|
||||||
c, err := s.ConflictsWithInstalled(a.Package)
|
c, err := s.ConflictsWithInstalled(a.Package)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -249,13 +339,14 @@ func (s *Solver) BuildFormula() (bf.Formula, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
W := bf.Var(encodedW)
|
W := bf.Var(encodedW)
|
||||||
|
installedWorld := s.Installed()
|
||||||
if len(s.Installed) == 0 {
|
//TODO:Optimize
|
||||||
|
if len(installedWorld) == 0 {
|
||||||
formulas = append(formulas, W) //bf.And(bf.True, W))
|
formulas = append(formulas, W) //bf.And(bf.True, W))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, installed := range s.Installed {
|
for _, installed := range installedWorld {
|
||||||
encodedI, err := installed.Encode(s.SolverDatabase)
|
encodedI, err := installed.Encode(s.SolverDatabase)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -297,23 +388,23 @@ func (s *Solver) Solve() (PackagesAssertions, error) {
|
|||||||
|
|
||||||
// Install given a list of packages, returns package assertions to indicate the packages that must be installed in the system in order
|
// Install given a list of packages, returns package assertions to indicate the packages that must be installed in the system in order
|
||||||
// to statisfy all the constraints
|
// to statisfy all the constraints
|
||||||
func (s *Solver) Install(coll []pkg.Package) (PackagesAssertions, error) {
|
func (s *Solver) Install(c []pkg.Package) (PackagesAssertions, error) {
|
||||||
for _, v := range coll {
|
|
||||||
v.IsFlagged(false)
|
coll, err := s.getList(s.DefinitionDatabase, c)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "Packages not found in definition db")
|
||||||
}
|
}
|
||||||
|
|
||||||
s.Wanted = coll
|
s.Wanted = coll
|
||||||
|
|
||||||
if s.noRulesWorld() {
|
if s.noRulesWorld() {
|
||||||
var ass PackagesAssertions
|
var ass PackagesAssertions
|
||||||
for _, p := range s.Installed {
|
for _, p := range s.Installed() {
|
||||||
pp := p.IsFlagged(true)
|
ass = append(ass, PackageAssert{Package: p.(*pkg.DefaultPackage), Value: true})
|
||||||
ass = append(ass, PackageAssert{Package: pp.(*pkg.DefaultPackage), Value: true})
|
|
||||||
|
|
||||||
}
|
}
|
||||||
for _, p := range s.Wanted {
|
for _, p := range s.Wanted {
|
||||||
pp := p.IsFlagged(true)
|
ass = append(ass, PackageAssert{Package: p.(*pkg.DefaultPackage), Value: true})
|
||||||
|
|
||||||
ass = append(ass, PackageAssert{Package: pp.(*pkg.DefaultPackage), Value: true})
|
|
||||||
}
|
}
|
||||||
return ass, nil
|
return ass, nil
|
||||||
}
|
}
|
||||||
|
@@ -17,7 +17,6 @@ package solver_test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
pkg "github.com/mudler/luet/pkg/package"
|
pkg "github.com/mudler/luet/pkg/package"
|
||||||
"github.com/mudler/luet/pkg/solver"
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
@@ -26,38 +25,66 @@ import (
|
|||||||
|
|
||||||
var _ = Describe("Solver", func() {
|
var _ = Describe("Solver", func() {
|
||||||
|
|
||||||
|
db := pkg.NewInMemoryDatabase(false)
|
||||||
|
dbInstalled := pkg.NewInMemoryDatabase(false)
|
||||||
|
dbDefinitions := pkg.NewInMemoryDatabase(false)
|
||||||
|
s := NewSolver(dbInstalled, dbDefinitions, db)
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
db = pkg.NewInMemoryDatabase(false)
|
||||||
|
dbInstalled = pkg.NewInMemoryDatabase(false)
|
||||||
|
dbDefinitions = pkg.NewInMemoryDatabase(false)
|
||||||
|
s = NewSolver(dbInstalled, dbDefinitions, db)
|
||||||
|
})
|
||||||
Context("Simple set", func() {
|
Context("Simple set", func() {
|
||||||
It("Solves correctly if the selected package has no requirements or conflicts and we have nothing installed yet", func() {
|
It("Solves correctly if the selected package has no requirements or conflicts and we have nothing installed yet", func() {
|
||||||
db := pkg.NewInMemoryDatabase(false)
|
|
||||||
|
|
||||||
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
|
|
||||||
s := NewSolver([]pkg.Package{}, []pkg.Package{A, B, C}, db)
|
for _, p := range []pkg.Package{A, B, C} {
|
||||||
|
_, err := dbDefinitions.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range []pkg.Package{} {
|
||||||
|
_, err := dbInstalled.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
s = NewSolver(dbInstalled, dbDefinitions, db)
|
||||||
|
|
||||||
solution, err := s.Install([]pkg.Package{A})
|
solution, err := s.Install([]pkg.Package{A})
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: A.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: A, Value: true}))
|
||||||
Expect(len(solution)).To(Equal(1))
|
Expect(len(solution)).To(Equal(1))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("Solves correctly if the selected package has no requirements or conflicts and we have installed one package", func() {
|
It("Solves correctly if the selected package has no requirements or conflicts and we have installed one package", func() {
|
||||||
db := pkg.NewInMemoryDatabase(false)
|
|
||||||
|
|
||||||
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
|
|
||||||
s := NewSolver([]pkg.Package{C}, []pkg.Package{A, B, C}, db)
|
for _, p := range []pkg.Package{A, B, C} {
|
||||||
|
_, err := dbDefinitions.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range []pkg.Package{C} {
|
||||||
|
_, err := dbInstalled.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
s = NewSolver(dbInstalled, dbDefinitions, db)
|
||||||
|
|
||||||
solution, err := s.Install([]pkg.Package{B})
|
solution, err := s.Install([]pkg.Package{B})
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: B.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: B, Value: true}))
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: C.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: C, Value: true}))
|
||||||
Expect(len(solution)).To(Equal(2))
|
Expect(len(solution)).To(Equal(2))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("Solves correctly if the selected package to install has no requirement or conflicts, but in the world there is one with a requirement", func() {
|
It("Solves correctly if the selected package to install has no requirement or conflicts, but in the world there is one with a requirement", func() {
|
||||||
db := pkg.NewInMemoryDatabase(false)
|
|
||||||
|
|
||||||
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
@@ -65,72 +92,107 @@ var _ = Describe("Solver", func() {
|
|||||||
D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{B}, []*pkg.DefaultPackage{})
|
D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{B}, []*pkg.DefaultPackage{})
|
||||||
E := pkg.NewPackage("E", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
E := pkg.NewPackage("E", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
|
|
||||||
s := NewSolver([]pkg.Package{E, C}, []pkg.Package{A, B, C, D, E}, db)
|
for _, p := range []pkg.Package{A, B, C, D, E} {
|
||||||
|
_, err := dbDefinitions.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range []pkg.Package{E, C} {
|
||||||
|
_, err := dbInstalled.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
s = NewSolver(dbInstalled, dbDefinitions, db)
|
||||||
|
|
||||||
solution, err := s.Install([]pkg.Package{A})
|
solution, err := s.Install([]pkg.Package{A})
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: A.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: A, Value: true}))
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: C.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: C, Value: true}))
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: E.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: E, Value: true}))
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: B.IsFlagged(true).(*pkg.DefaultPackage), Value: false}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: B, Value: false}))
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: D.IsFlagged(true).(*pkg.DefaultPackage), Value: false}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: D, Value: false}))
|
||||||
|
|
||||||
Expect(len(solution)).To(Equal(5))
|
Expect(len(solution)).To(Equal(5))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("Solves correctly if the selected package to install has requirements", func() {
|
It("Solves correctly if the selected package to install has requirements", func() {
|
||||||
db := pkg.NewInMemoryDatabase(false)
|
|
||||||
|
|
||||||
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{D}, []*pkg.DefaultPackage{})
|
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{D}, []*pkg.DefaultPackage{})
|
||||||
|
|
||||||
s := NewSolver([]pkg.Package{C}, []pkg.Package{A, B, C, D}, db)
|
for _, p := range []pkg.Package{A, B, C, D} {
|
||||||
|
_, err := dbDefinitions.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range []pkg.Package{C} {
|
||||||
|
_, err := dbInstalled.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
s = NewSolver(dbInstalled, dbDefinitions, db)
|
||||||
|
|
||||||
solution, err := s.Install([]pkg.Package{A})
|
solution, err := s.Install([]pkg.Package{A})
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: A.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: A, Value: true}))
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: C.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: C, Value: true}))
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: D.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: D, Value: true}))
|
||||||
|
|
||||||
Expect(len(solution)).To(Equal(3))
|
Expect(len(solution)).To(Equal(3))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("Solves correctly", func() {
|
It("Solves correctly", func() {
|
||||||
db := pkg.NewInMemoryDatabase(false)
|
|
||||||
|
|
||||||
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{B}, []*pkg.DefaultPackage{})
|
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{B}, []*pkg.DefaultPackage{})
|
||||||
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
|
|
||||||
s := NewSolver([]pkg.Package{C}, []pkg.Package{A, B, C}, db)
|
for _, p := range []pkg.Package{A, B, C} {
|
||||||
|
_, err := dbDefinitions.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range []pkg.Package{C} {
|
||||||
|
_, err := dbInstalled.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
s = NewSolver(dbInstalled, dbDefinitions, db)
|
||||||
|
|
||||||
solution, err := s.Install([]pkg.Package{A})
|
solution, err := s.Install([]pkg.Package{A})
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: A.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: A, Value: true}))
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: B.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: B, Value: true}))
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: C.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: C, Value: true}))
|
||||||
Expect(len(solution)).To(Equal(3))
|
Expect(len(solution)).To(Equal(3))
|
||||||
})
|
})
|
||||||
It("Solves correctly more complex ones", func() {
|
It("Solves correctly more complex ones", func() {
|
||||||
db := pkg.NewInMemoryDatabase(false)
|
|
||||||
|
|
||||||
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{D}, []*pkg.DefaultPackage{})
|
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{D}, []*pkg.DefaultPackage{})
|
||||||
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{B}, []*pkg.DefaultPackage{})
|
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{B}, []*pkg.DefaultPackage{})
|
||||||
|
|
||||||
s := NewSolver([]pkg.Package{C}, []pkg.Package{A, B, C, D}, db)
|
for _, p := range []pkg.Package{A, B, C, D} {
|
||||||
|
_, err := dbDefinitions.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range []pkg.Package{C} {
|
||||||
|
_, err := dbInstalled.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
s = NewSolver(dbInstalled, dbDefinitions, db)
|
||||||
|
|
||||||
solution, err := s.Install([]pkg.Package{A})
|
solution, err := s.Install([]pkg.Package{A})
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: A.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: A, Value: true}))
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: B.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: B, Value: true}))
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: D.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: D, Value: true}))
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: C.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: C, Value: true}))
|
||||||
Expect(len(solution)).To(Equal(4))
|
Expect(len(solution)).To(Equal(4))
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("Solves correctly more complex ones", func() {
|
It("Solves correctly more complex ones", func() {
|
||||||
db := pkg.NewInMemoryDatabase(false)
|
|
||||||
|
|
||||||
E := pkg.NewPackage("E", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
E := pkg.NewPackage("E", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
@@ -138,37 +200,53 @@ var _ = Describe("Solver", func() {
|
|||||||
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{D}, []*pkg.DefaultPackage{})
|
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{D}, []*pkg.DefaultPackage{})
|
||||||
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{B}, []*pkg.DefaultPackage{})
|
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{B}, []*pkg.DefaultPackage{})
|
||||||
|
|
||||||
s := NewSolver([]pkg.Package{}, []pkg.Package{A, B, C, D, E}, db)
|
for _, p := range []pkg.Package{A, B, C, D, E} {
|
||||||
|
_, err := dbDefinitions.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range []pkg.Package{} {
|
||||||
|
_, err := dbInstalled.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
s = NewSolver(dbInstalled, dbDefinitions, db)
|
||||||
|
|
||||||
solution, err := s.Install([]pkg.Package{A})
|
solution, err := s.Install([]pkg.Package{A})
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: A.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: A, Value: true}))
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: B.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: B, Value: true}))
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: D.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: D, Value: true}))
|
||||||
Expect(len(solution)).To(Equal(3))
|
Expect(len(solution)).To(Equal(3))
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("Uninstalls simple package correctly", func() {
|
It("Uninstalls simple package correctly", func() {
|
||||||
db := pkg.NewInMemoryDatabase(false)
|
|
||||||
|
|
||||||
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
|
|
||||||
s := NewSolver([]pkg.Package{A, B, C, D}, []pkg.Package{A, B, C, D}, db)
|
for _, p := range []pkg.Package{A, B, C, D} {
|
||||||
|
_, err := dbDefinitions.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range []pkg.Package{A, B, C, D} {
|
||||||
|
_, err := dbInstalled.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
s = NewSolver(dbInstalled, dbDefinitions, db)
|
||||||
|
|
||||||
solution, err := s.Uninstall(A)
|
solution, err := s.Uninstall(A)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
Expect(solution).To(ContainElement(A.IsFlagged(false)))
|
Expect(solution).To(ContainElement(A.IsFlagged(false)))
|
||||||
|
|
||||||
// Expect(solution).To(ContainElement(PackageAssert{Package: C.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
// Expect(solution).To(ContainElement(PackageAssert{Package: C, Value: true}))
|
||||||
Expect(len(solution)).To(Equal(1))
|
Expect(len(solution)).To(Equal(1))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("Find conflicts", func() {
|
It("Find conflicts", func() {
|
||||||
db := pkg.NewInMemoryDatabase(false)
|
|
||||||
|
|
||||||
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
@@ -176,7 +254,16 @@ var _ = Describe("Solver", func() {
|
|||||||
|
|
||||||
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{A}, []*pkg.DefaultPackage{})
|
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{A}, []*pkg.DefaultPackage{})
|
||||||
|
|
||||||
s := NewSolver([]pkg.Package{A, B, C, D}, []pkg.Package{A, B, C, D}, db)
|
for _, p := range []pkg.Package{A, B, C, D} {
|
||||||
|
_, err := dbDefinitions.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range []pkg.Package{A, B, C, D} {
|
||||||
|
_, err := dbInstalled.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
val, err := s.ConflictsWithInstalled(A)
|
val, err := s.ConflictsWithInstalled(A)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(val).To(BeTrue())
|
Expect(val).To(BeTrue())
|
||||||
@@ -184,7 +271,6 @@ var _ = Describe("Solver", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
It("Find nested conflicts", func() {
|
It("Find nested conflicts", func() {
|
||||||
db := pkg.NewInMemoryDatabase(false)
|
|
||||||
|
|
||||||
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
@@ -192,14 +278,22 @@ var _ = Describe("Solver", func() {
|
|||||||
|
|
||||||
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{A}, []*pkg.DefaultPackage{})
|
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{A}, []*pkg.DefaultPackage{})
|
||||||
|
|
||||||
s := NewSolver([]pkg.Package{A, B, C, D}, []pkg.Package{A, B, C, D}, db)
|
for _, p := range []pkg.Package{A, B, C, D} {
|
||||||
|
_, err := dbDefinitions.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range []pkg.Package{A, B, C, D} {
|
||||||
|
_, err := dbInstalled.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
val, err := s.ConflictsWithInstalled(D)
|
val, err := s.ConflictsWithInstalled(D)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(val).To(BeTrue())
|
Expect(val).To(BeTrue())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("Doesn't find nested conflicts", func() {
|
It("Doesn't find nested conflicts", func() {
|
||||||
db := pkg.NewInMemoryDatabase(false)
|
|
||||||
|
|
||||||
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
@@ -207,14 +301,22 @@ var _ = Describe("Solver", func() {
|
|||||||
|
|
||||||
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{A}, []*pkg.DefaultPackage{})
|
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{A}, []*pkg.DefaultPackage{})
|
||||||
|
|
||||||
s := NewSolver([]pkg.Package{A, B, C, D}, []pkg.Package{A, B, C, D}, db)
|
for _, p := range []pkg.Package{A, B, C, D} {
|
||||||
|
_, err := dbDefinitions.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range []pkg.Package{A, B, C, D} {
|
||||||
|
_, err := dbInstalled.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
val, err := s.ConflictsWithInstalled(C)
|
val, err := s.ConflictsWithInstalled(C)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(val).ToNot(BeTrue())
|
Expect(val).ToNot(BeTrue())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("Doesn't find conflicts", func() {
|
It("Doesn't find conflicts", func() {
|
||||||
db := pkg.NewInMemoryDatabase(false)
|
|
||||||
|
|
||||||
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
@@ -222,40 +324,59 @@ var _ = Describe("Solver", func() {
|
|||||||
|
|
||||||
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
|
|
||||||
s := NewSolver([]pkg.Package{A, B, C, D}, []pkg.Package{A, B, C, D}, db)
|
for _, p := range []pkg.Package{A, B, C, D} {
|
||||||
|
_, err := dbDefinitions.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range []pkg.Package{A, B, C, D} {
|
||||||
|
_, err := dbInstalled.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
val, err := s.ConflictsWithInstalled(C)
|
val, err := s.ConflictsWithInstalled(C)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(val).ToNot(BeTrue())
|
Expect(val).ToNot(BeTrue())
|
||||||
})
|
})
|
||||||
It("Uninstalls simple packages not in world correctly", func() {
|
It("Uninstalls simple packages not in world correctly", func() {
|
||||||
db := pkg.NewInMemoryDatabase(false)
|
|
||||||
|
|
||||||
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
|
|
||||||
s := NewSolver([]pkg.Package{A, B, C, D}, []pkg.Package{B, C, D}, db)
|
for _, p := range []pkg.Package{B, C, D} {
|
||||||
|
_, err := dbDefinitions.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range []pkg.Package{A, B, C, D} {
|
||||||
|
_, err := dbInstalled.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
solution, err := s.Uninstall(A)
|
solution, err := s.Uninstall(A)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
Expect(solution).To(ContainElement(A.IsFlagged(false)))
|
Expect(solution).To(ContainElement(A.IsFlagged(false)))
|
||||||
|
|
||||||
// Expect(solution).To(ContainElement(PackageAssert{Package: C.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
// Expect(solution).To(ContainElement(PackageAssert{Package: C, Value: true}))
|
||||||
Expect(len(solution)).To(Equal(1))
|
Expect(len(solution)).To(Equal(1))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("Uninstalls complex packages not in world correctly", func() {
|
It("Uninstalls complex packages not in world correctly", func() {
|
||||||
db := pkg.NewInMemoryDatabase(false)
|
|
||||||
|
|
||||||
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{B}, []*pkg.DefaultPackage{})
|
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{B}, []*pkg.DefaultPackage{})
|
||||||
|
|
||||||
s := NewSolver([]pkg.Package{A, B, C, D}, []pkg.Package{B, C, D}, db)
|
for _, p := range []pkg.Package{B, C, D} {
|
||||||
|
_, err := dbDefinitions.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range []pkg.Package{A, B, C, D} {
|
||||||
|
_, err := dbInstalled.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
solution, err := s.Uninstall(A)
|
solution, err := s.Uninstall(A)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
@@ -265,15 +386,20 @@ var _ = Describe("Solver", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
It("Uninstalls complex packages correctly, even if shared deps are required by system packages", func() {
|
It("Uninstalls complex packages correctly, even if shared deps are required by system packages", func() {
|
||||||
db := pkg.NewInMemoryDatabase(false)
|
|
||||||
|
|
||||||
D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{B}, []*pkg.DefaultPackage{})
|
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{B}, []*pkg.DefaultPackage{})
|
||||||
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{B}, []*pkg.DefaultPackage{})
|
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{B}, []*pkg.DefaultPackage{})
|
||||||
|
|
||||||
s := NewSolver([]pkg.Package{A, B, C, D}, []pkg.Package{A, B, C, D}, db)
|
for _, p := range []pkg.Package{A, B, C, D} {
|
||||||
|
_, err := dbDefinitions.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range []pkg.Package{A, B, C, D} {
|
||||||
|
_, err := dbInstalled.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
solution, err := s.Uninstall(A)
|
solution, err := s.Uninstall(A)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
@@ -284,14 +410,20 @@ var _ = Describe("Solver", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
It("Uninstalls complex packages in world correctly", func() {
|
It("Uninstalls complex packages in world correctly", func() {
|
||||||
db := pkg.NewInMemoryDatabase(false)
|
|
||||||
|
|
||||||
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{C}, []*pkg.DefaultPackage{})
|
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{C}, []*pkg.DefaultPackage{})
|
||||||
|
|
||||||
s := NewSolver([]pkg.Package{A, C, D}, []pkg.Package{A, B, C, D}, db)
|
for _, p := range []pkg.Package{A, B, C, D} {
|
||||||
|
_, err := dbDefinitions.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range []pkg.Package{A, C, D} {
|
||||||
|
_, err := dbInstalled.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
solution, err := s.Uninstall(A)
|
solution, err := s.Uninstall(A)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
@@ -303,23 +435,30 @@ var _ = Describe("Solver", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
It("Uninstalls complex package correctly", func() {
|
It("Uninstalls complex package correctly", func() {
|
||||||
db := pkg.NewInMemoryDatabase(false)
|
|
||||||
|
|
||||||
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{D}, []*pkg.DefaultPackage{})
|
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{D}, []*pkg.DefaultPackage{})
|
||||||
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{B}, []*pkg.DefaultPackage{})
|
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{B}, []*pkg.DefaultPackage{})
|
||||||
C.IsFlagged(true) // installed
|
// C // installed
|
||||||
|
|
||||||
s := NewSolver([]pkg.Package{A, B, C, D}, []pkg.Package{A, B, C, D}, db)
|
for _, p := range []pkg.Package{A, B, C, D} {
|
||||||
|
_, err := dbDefinitions.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range []pkg.Package{A, B, C, D} {
|
||||||
|
_, err := dbInstalled.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
solution, err := s.Uninstall(A)
|
solution, err := s.Uninstall(A)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
Expect(solution).To(ContainElement(A.IsFlagged(false)))
|
Expect(solution).To(ContainElement(A.IsFlagged(false)))
|
||||||
Expect(solution).To(ContainElement(B.IsFlagged(false)))
|
Expect(solution).To(ContainElement(B.IsFlagged(false)))
|
||||||
Expect(solution).To(ContainElement(D.IsFlagged(false)))
|
Expect(solution).To(ContainElement(D.IsFlagged(false)))
|
||||||
|
|
||||||
Expect(len(solution)).To(Equal(3))
|
Expect(len(solution)).To(Equal(3))
|
||||||
Expect(err).ToNot(HaveOccurred())
|
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -328,14 +467,20 @@ var _ = Describe("Solver", func() {
|
|||||||
Context("Conflict set", func() {
|
Context("Conflict set", func() {
|
||||||
|
|
||||||
It("is unsolvable - as we something we ask to install conflict with system stuff", func() {
|
It("is unsolvable - as we something we ask to install conflict with system stuff", func() {
|
||||||
db := pkg.NewInMemoryDatabase(false)
|
|
||||||
|
|
||||||
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
// D := pkg.NewPackage("D", "", []pkg.Package{}, []pkg.Package{})
|
// D := pkg.NewPackage("D", "", []pkg.Package{}, []pkg.Package{})
|
||||||
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{C})
|
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{C})
|
||||||
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{B}, []*pkg.DefaultPackage{})
|
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{B}, []*pkg.DefaultPackage{})
|
||||||
|
|
||||||
s := NewSolver([]pkg.Package{C}, []pkg.Package{A, B, C}, db)
|
for _, p := range []pkg.Package{A, B, C} {
|
||||||
|
_, err := dbDefinitions.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range []pkg.Package{C} {
|
||||||
|
_, err := dbInstalled.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
solution, err := s.Install([]pkg.Package{A})
|
solution, err := s.Install([]pkg.Package{A})
|
||||||
Expect(len(solution)).To(Equal(0))
|
Expect(len(solution)).To(Equal(0))
|
||||||
@@ -346,8 +491,6 @@ var _ = Describe("Solver", func() {
|
|||||||
|
|
||||||
Context("Complex data sets", func() {
|
Context("Complex data sets", func() {
|
||||||
It("Solves them correctly", func() {
|
It("Solves them correctly", func() {
|
||||||
db := pkg.NewInMemoryDatabase(false)
|
|
||||||
|
|
||||||
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
E := pkg.NewPackage("E", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
E := pkg.NewPackage("E", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
F := pkg.NewPackage("F", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
F := pkg.NewPackage("F", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
@@ -357,18 +500,26 @@ var _ = Describe("Solver", func() {
|
|||||||
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{D}, []*pkg.DefaultPackage{})
|
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{D}, []*pkg.DefaultPackage{})
|
||||||
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{B}, []*pkg.DefaultPackage{})
|
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{B}, []*pkg.DefaultPackage{})
|
||||||
|
|
||||||
s := NewSolver([]pkg.Package{C}, []pkg.Package{A, B, C, D, E, F, G}, db)
|
for _, p := range []pkg.Package{A, B, C, D, E, F, G} {
|
||||||
|
_, err := dbDefinitions.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range []pkg.Package{C} {
|
||||||
|
_, err := dbInstalled.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
solution, err := s.Install([]pkg.Package{A})
|
solution, err := s.Install([]pkg.Package{A})
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: A.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: B.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: D.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: A, Value: true}))
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: C.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: B, Value: true}))
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: H.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: D, Value: true}))
|
||||||
Expect(solution).To(ContainElement(PackageAssert{Package: G.IsFlagged(true).(*pkg.DefaultPackage), Value: true}))
|
Expect(solution).To(ContainElement(PackageAssert{Package: C, Value: true}))
|
||||||
|
Expect(solution).To(ContainElement(PackageAssert{Package: H, Value: true}))
|
||||||
|
Expect(solution).To(ContainElement(PackageAssert{Package: G, Value: true}))
|
||||||
|
|
||||||
Expect(len(solution)).To(Equal(6))
|
Expect(len(solution)).To(Equal(6))
|
||||||
Expect(err).ToNot(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -391,7 +542,6 @@ var _ = Describe("Solver", func() {
|
|||||||
Expect(lst).To(ContainElement(a03))
|
Expect(lst).To(ContainElement(a03))
|
||||||
Expect(lst).ToNot(ContainElement(old))
|
Expect(lst).ToNot(ContainElement(old))
|
||||||
Expect(len(lst)).To(Equal(5))
|
Expect(len(lst)).To(Equal(5))
|
||||||
s := solver.NewSolver([]pkg.Package{}, []pkg.Package{}, pkg.NewInMemoryDatabase(false))
|
|
||||||
p := s.Best(lst)
|
p := s.Best(lst)
|
||||||
Expect(p).To(Equal(a03))
|
Expect(p).To(Equal(a03))
|
||||||
})
|
})
|
||||||
|
Reference in New Issue
Block a user