Skip to content

Commit 0bb8c1e

Browse files
committed
Correctly omit skipped channel entries during resolution.
A behavior was added with the intention of preventing the installation of channel entries that are skipped by other entries, but in practice it was omitting entries that were replaced by skipped entries. This is fixed. There are now unit test cases and one higher-level test for this behavior. Signed-off-by: Ben Luddy <[email protected]>
1 parent 014bd31 commit 0bb8c1e

File tree

2 files changed

+81
-5
lines changed

2 files changed

+81
-5
lines changed

pkg/controller/registry/resolver/resolver.go

+1-5
Original file line numberDiff line numberDiff line change
@@ -680,10 +680,9 @@ func sortChannel(bundles []*Operator) ([]*Operator, error) {
680680
var chain []*Operator
681681
visited := make(map[*Operator]struct{})
682682
current := head
683-
skip := false
684683
for {
685684
visited[current] = struct{}{}
686-
if !skip {
685+
if _, ok := skipped[current.Identifier()]; !ok {
687686
chain = append(chain, current)
688687
}
689688
next, ok := replaces[current]
@@ -693,9 +692,6 @@ func sortChannel(bundles []*Operator) ([]*Operator, error) {
693692
if _, ok := visited[next]; ok {
694693
return nil, fmt.Errorf("a cycle exists in the chain of replacement beginning with %q in channel %q of package %q", head.Identifier(), channelName, packageName)
695694
}
696-
if _, ok := skipped[current.Identifier()]; ok {
697-
skip = true
698-
}
699695
current = next
700696
}
701697
chains = append(chains, chain)

pkg/controller/registry/resolver/resolver_test.go

+80
Original file line numberDiff line numberDiff line change
@@ -1481,6 +1481,38 @@ func TestSolveOperators_WithSkips(t *testing.T) {
14811481
require.EqualValues(t, expected, operators)
14821482
}
14831483

1484+
func TestSolveOperatorsWithSkipsPreventingSelection(t *testing.T) {
1485+
const namespace = "test-namespace"
1486+
catalog := registry.CatalogKey{Name: "test-catalog", Namespace: namespace}
1487+
gvks := APISet{opregistry.APIKey{Group: "g", Version: "v", Kind: "k", Plural: "ks"}: struct{}{}}
1488+
1489+
// Subscription candidate a-1 requires a GVK provided
1490+
// exclusively by b-1, but b-1 is skipped by b-3 and can't be
1491+
// chosen.
1492+
subs := []*v1alpha1.Subscription{newSub(namespace, "a", "channel", catalog)}
1493+
a1 := genOperator("a-1", "1.0.0", "", "a", "channel", catalog.Name, catalog.Namespace, gvks, nil, nil, "", false)
1494+
b3 := genOperator("b-3", "3.0.0", "b-2", "b", "channel", catalog.Name, catalog.Namespace, nil, nil, nil, "", false)
1495+
b3.skips = []string{"b-1"}
1496+
b2 := genOperator("b-2", "2.0.0", "b-1", "b", "channel", catalog.Name, catalog.Namespace, nil, nil, nil, "", false)
1497+
b1 := genOperator("b-1", "1.0.0", "", "b", "channel", catalog.Name, catalog.Namespace, nil, gvks, nil, "", false)
1498+
1499+
logger, _ := test.NewNullLogger()
1500+
satResolver := SatResolver{
1501+
cache: getFakeOperatorCache(NamespacedOperatorCache{
1502+
snapshots: map[registry.CatalogKey]*CatalogSnapshot{
1503+
catalog: {
1504+
key: catalog,
1505+
operators: []*Operator{a1, b3, b2, b1},
1506+
},
1507+
},
1508+
}),
1509+
log: logger,
1510+
}
1511+
1512+
_, err := satResolver.SolveOperators([]string{namespace}, nil, subs)
1513+
assert.IsType(t, solver.NotSatisfiable{}, err)
1514+
}
1515+
14841516
func TestSolveOperatorsWithClusterServiceVersionHavingDependency(t *testing.T) {
14851517
const namespace = "test-namespace"
14861518
catalog := registry.CatalogKey{Name: "test-catalog", Namespace: namespace}
@@ -1824,6 +1856,54 @@ func TestSortChannel(t *testing.T) {
18241856
},
18251857
Err: errors.New(`a cycle exists in the chain of replacement beginning with "a" in channel "channel" of package "package"`),
18261858
},
1859+
{
1860+
Name: "skipped and replaced entry omitted",
1861+
In: []*Operator{
1862+
{
1863+
name: "a",
1864+
replaces: "b",
1865+
skips: []string{"b"},
1866+
},
1867+
{
1868+
name: "b",
1869+
},
1870+
},
1871+
Out: []*Operator{
1872+
{
1873+
name: "a",
1874+
replaces: "b",
1875+
skips: []string{"b"},
1876+
},
1877+
},
1878+
},
1879+
{
1880+
Name: "skipped entry omitted",
1881+
In: []*Operator{
1882+
{
1883+
name: "a",
1884+
replaces: "b",
1885+
skips: []string{"c"},
1886+
},
1887+
{
1888+
name: "b",
1889+
replaces: "c",
1890+
},
1891+
{
1892+
name: "c",
1893+
},
1894+
},
1895+
Out: []*Operator{
1896+
{
1897+
name: "a",
1898+
replaces: "b",
1899+
skips: []string{"c"},
1900+
},
1901+
{
1902+
name: "b",
1903+
replaces: "c",
1904+
},
1905+
},
1906+
},
18271907
{
18281908
Name: "two replaces chains",
18291909
In: []*Operator{

0 commit comments

Comments
 (0)