Skip to content

Commit d873bdd

Browse files
committed
fix(resolver): take a snapshot of the current generation before updates
this prevents detecting two updates to the same operator during one resolution
1 parent 30ac15c commit d873bdd

File tree

4 files changed

+120
-90
lines changed

4 files changed

+120
-90
lines changed

pkg/controller/registry/resolver/evolver.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ func (e *NamespaceGenerationEvolver) Evolve(add map[OperatorSourceInfo]struct{})
5050
}
5151

5252
func (e *NamespaceGenerationEvolver) checkForUpdates() error {
53-
for _, op := range e.gen.Operators() {
53+
// take a snapshot of the current generation so that we don't update the same operator twice in one resolution
54+
for _, op := range e.gen.Operators().Snapshot() {
5455
// only check for updates if we have sourceinfo
5556
if op.SourceInfo() == &ExistingOperator {
5657
continue

pkg/controller/registry/resolver/evolver_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,27 @@ func TestNamespaceGenerationEvolver(t *testing.T) {
373373
NewFakeOperatorSurface("provider.v1", "provider", "channel", "", "catsrc", "", []opregistry.APIKey{{"g", "v", "k", "ks"}}, nil, nil, nil),
374374
),
375375
},
376+
{
377+
// an existing operator has multiple updates available
378+
// a single evolution should update to next, not latest
379+
name: "UpdateRequired/MultipleUpdates",
380+
fields: fields{
381+
querier: NewFakeSourceQuerier(map[CatalogKey][]*opregistry.Bundle{
382+
CatalogKey{"catsrc", "catsrc-namespace"}: {
383+
bundle("updated", "o", "c", "original", nil, nil, nil, nil),
384+
bundle("updated.v2", "o", "c", "updated", nil, nil, nil, nil),
385+
bundle("updated.v3", "o", "c", "updated.v2", nil, nil, nil, nil),
386+
},
387+
}),
388+
gen: NewGenerationFromOperators(
389+
NewFakeOperatorSurface("original", "o", "c", "", "catsrc", "", nil, nil, nil, nil),
390+
),
391+
},
392+
args: args{},
393+
wantGen: NewGenerationFromOperators(
394+
NewFakeOperatorSurface("updated", "o", "c", "original", "catsrc", "", nil, nil, nil, nil),
395+
),
396+
},
376397
}
377398
for _, tt := range tests {
378399
t.Run(tt.name, func(t *testing.T) {

pkg/controller/registry/resolver/operators.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,15 @@ func EmptyOperatorSet() OperatorSet {
147147
return map[string]OperatorSurface{}
148148
}
149149

150+
// Snapshot returns a new set, pointing to the same values
151+
func (o OperatorSet) Snapshot() OperatorSet {
152+
out := make(map[string]OperatorSurface)
153+
for key, val := range o {
154+
out[key] = val
155+
}
156+
return out
157+
}
158+
150159
type APIMultiOwnerSet map[opregistry.APIKey]OperatorSet
151160

152161
func EmptyAPIMultiOwnerSet() APIMultiOwnerSet {

0 commit comments

Comments
 (0)