bootcfg/storage: Add Copy methods to Profile and Group

This commit is contained in:
Dalton Hubble
2016-05-10 11:05:23 -07:00
parent 53a97f2d17
commit 16bc87c70a
4 changed files with 114 additions and 30 deletions

View File

@@ -29,16 +29,18 @@ func ParseGroup(data []byte) (*Group, error) {
return group, err
}
// AssertValid validates a Group. Returns nil if there are no validation
// errors.
func (g *Group) AssertValid() error {
if g.Id == "" {
return ErrIdRequired
func (g *Group) Copy() *Group {
selectors := make(map[string]string)
for k, v := range g.Selector {
selectors[k] = v
}
if g.Profile == "" {
return ErrProfileRequired
return &Group{
Id: g.Id,
Name: g.Name,
Profile: g.Profile,
Selector: selectors,
Metadata: g.Metadata,
}
return nil
}
// Matches returns true if the given labels satisfy all the selector
@@ -69,6 +71,18 @@ func (g *Group) Normalize() error {
return nil
}
// AssertValid validates a Group. Returns nil if there are no validation
// errors.
func (g *Group) AssertValid() error {
if g.Id == "" {
return ErrIdRequired
}
if g.Profile == "" {
return ErrProfileRequired
}
return nil
}
// selectorString returns Group selectors as a string of sorted key value
// pairs for comparisons.
func (g *Group) selectorString() string {

View File

@@ -39,19 +39,40 @@ func TestGroupParse(t *testing.T) {
}
}
func TestGroupValidate(t *testing.T) {
func TestGroupCopy(t *testing.T) {
copy := testGroup.Copy()
// assert that:
// - Group fields are copied
// - mutation of the copy does not affect the original
assert.Equal(t, testGroup.Id, copy.Id)
assert.Equal(t, testGroup.Name, copy.Name)
assert.Equal(t, testGroup.Profile, copy.Profile)
assert.Equal(t, testGroup.Selector, copy.Selector)
assert.Equal(t, testGroup.Metadata, copy.Metadata)
copy.Id = "a-copy"
copy.Selector["region"] = "us-west"
assert.NotEqual(t, testGroup.Id, copy.Id)
assert.NotEqual(t, testGroup.Selector, copy.Selector)
}
func TestGroupMatches(t *testing.T) {
cases := []struct {
group *Group
valid bool
labels map[string]string
selectors map[string]string
expected bool
}{
{&Group{Id: "node1", Profile: "k8s-master"}, true},
{testGroupWithoutProfile, false},
{&Group{Id: "node1"}, false},
{&Group{}, false},
{map[string]string{"a": "b"}, map[string]string{"a": "b"}, true},
{map[string]string{"a": "b"}, map[string]string{"a": "c"}, false},
{map[string]string{"uuid": "a", "mac": "b"}, map[string]string{"uuid": "a"}, true},
{map[string]string{"uuid": "a"}, map[string]string{"uuid": "a", "mac": "b"}, false},
}
// assert that:
// - Group selectors must be satisfied for a match
// - labels may provide additional key/value pairs
for _, c := range cases {
valid := c.group.AssertValid() == nil
assert.Equal(t, c.valid, valid)
group := &Group{Selector: c.selectors}
assert.Equal(t, c.expected, group.Matches(c.labels))
}
}
@@ -82,23 +103,19 @@ func TestNormalize(t *testing.T) {
}
}
func TestGroupMatches(t *testing.T) {
func TestGroupValidate(t *testing.T) {
cases := []struct {
labels map[string]string
selectors map[string]string
expected bool
group *Group
valid bool
}{
{map[string]string{"a": "b"}, map[string]string{"a": "b"}, true},
{map[string]string{"a": "b"}, map[string]string{"a": "c"}, false},
{map[string]string{"uuid": "a", "mac": "b"}, map[string]string{"uuid": "a"}, true},
{map[string]string{"uuid": "a"}, map[string]string{"uuid": "a", "mac": "b"}, false},
{&Group{Id: "node1", Profile: "k8s-master"}, true},
{testGroupWithoutProfile, false},
{&Group{Id: "node1"}, false},
{&Group{}, false},
}
// assert that:
// - Group selectors must be satisfied for a match
// - labels may provide additional key/value pairs
for _, c := range cases {
group := &Group{Selector: c.selectors}
assert.Equal(t, c.expected, group.Matches(c.labels))
valid := c.group.AssertValid() == nil
assert.Equal(t, c.valid, valid)
}
}

View File

@@ -25,3 +25,27 @@ func (p *Profile) AssertValid() error {
}
return nil
}
func (p *Profile) Copy() *Profile {
return &Profile{
Id: p.Id,
Name: p.Name,
IgnitionId: p.IgnitionId,
CloudId: p.CloudId,
Boot: p.Boot.Copy(),
}
}
func (b *NetBoot) Copy() *NetBoot {
initrd := make([]string, len(b.Initrd))
copy(initrd, b.Initrd)
cmdline := make(map[string]string)
for k, v := range b.Cmdline {
cmdline[k] = v
}
return &NetBoot{
Kernel: b.Kernel,
Initrd: initrd,
Cmdline: cmdline,
}
}

View File

@@ -41,3 +41,32 @@ func TestProfileValidate(t *testing.T) {
assert.Equal(t, c.valid, valid)
}
}
func TestProfileCopy(t *testing.T) {
profile := &Profile{
Id: "id",
CloudId: "cloudy.tmpl",
IgnitionId: "ignition.tmpl",
Boot: &NetBoot{
Kernel: "/image/kernel",
Initrd: []string{"/image/initrd_a"},
Cmdline: map[string]string{"a": "b"},
},
}
copy := profile.Copy()
// assert that:
// - Profile fields are copied
// - mutation of the copy does not affect the original
assert.Equal(t, profile.Id, copy.Id)
assert.Equal(t, profile.Name, copy.Name)
assert.Equal(t, profile.IgnitionId, copy.IgnitionId)
assert.Equal(t, profile.CloudId, copy.CloudId)
assert.Equal(t, profile.Boot, copy.Boot)
copy.Id = "a-copy"
copy.Boot.Initrd = []string{"/image/initrd_b"}
copy.Boot.Cmdline["c"] = "d"
assert.NotEqual(t, profile.Id, copy.Id)
assert.NotEqual(t, profile.Boot.Initrd, copy.Boot.Initrd)
assert.NotEqual(t, profile.Boot.Cmdline, copy.Boot.Cmdline)
}