diff --git a/CHANGELOG.md b/CHANGELOG.md index 135922c881..ea6b1030cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ - [#8001](https://github.com/influxdata/influxdb/issues/8001): Map types correctly when using a regex and one of the measurements is empty. - [#8040](https://github.com/influxdata/influxdb/issues/8040): Reduce the expression in a subquery to avoid a panic. - [#7968](https://github.com/influxdata/influxdb/issues/7968): Properly select a tag within a subquery. +- [#8028](https://github.com/influxdata/influxdb/issues/8028): Fix panic in collectd when configured to read types DB from directory. ## v1.2.0 [2017-01-24] diff --git a/services/collectd/service.go b/services/collectd/service.go index 1f8175d9f1..cbfb90a0d7 100644 --- a/services/collectd/service.go +++ b/services/collectd/service.go @@ -2,6 +2,7 @@ package collectd // import "github.com/influxdata/influxdb/services/collectd" import ( + "bytes" "fmt" "io/ioutil" "net" @@ -114,7 +115,10 @@ func (s *Service) Open() error { if stat, err := os.Stat(s.Config.TypesDB); err != nil { return fmt.Errorf("Stat(): %s", err) } else if stat.IsDir() { - alltypesdb := new(api.TypesDB) + alltypesdb, err := api.NewTypesDB(&bytes.Buffer{}) + if err != nil { + return err + } var readdir func(path string) readdir = func(path string) { files, err := ioutil.ReadDir(path) diff --git a/services/collectd/service_test.go b/services/collectd/service_test.go index fd588e6446..63e4e72e38 100644 --- a/services/collectd/service_test.go +++ b/services/collectd/service_test.go @@ -3,8 +3,10 @@ package collectd import ( "encoding/hex" "errors" + "io/ioutil" "net" "os" + "path" "strings" "testing" "time" @@ -53,6 +55,60 @@ func TestService_OpenClose(t *testing.T) { } } +// Test that the service can read types DB files from a directory. +func TestService_Open_TypesDBDir(t *testing.T) { + t.Parallel() + + // Make a temp dir to write types.db into. + tmpDir, err := ioutil.TempDir(os.TempDir(), "") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(tmpDir) + + // Write types.db. + if err := ioutil.WriteFile(path.Join(tmpDir, "types.db"), []byte(typesDBText), 0777); err != nil { + t.Fatal(err) + } + + // Setup config to read all files in the temp dir. + c := Config{ + BindAddress: "127.0.0.1:0", + Database: "collectd_test", + BatchSize: 1000, + BatchDuration: toml.Duration(time.Second), + TypesDB: tmpDir, + } + + s := &TestService{ + Config: c, + Service: NewService(c), + MetaClient: &internal.MetaClientMock{}, + } + + if testing.Verbose() { + s.Service.WithLogger(zap.New( + zap.NewTextEncoder(), + zap.Output(os.Stderr), + )) + } + + s.MetaClient.CreateDatabaseFn = func(name string) (*meta.DatabaseInfo, error) { + return nil, nil + } + + s.Service.PointsWriter = s + s.Service.MetaClient = s.MetaClient + + if err := s.Service.Open(); err != nil { + t.Fatal(err) + } + + if err := s.Service.Close(); err != nil { + t.Fatal(err) + } +} + // Test that the service checks / creates the target database every time we // try to write points. func TestService_CreatesDatabase(t *testing.T) {