Skip to content

Commit cf8b866

Browse files
authored
Improve Catalog Selection Testing + Fix small issue (#1174)
We initially assumed that the resolvedBundle index we check doesn't matter when it comes to checking for prior package deprecations in the resolver but the index needs to match the prior result or the bundle names may not match and give a false negative. Also improved the unit test cases (which caught the above issue). Signed-off-by: dtfranz <dfranz@redhat.com>
1 parent 162c4f1 commit cf8b866

File tree

2 files changed

+84
-17
lines changed

2 files changed

+84
-17
lines changed

internal/resolve/catalog.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ func (r *CatalogResolver) Resolve(ctx context.Context, ext *ocv1alpha1.ClusterEx
114114
if len(resolvedBundles) != 0 {
115115
// We've already found one or more package candidates
116116
currentIsDeprecated := isDeprecated(thisBundle, thisDeprecation)
117-
priorIsDeprecated := isDeprecated(*resolvedBundles[0], priorDeprecation) // Slice index doesn't matter; the whole slice is either deprecated or not
117+
priorIsDeprecated := isDeprecated(*resolvedBundles[len(resolvedBundles)-1], priorDeprecation)
118118
if currentIsDeprecated && !priorIsDeprecated {
119119
// Skip this deprecated package and retain the non-deprecated package(s)
120120
return nil

internal/resolve/catalog_test.go

Lines changed: 83 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -236,50 +236,117 @@ func TestAcceptDeprecated(t *testing.T) {
236236

237237
func TestPackageVariationsBetweenCatalogs(t *testing.T) {
238238
pkgName := randPkg()
239-
genImgRef := func(catalog, name string) string {
240-
return fmt.Sprintf("%s/%s", catalog, name)
241-
}
242239
w := staticCatalogWalker{
243240
"a": func() (*declcfg.DeclarativeConfig, error) { return &declcfg.DeclarativeConfig{}, nil },
244241
"b": func() (*declcfg.DeclarativeConfig, error) {
245-
fbc := genPackage(pkgName)
246-
fbc.Bundles = append(fbc.Bundles, genBundle(pkgName, "1.0.3"))
247-
for i := range fbc.Bundles {
248-
fbc.Bundles[i].Image = genImgRef("catalog-b", fbc.Bundles[i].Name)
242+
fbc := &declcfg.DeclarativeConfig{
243+
Packages: []declcfg.Package{{Name: pkgName}},
244+
Bundles: []declcfg.Bundle{genBundle(pkgName, "1.0.0")},
245+
Deprecations: []declcfg.Deprecation{{
246+
Package: pkgName,
247+
Entries: []declcfg.DeprecationEntry{
248+
{
249+
Reference: declcfg.PackageScopedReference{Schema: declcfg.SchemaBundle, Name: bundleName(pkgName, "1.0.0")},
250+
Message: fmt.Sprintf("bundle %s is deprecated", bundleName(pkgName, "1.0.0")),
251+
},
252+
},
253+
}},
249254
}
250255
return fbc, nil
251256
},
252257
"c": func() (*declcfg.DeclarativeConfig, error) {
253-
fbc := genPackage(pkgName)
254-
fbc.Bundles = append(fbc.Bundles, genBundle(pkgName, "0.1.1"))
255-
fbc.Deprecations = nil
256-
for i := range fbc.Bundles {
257-
fbc.Bundles[i].Image = genImgRef("catalog-c", fbc.Bundles[i].Name)
258+
fbc := &declcfg.DeclarativeConfig{
259+
Packages: []declcfg.Package{{Name: pkgName}},
260+
Bundles: []declcfg.Bundle{genBundle(pkgName, "1.0.1")},
261+
Deprecations: []declcfg.Deprecation{{
262+
Package: pkgName,
263+
Entries: []declcfg.DeprecationEntry{
264+
{
265+
Reference: declcfg.PackageScopedReference{Schema: declcfg.SchemaBundle, Name: bundleName(pkgName, "1.0.1")},
266+
Message: fmt.Sprintf("bundle %s is deprecated", bundleName(pkgName, "1.0.1")),
267+
},
268+
},
269+
}},
270+
}
271+
return fbc, nil
272+
},
273+
"d": func() (*declcfg.DeclarativeConfig, error) {
274+
fbc := &declcfg.DeclarativeConfig{
275+
Packages: []declcfg.Package{{Name: pkgName}},
276+
Bundles: []declcfg.Bundle{genBundle(pkgName, "1.0.2")},
277+
}
278+
return fbc, nil
279+
},
280+
"e": func() (*declcfg.DeclarativeConfig, error) {
281+
fbc := &declcfg.DeclarativeConfig{
282+
Packages: []declcfg.Package{{Name: pkgName}},
283+
Bundles: []declcfg.Bundle{genBundle(pkgName, "1.0.3")},
284+
Deprecations: []declcfg.Deprecation{{
285+
Package: pkgName,
286+
Entries: []declcfg.DeprecationEntry{
287+
{
288+
Reference: declcfg.PackageScopedReference{Schema: declcfg.SchemaBundle, Name: bundleName(pkgName, "1.0.3")},
289+
Message: fmt.Sprintf("bundle %s is deprecated", bundleName(pkgName, "1.0.3")),
290+
},
291+
},
292+
}},
293+
}
294+
return fbc, nil
295+
},
296+
"f": func() (*declcfg.DeclarativeConfig, error) {
297+
fbc := &declcfg.DeclarativeConfig{
298+
Packages: []declcfg.Package{{Name: pkgName}},
299+
Bundles: []declcfg.Bundle{
300+
genBundle(pkgName, "1.0.4"),
301+
genBundle(pkgName, "1.0.5"),
302+
},
258303
}
259304
return fbc, nil
260305
},
261306
}
262307
r := CatalogResolver{WalkCatalogsFunc: w.WalkCatalogs}
263308

264-
t.Run("when catalog b has a newer version that matches the range", func(t *testing.T) {
309+
t.Run("when bundle candidates for a package are deprecated in all but one catalog", func(t *testing.T) {
265310
ce := buildFooClusterExtension(pkgName, "", ">=1.0.0 <=1.0.3", ocv1alpha1.UpgradeConstraintPolicyEnforce)
266311
gotBundle, gotVersion, gotDeprecation, err := r.Resolve(context.Background(), ce, nil)
312+
require.NoError(t, err)
313+
// We choose the only non-deprecated package
314+
assert.Equal(t, genBundle(pkgName, "1.0.2").Name, gotBundle.Name)
315+
assert.Equal(t, bsemver.MustParse("1.0.2"), *gotVersion)
316+
assert.Equal(t, (*declcfg.Deprecation)(nil), gotDeprecation)
317+
})
318+
319+
t.Run("when bundle candidates are found and deprecated in multiple catalogs", func(t *testing.T) {
320+
ce := buildFooClusterExtension(pkgName, "", ">=1.0.0 <=1.0.1", ocv1alpha1.UpgradeConstraintPolicyEnforce)
321+
gotBundle, gotVersion, gotDeprecation, err := r.Resolve(context.Background(), ce, nil)
267322
require.Error(t, err)
323+
// We will not make a decision on which catalog to use
268324
assert.ErrorContains(t, err, "found in multiple catalogs: [b c]")
269325
assert.Nil(t, gotBundle)
270326
assert.Nil(t, gotVersion)
271327
assert.Nil(t, gotDeprecation)
272328
})
273329

274-
t.Run("when catalog c has a newer version that matches the range", func(t *testing.T) {
275-
ce := buildFooClusterExtension(pkgName, "", ">=0.1.0 <1.0.0", ocv1alpha1.UpgradeConstraintPolicyEnforce)
330+
t.Run("when bundle candidates are found and not deprecated in multiple catalogs", func(t *testing.T) {
331+
ce := buildFooClusterExtension(pkgName, "", ">=1.0.0 <=1.0.4", ocv1alpha1.UpgradeConstraintPolicyEnforce)
276332
gotBundle, gotVersion, gotDeprecation, err := r.Resolve(context.Background(), ce, nil)
277333
require.Error(t, err)
278-
assert.ErrorContains(t, err, "found in multiple catalogs: [b c]")
334+
// We will not make a decision on which catalog to use
335+
assert.ErrorContains(t, err, "found in multiple catalogs: [d f]")
279336
assert.Nil(t, gotBundle)
280337
assert.Nil(t, gotVersion)
281338
assert.Nil(t, gotDeprecation)
282339
})
340+
341+
t.Run("highest semver bundle is chosen when candidates are all from the same catalog", func(t *testing.T) {
342+
ce := buildFooClusterExtension(pkgName, "", ">=1.0.4 <=1.0.5", ocv1alpha1.UpgradeConstraintPolicyEnforce)
343+
gotBundle, gotVersion, gotDeprecation, err := r.Resolve(context.Background(), ce, nil)
344+
require.NoError(t, err)
345+
// Bundles within one catalog for a package will be sorted by semver and deprecation and the best is returned
346+
assert.Equal(t, genBundle(pkgName, "1.0.5").Name, gotBundle.Name)
347+
assert.Equal(t, bsemver.MustParse("1.0.5"), *gotVersion)
348+
assert.Equal(t, (*declcfg.Deprecation)(nil), gotDeprecation)
349+
})
283350
}
284351

285352
func TestUpgradeFoundLegacy(t *testing.T) {

0 commit comments

Comments
 (0)