250 lines
5.9 KiB
Go
250 lines
5.9 KiB
Go
package storage_test
|
|
|
|
import (
|
|
"io/ioutil"
|
|
"os"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/influxdata/platform"
|
|
"github.com/influxdata/platform/models"
|
|
"github.com/influxdata/platform/storage"
|
|
"github.com/influxdata/platform/tsdb"
|
|
)
|
|
|
|
func TestEngine_WriteAndIndex(t *testing.T) {
|
|
engine := NewDefaultEngine()
|
|
defer engine.Close()
|
|
|
|
// Calling WritePoints when the engine is not open will return
|
|
// ErrEngineClosed.
|
|
if got, exp := engine.Write1xPoints(nil), storage.ErrEngineClosed; got != exp {
|
|
t.Fatalf("got %v, expected %v", got, exp)
|
|
}
|
|
|
|
engine.MustOpen()
|
|
|
|
pt := models.MustNewPoint(
|
|
"cpu",
|
|
models.Tags{{Key: []byte("host"), Value: []byte("server")}},
|
|
map[string]interface{}{"value": 1.0},
|
|
time.Unix(1, 2),
|
|
)
|
|
|
|
if err := engine.Write1xPoints([]models.Point{pt}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
pt.SetTime(time.Unix(2, 3))
|
|
if err := engine.Write1xPoints([]models.Point{pt}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if got, exp := engine.SeriesCardinality(), int64(1); got != exp {
|
|
t.Fatalf("got %v series, exp %v series in index", got, exp)
|
|
}
|
|
|
|
// ensure the index gets loaded after closing and opening the shard
|
|
engine.Engine.Close() // Don't remove the data
|
|
engine.MustOpen()
|
|
|
|
if got, exp := engine.SeriesCardinality(), int64(1); got != exp {
|
|
t.Fatalf("got %v series, exp %v series in index", got, exp)
|
|
}
|
|
|
|
// and ensure that we can still write data
|
|
pt.SetTime(time.Unix(2, 6))
|
|
if err := engine.Write1xPoints([]models.Point{pt}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestEngine_TimeTag(t *testing.T) {
|
|
engine := NewDefaultEngine()
|
|
defer engine.Close()
|
|
engine.MustOpen()
|
|
|
|
pt := models.MustNewPoint(
|
|
"cpu",
|
|
models.NewTags(map[string]string{"time": "value"}),
|
|
map[string]interface{}{"value": 1.0},
|
|
time.Unix(1, 2),
|
|
)
|
|
|
|
if err := engine.Write1xPoints([]models.Point{pt}); err == nil {
|
|
t.Fatal("expected error: got nil")
|
|
}
|
|
|
|
pt = models.MustNewPoint(
|
|
"cpu",
|
|
models.NewTags(map[string]string{"foo": "bar", "time": "value"}),
|
|
map[string]interface{}{"value": 1.0},
|
|
time.Unix(1, 2),
|
|
)
|
|
|
|
if err := engine.Write1xPoints([]models.Point{pt}); err == nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestWrite_TimeField(t *testing.T) {
|
|
engine := NewDefaultEngine()
|
|
defer engine.Close()
|
|
engine.MustOpen()
|
|
|
|
pt := models.MustNewPoint(
|
|
"cpu",
|
|
models.NewTags(map[string]string{}),
|
|
map[string]interface{}{"time": 1.0},
|
|
time.Unix(1, 2),
|
|
)
|
|
|
|
if err := engine.Write1xPoints([]models.Point{pt}); err == nil {
|
|
t.Fatal("expected error: got nil")
|
|
}
|
|
|
|
pt = models.MustNewPoint(
|
|
"cpu",
|
|
models.NewTags(map[string]string{}),
|
|
map[string]interface{}{"value": 1.1, "time": 1.0},
|
|
time.Unix(1, 2),
|
|
)
|
|
|
|
if err := engine.Write1xPoints([]models.Point{pt}); err == nil {
|
|
t.Fatal("expected error: got nil")
|
|
}
|
|
}
|
|
|
|
func TestEngine_WriteAddNewField(t *testing.T) {
|
|
engine := NewDefaultEngine()
|
|
defer engine.Close()
|
|
engine.MustOpen()
|
|
|
|
pt := models.MustNewPoint(
|
|
"cpu",
|
|
models.NewTags(map[string]string{"host": "server"}),
|
|
map[string]interface{}{"value": 1.0},
|
|
time.Unix(1, 2),
|
|
)
|
|
|
|
err := engine.Write1xPoints([]models.Point{pt})
|
|
if err != nil {
|
|
t.Fatalf(err.Error())
|
|
}
|
|
|
|
pt = models.MustNewPoint(
|
|
"cpu",
|
|
models.NewTags(map[string]string{"host": "server"}),
|
|
map[string]interface{}{"value": 1.0, "value2": 2.0},
|
|
time.Unix(1, 2),
|
|
)
|
|
|
|
err = engine.Write1xPoints([]models.Point{pt})
|
|
if err != nil {
|
|
t.Fatalf(err.Error())
|
|
}
|
|
|
|
if got, exp := engine.SeriesCardinality(), int64(2); got != exp {
|
|
t.Fatalf("got %d series, exp %d series in index", got, exp)
|
|
}
|
|
}
|
|
|
|
// Ensures that when a shard is closed, it removes any series meta-data
|
|
// from the index.
|
|
func TestEngineClose_RemoveIndex(t *testing.T) {
|
|
engine := NewDefaultEngine()
|
|
defer engine.Close()
|
|
engine.MustOpen()
|
|
|
|
pt := models.MustNewPoint(
|
|
"cpu",
|
|
models.NewTags(map[string]string{"host": "server"}),
|
|
map[string]interface{}{"value": 1.0},
|
|
time.Unix(1, 2),
|
|
)
|
|
|
|
err := engine.Write1xPoints([]models.Point{pt})
|
|
if err != nil {
|
|
t.Fatalf(err.Error())
|
|
}
|
|
|
|
if got, exp := engine.SeriesCardinality(), int64(1); got != exp {
|
|
t.Fatalf("got %d series, exp %d series in index", got, exp)
|
|
}
|
|
|
|
// ensure the index gets loaded after closing and opening the shard
|
|
engine.Engine.Close() // Don't destroy temporary data.
|
|
engine.Open()
|
|
|
|
if got, exp := engine.SeriesCardinality(), int64(1); got != exp {
|
|
t.Fatalf("got %d series, exp %d series in index", got, exp)
|
|
}
|
|
}
|
|
|
|
func TestEngine_WALDisabled(t *testing.T) {
|
|
config := storage.NewConfig()
|
|
config.WAL.Enabled = false
|
|
|
|
engine := NewEngine(config)
|
|
defer engine.Close()
|
|
engine.MustOpen()
|
|
|
|
pt := models.MustNewPoint(
|
|
"cpu",
|
|
models.NewTags(map[string]string{"host": "server"}),
|
|
map[string]interface{}{"value": 1.0},
|
|
time.Unix(1, 2),
|
|
)
|
|
|
|
if err := engine.Write1xPoints([]models.Point{pt}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
type Engine struct {
|
|
path string
|
|
*storage.Engine
|
|
}
|
|
|
|
// NewEngine create a new wrapper around a storage engine.
|
|
func NewEngine(c storage.Config) *Engine {
|
|
path, _ := ioutil.TempDir("", "storage_engine_test")
|
|
|
|
engine := storage.NewEngine(path, c)
|
|
return &Engine{
|
|
path: path,
|
|
Engine: engine,
|
|
}
|
|
}
|
|
|
|
// NewDefaultEngine returns a new Engine with a default configuration.
|
|
func NewDefaultEngine() *Engine {
|
|
return NewEngine(storage.NewConfig())
|
|
}
|
|
|
|
// MustOpen opens the engine or panicks.
|
|
func (e *Engine) MustOpen() {
|
|
if err := e.Engine.Open(); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
// Write1xPoints converts old style points into the new 2.0 engine format.
|
|
// This allows us to use the old `models` package helper functions and still write
|
|
// the points in the correct format.
|
|
func (e *Engine) Write1xPoints(pts []models.Point) error {
|
|
org, _ := platform.IDFromString("3131313131313131")
|
|
bucket, _ := platform.IDFromString("3232323232323232")
|
|
points, err := tsdb.ExplodePoints(*org, *bucket, pts)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return e.Engine.WritePoints(points)
|
|
}
|
|
|
|
// Close closes the engine and removes all temporary data.
|
|
func (e *Engine) Close() error {
|
|
defer os.RemoveAll(e.path)
|
|
return e.Engine.Close()
|
|
}
|