Skip to content

Commit 9e92474

Browse files
Merge pull request #528 from njhale/fix-default-chan
Bug 1902824: fix(index): account for default channel in index add order
2 parents 2e165d3 + abdd0f2 commit 9e92474

File tree

3 files changed

+152
-7
lines changed

3 files changed

+152
-7
lines changed

pkg/registry/input_stream.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,23 @@ func (r *ReplacesInputStream) canAdd(bundle *Bundle, packageGraph *Package) erro
9393
return fmt.Errorf("Invalid bundle %s, replaces nonexistent bundle %s", bundle.Name, replaces)
9494
}
9595

96+
defaultChannel := bundle.Annotations.DefaultChannelName
97+
if defaultChannel != "" && !packageGraph.HasChannel(defaultChannel) {
98+
// We also can't add if the bundle isn't in the default channel it specifies or it doesn't already exist in the package
99+
var defaultFound bool
100+
for _, channel := range bundle.Channels {
101+
if channel != defaultChannel {
102+
continue
103+
}
104+
defaultFound = true
105+
break
106+
}
107+
108+
if !defaultFound {
109+
return fmt.Errorf("Invalid bundle %s, references nonexistent default channel %s", bundle.Name, defaultChannel)
110+
}
111+
}
112+
96113
images, ok := r.packages[packageGraph.Name]
97114
if !ok || images == nil {
98115
// This shouldn't happen unless canAdd is being called without the correct setup

pkg/registry/input_stream_test.go

Lines changed: 134 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"math"
55
"math/rand"
66
"reflect"
7+
"strings"
78
"testing"
89
"testing/quick"
910

@@ -31,17 +32,25 @@ func unstructuredCSV() *unstructured.Unstructured {
3132
}
3233

3334
type inputConfig struct {
34-
pkg string
35-
name string
36-
version string
37-
replaces string
35+
pkg string
36+
name string
37+
version string
38+
replaces string
39+
defaultChannel string
40+
channels []string
3841
}
3942

4043
func newImageInput(config *inputConfig) *registry.ImageInput {
4144
image := &registry.ImageInput{
4245
Bundle: &registry.Bundle{
43-
Package: config.pkg,
44-
Name: config.name,
46+
Package: config.pkg,
47+
Name: config.name,
48+
Channels: config.channels,
49+
Annotations: &registry.Annotations{
50+
PackageName: config.pkg,
51+
Channels: strings.Join(config.channels, ","),
52+
DefaultChannelName: config.defaultChannel,
53+
},
4554
},
4655
}
4756

@@ -280,6 +289,125 @@ func TestReplacesTakesPrecedence(t *testing.T) {
280289
}
281290
}
282291

292+
func TestDefaultChannelAffectsOrder(t *testing.T) {
293+
type args struct {
294+
input []*registry.ImageInput
295+
}
296+
type expect struct {
297+
err bool
298+
ordered []string
299+
}
300+
for _, tt := range []struct {
301+
description string
302+
args args
303+
expect expect
304+
}{
305+
{
306+
description: "BundleDefiningDefaultChannelIsFirst",
307+
args: args{
308+
input: []*registry.ImageInput{
309+
newImageInput(&inputConfig{
310+
name: "a",
311+
version: "1.0.0",
312+
channels: []string{"stable"},
313+
defaultChannel: "alpha",
314+
}),
315+
newImageInput(&inputConfig{
316+
name: "b",
317+
version: "1.1.0",
318+
channels: []string{"alpha", "stable"},
319+
defaultChannel: "alpha",
320+
}),
321+
},
322+
},
323+
expect: expect{
324+
ordered: []string{"b", "a"},
325+
},
326+
},
327+
{
328+
description: "ConflictingReplacesAndDefaultChannelReturnsError",
329+
args: args{
330+
input: []*registry.ImageInput{
331+
newImageInput(&inputConfig{
332+
name: "a",
333+
version: "1.0.0",
334+
channels: []string{"stable"},
335+
defaultChannel: "alpha",
336+
}),
337+
newImageInput(&inputConfig{
338+
name: "b",
339+
version: "1.1.0",
340+
replaces: "a",
341+
channels: []string{"alpha", "stable"},
342+
defaultChannel: "alpha",
343+
}),
344+
},
345+
},
346+
expect: expect{
347+
err: true,
348+
},
349+
},
350+
} {
351+
t.Run(tt.description, func(t *testing.T) {
352+
addedChannels := map[string]registry.Channel{}
353+
loader := &registryfakes.FakeGraphLoader{
354+
GenerateStub: func(pkg string) (*registry.Package, error) {
355+
return &registry.Package{
356+
Name: pkg,
357+
Channels: addedChannels,
358+
}, nil
359+
},
360+
}
361+
362+
stream, err := registry.NewReplacesInputStream(loader, tt.args.input)
363+
if err != nil {
364+
t.Error(err)
365+
return
366+
}
367+
368+
if tt.expect.err {
369+
_, err := stream.Next()
370+
if err == nil {
371+
t.Error("expected next to return error, returned nil instead")
372+
}
373+
return
374+
}
375+
376+
for _, expected := range tt.expect.ordered {
377+
next, err := stream.Next()
378+
if err != nil {
379+
t.Errorf("next returned unexpected error %s", err)
380+
return
381+
}
382+
if next == nil {
383+
t.Errorf("next returned unexpected nil, expecting %s", expected)
384+
return
385+
}
386+
387+
name := next.Bundle.Name
388+
if name != expected {
389+
t.Errorf("next returned unexpected bundle %s, expecting %s", name, expected)
390+
return
391+
}
392+
393+
// Simulate an add
394+
for _, channel := range next.Bundle.Channels {
395+
added := addedChannels[channel]
396+
if added.Nodes == nil {
397+
added.Nodes = map[registry.BundleKey]map[registry.BundleKey]struct{}{}
398+
}
399+
added.Nodes[registry.BundleKey{CsvName: name}] = nil
400+
addedChannels[channel] = added
401+
}
402+
}
403+
404+
if !stream.Empty() {
405+
t.Errorf("stream still contains content, expected end of content")
406+
}
407+
})
408+
}
409+
}
410+
283411
type missingReplaces struct {
284412
input []*registry.ImageInput
285413
valid int

pkg/registry/populator.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ func SemverPackageManifest(bundles []*Bundle) (*PackageManifest, error) {
487487
}
488488

489489
if !defaultFound {
490-
return nil, fmt.Errorf("unable to determine default channel")
490+
return nil, fmt.Errorf("unable to determine default channel among channel heads: %+v", heads)
491491
}
492492

493493
return pkg, nil

0 commit comments

Comments
 (0)