Skip to content

Commit

Permalink
Merge pull request #1970 from openshift-cherrypick-robot/cherry-pick-…
Browse files Browse the repository at this point in the history
…1966-to-release-4.6

[release-4.6] Bug 1918525: Fix infinite loop when a CSV replacement chain contains a cycle.
  • Loading branch information
openshift-merge-robot committed Jan 28, 2021
2 parents ca4a46c + 834e11f commit f437d2b
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 0 deletions.
6 changes: 6 additions & 0 deletions pkg/controller/operators/olm/operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -1874,6 +1874,9 @@ func (a *Operator) getReplacementChain(in *v1alpha1.ClusterServiceVersion, csvsI

next := replacement(current)
for next != nil {
if _, ok := csvsInChain[*next]; ok {
break // cycle
}
csvsInChain[*next] = struct{}{}
current = *next
next = replacement(current)
Expand All @@ -1885,6 +1888,9 @@ func (a *Operator) getReplacementChain(in *v1alpha1.ClusterServiceVersion, csvsI
csvsInChain[current] = struct{}{}
}
for prev != nil && *prev != "" {
if _, ok := csvsInChain[*prev]; ok {
break // cycle
}
current = *prev
csvsInChain[current] = struct{}{}
prev = replaces(current)
Expand Down
57 changes: 57 additions & 0 deletions pkg/controller/operators/olm/operator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4805,3 +4805,60 @@ func csvWithWebhook(csv *v1alpha1.ClusterServiceVersion, deploymentName string,
}
return csv
}

func TestGetReplacementChain(t *testing.T) {
CSV := func(name, replaces string) *v1alpha1.ClusterServiceVersion {
return &v1alpha1.ClusterServiceVersion{
ObjectMeta: metav1.ObjectMeta{
Name: name,
},
Spec: v1alpha1.ClusterServiceVersionSpec{
Replaces: replaces,
},
}
}

for _, tc := range []struct {
Name string
From *v1alpha1.ClusterServiceVersion
All map[string]*v1alpha1.ClusterServiceVersion
Expected []string
}{
{
Name: "csv replaces itself",
From: CSV("itself", "itself"),
All: map[string]*v1alpha1.ClusterServiceVersion{
"itself": CSV("itself", "itself"),
},
Expected: []string{"itself"},
},
{
Name: "two csvs replace each other",
From: CSV("a", "b"),
All: map[string]*v1alpha1.ClusterServiceVersion{
"a": CSV("a", "b"),
"b": CSV("b", "a"),
},
Expected: []string{"a", "b"},
},
{
Name: "starting from head of chain without cycles",
From: CSV("a", "b"),
All: map[string]*v1alpha1.ClusterServiceVersion{
"a": CSV("a", "b"),
"b": CSV("b", "c"),
"c": CSV("c", ""),
},
Expected: []string{"a", "b", "c"},
},
} {
t.Run(tc.Name, func(t *testing.T) {
assert := assert.New(t)
var actual []string
for name := range (&Operator{}).getReplacementChain(tc.From, tc.All) {
actual = append(actual, name)
}
assert.ElementsMatch(tc.Expected, actual)
})
}
}

0 comments on commit f437d2b

Please sign in to comment.