2017-11-15 23:09:25 +00:00
|
|
|
package tsdb_test
|
2017-09-14 15:41:58 +00:00
|
|
|
|
|
|
|
import (
|
2017-12-27 15:09:36 +00:00
|
|
|
"fmt"
|
2017-09-14 15:41:58 +00:00
|
|
|
"io/ioutil"
|
|
|
|
"os"
|
2017-12-15 14:24:26 +00:00
|
|
|
"runtime"
|
2017-09-14 15:41:58 +00:00
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/influxdata/influxdb/models"
|
2017-11-15 23:09:25 +00:00
|
|
|
"github.com/influxdata/influxdb/tsdb"
|
2017-09-14 15:41:58 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// Ensure series file contains the correct set of series.
|
|
|
|
func TestSeriesFile_Series(t *testing.T) {
|
|
|
|
sfile := MustOpenSeriesFile()
|
|
|
|
defer sfile.Close()
|
|
|
|
|
|
|
|
series := []Series{
|
|
|
|
{Name: []byte("cpu"), Tags: models.NewTags(map[string]string{"region": "east"})},
|
|
|
|
{Name: []byte("cpu"), Tags: models.NewTags(map[string]string{"region": "west"})},
|
|
|
|
{Name: []byte("mem"), Tags: models.NewTags(map[string]string{"region": "east"})},
|
|
|
|
}
|
|
|
|
for _, s := range series {
|
2017-09-25 15:31:20 +00:00
|
|
|
if _, err := sfile.CreateSeriesListIfNotExists([][]byte{[]byte(s.Name)}, []models.Tags{s.Tags}, nil); err != nil {
|
2017-09-14 15:41:58 +00:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Verify total number of series is correct.
|
|
|
|
if n := sfile.SeriesCount(); n != 3 {
|
|
|
|
t.Fatalf("unexpected series count: %d", n)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Verify all series exist.
|
|
|
|
for i, s := range series {
|
2017-12-19 17:31:33 +00:00
|
|
|
if seriesID := sfile.SeriesID(s.Name, s.Tags, nil); seriesID == 0 {
|
2017-09-14 15:41:58 +00:00
|
|
|
t.Fatalf("series does not exist: i=%d", i)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Verify non-existent series doesn't exist.
|
|
|
|
if sfile.HasSeries([]byte("foo"), models.NewTags(map[string]string{"region": "north"}), nil) {
|
|
|
|
t.Fatal("series should not exist")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-27 15:09:36 +00:00
|
|
|
// Ensure series file can be compacted.
|
|
|
|
func TestSeriesFileCompactor(t *testing.T) {
|
|
|
|
sfile := MustOpenSeriesFile()
|
|
|
|
defer sfile.Close()
|
|
|
|
|
|
|
|
var names [][]byte
|
|
|
|
var tagsSlice []models.Tags
|
|
|
|
for i := 0; i < 10000; i++ {
|
|
|
|
names = append(names, []byte(fmt.Sprintf("m%d", i)))
|
|
|
|
tagsSlice = append(tagsSlice, models.NewTags(map[string]string{"foo": "bar"}))
|
|
|
|
}
|
|
|
|
if _, err := sfile.CreateSeriesListIfNotExists(names, tagsSlice, nil); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Verify total number of series is correct.
|
|
|
|
if n := sfile.SeriesCount(); n != uint64(len(names)) {
|
|
|
|
t.Fatalf("unexpected series count: %d", n)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Compact to new file.
|
|
|
|
compactionPath := sfile.Path() + ".compacting"
|
|
|
|
defer os.Remove(compactionPath)
|
|
|
|
|
|
|
|
compactor := tsdb.NewSeriesFileCompactor(sfile.SeriesFile)
|
|
|
|
if err := compactor.CompactTo(compactionPath); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Open new series file.
|
|
|
|
other := tsdb.NewSeriesFile(compactionPath)
|
|
|
|
if err := other.Open(); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
defer other.Close()
|
|
|
|
|
|
|
|
// Verify all series exist.
|
|
|
|
for i := range names {
|
|
|
|
if seriesID := other.SeriesID(names[i], tagsSlice[i], nil); seriesID == 0 {
|
|
|
|
t.Fatalf("series does not exist: %s,%s", names[i], tagsSlice[i].String())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-14 15:41:58 +00:00
|
|
|
// Series represents name/tagset pairs that are used in testing.
|
|
|
|
type Series struct {
|
|
|
|
Name []byte
|
|
|
|
Tags models.Tags
|
|
|
|
Deleted bool
|
|
|
|
}
|
|
|
|
|
2017-11-15 23:09:25 +00:00
|
|
|
// SeriesFile is a test wrapper for tsdb.SeriesFile.
|
2017-09-14 15:41:58 +00:00
|
|
|
type SeriesFile struct {
|
2017-11-15 23:09:25 +00:00
|
|
|
*tsdb.SeriesFile
|
2017-09-14 15:41:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// NewSeriesFile returns a new instance of SeriesFile with a temporary file path.
|
|
|
|
func NewSeriesFile() *SeriesFile {
|
2017-11-15 23:09:25 +00:00
|
|
|
file, err := ioutil.TempFile("", "tsdb-series-file-")
|
2017-09-14 15:41:58 +00:00
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
file.Close()
|
|
|
|
|
2017-12-15 14:24:26 +00:00
|
|
|
s := &SeriesFile{SeriesFile: tsdb.NewSeriesFile(file.Name())}
|
|
|
|
// If we're running on a 32-bit system then reduce the SeriesFile size, so we
|
|
|
|
// can address is in memory.
|
|
|
|
if runtime.GOARCH == "386" {
|
2017-12-17 22:40:00 +00:00
|
|
|
s.SeriesFile.MaxSize = 1 << 27 // 128MB
|
2017-12-15 14:24:26 +00:00
|
|
|
}
|
|
|
|
return s
|
2017-09-14 15:41:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// MustOpenSeriesFile returns a new, open instance of SeriesFile. Panic on error.
|
|
|
|
func MustOpenSeriesFile() *SeriesFile {
|
|
|
|
f := NewSeriesFile()
|
|
|
|
if err := f.Open(); err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
return f
|
|
|
|
}
|
|
|
|
|
|
|
|
// Close closes the log file and removes it from disk.
|
|
|
|
func (f *SeriesFile) Close() error {
|
|
|
|
defer os.Remove(f.Path())
|
|
|
|
return f.SeriesFile.Close()
|
|
|
|
}
|