Enforce default constraints on first/last source

Whenver sources are present, there should be exactly one default source.
Prior to this commit, it was possible to add the first source as a
non-default source and circumvent this invariant. This unfortunately
requires a bit of special-casing logic in s.Add and requires a query to
fetch the number of sources currently persisted.

Tests have been added to cover this as well as deleting the final
source, to ensure that there aren't any odd indexing panics that might
result from trying to find another candidate default source when
deleting.
pull/403/head
Tim Raymond 2016-11-07 18:13:02 -05:00
parent 44dd7665ea
commit 3191ef31d2
2 changed files with 30 additions and 0 deletions

View File

@ -42,6 +42,14 @@ func (s *SourcesStore) All(ctx context.Context) ([]chronograf.Source, error) {
// Add creates a new Source in the SourceStore.
func (s *SourcesStore) Add(ctx context.Context, src chronograf.Source) (chronograf.Source, error) {
// force first source added to be default
if srcs, err := s.All(ctx); err != nil {
return chronograf.Source{}, err
} else if len(srcs) == 0 {
src.Default = true
}
if err := s.client.db.Update(func(tx *bolt.Tx) error {
b := tx.Bucket(SourcesBucket)
seq, err := b.NextSequence()

View File

@ -130,6 +130,28 @@ func TestSourceStore(t *testing.T) {
} else if !reflect.DeepEqual(bsrcs[0], srcs[1]) {
t.Fatalf("After delete All returned incorrect source; got %v, expected %v", bsrcs[0], srcs[1])
}
// Delete the final source
if err := s.Delete(nil, srcs[1]); err != nil {
t.Fatal(err)
}
// Try to add one source as a non-default and ensure that it becomes a
// default
src := mustAddSource(t, s, chronograf.Source{
Name: "Biff Tannen",
Type: "influx",
Username: "HELLO",
Password: "MCFLY",
URL: "anybody.in.there.local",
Default: false,
})
if actual, err := s.Get(nil, src.ID); err != nil {
t.Fatal(err)
} else if !actual.Default {
t.Fatal("Expected first source added to be default but wasn't")
}
}
func mustUpdateSource(t *testing.T, s *bolt.SourcesStore, src chronograf.Source) {