diff --git a/cmd/build.go b/cmd/build.go index 08fc59cd..baa1b565 100644 --- a/cmd/build.go +++ b/cmd/build.go @@ -111,7 +111,6 @@ Build packages specifying multiple definition trees: full, _ := cmd.Flags().GetBool("full") rebuild, _ := cmd.Flags().GetBool("rebuild") - concurrent, _ := cmd.Flags().GetBool("solver-concurrent") var results Results backendArgs := LuetCfg.Viper.GetStringSlice("backend-args") @@ -153,11 +152,7 @@ Build packages specifying multiple definition trees: Debug("Solver", opts.CompactString()) - if concurrent { - opts.Options = solver.Options{Type: solver.ParallelSimple, Concurrency: concurrency} - } else { - opts.Options = solver.Options{Type: solver.SingleCoreSimple, Concurrency: concurrency} - } + opts.Options = solver.Options{Type: solver.SingleCoreSimple, Concurrency: concurrency} luetCompiler := compiler.NewLuetCompiler(compilerBackend, generalRecipe.GetDatabase(), options.NoDeps(nodeps), diff --git a/cmd/install.go b/cmd/install.go index 7c9e747b..813513ff 100644 --- a/cmd/install.go +++ b/cmd/install.go @@ -69,19 +69,15 @@ To force install a package: force := LuetCfg.Viper.GetBool("force") nodeps := LuetCfg.Viper.GetBool("nodeps") onlydeps := LuetCfg.Viper.GetBool("onlydeps") - concurrent, _ := cmd.Flags().GetBool("solver-concurrent") yes := LuetCfg.Viper.GetBool("yes") downloadOnly, _ := cmd.Flags().GetBool("download-only") finalizerEnvs, _ := cmd.Flags().GetStringArray("finalizer-env") + relax, _ := cmd.Flags().GetBool("relax") util.SetSystemConfig() util.SetSolverConfig() - if concurrent { - LuetCfg.GetSolverOptions().Implementation = solver.ParallelSimple - } else { - LuetCfg.GetSolverOptions().Implementation = solver.SingleCoreSimple - } + LuetCfg.GetSolverOptions().Implementation = solver.SingleCoreSimple Debug("Solver", LuetCfg.GetSolverOptions().CompactString()) repos := installer.SystemRepositories(LuetCfg) diff --git a/cmd/reinstall.go b/cmd/reinstall.go index d042d4a7..0501fd2e 100644 --- a/cmd/reinstall.go +++ b/cmd/reinstall.go @@ -49,7 +49,6 @@ var reinstallCmd = &cobra.Command{ force := LuetCfg.Viper.GetBool("force") onlydeps := LuetCfg.Viper.GetBool("onlydeps") - concurrent, _ := cmd.Flags().GetBool("solver-concurrent") yes := LuetCfg.Viper.GetBool("yes") downloadOnly, _ := cmd.Flags().GetBool("download-only") @@ -77,11 +76,7 @@ var reinstallCmd = &cobra.Command{ util.SetSolverConfig() - if concurrent { - LuetCfg.GetSolverOptions().Implementation = solver.ParallelSimple - } else { - LuetCfg.GetSolverOptions().Implementation = solver.SingleCoreSimple - } + LuetCfg.GetSolverOptions().Implementation = solver.SingleCoreSimple Debug("Solver", LuetCfg.GetSolverOptions().CompactString()) diff --git a/cmd/replace.go b/cmd/replace.go index aa896aa4..fa21b464 100644 --- a/cmd/replace.go +++ b/cmd/replace.go @@ -53,7 +53,6 @@ var replaceCmd = &cobra.Command{ force := LuetCfg.Viper.GetBool("force") nodeps := LuetCfg.Viper.GetBool("nodeps") onlydeps := LuetCfg.Viper.GetBool("onlydeps") - concurrent, _ := cmd.Flags().GetBool("solver-concurrent") yes := LuetCfg.Viper.GetBool("yes") downloadOnly, _ := cmd.Flags().GetBool("download-only") @@ -85,11 +84,7 @@ var replaceCmd = &cobra.Command{ repos = append(repos, r) } - if concurrent { - LuetCfg.GetSolverOptions().Implementation = solver.ParallelSimple - } else { - LuetCfg.GetSolverOptions().Implementation = solver.SingleCoreSimple - } + LuetCfg.GetSolverOptions().Implementation = solver.SingleCoreSimple Debug("Solver", LuetCfg.GetSolverOptions().CompactString()) diff --git a/cmd/uninstall.go b/cmd/uninstall.go index 85d90258..0b755b9e 100644 --- a/cmd/uninstall.go +++ b/cmd/uninstall.go @@ -54,7 +54,6 @@ var uninstallCmd = &cobra.Command{ full, _ := cmd.Flags().GetBool("full") checkconflicts, _ := cmd.Flags().GetBool("conflictscheck") fullClean, _ := cmd.Flags().GetBool("full-clean") - concurrent, _ := cmd.Flags().GetBool("solver-concurrent") yes := LuetCfg.Viper.GetBool("yes") keepProtected, _ := cmd.Flags().GetBool("keep-protected-files") @@ -62,11 +61,9 @@ var uninstallCmd = &cobra.Command{ util.SetSolverConfig() LuetCfg.ConfigProtectSkip = !keepProtected - if concurrent { - LuetCfg.GetSolverOptions().Implementation = solver.ParallelSimple - } else { - LuetCfg.GetSolverOptions().Implementation = solver.SingleCoreSimple - } + + LuetCfg.GetSolverOptions().Implementation = solver.SingleCoreSimple + Debug("Solver", LuetCfg.GetSolverOptions().CompactString()) // Load config protect configs diff --git a/cmd/upgrade.go b/cmd/upgrade.go index fc341412..c93541f9 100644 --- a/cmd/upgrade.go +++ b/cmd/upgrade.go @@ -53,18 +53,13 @@ var upgradeCmd = &cobra.Command{ universe, _ := cmd.Flags().GetBool("universe") clean, _ := cmd.Flags().GetBool("clean") sync, _ := cmd.Flags().GetBool("sync") - concurrent, _ := cmd.Flags().GetBool("solver-concurrent") yes := LuetCfg.Viper.GetBool("yes") downloadOnly, _ := cmd.Flags().GetBool("download-only") util.SetSystemConfig() opts := util.SetSolverConfig() - if concurrent { - LuetCfg.GetSolverOptions().Implementation = solver.ParallelSimple - } else { - LuetCfg.GetSolverOptions().Implementation = solver.SingleCoreSimple - } + LuetCfg.GetSolverOptions().Implementation = solver.SingleCoreSimple Debug("Solver", opts.CompactString()) diff --git a/pkg/solver/benchmark_test.go b/pkg/solver/benchmark_test.go index 05dfafe2..13f8ab55 100644 --- a/pkg/solver/benchmark_test.go +++ b/pkg/solver/benchmark_test.go @@ -94,7 +94,7 @@ var _ = Describe("Solver Benchmarks", func() { db = pkg.NewInMemoryDatabase(false) dbInstalled = pkg.NewInMemoryDatabase(false) dbDefinitions = pkg.NewInMemoryDatabase(false) - s = NewSolver(Options{Type: ParallelSimple, Concurrency: 10}, dbInstalled, dbDefinitions, db) + s = NewSolver(Options{Type: SingleCoreSimple, Concurrency: 10}, dbInstalled, dbDefinitions, db) if os.Getenv("BENCHMARK_TESTS") != "true" { Skip("BENCHMARK_TESTS not enabled") } @@ -148,7 +148,7 @@ var _ = Describe("Solver Benchmarks", func() { db = pkg.NewInMemoryDatabase(false) // dbInstalled = pkg.NewInMemoryDatabase(false) dbDefinitions = pkg.NewInMemoryDatabase(false) - s = NewSolver(Options{Type: ParallelSimple, Concurrency: 100}, dbInstalled, dbDefinitions, db) + s = NewSolver(Options{Type: SingleCoreSimple, Concurrency: 100}, dbInstalled, dbDefinitions, db) if os.Getenv("BENCHMARK_TESTS") != "true" { Skip("BENCHMARK_TESTS not enabled") } diff --git a/pkg/solver/parallel.go b/pkg/solver/parallel.go deleted file mode 100644 index 565d353e..00000000 --- a/pkg/solver/parallel.go +++ /dev/null @@ -1,893 +0,0 @@ -// Copyright © 2019 Ettore Di Giacinto -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program; if not, see . - -package solver - -import ( - - //. "github.com/mudler/luet/pkg/logger" - "fmt" - "sync" - - "github.com/pkg/errors" - - "github.com/crillab/gophersat/bf" - pkg "github.com/mudler/luet/pkg/package" -) - -// Parallel is the default Parallel for luet -type Parallel struct { - Concurrency int - DefinitionDatabase pkg.PackageDatabase - ParallelDatabase pkg.PackageDatabase - Wanted pkg.Packages - InstalledDatabase pkg.PackageDatabase - - Resolver PackageResolver -} - -func (s *Parallel) SetDefinitionDatabase(db pkg.PackageDatabase) { - s.DefinitionDatabase = db -} - -// SetReSolver is a setter for the unsat ReSolver backend -func (s *Parallel) SetResolver(r PackageResolver) { - s.Resolver = r -} - -func (s *Parallel) World() pkg.Packages { - return s.DefinitionDatabase.World() -} - -func (s *Parallel) Installed() pkg.Packages { - - return s.InstalledDatabase.World() -} - -func (s *Parallel) noRulesWorld() bool { - for _, p := range s.World() { - if len(p.GetConflicts()) != 0 || len(p.GetRequires()) != 0 { - return false - } - } - - return true -} - -func (s *Parallel) noRulesInstalled() bool { - for _, p := range s.Installed() { - if len(p.GetConflicts()) != 0 || len(p.GetRequires()) != 0 { - return false - } - } - - return true -} - -func (s *Parallel) buildParallelFormula(db pkg.PackageDatabase, formulas []bf.Formula, packages pkg.Packages) (bf.Formula, error) { - var wg = new(sync.WaitGroup) - var wg2 = new(sync.WaitGroup) - - all := make(chan pkg.Package) - results := make(chan bf.Formula, 1) - for i := 0; i < s.Concurrency; i++ { - wg.Add(1) - go func(wg *sync.WaitGroup, c <-chan pkg.Package) { - defer wg.Done() - for p := range c { - solvable, err := p.BuildFormula(db, s.ParallelDatabase) - if err != nil { - panic(err) - } - for _, s := range solvable { - results <- s - } - } - }(wg, all) - } - wg2.Add(1) - go func() { - defer wg2.Done() - for t := range results { - formulas = append(formulas, t) - } - }() - - for _, p := range packages { - all <- p - } - - close(all) - wg.Wait() - close(results) - wg2.Wait() - - if len(formulas) != 0 { - return bf.And(formulas...), nil - } - return bf.True, nil -} - -func (s *Parallel) BuildInstalled() (bf.Formula, error) { - var formulas []bf.Formula - - var packages pkg.Packages - for _, p := range s.Installed() { - packages = append(packages, p) - for _, dep := range p.Related(s.InstalledDatabase) { - packages = append(packages, dep) - } - - } - - return s.buildParallelFormula(s.InstalledDatabase, formulas, packages) -} - -// BuildWorld builds the formula which olds the requirements from the package definitions -// which are available (global state) -func (s *Parallel) BuildWorld(includeInstalled bool) (bf.Formula, error) { - var formulas []bf.Formula - // NOTE: This block should be enabled in case of very old systems with outdated world sets - if includeInstalled { - solvable, err := s.BuildInstalled() - if err != nil { - return nil, err - } - //f = bf.And(f, solvable) - formulas = append(formulas, solvable) - } - return s.buildParallelFormula(s.DefinitionDatabase, formulas, s.World()) -} - -// BuildWorld builds the formula which olds the requirements from the package definitions -// which are available (global state) -func (s *Parallel) BuildPartialWorld(includeInstalled bool) (bf.Formula, error) { - var formulas []bf.Formula - // NOTE: This block should be enabled in case of very old systems with outdated world sets - if includeInstalled { - solvable, err := s.BuildInstalled() - if err != nil { - return nil, err - } - //f = bf.And(f, solvable) - formulas = append(formulas, solvable) - } - - var wg = new(sync.WaitGroup) - var wg2 = new(sync.WaitGroup) - var packages pkg.Packages - - all := make(chan pkg.Package) - results := make(chan pkg.Package, 1) - for i := 0; i < s.Concurrency; i++ { - wg.Add(1) - go func(wg *sync.WaitGroup, c <-chan pkg.Package) { - defer wg.Done() - for p := range c { - for _, dep := range p.Related(s.DefinitionDatabase) { - results <- dep - } - - } - }(wg, all) - } - wg2.Add(1) - go func() { - defer wg2.Done() - for t := range results { - packages = append(packages, t) - } - }() - - for _, p := range s.Wanted { - all <- p - } - - close(all) - wg.Wait() - close(results) - wg2.Wait() - - return s.buildParallelFormula(s.DefinitionDatabase, formulas, packages) - - //return s.buildParallelFormula(formulas, s.World()) -} - -func (s *Parallel) getList(db pkg.PackageDatabase, lsp pkg.Packages) (pkg.Packages, error) { - var ls pkg.Packages - var wg = new(sync.WaitGroup) - var wg2 = new(sync.WaitGroup) - - all := make(chan pkg.Package) - results := make(chan pkg.Package, 1) - for i := 0; i < s.Concurrency; i++ { - wg.Add(1) - go func(wg *sync.WaitGroup, c <-chan pkg.Package) { - defer wg.Done() - for p := range c { - cp, err := db.FindPackage(p) - if err != nil { - packages, err := p.Expand(db) - // Expand, and relax search - if not found pick the same one - if err != nil || len(packages) == 0 { - cp = p - } else { - cp = packages.Best(nil) - } - } - results <- cp - } - }(wg, all) - } - - wg2.Add(1) - go func(wg *sync.WaitGroup) { - defer wg2.Done() - for t := range results { - ls = append(ls, t) - } - }(wg) - - for _, pp := range lsp { - all <- pp - } - - close(all) - wg.Wait() - close(results) - wg2.Wait() - - return ls, nil -} - -// Conflicts acts like ConflictsWith, but uses package's reverse dependencies to -// determine if it conflicts with the given set -func (s *Parallel) Conflicts(pack pkg.Package, lsp pkg.Packages) (bool, error) { - p, err := s.DefinitionDatabase.FindPackage(pack) - if err != nil { - p = pack - } - - ls, err := s.getList(s.DefinitionDatabase, lsp) - if err != nil { - return false, errors.Wrap(err, "Package not found in definition db") - } - - if s.noRulesWorld() { - return false, nil - } - - temporarySet := pkg.NewInMemoryDatabase(false) - for _, p := range ls { - temporarySet.CreatePackage(p) - } - - revdeps, err := temporarySet.GetRevdeps(p) - if err != nil { - return false, errors.Wrap(err, "error scanning revdeps") - } - var revdepsErr error - for _, r := range revdeps { - if revdepsErr == nil { - revdepsErr = errors.New("") - } - revdepsErr = errors.New(fmt.Sprintf("%s\n%s", revdepsErr.Error(), r.HumanReadableString())) - } - - return len(revdeps) != 0, revdepsErr -} - -// ConflictsWith return true if a package is part of the requirement set of a list of package -// return false otherwise (and thus it is NOT relevant to the given list) -func (s *Parallel) ConflictsWith(pack pkg.Package, lsp pkg.Packages) (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 - } - - ls, err := s.getList(s.DefinitionDatabase, lsp) - if err != nil { - return false, errors.Wrap(err, "Package not found in definition db") - } - - var formulas []bf.Formula - - if s.noRulesWorld() { - return false, nil - } - - encodedP, err := p.Encode(s.ParallelDatabase) - if err != nil { - return false, err - } - P := bf.Var(encodedP) - - r, err := s.BuildWorld(false) - if err != nil { - return false, err - } - formulas = append(formulas, bf.And(bf.Not(P), r)) - - var wg = new(sync.WaitGroup) - var wg2 = new(sync.WaitGroup) - - all := make(chan pkg.Package) - results := make(chan bf.Formula, 1) - for i := 0; i < s.Concurrency; i++ { - wg.Add(1) - go func(wg *sync.WaitGroup, c <-chan pkg.Package) { - defer wg.Done() - for i := range c { - if i.Matches(p) { - continue - } - - // XXX: Skip check on any of its requires ? ( Drop to avoid removing system packages when selecting an uninstall) - // if i.RequiresContains(p) { - // fmt.Println("Requires found") - // continue - // } - - encodedI, err := i.Encode(s.ParallelDatabase) - if err != nil { - panic(err) - } - I := bf.Var(encodedI) - - results <- bf.And(I, r) - } - }(wg, all) - } - - wg2.Add(1) - go func() { - defer wg2.Done() - for t := range results { - formulas = append(formulas, t) - } - }() - - for _, p := range ls { - all <- p - } - - close(all) - wg.Wait() - close(results) - wg2.Wait() - - model := bf.Solve(bf.And(formulas...)) - if model == nil { - return true, nil - } - - return false, nil - -} - -func (s *Parallel) ConflictsWithInstalled(p pkg.Package) (bool, error) { - return s.ConflictsWith(p, s.Installed()) -} - -// UninstallUniverse takes a list of candidate package and return a list of packages that would be removed -// in order to purge the candidate. Uses the Parallel to check constraints and nothing else -// -// It can be compared to the counterpart Uninstall as this method acts like a uninstall --full -// it removes all the packages and its deps. taking also in consideration other packages that might have -// revdeps -func (s *Parallel) UninstallUniverse(toremove pkg.Packages) (pkg.Packages, error) { - - if s.noRulesInstalled() { - return s.getList(s.InstalledDatabase, toremove) - } - - // resolve to packages from the db - toRemove, err := s.getList(s.InstalledDatabase, toremove) - if err != nil { - return nil, errors.Wrap(err, "Package not found in definition db") - } - - var formulas []bf.Formula - r, err := s.BuildInstalled() - if err != nil { - return nil, errors.Wrap(err, "Package not found in definition db") - } - - // SAT encode the clauses against the world - for _, p := range toRemove.Unique() { - encodedP, err := p.Encode(s.InstalledDatabase) - if err != nil { - return nil, errors.Wrap(err, "Package not found in definition db") - } - P := bf.Var(encodedP) - formulas = append(formulas, bf.And(bf.Not(P), r)) - } - - markedForRemoval := pkg.Packages{} - model := bf.Solve(bf.And(formulas...)) - if model == nil { - return nil, errors.New("Failed finding a solution") - } - assertion, err := DecodeModel(model, s.InstalledDatabase) - if err != nil { - return nil, errors.Wrap(err, "while decoding model from solution") - } - for _, a := range assertion { - if !a.Value { - if p, err := s.InstalledDatabase.FindPackage(a.Package); err == nil { - markedForRemoval = append(markedForRemoval, p) - } - - } - } - return markedForRemoval, nil -} - -// UpgradeUniverse mark packages for removal and returns a solution. It considers -// the Universe db as authoritative -// See also on the subject: https://arxiv.org/pdf/1007.1021.pdf -func (s *Parallel) UpgradeUniverse(dropremoved bool) (pkg.Packages, PackagesAssertions, error) { - var formulas []bf.Formula - // we first figure out which aren't up-to-date - // which has to be removed - // and which needs to be upgraded - removed := pkg.Packages{} - - // TODO: this is memory expensive, we need to optimize this - universe, err := s.DefinitionDatabase.Copy() - if err != nil { - return nil, nil, errors.Wrap(err, "couldn't build world copy") - } - for _, p := range s.Installed() { - universe.CreatePackage(p) - } - - // Build constraints for the whole defdb - r, err := s.BuildWorld(true) - if err != nil { - return nil, nil, errors.Wrap(err, "couldn't build world constraints") - } - - var wg = new(sync.WaitGroup) - var wg2 = new(sync.WaitGroup) - - all := make(chan pkg.Package) - results := make(chan bf.Formula, 1) - for i := 0; i < s.Concurrency; i++ { - wg.Add(1) - go func(wg *sync.WaitGroup, c <-chan pkg.Package) { - defer wg.Done() - for p := range c { - available, err := s.DefinitionDatabase.FindPackageVersions(p) - if len(available) == 0 || err != nil { - removed = append(removed, p) - continue - } - - bestmatch := available.Best(nil) - // Found a better version available - if !bestmatch.Matches(p) { - oldP, _ := p.Encode(universe) - toreplaceP := bf.Var(oldP) - best, _ := bestmatch.Encode(universe) - toUpgrade := bf.Var(best) - - solvablenew, _ := bestmatch.BuildFormula(s.DefinitionDatabase, s.ParallelDatabase) - results <- bf.And(bf.Not(toreplaceP), bf.And(append(solvablenew, toUpgrade)...)) - } - } - }(wg, all) - } - - wg2.Add(1) - go func() { - defer wg2.Done() - for t := range results { - formulas = append(formulas, t) - } - }() - - // Grab all the installed ones, see if they are eligible for update - for _, p := range s.Installed() { - all <- p - } - - close(all) - wg.Wait() - close(results) - wg2.Wait() - - // Treat removed packages from universe as marked for deletion - if dropremoved { - - for _, p := range removed.Unique() { - encodedP, err := p.Encode(universe) - if err != nil { - return nil, nil, errors.Wrap(err, "couldn't encode package") - } - P := bf.Var(encodedP) - formulas = append(formulas, bf.And(bf.Not(P), r)) - } - } - - markedForRemoval := pkg.Packages{} - if len(formulas) == 0 { - return pkg.Packages{}, PackagesAssertions{}, nil - } - model := bf.Solve(bf.And(formulas...)) - if model == nil { - return nil, nil, errors.New("Failed finding a solution") - } - - assertion, err := DecodeModel(model, universe) - if err != nil { - return nil, nil, errors.Wrap(err, "while decoding model from solution") - } - for _, a := range assertion { - if !a.Value { - if p, err := s.InstalledDatabase.FindPackage(a.Package); err == nil { - markedForRemoval = append(markedForRemoval, p) - } - - } - - } - return markedForRemoval, assertion, nil -} - -// Upgrade compute upgrades of the package against the world definition. -// It accepts two boolean indicating if it has to check for conflicts or try to attempt a full upgrade -func (s *Parallel) Upgrade(checkconflicts, full bool) (pkg.Packages, PackagesAssertions, error) { - return s.upgrade(s.DefinitionDatabase, s.InstalledDatabase, checkconflicts, full) - -} - -// Upgrade compute upgrades of the package against the world definition. -// It accepts two boolean indicating if it has to check for conflicts or try to attempt a full upgrade -func (s *Parallel) upgrade(defDB pkg.PackageDatabase, installDB pkg.PackageDatabase, checkconflicts, full bool) (pkg.Packages, PackagesAssertions, error) { - - // First get candidates that needs to be upgraded.. - - toUninstall := pkg.Packages{} - toInstall := pkg.Packages{} - - // we do this in memory so we take into account of provides - universe, err := defDB.Copy() - if err != nil { - return nil, nil, errors.Wrap(err, "Could not copy def db") - } - - installedcopy := pkg.NewInMemoryDatabase(false) - - var wg = new(sync.WaitGroup) - var wg2 = new(sync.WaitGroup) - - all := make(chan pkg.Package) - results := make(chan []pkg.Package, 1) - for i := 0; i < s.Concurrency; i++ { - wg.Add(1) - go func(wg *sync.WaitGroup, c <-chan pkg.Package) { - defer wg.Done() - for p := range c { - installedcopy.CreatePackage(p) - packages, err := universe.FindPackageVersions(p) - if err == nil && len(packages) != 0 { - best := packages.Best(nil) - if !best.Matches(p) { - results <- []pkg.Package{p, best} - } - } - } - }(wg, all) - } - - wg2.Add(1) - go func() { - defer wg2.Done() - for t := range results { - toUninstall = append(toUninstall, t[0]) - toInstall = append(toInstall, t[1]) - } - }() - - for _, p := range installDB.World() { - all <- p - } - - close(all) - wg.Wait() - close(results) - wg2.Wait() - - s2 := &Parallel{Concurrency: s.Concurrency, InstalledDatabase: installedcopy, DefinitionDatabase: defDB, ParallelDatabase: pkg.NewInMemoryDatabase(false)} - s2.SetResolver(s.Resolver) - if !full { - ass := PackagesAssertions{} - for _, i := range toInstall { - ass = append(ass, PackageAssert{Package: i.(*pkg.DefaultPackage), Value: true}) - } - } - - // Then try to uninstall the versions in the system, and store that tree - r, err := s.Uninstall(checkconflicts, false, toUninstall...) - if err != nil { - return nil, nil, errors.Wrap(err, "Could not compute upgrade - couldn't uninstall candidates ") - } - for _, z := range r { - err = installedcopy.RemovePackage(z) - if err != nil { - return nil, nil, errors.Wrap(err, "Could not compute upgrade - couldn't remove copy of package targetted for removal") - } - } - - if len(toInstall) == 0 { - return toUninstall, PackagesAssertions{}, nil - } - assertions, e := s2.Install(toInstall) - return toUninstall, assertions, e - // To that tree, ask to install the versions that should be upgraded, and try to solve - // Return the solution - -} - -// 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. -func (s *Parallel) Uninstall(checkconflicts, full bool, packs ...pkg.Package) (pkg.Packages, error) { - if len(packs) == 0 { - return pkg.Packages{}, nil - } - var res pkg.Packages - toRemove := pkg.Packages{} - - for _, c := range packs { - candidate, err := s.InstalledDatabase.FindPackage(c) - if err != nil { - - // return nil, errors.Wrap(err, "Couldn't find required package in db definition") - packages, err := c.Expand(s.InstalledDatabase) - // Info("Expanded", packages, err) - if err != nil || len(packages) == 0 { - candidate = c - } else { - candidate = packages.Best(nil) - } - //Relax search, otherwise we cannot compute solutions for packages not in definitions - // return nil, errors.Wrap(err, "Package not found between installed") - } - - toRemove = append(toRemove, candidate) - } - // Build a fake "Installed" - Candidate and its requires tree - var InstalledMinusCandidate pkg.Packages - - // We are asked to not perform a full uninstall (checking all the possible requires that could - // be removed). Let's only check if we can remove the selected package - if !full && checkconflicts { - for _, candidate := range toRemove { - if conflicts, err := s.Conflicts(candidate, s.Installed()); conflicts { - return nil, err - } - } - return toRemove, nil - } - - // TODO: Can be optimized - for _, i := range s.Installed() { - matched := false - for _, candidate := range toRemove { - if !i.Matches(candidate) { - contains, err := candidate.RequiresContains(s.ParallelDatabase, i) - if err != nil { - return nil, errors.Wrap(err, "Failed getting installed list") - } - if !contains { - matched = true - } - - } - } - if matched { - InstalledMinusCandidate = append(InstalledMinusCandidate, i) - } - } - - s2 := &Parallel{Concurrency: s.Concurrency, InstalledDatabase: pkg.NewInMemoryDatabase(false), DefinitionDatabase: s.InstalledDatabase, ParallelDatabase: pkg.NewInMemoryDatabase(false)} - s2.SetResolver(s.Resolver) - // Get the requirements to install the candidate - asserts, err := s2.Install(toRemove) - if err != nil { - return nil, err - } - for _, a := range asserts { - if a.Value { - if !checkconflicts { - res = append(res, a.Package) - continue - } - - c, err := s.ConflictsWithInstalled(a.Package) - if err != nil { - return nil, err - } - - // If doesn't conflict with installed we just consider it for removal and look for the next one - if !c { - res = append(res, a.Package) - continue - } - - // If does conflicts, give it another chance by checking conflicts if in case we didn't installed our candidate and all the required packages in the system - c, err = s.ConflictsWith(a.Package, InstalledMinusCandidate) - if err != nil { - return nil, err - } - if !c { - res = append(res, a.Package) - } - - } - - } - - return res, nil -} - -// BuildFormula builds the main solving formula that is evaluated by the sat Parallel. -func (s *Parallel) BuildFormula() (bf.Formula, error) { - var formulas []bf.Formula - - r, err := s.BuildWorld(false) - if err != nil { - return nil, err - } - - var wg = new(sync.WaitGroup) - var wg2 = new(sync.WaitGroup) - - all := make(chan pkg.Package) - results := make(chan bf.Formula, 1) - for i := 0; i < s.Concurrency; i++ { - wg.Add(1) - go func(wg *sync.WaitGroup, c <-chan pkg.Package) { - defer wg.Done() - for wanted := range c { - encodedW, err := wanted.Encode(s.ParallelDatabase) - if err != nil { - panic(err) - } - W := bf.Var(encodedW) - installedWorld := s.Installed() - //TODO:Optimize - if len(installedWorld) == 0 { - results <- W - continue - } - - for _, installed := range installedWorld { - encodedI, err := installed.Encode(s.ParallelDatabase) - if err != nil { - panic(err) - } - I := bf.Var(encodedI) - results <- bf.And(W, I) - } - } - }(wg, all) - } - wg2.Add(1) - go func() { - defer wg2.Done() - for t := range results { - formulas = append(formulas, t) - } - }() - - for _, wanted := range s.Wanted { - all <- wanted - } - - close(all) - wg.Wait() - close(results) - wg2.Wait() - - formulas = append(formulas, r) - - return bf.And(formulas...), nil -} - -func (s *Parallel) solve(f bf.Formula) (map[string]bool, bf.Formula, error) { - model := bf.Solve(f) - if model == nil { - return model, f, errors.New("Unsolvable") - } - - return model, f, nil -} - -// Solve builds the formula given the current state and returns package assertions -func (s *Parallel) Solve() (PackagesAssertions, error) { - var model map[string]bool - var err error - - f, err := s.BuildFormula() - - if err != nil { - return nil, err - } - - model, _, err = s.solve(f) - if err != nil && s.Resolver != nil { - return s.Resolver.Solve(f, s) - } - - if err != nil { - return nil, err - } - - return DecodeModel(model, s.ParallelDatabase) -} - -// 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 -func (s *Parallel) Install(c pkg.Packages) (PackagesAssertions, error) { - - coll, err := s.getList(s.DefinitionDatabase, c) - if err != nil { - return nil, errors.Wrap(err, "Packages not found in definition db") - } - - s.Wanted = coll - - if s.noRulesWorld() { - var ass PackagesAssertions - for _, p := range s.Installed() { - ass = append(ass, PackageAssert{Package: p.(*pkg.DefaultPackage), Value: true}) - - } - for _, p := range s.Wanted { - ass = append(ass, PackageAssert{Package: p.(*pkg.DefaultPackage), Value: true}) - } - return ass, nil - } - assertions, err := s.Solve() - if err != nil { - return nil, err - } - - return s.upgradeAssertions(assertions) -} - -func (s *Parallel) upgradeAssertions(assertions PackagesAssertions) (PackagesAssertions, error) { - - systemAfterInstall := pkg.NewInMemoryDatabase(false) - - for _, p := range assertions { - if p.Value { - systemAfterInstall.CreatePackage(p.Package) - } - } - - _, assertions, err := s.upgrade(s.DefinitionDatabase, systemAfterInstall, false, false) - if err != nil { - return nil, err - } - - // for _, u := range toUninstall { - // systemAfterInstall.RemovePackage() - - // } - return assertions, nil -} diff --git a/pkg/solver/parallel_test.go b/pkg/solver/parallel_test.go deleted file mode 100644 index 556fa683..00000000 --- a/pkg/solver/parallel_test.go +++ /dev/null @@ -1,1457 +0,0 @@ -// Copyright © 2019 Ettore Di Giacinto -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program; if not, see . - -package solver_test - -import ( - pkg "github.com/mudler/luet/pkg/package" - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - - . "github.com/mudler/luet/pkg/solver" -) - -var _ = Describe("Parallel", func() { - - db := pkg.NewInMemoryDatabase(false) - dbInstalled := pkg.NewInMemoryDatabase(false) - dbDefinitions := pkg.NewInMemoryDatabase(false) - s := &Parallel{InstalledDatabase: dbInstalled, Concurrency: 4, DefinitionDatabase: dbDefinitions, ParallelDatabase: db} - - BeforeEach(func() { - db = pkg.NewInMemoryDatabase(false) - dbInstalled = pkg.NewInMemoryDatabase(false) - dbDefinitions = pkg.NewInMemoryDatabase(false) - s = &Parallel{InstalledDatabase: dbInstalled, Concurrency: 4, DefinitionDatabase: dbDefinitions, ParallelDatabase: db} - }) - Context("Simple set", func() { - It("Solves correctly if the selected package has no requirements or conflicts and we have nothing installed yet", func() { - - B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - - 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 = &Parallel{InstalledDatabase: dbInstalled, Concurrency: 4, DefinitionDatabase: dbDefinitions, ParallelDatabase: db} - - solution, err := s.Install([]pkg.Package{A}) - Expect(err).ToNot(HaveOccurred()) - Expect(solution).To(ContainElement(PackageAssert{Package: A, Value: true})) - 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() { - - B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - - 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 = &Parallel{InstalledDatabase: dbInstalled, Concurrency: 4, DefinitionDatabase: dbDefinitions, ParallelDatabase: db} - - solution, err := s.Install([]pkg.Package{B}) - Expect(err).ToNot(HaveOccurred()) - Expect(solution).To(ContainElement(PackageAssert{Package: B, Value: true})) - Expect(solution).To(ContainElement(PackageAssert{Package: C, Value: true})) - 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() { - - B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{B}, []*pkg.DefaultPackage{}) - E := pkg.NewPackage("E", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - - 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 = &Parallel{InstalledDatabase: dbInstalled, Concurrency: 4, DefinitionDatabase: dbDefinitions, ParallelDatabase: db} - - solution, err := s.Install([]pkg.Package{A}) - Expect(err).ToNot(HaveOccurred()) - Expect(solution).To(ContainElement(PackageAssert{Package: A, Value: true})) - Expect(solution).To(ContainElement(PackageAssert{Package: C, Value: true})) - Expect(solution).To(ContainElement(PackageAssert{Package: E, Value: true})) - Expect(solution).ToNot(ContainElement(PackageAssert{Package: B, Value: true})) - Expect(solution).ToNot(ContainElement(PackageAssert{Package: D, Value: true})) - - Expect(len(solution)).To(Equal(5)) - }) - - It("Solves correctly if the selected package to install has requirements", func() { - - B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{D}, []*pkg.DefaultPackage{}) - - 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 = &Parallel{InstalledDatabase: dbInstalled, Concurrency: 4, DefinitionDatabase: dbDefinitions, ParallelDatabase: db} - - solution, err := s.Install([]pkg.Package{A}) - Expect(err).ToNot(HaveOccurred()) - Expect(solution).To(ContainElement(PackageAssert{Package: A, Value: true})) - Expect(solution).To(ContainElement(PackageAssert{Package: C, Value: true})) - Expect(solution).To(ContainElement(PackageAssert{Package: D, Value: true})) - - Expect(len(solution)).To(Equal(3)) - }) - - It("Solves correctly", func() { - - B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{B}, []*pkg.DefaultPackage{}) - C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - - 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 = &Parallel{InstalledDatabase: dbInstalled, Concurrency: 4, DefinitionDatabase: dbDefinitions, ParallelDatabase: db} - - solution, err := s.Install([]pkg.Package{A}) - Expect(err).ToNot(HaveOccurred()) - Expect(solution).To(ContainElement(PackageAssert{Package: A, Value: true})) - Expect(solution).To(ContainElement(PackageAssert{Package: B, Value: true})) - Expect(solution).To(ContainElement(PackageAssert{Package: C, Value: true})) - Expect(len(solution)).To(Equal(3)) - }) - It("Solves correctly more complex ones", func() { - - C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{D}, []*pkg.DefaultPackage{}) - A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{B}, []*pkg.DefaultPackage{}) - - 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 = &Parallel{InstalledDatabase: dbInstalled, Concurrency: 4, DefinitionDatabase: dbDefinitions, ParallelDatabase: db} - - solution, err := s.Install([]pkg.Package{A}) - Expect(solution).To(ContainElement(PackageAssert{Package: A, Value: true})) - Expect(solution).To(ContainElement(PackageAssert{Package: B, Value: true})) - Expect(solution).To(ContainElement(PackageAssert{Package: D, Value: true})) - Expect(solution).To(ContainElement(PackageAssert{Package: C, Value: true})) - Expect(len(solution)).To(Equal(4)) - Expect(err).ToNot(HaveOccurred()) - }) - - It("Solves correctly more complex ones", func() { - - E := pkg.NewPackage("E", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{D}, []*pkg.DefaultPackage{}) - A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{B}, []*pkg.DefaultPackage{}) - - 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 = &Parallel{InstalledDatabase: dbInstalled, Concurrency: 4, DefinitionDatabase: dbDefinitions, ParallelDatabase: db} - - solution, err := s.Install([]pkg.Package{A}) - Expect(solution).To(ContainElement(PackageAssert{Package: A, Value: true})) - Expect(solution).To(ContainElement(PackageAssert{Package: B, Value: true})) - Expect(solution).To(ContainElement(PackageAssert{Package: D, Value: true})) - Expect(len(solution)).To(Equal(3)) - Expect(err).ToNot(HaveOccurred()) - }) - - It("Solves deps with expansion", func() { - - E := pkg.NewPackage("E", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - B := pkg.NewPackage("B", "1.1", []*pkg.DefaultPackage{D}, []*pkg.DefaultPackage{}) - A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "B", Version: ">1.0"}}, []*pkg.DefaultPackage{}) - - 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 = &Parallel{InstalledDatabase: dbInstalled, Concurrency: 4, DefinitionDatabase: dbDefinitions, ParallelDatabase: db} - - solution, err := s.Install([]pkg.Package{A}) - Expect(solution).To(ContainElement(PackageAssert{Package: A, Value: true})) - Expect(solution).To(ContainElement(PackageAssert{Package: B, Value: true})) - Expect(solution).To(ContainElement(PackageAssert{Package: D, Value: true})) - Expect(len(solution)).To(Equal(3)) - Expect(err).ToNot(HaveOccurred()) - }) - It("Solves deps with more expansion", func() { - - C := pkg.NewPackage("c", "", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "a", Version: ">=1.0", Category: "test"}}, []*pkg.DefaultPackage{}) - C.SetCategory("test") - B := pkg.NewPackage("b", "1.0", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - B.SetCategory("test") - A := pkg.NewPackage("a", "1.1", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "b", Version: "1.0", Category: "test"}}, []*pkg.DefaultPackage{}) - A.SetCategory("test") - - 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 = &Parallel{InstalledDatabase: dbInstalled, Concurrency: 4, DefinitionDatabase: dbDefinitions, ParallelDatabase: db} - - solution, err := s.Install([]pkg.Package{C}) - Expect(solution).To(ContainElement(PackageAssert{Package: A, Value: true})) - Expect(solution).To(ContainElement(PackageAssert{Package: B, Value: true})) - Expect(solution).To(ContainElement(PackageAssert{Package: C, Value: true})) - Expect(len(solution)).To(Equal(3)) - Expect(err).ToNot(HaveOccurred()) - }) - - It("Solves deps with more expansion", func() { - - C := pkg.NewPackage("c", "1.5", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "a", Version: ">=1.0", Category: "test"}}, []*pkg.DefaultPackage{}) - C.SetCategory("test") - B := pkg.NewPackage("b", "1.0", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - B.SetCategory("test") - A := pkg.NewPackage("a", "1.1", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "b", Version: "1.0", Category: "test"}}, []*pkg.DefaultPackage{}) - A.SetCategory("test") - - 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 = &Parallel{InstalledDatabase: dbInstalled, Concurrency: 4, DefinitionDatabase: dbDefinitions, ParallelDatabase: db} - - solution, err := s.Install([]pkg.Package{&pkg.DefaultPackage{Name: "c", Version: ">1.0", Category: "test"}}) - Expect(solution).To(ContainElement(PackageAssert{Package: A, Value: true})) - Expect(solution).To(ContainElement(PackageAssert{Package: B, Value: true})) - Expect(solution).To(ContainElement(PackageAssert{Package: C, Value: true})) - Expect(len(solution)).To(Equal(3)) - Expect(err).ToNot(HaveOccurred()) - }) - It("Solves deps with more expansion", func() { - - E := pkg.NewPackage("E", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - D := pkg.NewPackage("D", "1.4", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - B := pkg.NewPackage("B", "1.1", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "D", Version: ">=1.0"}}, []*pkg.DefaultPackage{}) - A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "B", Version: ">=1.0"}}, []*pkg.DefaultPackage{}) - - 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 = &Parallel{InstalledDatabase: dbInstalled, Concurrency: 4, DefinitionDatabase: dbDefinitions, ParallelDatabase: db} - - solution, err := s.Install([]pkg.Package{A}) - Expect(solution).To(ContainElement(PackageAssert{Package: A, Value: true})) - Expect(solution).To(ContainElement(PackageAssert{Package: B, Value: true})) - Expect(solution).To(ContainElement(PackageAssert{Package: D, Value: true})) - Expect(len(solution)).To(Equal(3)) - Expect(err).ToNot(HaveOccurred()) - }) - It("Selects one version", func() { - - E := pkg.NewPackage("E", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - D2 := pkg.NewPackage("D", "1.9", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - D := pkg.NewPackage("D", "1.8", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - D1 := pkg.NewPackage("D", "1.4", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - B := pkg.NewPackage("B", "1.1", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "D", Version: "1.4"}}, []*pkg.DefaultPackage{}) - A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "D", Version: ">=1.0"}}, []*pkg.DefaultPackage{}) - - for _, p := range []pkg.Package{A, B, C, D, D1, D2, E} { - _, err := dbDefinitions.CreatePackage(p) - Expect(err).ToNot(HaveOccurred()) - } - - for _, p := range []pkg.Package{} { - _, err := dbInstalled.CreatePackage(p) - Expect(err).ToNot(HaveOccurred()) - } - s = &Parallel{InstalledDatabase: dbInstalled, Concurrency: 4, DefinitionDatabase: dbDefinitions, ParallelDatabase: db} - - solution, err := s.Install([]pkg.Package{A, B}) - Expect(solution).To(ContainElement(PackageAssert{Package: A, Value: true})) - Expect(solution).To(ContainElement(PackageAssert{Package: B, Value: true})) - Expect(solution).To(ContainElement(PackageAssert{Package: D1, Value: true})) - Expect(solution).ToNot(ContainElement(PackageAssert{Package: D, Value: true})) - Expect(solution).ToNot(ContainElement(PackageAssert{Package: D2, Value: true})) - Expect(solution).To(ContainElement(PackageAssert{Package: D, Value: false})) - Expect(solution).To(ContainElement(PackageAssert{Package: D2, Value: false})) - - Expect(len(solution)).To(Equal(5)) - Expect(err).ToNot(HaveOccurred()) - }) - - It("Install only package requires", func() { - - E := pkg.NewPackage("E", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - C := pkg.NewPackage("C", "1.1", []*pkg.DefaultPackage{&pkg.DefaultPackage{ - Name: "A", - Version: ">=1.0", - }}, []*pkg.DefaultPackage{}) - D := pkg.NewPackage("D", "1.9", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - B := pkg.NewPackage("B", "1.1", []*pkg.DefaultPackage{ - &pkg.DefaultPackage{ - Name: "D", - Version: ">=0", - }, - }, []*pkg.DefaultPackage{}) - - A := pkg.NewPackage("A", "1.2", []*pkg.DefaultPackage{ - &pkg.DefaultPackage{ - Name: "D", - Version: ">=1.0", - }, - }, []*pkg.DefaultPackage{}) - - 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 = &Parallel{InstalledDatabase: dbInstalled, Concurrency: 4, DefinitionDatabase: dbDefinitions, ParallelDatabase: db} - - solution, err := s.Install([]pkg.Package{C}) - Expect(solution).To(ContainElement(PackageAssert{Package: A, Value: true})) - Expect(solution).ToNot(ContainElement(PackageAssert{Package: B, Value: true})) - Expect(solution).To(ContainElement(PackageAssert{Package: C, Value: true})) - Expect(solution).To(ContainElement(PackageAssert{Package: D, Value: true})) - Expect(solution).ToNot(ContainElement(PackageAssert{Package: D, Value: false})) - Expect(solution).ToNot(ContainElement(PackageAssert{Package: E, Value: true})) - - Expect(len(solution)).To(Equal(4)) - Expect(err).ToNot(HaveOccurred()) - }) - - It("Selects best version", func() { - - E := pkg.NewPackage("E", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - E.SetCategory("test") - C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - C.SetCategory("test") - D2 := pkg.NewPackage("D", "1.9", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - D2.SetCategory("test") - D := pkg.NewPackage("D", "1.8", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - D.SetCategory("test") - D1 := pkg.NewPackage("D", "1.4", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - D1.SetCategory("test") - B := pkg.NewPackage("B", "1.1", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "D", Version: ">=1.0", Category: "test"}}, []*pkg.DefaultPackage{}) - B.SetCategory("test") - A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "D", Version: ">=1.0", Category: "test"}}, []*pkg.DefaultPackage{}) - A.SetCategory("test") - - for _, p := range []pkg.Package{A, B, C, D, D1, D2, E} { - _, err := dbDefinitions.CreatePackage(p) - Expect(err).ToNot(HaveOccurred()) - } - - for _, p := range []pkg.Package{} { - _, err := dbInstalled.CreatePackage(p) - Expect(err).ToNot(HaveOccurred()) - } - s = &Parallel{InstalledDatabase: dbInstalled, Concurrency: 4, DefinitionDatabase: dbDefinitions, ParallelDatabase: db} - - solution, err := s.Install([]pkg.Package{A, B}) - Expect(solution).To(ContainElement(PackageAssert{Package: A, Value: true})) - Expect(solution).To(ContainElement(PackageAssert{Package: B, Value: true})) - Expect(solution).ToNot(ContainElement(PackageAssert{Package: D1, Value: true})) - Expect(solution).ToNot(ContainElement(PackageAssert{Package: D, Value: true})) - Expect(solution).To(ContainElement(PackageAssert{Package: D2, Value: true})) - Expect(solution).To(ContainElement(PackageAssert{Package: D, Value: false})) - Expect(solution).To(ContainElement(PackageAssert{Package: D1, Value: false})) - - Expect(len(solution)).To(Equal(5)) - Expect(err).ToNot(HaveOccurred()) - }) - - It("Support provides", func() { - - E := pkg.NewPackage("E", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - E.SetCategory("test") - C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - C.SetCategory("test") - D2 := pkg.NewPackage("D", "1.9", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - D2.SetCategory("test") - D := pkg.NewPackage("D", "1.8", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - D.SetCategory("test") - D1 := pkg.NewPackage("D", "1.4", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - D1.SetCategory("test") - B := pkg.NewPackage("B", "1.1", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "D", Version: ">=1.0", Category: "test"}}, []*pkg.DefaultPackage{}) - B.SetCategory("test") - A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "D", Version: ">=1.0", Category: "test"}}, []*pkg.DefaultPackage{}) - A.SetCategory("test") - - D2.SetProvides([]*pkg.DefaultPackage{{Name: "E", Category: "test"}}) - A2 := pkg.NewPackage("A", "1.3", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "E", Version: "", Category: "test"}}, []*pkg.DefaultPackage{}) - A2.SetCategory("test") - - for _, p := range []pkg.Package{A, B, C, D, D1, D2, A2, E} { - _, err := dbDefinitions.CreatePackage(p) - Expect(err).ToNot(HaveOccurred()) - } - - for _, p := range []pkg.Package{} { - _, err := dbInstalled.CreatePackage(p) - Expect(err).ToNot(HaveOccurred()) - } - s = &Parallel{InstalledDatabase: dbInstalled, Concurrency: 4, DefinitionDatabase: dbDefinitions, ParallelDatabase: db} - - solution, err := s.Install([]pkg.Package{A2, B}) - Expect(solution).To(ContainElement(PackageAssert{Package: A2, Value: true})) - Expect(solution).To(ContainElement(PackageAssert{Package: B, Value: true})) - Expect(solution).ToNot(ContainElement(PackageAssert{Package: D1, Value: true})) - Expect(solution).ToNot(ContainElement(PackageAssert{Package: D, Value: true})) - Expect(solution).To(ContainElement(PackageAssert{Package: D2, Value: true})) - Expect(solution).To(ContainElement(PackageAssert{Package: D, Value: false})) - Expect(solution).To(ContainElement(PackageAssert{Package: D1, Value: false})) - Expect(solution).ToNot(ContainElement(PackageAssert{Package: E, Value: true})) - - Expect(len(solution)).To(Equal(6)) - Expect(err).ToNot(HaveOccurred()) - }) - - It("Support provides with versions", func() { - E := pkg.NewPackage("E", "1.3", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - - C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - D2 := pkg.NewPackage("D", "1.9", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - D := pkg.NewPackage("D", "1.8", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - D1 := pkg.NewPackage("D", "1.4", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - B := pkg.NewPackage("B", "1.1", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "D", Version: ">=1.0"}}, []*pkg.DefaultPackage{}) - A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "D", Version: ">=1.0"}}, []*pkg.DefaultPackage{}) - - D2.SetProvides([]*pkg.DefaultPackage{{Name: "E", Version: "1.3"}}) - A2 := pkg.NewPackage("A", "1.3", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "E", Version: ">=1.0"}}, []*pkg.DefaultPackage{}) - - for _, p := range []pkg.Package{A, B, C, D, D1, D2, A2, E} { - _, err := dbDefinitions.CreatePackage(p) - Expect(err).ToNot(HaveOccurred()) - } - - for _, p := range []pkg.Package{} { - _, err := dbInstalled.CreatePackage(p) - Expect(err).ToNot(HaveOccurred()) - } - s = &Parallel{InstalledDatabase: dbInstalled, Concurrency: 4, DefinitionDatabase: dbDefinitions, ParallelDatabase: db} - - solution, err := s.Install([]pkg.Package{A2}) - Expect(solution).To(ContainElement(PackageAssert{Package: A2, Value: true})) - Expect(solution).ToNot(ContainElement(PackageAssert{Package: B, Value: true})) - Expect(solution).ToNot(ContainElement(PackageAssert{Package: D1, Value: true})) - Expect(solution).ToNot(ContainElement(PackageAssert{Package: D, Value: true})) - Expect(solution).ToNot(ContainElement(PackageAssert{Package: C, Value: true})) - Expect(solution).ToNot(ContainElement(PackageAssert{Package: A, Value: true})) - - Expect(solution).To(ContainElement(PackageAssert{Package: D2, Value: true})) - Expect(solution).To(ContainElement(PackageAssert{Package: D, Value: false})) - Expect(solution).To(ContainElement(PackageAssert{Package: D1, Value: false})) - Expect(solution).ToNot(ContainElement(PackageAssert{Package: E, Value: true})) - - Expect(len(solution)).To(Equal(6)) - Expect(err).ToNot(HaveOccurred()) - }) - - It("Support provides with selectors", func() { - E := pkg.NewPackage("E", "1.3", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - - C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - D2 := pkg.NewPackage("D", "1.9", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - D := pkg.NewPackage("D", "1.8", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - D1 := pkg.NewPackage("D", "1.4", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - B := pkg.NewPackage("B", "1.1", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "D", Version: ">=1.0"}}, []*pkg.DefaultPackage{}) - A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "D", Version: ">=1.0"}}, []*pkg.DefaultPackage{}) - - D2.SetProvides([]*pkg.DefaultPackage{{Name: "E", Version: ">=1.3"}}) - A2 := pkg.NewPackage("A", "1.3", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "E", Version: ">=1.0"}}, []*pkg.DefaultPackage{}) - - for _, p := range []pkg.Package{A, B, C, D, D1, D2, A2, E} { - _, err := dbDefinitions.CreatePackage(p) - Expect(err).ToNot(HaveOccurred()) - } - - for _, p := range []pkg.Package{} { - _, err := dbInstalled.CreatePackage(p) - Expect(err).ToNot(HaveOccurred()) - } - s = &Parallel{InstalledDatabase: dbInstalled, Concurrency: 4, DefinitionDatabase: dbDefinitions, ParallelDatabase: db} - - solution, err := s.Install([]pkg.Package{A2}) - Expect(solution).To(ContainElement(PackageAssert{Package: A2, Value: true})) - Expect(solution).ToNot(ContainElement(PackageAssert{Package: B, Value: true})) - Expect(solution).ToNot(ContainElement(PackageAssert{Package: D1, Value: true})) - Expect(solution).ToNot(ContainElement(PackageAssert{Package: D, Value: true})) - Expect(solution).ToNot(ContainElement(PackageAssert{Package: C, Value: true})) - Expect(solution).ToNot(ContainElement(PackageAssert{Package: A, Value: true})) - - Expect(solution).To(ContainElement(PackageAssert{Package: D2, Value: true})) - Expect(solution).To(ContainElement(PackageAssert{Package: D, Value: false})) - Expect(solution).To(ContainElement(PackageAssert{Package: D1, Value: false})) - Expect(solution).ToNot(ContainElement(PackageAssert{Package: E, Value: true})) - - Expect(len(solution)).To(Equal(6)) - Expect(err).ToNot(HaveOccurred()) - }) - - Context("Uninstall", func() { - It("Uninstalls simple package correctly", func() { - - C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - - 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 = &Parallel{InstalledDatabase: dbInstalled, Concurrency: 4, DefinitionDatabase: dbDefinitions, ParallelDatabase: db} - - solution, err := s.Uninstall(true, true, A) - Expect(err).ToNot(HaveOccurred()) - - Expect(solution).To(ContainElement(A)) - - // Expect(solution).To(ContainElement(PackageAssert{Package: C, Value: true})) - Expect(len(solution)).To(Equal(1)) - }) - It("Uninstalls simple package expanded correctly", func() { - - C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - A := pkg.NewPackage("A", "1.2", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - - 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 = &Parallel{InstalledDatabase: dbInstalled, Concurrency: 4, DefinitionDatabase: dbDefinitions, ParallelDatabase: db} - - solution, err := s.Uninstall(true, true, &pkg.DefaultPackage{Name: "A", Version: ">1.0"}) - Expect(err).ToNot(HaveOccurred()) - - Expect(solution).To(ContainElement(A)) - - // Expect(solution).To(ContainElement(PackageAssert{Package: C, Value: true})) - Expect(len(solution)).To(Equal(1)) - }) - It("Uninstalls simple packages not in world correctly", func() { - - C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - - 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(true, true, A) - Expect(err).ToNot(HaveOccurred()) - - Expect(solution).To(ContainElement(A)) - - // Expect(solution).To(ContainElement(PackageAssert{Package: C, Value: true})) - Expect(len(solution)).To(Equal(1)) - }) - - It("Uninstalls complex packages not in world correctly", func() { - C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{B}, []*pkg.DefaultPackage{}) - - 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(true, true, A) - Expect(err).ToNot(HaveOccurred()) - - Expect(solution).To(ContainElement(A)) - Expect(solution).To(ContainElement(B)) - - Expect(len(solution)).To(Equal(2)) - }) - - It("Uninstalls complex packages correctly, even if shared deps are required by system packages", func() { - D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{B}, []*pkg.DefaultPackage{}) - C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{B}, []*pkg.DefaultPackage{}) - - 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(true, true, A) - Expect(err).ToNot(HaveOccurred()) - - Expect(solution).To(ContainElement(A)) - Expect(solution).ToNot(ContainElement(B)) - - Expect(len(solution)).To(Equal(1)) - }) - - It("Uninstalls multiple complex packages correctly, even if shared deps are required by system packages", func() { - D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{B}, []*pkg.DefaultPackage{}) - C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{B}, []*pkg.DefaultPackage{}) - - 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(true, true, A, C) - Expect(err).ToNot(HaveOccurred()) - Expect(solution).To(ContainElement(C)) - - Expect(solution).To(ContainElement(A)) - Expect(solution).ToNot(ContainElement(B)) - - Expect(len(solution)).To(Equal(2)) - }) - - It("Uninstalls complex packages in world correctly", func() { - C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{C}, []*pkg.DefaultPackage{}) - - 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(true, true, A) - Expect(err).ToNot(HaveOccurred()) - - Expect(solution).To(ContainElement(A)) - Expect(solution).To(ContainElement(C)) - - Expect(len(solution)).To(Equal(2)) - }) - - It("Uninstalls complex package correctly", func() { - C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{D}, []*pkg.DefaultPackage{}) - A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{B}, []*pkg.DefaultPackage{}) - // C // installed - - 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(true, true, A) - Expect(err).ToNot(HaveOccurred()) - - Expect(solution).To(ContainElement(A)) - Expect(solution).To(ContainElement(B)) - Expect(solution).To(ContainElement(D)) - - Expect(len(solution)).To(Equal(3)) - - }) - - It("UninstallUniverse simple package correctly", func() { - - C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - - 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 = &Parallel{InstalledDatabase: dbInstalled, Concurrency: 4, DefinitionDatabase: dbDefinitions, ParallelDatabase: db} - - solution, err := s.UninstallUniverse(pkg.Packages{A}) - Expect(err).ToNot(HaveOccurred()) - - Expect(solution).To(ContainElement(A)) - - // Expect(solution).To(ContainElement(PackageAssert{Package: C, Value: true})) - Expect(len(solution)).To(Equal(1)) - }) - It("UninstallUniverse simple package expanded correctly", func() { - - C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - A := pkg.NewPackage("A", "1.2", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - - 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 = &Parallel{InstalledDatabase: dbInstalled, Concurrency: 4, DefinitionDatabase: dbDefinitions, ParallelDatabase: db} - - solution, err := s.UninstallUniverse(pkg.Packages{ - &pkg.DefaultPackage{Name: "A", Version: ">1.0"}}) - Expect(err).ToNot(HaveOccurred()) - - Expect(solution).To(ContainElement(A)) - - // Expect(solution).To(ContainElement(PackageAssert{Package: C, Value: true})) - Expect(len(solution)).To(Equal(1)) - }) - It("UninstallUniverse simple packages not in world correctly", func() { - - C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - - 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.UninstallUniverse(pkg.Packages{A}) - Expect(err).ToNot(HaveOccurred()) - - Expect(solution).To(ContainElement(A)) - - // Expect(solution).To(ContainElement(PackageAssert{Package: C, Value: true})) - Expect(len(solution)).To(Equal(1)) - }) - - It("UninstallUniverse complex packages not in world correctly", func() { - C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{B}, []*pkg.DefaultPackage{}) - - 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.UninstallUniverse(pkg.Packages{A}) - Expect(err).ToNot(HaveOccurred()) - - Expect(solution).To(ContainElement(A)) - Expect(solution).To(ContainElement(B)) - - Expect(len(solution)).To(Equal(2)) - }) - - It("UninstallUniverse complex packages correctly, even if shared deps are required by system packages", func() { - // Here we diff a lot from standard Uninstall: - // all the packages that has reverse deps will be removed (aka --full) - D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{B}, []*pkg.DefaultPackage{}) - C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{B}, []*pkg.DefaultPackage{}) - - 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.UninstallUniverse(pkg.Packages{A}) - Expect(err).ToNot(HaveOccurred()) - - Expect(solution).To(ContainElement(A)) - Expect(solution).To(ContainElement(B)) - Expect(solution).To(ContainElement(C)) - - Expect(len(solution)).To(Equal(3)) - }) - - It("UninstallUniverse complex packages in world correctly", func() { - C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{C}, []*pkg.DefaultPackage{}) - - 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.UninstallUniverse(pkg.Packages{A}) - Expect(err).ToNot(HaveOccurred()) - - Expect(solution).To(ContainElement(A)) - Expect(solution).To(ContainElement(C)) - - Expect(len(solution)).To(Equal(2)) - }) - - It("UninstallUniverse complex package correctly", func() { - C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{D}, []*pkg.DefaultPackage{}) - A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{B}, []*pkg.DefaultPackage{}) - // C // installed - - 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.UninstallUniverse(pkg.Packages{A}) - Expect(err).ToNot(HaveOccurred()) - - Expect(solution).To(ContainElement(A)) - Expect(solution).To(ContainElement(B)) - Expect(solution).To(ContainElement(D)) - - Expect(len(solution)).To(Equal(3)) - - }) - - }) - It("Find conflicts", func() { - - C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - - B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{A}, []*pkg.DefaultPackage{}) - - 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) - Expect(err).ToNot(HaveOccurred()) - Expect(val).To(BeTrue()) - - }) - - It("Find nested conflicts", func() { - - C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{D}, []*pkg.DefaultPackage{}) - - B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{A}, []*pkg.DefaultPackage{}) - - 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) - Expect(err).ToNot(HaveOccurred()) - Expect(val).To(BeTrue()) - }) - - It("Doesn't find nested conflicts", func() { - - C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{D}, []*pkg.DefaultPackage{}) - - B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{A}, []*pkg.DefaultPackage{}) - - 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) - Expect(err).ToNot(HaveOccurred()) - Expect(val).ToNot(BeTrue()) - }) - - It("Doesn't find conflicts", func() { - - C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - - B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - - 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) - Expect(err).ToNot(HaveOccurred()) - Expect(val).ToNot(BeTrue()) - }) - - It("Find conflicts using revdeps", func() { - - C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - - B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{A}, []*pkg.DefaultPackage{}) - - 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.Conflicts(A, dbInstalled.World()) - Expect(err.Error()).To(Equal("\n/B-")) - Expect(val).To(BeTrue()) - - }) - - It("Find nested conflicts with revdeps", func() { - - C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{D}, []*pkg.DefaultPackage{}) - - B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{A}, []*pkg.DefaultPackage{}) - - 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.Conflicts(D, dbInstalled.World()) - Expect(err.Error()).To(Or(Equal("\n/A-\n/B-"), Equal("\n/B-\n/A-"))) - Expect(val).To(BeTrue()) - }) - - It("Doesn't find nested conflicts with revdeps", func() { - - C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{D}, []*pkg.DefaultPackage{}) - - B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{A}, []*pkg.DefaultPackage{}) - - 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.Conflicts(C, dbInstalled.World()) - Expect(err).ToNot(HaveOccurred()) - Expect(val).ToNot(BeTrue()) - }) - - It("Doesn't find conflicts with revdeps", func() { - - C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - - B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - - 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.Conflicts(C, dbInstalled.World()) - Expect(err).ToNot(HaveOccurred()) - Expect(val).ToNot(BeTrue()) - }) - - }) - - Context("Conflict set", func() { - - It("is unsolvable - as we something we ask to install conflict with system stuff", func() { - C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - // D := pkg.NewPackage("D", "", []pkg.Package{}, []pkg.Package{}) - B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{C}) - A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{B}, []*pkg.DefaultPackage{}) - - 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}) - Expect(len(solution)).To(Equal(0)) - Expect(err).To(HaveOccurred()) - }) - - }) - - Context("Complex data sets", func() { - It("Solves them correctly", func() { - C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - E := pkg.NewPackage("E", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - F := pkg.NewPackage("F", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - G := pkg.NewPackage("G", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - H := pkg.NewPackage("H", "", []*pkg.DefaultPackage{G}, []*pkg.DefaultPackage{}) - D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{H}, []*pkg.DefaultPackage{}) - B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{D}, []*pkg.DefaultPackage{}) - A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{B}, []*pkg.DefaultPackage{}) - - 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}) - Expect(err).ToNot(HaveOccurred()) - - Expect(solution).To(ContainElement(PackageAssert{Package: A, Value: true})) - Expect(solution).To(ContainElement(PackageAssert{Package: B, Value: true})) - Expect(solution).To(ContainElement(PackageAssert{Package: D, 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)) - }) - }) - - Context("Selection", func() { - a := pkg.NewPackage("A", ">=2.0", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - a1 := pkg.NewPackage("A", "2.0", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - a11 := pkg.NewPackage("A", "2.1", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - a01 := pkg.NewPackage("A", "2.2", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - a02 := pkg.NewPackage("A", "2.3", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - a03 := pkg.NewPackage("A", "2.3.4", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - old := pkg.NewPackage("A", "1.3.1", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - - It("Expands correctly", func() { - definitions := pkg.NewInMemoryDatabase(false) - for _, p := range []pkg.Package{a1, a11, a01, a02, a03, old} { - _, err := definitions.CreatePackage(p) - Expect(err).ToNot(HaveOccurred()) - } - lst, err := a.Expand(definitions) - Expect(err).ToNot(HaveOccurred()) - Expect(lst).To(ContainElement(a11)) - Expect(lst).To(ContainElement(a1)) - Expect(lst).To(ContainElement(a01)) - Expect(lst).To(ContainElement(a02)) - Expect(lst).To(ContainElement(a03)) - Expect(lst).ToNot(ContainElement(old)) - Expect(len(lst)).To(Equal(5)) - p := lst.Best(nil) - Expect(p).To(Equal(a03)) - }) - }) - Context("Upgrades", func() { - - C := pkg.NewPackage("c", "1.5", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "a", Version: ">=1.0", Category: "test"}}, []*pkg.DefaultPackage{}) - C.SetCategory("test") - B := pkg.NewPackage("b", "1.0", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - B.SetCategory("test") - A := pkg.NewPackage("a", "1.1", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "b", Version: "1.0", Category: "test"}}, []*pkg.DefaultPackage{}) - A.SetCategory("test") - A1 := pkg.NewPackage("a", "1.2", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "b", Version: "1.0", Category: "test"}}, []*pkg.DefaultPackage{}) - A1.SetCategory("test") - - It("upgrades correctly", func() { - for _, p := range []pkg.Package{A1, B, C} { - _, err := dbDefinitions.CreatePackage(p) - Expect(err).ToNot(HaveOccurred()) - } - - for _, p := range []pkg.Package{A, B} { - _, err := dbInstalled.CreatePackage(p) - Expect(err).ToNot(HaveOccurred()) - } - uninstall, solution, err := s.Upgrade(true, true) - Expect(err).ToNot(HaveOccurred()) - - Expect(len(uninstall)).To(Equal(1)) - Expect(uninstall[0].GetName()).To(Equal("a")) - Expect(uninstall[0].GetVersion()).To(Equal("1.1")) - - Expect(solution).To(ContainElement(PackageAssert{Package: A1, Value: true})) - Expect(solution).To(ContainElement(PackageAssert{Package: B, Value: true})) - Expect(solution).To(ContainElement(PackageAssert{Package: C, Value: false})) - Expect(len(solution)).To(Equal(3)) - - }) - - It("UpgradeUniverse upgrades correctly", func() { - for _, p := range []pkg.Package{A1, B, C} { - _, err := dbDefinitions.CreatePackage(p) - Expect(err).ToNot(HaveOccurred()) - } - - for _, p := range []pkg.Package{A, B} { - _, err := dbInstalled.CreatePackage(p) - Expect(err).ToNot(HaveOccurred()) - } - uninstall, solution, err := s.UpgradeUniverse(true) - Expect(err).ToNot(HaveOccurred()) - - Expect(len(uninstall)).To(Equal(1)) - Expect(uninstall[0].GetName()).To(Equal("a")) - Expect(uninstall[0].GetVersion()).To(Equal("1.1")) - - Expect(solution).ToNot(ContainElement(PackageAssert{Package: C, Value: true})) - Expect(solution).ToNot(ContainElement(PackageAssert{Package: A, Value: true})) - - Expect(len(solution)).To(Equal(3)) - }) - - It("UpgradeUniverse upgrades correctly", func() { - - D := pkg.NewPackage("d", "1.5", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "a", Version: ">=1.0", Category: "test"}}, []*pkg.DefaultPackage{}) - D.SetCategory("test") - C = pkg.NewPackage("c", "1.5", []*pkg.DefaultPackage{ - &pkg.DefaultPackage{Name: "a", Version: ">=1.0", Category: "test"}, - &pkg.DefaultPackage{Name: "d", Version: ">=1.0", Category: "test"}, - }, []*pkg.DefaultPackage{}) - C.SetCategory("test") - C1 := pkg.NewPackage("c", "1.6", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "a", Version: ">=1.0", Category: "test"}}, []*pkg.DefaultPackage{}) - C1.SetCategory("test") - B = pkg.NewPackage("b", "1.0", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - B.SetCategory("test") - - B1 := pkg.NewPackage("b", "1.1", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "c", Version: ">=1.0", Category: "test"}}, []*pkg.DefaultPackage{}) - B1.SetCategory("test") - A = pkg.NewPackage("a", "1.1", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "b", Version: "1.0", Category: "test"}}, []*pkg.DefaultPackage{}) - A.SetCategory("test") - A1 = pkg.NewPackage("a", "1.2", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "b", Version: ">=1.0", Category: "test"}}, []*pkg.DefaultPackage{}) - A1.SetCategory("test") - - for _, p := range []pkg.Package{A1, B, B1, C, C1, D} { - _, err := dbDefinitions.CreatePackage(p) - Expect(err).ToNot(HaveOccurred()) - } - - for _, p := range []pkg.Package{A, B, D} { - _, err := dbInstalled.CreatePackage(p) - Expect(err).ToNot(HaveOccurred()) - } - uninstall, solution, err := s.UpgradeUniverse(false) - Expect(err).ToNot(HaveOccurred()) - - Expect(len(uninstall)).To(Equal(2)) - Expect(uninstall).To(ContainElement(A)) - Expect(uninstall).To(ContainElement(B)) - - Expect(solution).To(ContainElement(PackageAssert{Package: A1, Value: true})) - Expect(solution).To(ContainElement(PackageAssert{Package: B1, Value: true})) - Expect(solution).To(ContainElement(PackageAssert{Package: C1, Value: true})) - - Expect(len(solution)).To(Equal(6)) - }) - - It("UpgradeUniverse upgrades correctly", func() { - - D := pkg.NewPackage("d", "1.5", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "a", Version: ">=1.0", Category: "test"}}, []*pkg.DefaultPackage{}) - D.SetCategory("test") - D1 := pkg.NewPackage("d", "1.6", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "a", Version: ">=1.0", Category: "test"}}, []*pkg.DefaultPackage{}) - D1.SetCategory("test") - C = pkg.NewPackage("c", "1.5", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - C.SetCategory("test") - B = pkg.NewPackage("b", "1.0", []*pkg.DefaultPackage{ - &pkg.DefaultPackage{Name: "c", Version: ">=1.0", Category: "test"}, - }, []*pkg.DefaultPackage{}) - B.SetCategory("test") - - A = pkg.NewPackage("a", "1.1", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "b", Version: "1.0", Category: "test"}}, []*pkg.DefaultPackage{}) - A.SetCategory("test") - - for _, p := range []pkg.Package{A, B, C, D, D1} { - _, 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()) - } - uninstall, solution, err := s.UpgradeUniverse(false) - Expect(err).ToNot(HaveOccurred()) - - Expect(len(uninstall)).To(Equal(1)) - Expect(uninstall[0].GetName()).To(Equal("d")) - Expect(uninstall[0].GetVersion()).To(Equal("1.5")) - - Expect(solution).To(ContainElement(PackageAssert{Package: D1, Value: true})) - - Expect(len(solution)).To(Equal(3)) - }) - - It("Upgrade upgrades correctly", func() { - - D := pkg.NewPackage("d", "1.5", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "a", Version: ">=1.0", Category: "test"}}, []*pkg.DefaultPackage{}) - D.SetCategory("test") - C = pkg.NewPackage("c", "1.5", []*pkg.DefaultPackage{ - &pkg.DefaultPackage{Name: "a", Version: ">=1.0", Category: "test"}, - &pkg.DefaultPackage{Name: "d", Version: ">=1.0", Category: "test"}, - }, []*pkg.DefaultPackage{}) - C.SetCategory("test") - C1 := pkg.NewPackage("c", "1.6", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "a", Version: ">=1.0", Category: "test"}}, []*pkg.DefaultPackage{}) - C1.SetCategory("test") - B = pkg.NewPackage("b", "1.0", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - B.SetCategory("test") - - B1 := pkg.NewPackage("b", "1.1", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "c", Version: ">=1.0", Category: "test"}}, []*pkg.DefaultPackage{}) - B1.SetCategory("test") - A = pkg.NewPackage("a", "1.1", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "b", Version: "1.0", Category: "test"}}, []*pkg.DefaultPackage{}) - A.SetCategory("test") - A1 = pkg.NewPackage("a", "1.2", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "b", Version: ">=1.0", Category: "test"}}, []*pkg.DefaultPackage{}) - A1.SetCategory("test") - - for _, p := range []pkg.Package{A1, B, B1, C, C1, D} { - _, err := dbDefinitions.CreatePackage(p) - Expect(err).ToNot(HaveOccurred()) - } - - for _, p := range []pkg.Package{A, B, D} { - _, err := dbInstalled.CreatePackage(p) - Expect(err).ToNot(HaveOccurred()) - } - uninstall, solution, err := s.Upgrade(false, false) - Expect(err).ToNot(HaveOccurred()) - - Expect(len(uninstall)).To(Equal(2)) - Expect(uninstall).To(ContainElement(A)) - Expect(uninstall).To(ContainElement(B)) - - Expect(solution).To(ContainElement(PackageAssert{Package: A1, Value: true})) - Expect(solution).To(ContainElement(PackageAssert{Package: B1, Value: true})) - Expect(solution).To(ContainElement(PackageAssert{Package: C1, Value: true})) - - Expect(len(solution)).To(Equal(6)) - }) - - It("Upgrade upgrades correctly", func() { - - D := pkg.NewPackage("d", "1.5", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "a", Version: ">=1.0", Category: "test"}}, []*pkg.DefaultPackage{}) - D.SetCategory("test") - D1 := pkg.NewPackage("d", "1.6", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "a", Version: ">=1.0", Category: "test"}}, []*pkg.DefaultPackage{}) - D1.SetCategory("test") - C = pkg.NewPackage("c", "1.5", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) - C.SetCategory("test") - B = pkg.NewPackage("b", "1.0", []*pkg.DefaultPackage{ - &pkg.DefaultPackage{Name: "c", Version: ">=1.0", Category: "test"}, - }, []*pkg.DefaultPackage{}) - B.SetCategory("test") - - A = pkg.NewPackage("a", "1.1", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "b", Version: "1.0", Category: "test"}}, []*pkg.DefaultPackage{}) - A.SetCategory("test") - - for _, p := range []pkg.Package{A, B, C, D, D1} { - _, 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()) - } - uninstall, solution, err := s.Upgrade(false, false) - Expect(err).ToNot(HaveOccurred()) - - Expect(len(uninstall)).To(Equal(1)) - Expect(uninstall[0].GetName()).To(Equal("d")) - Expect(uninstall[0].GetVersion()).To(Equal("1.5")) - - Expect(solution).To(ContainElement(PackageAssert{Package: D1, Value: true})) - - Expect(len(solution)).To(Equal(5)) - }) - }) -}) diff --git a/pkg/solver/solver.go b/pkg/solver/solver.go index 8cf1a9f4..92a222b1 100644 --- a/pkg/solver/solver.go +++ b/pkg/solver/solver.go @@ -30,7 +30,6 @@ type SolverType int const ( SingleCoreSimple = 0 - ParallelSimple = iota ) // PackageSolver is an interface to a generic package solving algorithm @@ -85,8 +84,6 @@ func NewResolver(t Options, installed pkg.PackageDatabase, definitiondb pkg.Pack switch t.Type { case SingleCoreSimple: s = &Solver{InstalledDatabase: installed, DefinitionDatabase: definitiondb, SolverDatabase: solverdb, Resolver: re} - case ParallelSimple: - s = &Parallel{InstalledDatabase: installed, DefinitionDatabase: definitiondb, ParallelDatabase: solverdb, Resolver: re, Concurrency: t.Concurrency} } return s