diff --git a/bootcfg/server/server.go b/bootcfg/server/server.go index 1c937018..e4d32eba 100644 --- a/bootcfg/server/server.go +++ b/bootcfg/server/server.go @@ -91,6 +91,9 @@ func (s *server) ProfileGet(ctx context.Context, req *pb.ProfileGetRequest) (*st if err != nil { return nil, err } + if err := profile.AssertValid(); err != nil { + return nil, err + } return profile, nil } diff --git a/bootcfg/server/server_test.go b/bootcfg/server/server_test.go index c25aa2e8..db16361c 100644 --- a/bootcfg/server/server_test.go +++ b/bootcfg/server/server_test.go @@ -17,21 +17,97 @@ func TestSelectGroup(t *testing.T) { Groups: map[string]*storagepb.Group{fake.Group.Id: fake.Group}, } cases := []struct { - store storage.Store - labels map[string]string - expectedGroup *storagepb.Group - expectedErr error + store storage.Store + labels map[string]string + group *storagepb.Group + err error }{ {store, map[string]string{"uuid": "a1b2c3d4"}, fake.Group, nil}, + // no labels provided {store, nil, nil, ErrNoMatchingGroup}, - // no groups in the store + // empty store {&fake.EmptyStore{}, map[string]string{"a": "b"}, nil, ErrNoMatchingGroup}, } for _, c := range cases { srv := NewServer(&Config{c.store}) group, err := srv.SelectGroup(context.Background(), &pb.SelectGroupRequest{Labels: c.labels}) - if assert.Equal(t, c.expectedErr, err) { - assert.Equal(t, c.expectedGroup, group) + if assert.Equal(t, c.err, err) { + assert.Equal(t, c.group, group) } } } + +func TestSelectProfile(t *testing.T) { + store := &fake.FixedStore{ + Groups: map[string]*storagepb.Group{fake.Group.Id: fake.Group}, + Profiles: map[string]*storagepb.Profile{fake.Group.Profile: fake.Profile}, + } + missingProfileStore := &fake.FixedStore{ + Groups: map[string]*storagepb.Group{fake.Group.Id: fake.Group}, + } + cases := []struct { + store storage.Store + labels map[string]string + profile *storagepb.Profile + err error + }{ + {store, map[string]string{"uuid": "a1b2c3d4"}, fake.Profile, nil}, + // matching group, but missing profile + {missingProfileStore, map[string]string{"uuid": "a1b2c3d4"}, nil, ErrNoMatchingProfile}, + // no labels provided + {store, nil, nil, ErrNoMatchingGroup}, + // empty store + {&fake.EmptyStore{}, map[string]string{"a": "b"}, nil, ErrNoMatchingGroup}, + } + for _, c := range cases { + srv := NewServer(&Config{c.store}) + profile, err := srv.SelectProfile(context.Background(), &pb.SelectProfileRequest{Labels: c.labels}) + if assert.Equal(t, c.err, err) { + assert.Equal(t, c.profile, profile) + } + } +} + +func TestProfilePut(t *testing.T) { + srv := NewServer(&Config{Store: fake.NewFixedStore()}) + _, err := srv.ProfilePut(context.Background(), &pb.ProfilePutRequest{Profile: fake.Profile}) + assert.Nil(t, err) +} + +func TestProfileGet(t *testing.T) { + store := &fake.FixedStore{ + Profiles: map[string]*storagepb.Profile{fake.Profile.Id: fake.Profile}, + } + cases := []struct { + id string + profile *storagepb.Profile + err error + }{ + {fake.Profile.Id, fake.Profile, nil}, + } + srv := NewServer(&Config{store}) + for _, c := range cases { + profile, err := srv.ProfileGet(context.Background(), &pb.ProfileGetRequest{Id: c.id}) + assert.Equal(t, c.err, err) + assert.Equal(t, c.profile, profile) + } +} + +func TestProfileList(t *testing.T) { + store := &fake.FixedStore{ + Profiles: map[string]*storagepb.Profile{fake.Profile.Id: fake.Profile}, + } + srv := NewServer(&Config{store}) + profiles, err := srv.ProfileList(context.Background(), &pb.ProfileListRequest{}) + assert.Nil(t, err) + if assert.Equal(t, 1, len(profiles)) { + assert.Equal(t, fake.Profile, profiles[0]) + } +} + +func TestProfileList_Empty(t *testing.T) { + srv := NewServer(&Config{&fake.EmptyStore{}}) + profiles, err := srv.ProfileList(context.Background(), &pb.ProfileListRequest{}) + assert.Nil(t, err) + assert.Equal(t, 0, len(profiles)) +} diff --git a/bootcfg/storage/filestore_test.go b/bootcfg/storage/filestore_test.go index 421755fa..f9b5556c 100644 --- a/bootcfg/storage/filestore_test.go +++ b/bootcfg/storage/filestore_test.go @@ -13,6 +13,36 @@ import ( fake "github.com/coreos/coreos-baremetal/bootcfg/storage/testfakes" ) +func TestProfilePut(t *testing.T) { + dir, err := setup(&fake.FixedStore{}) + assert.Nil(t, err) + defer os.RemoveAll(dir) + + store := NewFileStore(&Config{Root: dir}) + // assert that: + // - Profile put was successful + // - same Profile can be retrieved + err = store.ProfilePut(fake.Profile) + assert.Nil(t, err) + profile, err := store.ProfileGet(fake.Profile.Id) + assert.Nil(t, err) + assert.Equal(t, fake.Profile, profile) +} + +func TestProfilePut_Invalid(t *testing.T) { + dir, err := setup(&fake.FixedStore{}) + assert.Nil(t, err) + defer os.RemoveAll(dir) + + store := NewFileStore(&Config{Root: dir}) + // assert that: + // - invalid Profile is not saved + err = store.ProfilePut(&storagepb.Profile{}) + if assert.Error(t, err) { + assert.Equal(t, err, storagepb.ErrIdRequired) + } +} + func TestProfileGet(t *testing.T) { dir, err := setup(&fake.FixedStore{ Profiles: map[string]*storagepb.Profile{fake.Profile.Id: fake.Profile}, diff --git a/bootcfg/storage/storagepb/profile_test.go b/bootcfg/storage/storagepb/profile_test.go new file mode 100644 index 00000000..142e3722 --- /dev/null +++ b/bootcfg/storage/storagepb/profile_test.go @@ -0,0 +1,42 @@ +package storagepb + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +var ( + testProfile = &Profile{ + Id: "id", + CloudId: "cloud.yaml", + IgnitionId: "ignition.json", + } +) + +func TestProfileParse(t *testing.T) { + cases := []struct { + json string + profile *Profile + }{ + {`{"id": "id", "cloud_id": "cloud.yaml", "ignition_id": "ignition.json"}`, testProfile}, + } + for _, c := range cases { + profile, _ := ParseProfile([]byte(c.json)) + assert.Equal(t, c.profile, profile) + } +} + +func TestProfileValidate(t *testing.T) { + cases := []struct { + profile *Profile + valid bool + }{ + {&Profile{Id: "a1b2c3d4"}, true}, + {&Profile{}, false}, + } + for _, c := range cases { + valid := c.profile.AssertValid() == nil + assert.Equal(t, c.valid, valid) + } +} diff --git a/bootcfg/storage/testfakes/fixed_store.go b/bootcfg/storage/testfakes/fixed_store.go index b43852e8..e285efd0 100644 --- a/bootcfg/storage/testfakes/fixed_store.go +++ b/bootcfg/storage/testfakes/fixed_store.go @@ -14,6 +14,16 @@ type FixedStore struct { CloudConfigs map[string]string } +// NewFixedStore returns a new FixedStore. +func NewFixedStore() *FixedStore { + return &FixedStore{ + Groups: make(map[string]*storagepb.Group), + Profiles: make(map[string]*storagepb.Profile), + IgnitionConfigs: make(map[string]string), + CloudConfigs: make(map[string]string), + } +} + // GroupGet returns the Group from the Groups map with the given id. func (s *FixedStore) GroupGet(id string) (*storagepb.Group, error) { if group, present := s.Groups[id]; present {