Replace all rpmmd.Depsolve() calls with dnfjson

All calls to rpmmd.Depsolve() are now replaced with the equivalent call
to solver.Depsolve() (or dnfjson.Depsolve() for one-off calls).

Attached an unconfigured dnfjson.BaseSolver to all APIs and server
configurations where rpmmd.RPMMD used to be.  This BaseSolver instance
loads the repository credentials from the system and carries the cache
directory, much like the RPMMD field used to do.  The BaseSolver is used
to create an initialised (configured) solver with the platform variables
(module platform ID, release ver, and arch) before running a Depsolve()
or FetchMetadata() using the NewWithConfig() method.

The FillDependencies() call in the modulesInfoHandler() of the weldr API
has been replaced by a direct call to the Depsolve() function.  This
rpmmd function was only used here.  Replacing the rpmmd.Depsolve() call
in rpmmd.FillDependencies() with dnfjson.Depsolve() would have created
an import cycle.  The FillDependencies() function could have been moved
to dnfjson, but since it's only used in one place, moving the one-line
function body into the caller is ok.

For testing:

The mock-dnf-json is compiled to a temporary directory during test
initialisation and used for each Depsolve() or FetchMetadata() call.

The weldr API tests now use the mock dnfjson.  Each rpmmd_mock.Fixture
now also has a dnfjson_mock.ResponseGenerator.

All API calls in the tests use the proper functions from dnfjson and
only the dnf-json script is mocked.  Because of this, some of the
expected results in responses_test had to be changed to match correct
behaviour:
- The "builds" array of each package in the result of a module or
  project list is now sorted by version number (ascending) because we
  sort the package list in the result of dnfjson by NVR.
- 'check_gpg: true' is added to the expected response of the depsolve
  test.  The repository configs in the test weldr API specify 'CheckGPG:
  True', but the mock responses returned it as false, so the expected
  result didn't need to include it.  Since now we're using the actual
  dnfjson code to convert the mock response to the internal structure,
  the repository settings are correctly used to set flag to true for
  each package associated with that repository.
- The word "occurred" was mistyped as "occured" in rpmmd and is now
  fixed in dnfjson.
This commit is contained in:
Achilleas Koutsou 2022-03-22 23:23:05 +01:00 committed by Tom Gundersen
parent e9a7a50496
commit 177ea1b08f
14 changed files with 1618 additions and 1606 deletions

View file

@ -16,6 +16,7 @@ import (
"github.com/osbuild/osbuild-composer/internal/distro"
"github.com/osbuild/osbuild-composer/internal/distro/fedora"
rhel "github.com/osbuild/osbuild-composer/internal/distro/rhel86"
"github.com/osbuild/osbuild-composer/internal/dnfjson"
"github.com/osbuild/osbuild-composer/internal/rpmmd"
"github.com/osbuild/osbuild-composer/internal/test"
)
@ -39,11 +40,13 @@ func TestFetchChecksum(t *testing.T) {
IgnoreSSL: true,
}
solver := dnfjson.NewSolver("platform:f31", "31", "x86_64", path.Join(dir, "rpmmd"))
// use a fullpath to dnf-json, this allows this test to have an arbitrary
// working directory
rpmMetadata := rpmmd.NewRPMMD(path.Join(dir, "rpmmd"))
_, c, err := rpmMetadata.FetchMetadata([]rpmmd.RepoConfig{repoCfg}, "platform:f31", "x86_64", "31")
solver.SetDNFJSONPath("/usr/libexec/osbuild-composer/dnf-json")
res, err := solver.FetchMetadata([]rpmmd.RepoConfig{repoCfg})
assert.Nilf(t, err, "Failed to fetch checksum: %v", err)
c := res.Checksums
assert.NotEqual(t, "", c["repo"], "The checksum is empty")
}
@ -63,10 +66,7 @@ func TestCrossArchDepsolve(t *testing.T) {
// Set up temporary directory for rpm/dnf cache
dir := t.TempDir()
// use a fullpath to dnf-json, this allows this test to have an arbitrary
// working directory
rpm := rpmmd.NewRPMMD(dir)
baseSolver := dnfjson.NewBaseSolver(dir)
repos, err := rpmmd.LoadRepositories([]string{repoDir}, distroStruct.Name())
require.NoErrorf(t, err, "Failed to LoadRepositories %v", distroStruct.Name())
@ -75,7 +75,7 @@ func TestCrossArchDepsolve(t *testing.T) {
t.Run(archStr, func(t *testing.T) {
arch, err := distroStruct.GetArch(archStr)
require.NoError(t, err)
solver := baseSolver.NewWithConfig(distroStruct.ModulePlatformID(), distroStruct.Releasever(), archStr)
for _, imgTypeStr := range arch.ListImageTypes() {
t.Run(imgTypeStr, func(t *testing.T) {
imgType, err := arch.GetImageType(imgTypeStr)
@ -83,10 +83,10 @@ func TestCrossArchDepsolve(t *testing.T) {
packages := imgType.PackageSets(blueprint.Blueprint{})
_, _, err = rpm.Depsolve(packages["build"], repos[archStr], distroStruct.ModulePlatformID(), archStr, distroStruct.Releasever())
_, err = solver.Depsolve(packages["build"], repos[archStr])
assert.NoError(t, err)
_, _, err = rpm.Depsolve(packages["packages"], repos[archStr], distroStruct.ModulePlatformID(), archStr, distroStruct.Releasever())
_, err = solver.Depsolve(packages["packages"], repos[archStr])
assert.NoError(t, err)
})
}
@ -111,10 +111,7 @@ func TestDepsolvePackageSets(t *testing.T) {
// Set up temporary directory for rpm/dnf cache
dir := t.TempDir()
// use a fullpath to dnf-json, this allows this test to have an arbitrary
// working directory
rpm := rpmmd.NewRPMMD(dir)
solver := dnfjson.NewSolver(distroStruct.ModulePlatformID(), distroStruct.Releasever(), distro.X86_64ArchName, dir)
repos, err := rpmmd.LoadRepositories([]string{repoDir}, distroStruct.Name())
require.NoErrorf(t, err, "Failed to LoadRepositories %v", distroStruct.Name())
@ -150,7 +147,29 @@ func TestDepsolvePackageSets(t *testing.T) {
return expectedPkgSpecsSetNames
}(imagePkgSets, imagePkgSetChains)
gotPackageSpecsSets, err := rpm.DepsolvePackageSets(imagePkgSetChains, imagePkgSets, x86Repos, nil, distroStruct.ModulePlatformID(), x86Arch.Name(), distroStruct.Releasever())
gotPackageSpecsSets := make(map[string]*dnfjson.DepsolveResult, len(imagePkgSets))
// first depsolve package sets that are part of a chain
for specName, setNames := range imagePkgSetChains {
pkgSets := make([]rpmmd.PackageSet, len(setNames))
for idx, pkgSetName := range setNames {
pkgSets[idx] = imagePkgSets[pkgSetName]
delete(imagePkgSets, pkgSetName) // will be depsolved here: remove from map
}
res, err := solver.ChainDepsolve(pkgSets, x86Repos, nil)
if err != nil {
require.Nil(t, err)
}
gotPackageSpecsSets[specName] = res
}
// depsolve the rest of the package sets
for name, pkgSet := range imagePkgSets {
res, err := solver.ChainDepsolve([]rpmmd.PackageSet{pkgSet}, x86Repos, nil)
if err != nil {
require.Nil(t, err)
}
gotPackageSpecsSets[name] = res
}
require.Nil(t, err)
require.EqualValues(t, len(expectedPackageSpecsSetNames), len(gotPackageSpecsSets))
for _, name := range expectedPackageSpecsSetNames {