Skip to content

Commit 8c0f4aa

Browse files
committed
feat(resolver): Indicate dependency class in resolution constraint text
This commit introduces a String() method to the Predicate interface, implementations of which are used to build clauses that are fed to the sat solver. Calling the predicate.String() method enhances the error messages displayed when dependency resolution fails. For example, an error message previously due to an unsatisfyiable contraint was diplayed as ``` ResolutionFailed' constraints not satisfiable: bundle etcdoperator-community.v0.6.1 has a dependency without any candidates to satisfy it, subscription etcd requires my-catalog/olm/alpha/etcdoperator-community.v0.6.1, subscription etcd exists ``` With this commit, the same error is displayed as: ``` ResolutionFailed' constraints not satisfiable: bundle etcdoperator-community.v0.6.1 requires an operator with package:foo and with version in range:>0.27.0, subscription etcd requires my-catalog/olm/alpha/etcdoperator-community.v0.6.1, subscription etcd exists ``` Signed-off-by: Anik Bhattacharjee <[email protected]>
1 parent 86998b0 commit 8c0f4aa

File tree

8 files changed

+331
-170
lines changed

8 files changed

+331
-170
lines changed

pkg/controller/registry/resolver/cache_test.go

+8-8
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ func TestOperatorCacheConcurrency(t *testing.T) {
123123
nc := c.Namespaced(namespaces...)
124124
for _, index := range indices {
125125
name := fmt.Sprintf("%s/%s", keys[index].Namespace, keys[index].Name)
126-
operators := nc.Find(WithCSVName(name))
126+
operators := nc.Find(CSVNamePredicate(name))
127127
if len(operators) != 1 {
128128
return fmt.Errorf("expected 1 operator, got %d", len(operators))
129129
}
@@ -159,7 +159,7 @@ func TestOperatorCacheExpiration(t *testing.T) {
159159
c := NewOperatorCache(rcp, logrus.New(), catsrcLister)
160160
c.ttl = 0 // instantly stale
161161

162-
require.Len(t, c.Namespaced("dummynamespace").Catalog(key).Find(WithCSVName("csvname")), 1)
162+
require.Len(t, c.Namespaced("dummynamespace").Catalog(key).Find(CSVNamePredicate("csvname")), 1)
163163
}
164164

165165
func TestOperatorCacheReuse(t *testing.T) {
@@ -182,7 +182,7 @@ func TestOperatorCacheReuse(t *testing.T) {
182182

183183
c := NewOperatorCache(rcp, logrus.New(), catsrcLister)
184184

185-
require.Len(t, c.Namespaced("dummynamespace").Catalog(key).Find(WithCSVName("csvname")), 1)
185+
require.Len(t, c.Namespaced("dummynamespace").Catalog(key).Find(CSVNamePredicate("csvname")), 1)
186186
}
187187

188188
func TestCatalogSnapshotExpired(t *testing.T) {
@@ -232,7 +232,7 @@ func TestCatalogSnapshotFind(t *testing.T) {
232232
for _, tt := range []tc{
233233
{
234234
Name: "nothing satisfies predicate",
235-
Predicate: OperatorPredicateFunc(func(*Operator) bool {
235+
Predicate: OperatorPredicateTestFunc(func(*Operator) bool {
236236
return false
237237
}),
238238
Operators: []*Operator{
@@ -244,15 +244,15 @@ func TestCatalogSnapshotFind(t *testing.T) {
244244
},
245245
{
246246
Name: "no operators in snapshot",
247-
Predicate: OperatorPredicateFunc(func(*Operator) bool {
247+
Predicate: OperatorPredicateTestFunc(func(*Operator) bool {
248248
return true
249249
}),
250250
Operators: nil,
251251
Expected: nil,
252252
},
253253
{
254254
Name: "everything satisfies predicate",
255-
Predicate: OperatorPredicateFunc(func(*Operator) bool {
255+
Predicate: OperatorPredicateTestFunc(func(*Operator) bool {
256256
return true
257257
}),
258258
Operators: []*Operator{
@@ -268,7 +268,7 @@ func TestCatalogSnapshotFind(t *testing.T) {
268268
},
269269
{
270270
Name: "some satisfy predicate",
271-
Predicate: OperatorPredicateFunc(func(o *Operator) bool {
271+
Predicate: OperatorPredicateTestFunc(func(o *Operator) bool {
272272
return o.name != "a"
273273
}),
274274
Operators: []*Operator{
@@ -333,7 +333,7 @@ func TestStripPluralRequiredAndProvidedAPIKeys(t *testing.T) {
333333
c := NewOperatorCache(rcp, logrus.New(), catsrcLister)
334334

335335
nc := c.Namespaced("testnamespace")
336-
result, err := AtLeast(1, nc.Find(ProvidingAPI(opregistry.APIKey{Group: "g", Version: "v1", Kind: "K"})))
336+
result, err := AtLeast(1, nc.Find(ProvidingAPIPredicate(opregistry.APIKey{Group: "g", Version: "v1", Kind: "K"})))
337337
assert.NoError(t, err)
338338
assert.Equal(t, 1, len(result))
339339
assert.Equal(t, "K.v1.g", result[0].providedAPIs.String())

pkg/controller/registry/resolver/installabletypes.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ func (i *BundleInstallable) AddConflict(id solver.Identifier) {
3232
i.constraints = append(i.constraints, solver.Conflict(id))
3333
}
3434

35-
func (i *BundleInstallable) AddDependency(dependencies []solver.Identifier) {
36-
i.constraints = append(i.constraints, solver.Dependency(dependencies...))
35+
func (i *BundleInstallable) AddConstraint(c solver.Constraint) {
36+
i.constraints = append(i.constraints, c)
3737
}
3838

3939
func (i *BundleInstallable) BundleSourceInfo() (string, string, registry.CatalogKey, error) {

pkg/controller/registry/resolver/operators.go

+8
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,10 @@ func NewOperatorFromV1Alpha1CSV(csv *v1alpha1.ClusterServiceVersion) (*Operator,
361361
}, nil
362362
}
363363

364+
func (o *Operator) Name() string {
365+
return o.name
366+
}
367+
364368
func (o *Operator) ProvidedAPIs() APISet {
365369
return o.providedAPIs
366370
}
@@ -411,6 +415,10 @@ func (o *Operator) Version() *semver.Version {
411415
return o.version
412416
}
413417

418+
func (o *Operator) SemverRange() (semver.Range, error) {
419+
return semver.ParseRange(o.Bundle().SkipRange)
420+
}
421+
414422
func (o *Operator) Inline() bool {
415423
return o.bundle != nil && o.bundle.GetBundlePath() == ""
416424
}

0 commit comments

Comments
 (0)