Skip to content

Conversation

@jrray
Copy link
Collaborator

@jrray jrray commented Sep 11, 2025

This test is a minimal reproduction of a problem we found when using the resolvo solver. Please read the test code first to understand the package relationships involved. The step solver passes the test because it solves successfully; the resolvo solver fails to solve with the following error:

The following packages are incompatible
└─ my-app:run my-app:run cannot be installed because there are no viable options:
   └─ my-app:run mem-01k4x9e8jtsez9ebc3qs1qtcg4/my-app/4.5.6/TSZZLWXD:run would require
      └─ openimageio:run openimageio:run/Binary:1.2.3, which cannot be
  installed because there are no viable options:
         └─ openimageio:run mem-01k4x9e8jtsez9ebc3qs1qtcg4/openimageio/1.2.3/XFWQWLQ2:run is
            excluded because build option spi-platform does not satisfy global var request:
            ~2025.1.1.1 does not intersect with ~2024.1.1.1

In the test the solver is invoked in a way to mimic solving for a build environment (it is in an spk build where we have the problem in the real world), or similar to spk env -o spi-platform=~2025.1.1.1 my-app.

The step solver doesn't think this is a problem but I'm struggling to understand why. If I say -o distro=rocky then I definitely expect that the solver won't pick any builds that have - var distro/centos, so what is different about the spi-platform var here? Why is the step solver willing to pick a build that has a different major version?

I'm not convinced the step solver is right here, but assuming it is, I need to understand what is wrong about how resolvo is operating. For example, if I comment out the part of the resolvo code that causes it to exclude the mismatched option, then 10 of the preexisting solver tests start to fail. If it is supposed to ignore mismatched options under a specific set of circumstances, what are those?

Edit: the mystery around host options being enforced was answered (see comments) and the step solver is working as intended (modulo options not really doing anything) so this PR changes resolvo to match the behavior of the step solver to the extent of our test coverage.

@jrray jrray self-assigned this Sep 11, 2025
@jrray
Copy link
Collaborator Author

jrray commented Sep 11, 2025

@rydrman I would appreciate your input here.

Comment on lines +3081 to +3148
solver.update_options(option_map! {
"spi-platform" => "~2025.1.1.1"
});
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC this is not the same as adding actual Var requests to the solver - the options only guide things but are not requirements to be satisfied

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Host options get lumped in with the other options but they are hard requirements. 🤔

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But it is true that if I add an actual var request then both solvers fail as unsolvable.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The step solver once used the current set of options as hard requirements, but it hasn't been that way for a long time. So I think resolvo should to the same - it can guide with these if needed but shouldn't consider them constraints - only actual requests.

I can only assume that the host options are also getting injected as requests through either the above or some other code path...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On a lark I tried changing the resolvo code to completely ignore options and all the tests now pass. I think this says more about the test coverage than it does about resolvo.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the one test that calls solver.update_options with a non-empty OptionMap:

solver.update_options(option_map! {"debug" => "on"});

When I comment out that line the test still passes.

Copy link
Collaborator Author

@jrray jrray Sep 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dcookspi pointed out that outside of the solver we are turning options into var requests, including host options so I think that explains how host options become hard requirements.

for r in options.get_var_requests()? {
solver.add_request(r.into());

It also suggests that it would be a proper change to make the resolvo internals stop turning options into var requests itself. That does make the new test pass. But we need more tests to show what the expected behavior is in the presence of options. Up to now resolvo has been treating all options as hard var requirements and it has taken a decent amount of time for that to show up as a problem in practice. After the change to not turn options into var requests is in place, resolvo won't be using options for anything.

I'm imagining a test where the repo has many variants of the same package with a color var set to red, blue, etc. Then if there is an option color=red set it should "prefer" to pick the red build, but that is not strictly mandatory for correct behavior if I'm understanding correctly.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm imagining a test where the repo has many variants of the same package with a color var set to red, blue, etc.

I created a test over in #1268.

@jrray
Copy link
Collaborator Author

jrray commented Sep 30, 2025

So at this point I think I want to just get a change merged in that stops resolvo from turning options into var requests to address our problem, and leave #1268 open to decide the fate of options. I'll rework this PR to be about adding this new test and making it pass.

@jrray jrray force-pushed the push-rvwyootwrpsk branch 2 times, most recently from 5abf273 to 20891e3 Compare September 30, 2025 01:42
@jrray jrray changed the title Add test demonstrating solver behavior discrepancy Fix resolvo treating options as var requirements Sep 30, 2025
@codecov
Copy link

codecov bot commented Sep 30, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

pub async fn solve(&self) -> Result<Solution> {
let repos = self.repos.clone();
let requests = self.requests.clone();
let options = self.options.clone();
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So basically options are not used by the solver at all now, but this field is kept around to uphold the SolverTrait contract of being able to call update_options and then see those options with get_options.

If a test is created that shows options doing something meaningful in the step solver then this field could start getting used again.

@jrray jrray requested a review from rydrman September 30, 2025 02:18
@jrray jrray added the SPI AOI Area of interest for SPI label Oct 9, 2025
@jrray jrray requested a review from dcookspi October 9, 2025 18:48
Add a test to demonstrate a solver setup that was succeeding with the
step solver but not resolvo. Resolvo was turning all solver options into
var requirements, but options are not actual requirements.

Confusingly, in practice command line options and host options _are_ turned
into var requirements, by adding them as additional requests, but that is
done outside of the solver implementations. The solver itself should not be
doing this.

Signed-off-by: J Robert Ray <[email protected]>
@jrray jrray force-pushed the push-rvwyootwrpsk branch from 20891e3 to 8798b7a Compare October 16, 2025 20:31
@jrray jrray merged commit 8cde6e3 into main Oct 16, 2025
9 checks passed
@jrray jrray deleted the push-rvwyootwrpsk branch October 16, 2025 21:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

SPI AOI Area of interest for SPI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants