#1185 Fix traceback in MMDResolver when transitive dependency cannot be satisfied.
Merged 6 months ago by jkaluza. Opened 6 months ago by jkaluza.
jkaluza/fm-orchestrator resolver-fav-not-installable  into  master

@@ -510,9 +510,8 @@ 

                      kfunc = s2nsvc

                  elif policy == MMDResolverPolicy.First:

                      kfunc = s2ns

+                 # `key` contains tuple similar to "('gtk:1', 'foo:1')"

                  key = tuple(kfunc(s) for s in opt)

-                 # `key` now contains tuple similar to "('gtk:1', 'foo:1')"

-                 alternative = src_alternatives.setdefault(key, [])


                  # Create the solving jobs.

                  # We need to say to libsolv that we want it to prefer modules from the combination

@@ -559,6 +558,7 @@ 

                  # Remember that src_alternatives are grouped by NS or NSVC depending on

                  # MMDResolverPolicy, so there might be more of them.

                  if all_solvables_found:

+                     alternative = src_alternatives.setdefault(key, [])



                      log.debug("  - ^ Not all favored solvables found in the result, skipping.")

@@ -326,3 +326,30 @@ 


          with pytest.raises(RuntimeError, match=err_msg_regex):



+     def test_solve_new_platform(self,):

+         """

+         Tests that MMDResolver works in case we add new platform and there is

+         modular dependency of input module which is built only against old

+         platforms and in the same time the input module wants to be built

+         with all available platforms.

+         """

+         modules = (

+             ("platform:f28:0:c0", {}),

+             ("platform:f29:0:c0", {}),

+             ("platform:f30:0:c0", {}),

+             ("gtk:3:0:c8", {"platform": ["f28"]}),

+             ("gtk:3:0:c9", {"platform": ["f29"]}),

+         )

+         for n, req in modules:

+             self.mmd_resolver.add_modules(self._make_mmd(n, req))


+         app = self._make_mmd("app:1:0", {"platform": [], "gtk": ["3"]})

+         expanded = self.mmd_resolver.solve(app)


+         # Build only against f28 and f29, because "gtk:3" is not built against f30.

+         expected = set([

+             frozenset(['gtk:3:0:c8:x86_64', 'app:1:0:0:src', 'platform:f28:0:c0:x86_64']),

+             frozenset(['gtk:3:0:c9:x86_64', 'app:1:0:0:src', 'platform:f29:0:c0:x86_64'])])


+         assert expanded == expected

This fixes problems from #1184 when new platform stream is added and the
input module depends on another module which is not built against this
new platform, but in the same time the input module wants to be built
against this new platform stream. See the unit-test for more info.

The problem is that MMDResolver.solve() method sets the alternative
to an empty list and stores the data there only if the alternative
is found valid. If the alternative is not found valid, then it stays
set to an empty list, but the code using alternative later expects
it to only contains valid alternatives.

This commit fixes this by setting the alternative only in a case
we found it is valid alternative.

Pull-Request has been merged by jkaluza

6 months ago