Skip to content

Commit 4e793cb

Browse files
committed
Add extra methods to FeatureSet and extract it to standalone file
1 parent 6b8609e commit 4e793cb

File tree

4 files changed

+156
-54
lines changed

4 files changed

+156
-54
lines changed

core/assumes/feature_set.go

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
// Copyright 2021 Canonical Ltd.
2+
// Licensed under the AGPLv3, see LICENCE file for details.
3+
4+
package assumes
5+
6+
import (
7+
chassumes "github.com/juju/charm/v8/assumes"
8+
"github.com/juju/collections/set"
9+
"github.com/juju/version/v2"
10+
)
11+
12+
// Feature identifies a particular piece of functionality provided by a Juju
13+
// controller depending on the substrate associated with a particular model.
14+
type Feature struct {
15+
// The name of the feature.
16+
Name string
17+
18+
// A user-friendly description of what the feature provides.
19+
Description string
20+
21+
// An optional semantic version for this feature. It can be left empty
22+
// to signify that a particular feature is available without explicitly
23+
// specifying a version
24+
Version *version.Number
25+
}
26+
27+
// FeatureSet describes a set of features supported by a particular model.
28+
type FeatureSet struct {
29+
features map[string]Feature
30+
}
31+
32+
// Merge the features from other into this feature set.
33+
func (fs *FeatureSet) Merge(other FeatureSet) {
34+
for _, feat := range other.features {
35+
fs.Add(feat)
36+
}
37+
}
38+
39+
// AsList returns the contents of this set as a list sorted by feature name.
40+
func (fs *FeatureSet) AsList() []Feature {
41+
set := set.NewStrings()
42+
for featName := range fs.features {
43+
set.Add(featName)
44+
}
45+
46+
var list []Feature
47+
for _, featName := range set.SortedValues() {
48+
list = append(list, fs.features[featName])
49+
}
50+
51+
return list
52+
}
53+
54+
// Add a list of Features to the feature set. Duplicate feature entries
55+
// will be ignored.
56+
func (fs *FeatureSet) Add(features ...Feature) {
57+
if fs.features == nil {
58+
fs.features = make(map[string]Feature)
59+
}
60+
61+
for _, feat := range features {
62+
fs.features[feat.Name] = feat
63+
}
64+
}
65+
66+
// Get a feature with the provide feature name. The method returns a boolean
67+
// value to indicate if the feature was found.
68+
func (fs FeatureSet) Get(featName string) (Feature, bool) {
69+
if fs.features == nil {
70+
return Feature{}, false
71+
}
72+
73+
feat, found := fs.features[featName]
74+
return feat, found
75+
}
76+
77+
// Satisfies checks whether the feature set contents satisfy the provided
78+
// "assumes" expression tree and returns an error otherwise.
79+
func (fs FeatureSet) Satisfies(assumesExprTree *chassumes.ExpressionTree) error {
80+
if assumesExprTree == nil || assumesExprTree.Expression == nil {
81+
return nil // empty expressions are implicitly satisfied
82+
}
83+
84+
return satisfyExpr(fs, assumesExprTree.Expression, 0)
85+
}

core/assumes/feature_set_test.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// Copyright 2021 Canonical Ltd.
2+
// Licensed under the AGPLv3, see LICENCE file for details.
3+
4+
package assumes
5+
6+
import (
7+
"github.com/juju/testing"
8+
jc "github.com/juju/testing/checkers"
9+
gc "gopkg.in/check.v1"
10+
)
11+
12+
type FeatureSetSuite struct {
13+
testing.IsolationSuite
14+
}
15+
16+
var _ = gc.Suite(&FeatureSetSuite{})
17+
18+
func (s *FeatureSetSuite) TestAsList(c *gc.C) {
19+
var fs FeatureSet
20+
fs.Add(
21+
Feature{Name: "zzz"},
22+
Feature{Name: "abc"},
23+
Feature{Name: "efg"},
24+
)
25+
26+
exp := []Feature{
27+
{Name: "abc"},
28+
{Name: "efg"},
29+
{Name: "zzz"},
30+
}
31+
32+
c.Assert(fs.AsList(), gc.DeepEquals, exp, gc.Commentf("expected AsList() to return the feature list sorted by name"))
33+
}
34+
35+
func (s *SatCheckerSuite) TestMerge(c *gc.C) {
36+
var fs1 FeatureSet
37+
fs1.Add(
38+
Feature{Name: "zzz"},
39+
Feature{Name: "efg"},
40+
)
41+
42+
var fs2 FeatureSet
43+
fs2.Add(
44+
Feature{Name: "abc"},
45+
Feature{Name: "efg"},
46+
)
47+
48+
exp := []Feature{
49+
{Name: "abc"},
50+
{Name: "efg"},
51+
{Name: "zzz"},
52+
}
53+
54+
fs1.Merge(fs2)
55+
56+
c.Assert(fs1.AsList(), gc.DeepEquals, exp, gc.Commentf("expected AsList() to return the union of the two sets with duplicates removed"))
57+
}
58+
59+
func (s *SatCheckerSuite) TestGet(c *gc.C) {
60+
var fs FeatureSet
61+
fs.Add(
62+
Feature{Name: "zzz"},
63+
)
64+
65+
_, found := fs.Get("zzz")
66+
c.Assert(found, jc.IsTrue)
67+
68+
_, found = fs.Get("bogus!")
69+
c.Assert(found, jc.IsFalse)
70+
}

core/assumes/sat_checker.go

Lines changed: 0 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ package assumes
66
import (
77
chassumes "github.com/juju/charm/v8/assumes"
88
"github.com/juju/errors"
9-
"github.com/juju/version/v2"
109
)
1110

1211
var (
@@ -22,58 +21,6 @@ var (
2221
// the Juju versions that support them etc.
2322
const featureDocsURL = "https://juju.is/docs/olm/supported-features"
2423

25-
// Feature identifies a particular piece of functionality provided by a Juju
26-
// controller depending on the substrate associated with a particular model.
27-
type Feature struct {
28-
// The name of the feature.
29-
Name string
30-
31-
// A user-friendly description of what the feature provides.
32-
Description string
33-
34-
// An optional semantic version for this feature. It can be left empty
35-
// to signify that a particular feature is available without explicitly
36-
// specifying a version
37-
Version *version.Number
38-
}
39-
40-
type FeatureSet struct {
41-
features map[string]Feature
42-
}
43-
44-
// Append a list of Features to the feature set. Duplicate feature entries
45-
// will be ignored.
46-
func (fs *FeatureSet) Append(features ...Feature) {
47-
if fs.features == nil {
48-
fs.features = make(map[string]Feature)
49-
}
50-
51-
for _, feat := range features {
52-
fs.features[feat.Name] = feat
53-
}
54-
}
55-
56-
// Get a feature with the provide feature name. The method returns a boolean
57-
// value to indicate if the feature was found.
58-
func (fs FeatureSet) Get(featName string) (Feature, bool) {
59-
if fs.features == nil {
60-
return Feature{}, false
61-
}
62-
63-
feat, found := fs.features[featName]
64-
return feat, found
65-
}
66-
67-
// Satisfies checks whether the feature set contents satisfy the provided
68-
// "assumes" expression tree and returns an error otherwise.
69-
func (fs FeatureSet) Satisfies(assumesExprTree *chassumes.ExpressionTree) error {
70-
if assumesExprTree == nil || assumesExprTree.Expression == nil {
71-
return nil // empty expressions are implicitly satisfied
72-
}
73-
74-
return satisfyExpr(fs, assumesExprTree.Expression, 0)
75-
}
76-
7724
// satisfyExpr checks whether the feature set contents satisfy the provided
7825
// "assumes" expression. The function can process either feature or composite
7926
// expressions.

core/assumes/sat_checker_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ assumes:
142142

143143
func genFeatureSet(c *gc.C) FeatureSet {
144144
var fs FeatureSet
145-
fs.Append(
145+
fs.Add(
146146
Feature{
147147
Name: "k8s-api",
148148
Description: "access to the kubernetes API",

0 commit comments

Comments
 (0)