Skip to content

Commit

Permalink
Fix software issues (#945)
Browse files Browse the repository at this point in the history
## Problem

Software issues are not updated after selecting/removing a pattern.

## Solution

Delegate package solver to the proposal object and update issues.

## Testing

* Added unit tests
* Tested manually

## Screenshots

![Screenshot from 2023-12-20
13-46-47](https://github.com/openSUSE/agama/assets/1112304/f25f639b-b45e-40a9-b772-8219d98e553f)
  • Loading branch information
joseivanlopez committed Dec 20, 2023
2 parents b12e42e + 30a3229 commit f55671d
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 33 deletions.
16 changes: 6 additions & 10 deletions service/lib/agama/software/manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -231,9 +231,7 @@ def add_pattern(id)
res = Yast::Pkg.ResolvableInstall(id, :pattern)
logger.info "Adding pattern #{res.inspect}"
Yast::PackagesProposal.AddResolvables(PROPOSAL_ID, :pattern, [id])

res = Yast::Pkg.PkgSolve(unused = true)
logger.info "Solver run #{res.inspect}"
proposal.solve_dependencies
selected_patterns_changed

true
Expand All @@ -245,9 +243,7 @@ def remove_pattern(id)
res = Yast::Pkg.ResolvableNeutral(id, :pattern, force = false)
logger.info "Removing pattern #{res.inspect}"
Yast::PackagesProposal.RemoveResolvables(PROPOSAL_ID, :pattern, [id])

res = Yast::Pkg.PkgSolve(unused = true)
logger.info "Solver run #{res.inspect}"
proposal.solve_dependencies
selected_patterns_changed

true
Expand All @@ -262,9 +258,7 @@ def assign_patterns(ids)
Yast::PackagesProposal.SetResolvables(PROPOSAL_ID, :pattern, ids)
ids.each { |p| Yast::Pkg.ResolvableInstall(p, :pattern) }
logger.info "Setting patterns to #{ids.inspect}"

res = Yast::Pkg.PkgSolve(unused = true)
logger.info "Solver run #{res.inspect}"
proposal.solve_dependencies
selected_patterns_changed

[]
Expand Down Expand Up @@ -383,7 +377,9 @@ def build_products
end

def proposal
@proposal ||= Proposal.new
@proposal ||= Proposal.new.tap do |proposal|
proposal.on_issues_change { update_issues }
end
end

def import_gpg_keys
Expand Down
41 changes: 20 additions & 21 deletions service/lib/agama/software/proposal.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,27 @@ def calculate
@proposal = Yast::Packages.Proposal(force_reset = true, reinit = false, _simple = true)
solve_dependencies

update_issues
valid?
end

# Runs the solver to satisfy the dependencies.
#
# Issues are updated once the solver finishes.
#
# @return [Boolean] whether the solver ran successfully
def solve_dependencies
res = Yast::Pkg.PkgSolve(unused = true)
logger.info "Solver run #{res.inspect}"
update_issues

return true if res

logger.error "Solver failed: #{Yast::Pkg.LastError}"
logger.error "Details: #{Yast::Pkg.LastErrorDetails}"
logger.error "Solver errors: #{Yast::Pkg.PkgSolveErrors}"
false
end

# Returns the count of packages to install
#
# @return [Integer] count of packages to install
Expand Down Expand Up @@ -172,12 +189,10 @@ def select_base_product
#
# @return [Array<Agama::Issue>]
def update_issues
self.issues = []
return unless proposal

msgs = []
msgs.concat(warning_messages(proposal))
msgs.concat(warning_messages(proposal)) if proposal
msgs.concat(solver_messages)

issues = msgs.map do |msg|
Issue.new(msg,
source: Issue::Source::CONFIG,
Expand All @@ -187,22 +202,6 @@ def update_issues
self.issues = issues
end

# Runs the solver to satisfy the solve_dependencies
#
# If the solver failed, it logs the error.
#
# @return [Boolean] whether the solver ran successfully
def solve_dependencies
res = Yast::Pkg.PkgSolve(unused = true)
logger.info "Solver run #{res.inspect}"
return true if res

logger.error "Solver failed: #{Yast::Pkg.LastError}"
logger.error "Details: #{Yast::Pkg.LastErrorDetails}"
logger.error "Solver errors: #{Yast::Pkg.PkgSolveErrors}"
false
end

# Extracts the warning messages from the proposal result
#
# @param proposal_result [Hash] Proposal result; it might contain a "warning" key with warning
Expand Down
6 changes: 6 additions & 0 deletions service/package/rubygem-agama.changes
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
-------------------------------------------------------------------
Wed Dec 20 15:30:40 UTC 2023 - José Iván López González <jlopez@suse.com>

- Update software issues after calling to solver
(gh#openSUSE/agama#945).

-------------------------------------------------------------------
Fri Dec 15 15:04:43 UTC 2023 - José Iván López González <jlopez@suse.com>

Expand Down
3 changes: 2 additions & 1 deletion service/test/agama/software/manager_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@
:languages= => nil,
set_resolvables: nil,
packages_count: "500 MB",
issues: proposal_issues
issues: proposal_issues,
on_issues_change: nil
)
end

Expand Down
38 changes: 37 additions & 1 deletion service/test/agama/software/proposal_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
describe Agama::Software::Proposal do
subject(:proposal) { described_class.new(logger: logger) }

let(:logger) { Logger.new($stdout) }
let(:logger) { Logger.new($stdout, level: :warn) }
let(:destdir) { "/mnt" }
let(:result) { {} }
let(:last_error) { "" }
Expand Down Expand Up @@ -111,6 +111,42 @@
end
end

describe "#solve_dependencies" do
it "calls the solver" do
expect(Yast::Pkg).to receive(:PkgSolve)
subject.solve_dependencies
end

context "if the solver successes" do
before do
allow(Yast::Pkg).to receive(:PkgSolve).and_return(true)
end

it "returns true" do
expect(subject.solve_dependencies).to eq(true)
end
end

context "if the solver fails" do
before do
allow(Yast::Pkg).to receive(:PkgSolve).and_return(false)
end

let(:solve_errors) { 2 }

it "returns false" do
expect(subject.solve_dependencies).to eq(false)
end

it "registers solver issue" do
subject.solve_dependencies
expect(subject.issues).to contain_exactly(
an_object_having_attributes(description: "Found 2 dependency issues.")
)
end
end
end

describe "#set_resolvables" do
it "adds the list of packages/patterns to the proposal" do
expect(Yast::PackagesProposal).to receive(:SetResolvables)
Expand Down

0 comments on commit f55671d

Please sign in to comment.