func TestTSMReader_Type(t *testing.T) { var b bytes.Buffer w, err := tsm1.NewTSMWriter(&b) if err != nil { t.Fatalf("unexpected error creating writer: %v", err) } values := []tsm1.Value{tsm1.NewValue(time.Unix(0, 0), int64(1))} if err := w.Write("cpu", values); err != nil { t.Fatalf("unexpected error writing: %v", err) } if err := w.WriteIndex(); err != nil { t.Fatalf("unexpected error closing: %v", err) } if err := w.Close(); err != nil { t.Fatalf("unexpected error closing: %v", err) } r, err := tsm1.NewTSMReader(bytes.NewReader(b.Bytes())) if err != nil { t.Fatalf("unexpected error created reader: %v", err) } typ, err := r.Type("cpu") if err != nil { fatal(t, "reading type", err) } if got, exp := typ, tsm1.BlockInteger; got != exp { t.Fatalf("type mismatch: got %v, exp %v", got, exp) } }
func TestTSMWriter_Write_Multiple(t *testing.T) { dir := MustTempDir() defer os.RemoveAll(dir) f := MustTempFile(dir) w, err := tsm1.NewTSMWriter(f) if err != nil { t.Fatalf("unexpected error creating writer: %v", err) } var data = []struct { key string values []tsm1.Value }{ {"cpu", []tsm1.Value{tsm1.NewValue(0, 1.0)}}, {"mem", []tsm1.Value{tsm1.NewValue(1, 2.0)}}, } for _, d := range data { if err := w.Write(d.key, d.values); err != nil { t.Fatalf("unexpected error writing: %v", err) } } if err := w.WriteIndex(); err != nil { t.Fatalf("unexpected error closing: %v", err) } if err := w.Close(); err != nil { t.Fatalf("unexpected error closing: %v", err) } fd, err := os.Open(f.Name()) if err != nil { t.Fatalf("unexpected error open file: %v", err) } r, err := tsm1.NewTSMReader(fd) if err != nil { t.Fatalf("unexpected error created reader: %v", err) } defer r.Close() for _, d := range data { readValues, err := r.ReadAll(d.key) if err != nil { t.Fatalf("unexpected error readin: %v", err) } if exp := len(d.values); exp != len(readValues) { t.Fatalf("read values length mismatch: got %v, exp %v", len(readValues), exp) } for i, v := range d.values { if v.Value() != readValues[i].Value() { t.Fatalf("read value mismatch(%d): got %v, exp %d", i, readValues[i].Value(), v.Value()) } } } }
func MustTSMWriter(dir string, gen int) (tsm1.TSMWriter, string) { f := MustTempFile(dir) oldName := f.Name() // Windows can't rename a file while it's open. Close first, rename and // then re-open if err := f.Close(); err != nil { panic(fmt.Sprintf("close temp file: %v", err)) } newName := filepath.Join(filepath.Dir(oldName), tsmFileName(gen)) if err := os.Rename(oldName, newName); err != nil { panic(fmt.Sprintf("create tsm file: %v", err)) } var err error f, err = os.OpenFile(newName, os.O_RDWR, 0666) if err != nil { panic(fmt.Sprintf("open tsm files: %v", err)) } w, err := tsm1.NewTSMWriter(f) if err != nil { panic(fmt.Sprintf("create TSM writer: %v", err)) } return w, newName }
func TestTSMWriter_WriteBlock_Empty(t *testing.T) { dir := MustTempDir() defer os.RemoveAll(dir) f := MustTempFile(dir) w, err := tsm1.NewTSMWriter(f) if err != nil { t.Fatalf("unexpected error creating writer: %v", err) } if err := w.WriteBlock("cpu", 0, 0, nil); err != nil { t.Fatalf("unexpected error writing block: %v", err) } if err := w.WriteIndex(); err != tsm1.ErrNoValues { t.Fatalf("unexpected error closing: %v", err) } fd, err := os.Open(f.Name()) if err != nil { t.Fatalf("unexpected error open file: %v", err) } defer fd.Close() b, err := ioutil.ReadAll(fd) if err != nil { t.Fatalf("unexpected error read all: %v", err) } if got, exp := len(b), 0; got < exp { t.Fatalf("file size mismatch: got %v, exp %v", got, exp) } }
func newFiles(values ...keyValues) ([]tsm1.TSMFile, error) { var files []tsm1.TSMFile for _, v := range values { var b bytes.Buffer w, err := tsm1.NewTSMWriter(&b) if err != nil { return nil, err } if err := w.Write(v.key, v.values); err != nil { return nil, err } if err := w.WriteIndex(); err != nil { return nil, err } if err := w.Close(); err != nil { return nil, err } r, err := tsm1.NewTSMReader(bytes.NewReader(b.Bytes())) if err != nil { return nil, err } files = append(files, r) } return files, nil }
func TestIndirectIndex_UnmarshalBinary_BlockCountOverflow(t *testing.T) { dir := MustTempDir() defer os.RemoveAll(dir) f := MustTempFile(dir) defer f.Close() w, err := tsm1.NewTSMWriter(f) if err != nil { t.Fatalf("unexpected error creating writer: %v", err) } for i := 0; i < 3280; i++ { w.Write("cpu", []tsm1.Value{tsm1.NewValue(int64(i), float64(i))}) } if err := w.WriteIndex(); err != nil { t.Fatalf("unexpected error closing: %v", err) } if err := w.Close(); err != nil { t.Fatalf("unexpected error closing: %v", err) } f, err = os.Open(f.Name()) if err != nil { t.Fatalf("unexpected error open file: %v", err) } r, err := tsm1.NewTSMReader(f) if err != nil { t.Fatalf("unexpected error created reader: %v", err) } defer r.Close() }
func newFileDir(dir string, values ...keyValues) ([]string, error) { var files []string id := 1 for _, v := range values { f := MustTempFile(dir) w, err := tsm1.NewTSMWriter(f) if err != nil { return nil, err } if err := w.Write(v.key, v.values); err != nil { return nil, err } if err := w.WriteIndex(); err != nil { return nil, err } if err := w.Close(); err != nil { return nil, err } newName := filepath.Join(filepath.Dir(f.Name()), tsmFileName(id)) if err := os.Rename(f.Name(), newName); err != nil { return nil, err } id++ files = append(files, newName) } return files, nil }
func TestTSMReader_MMAP_Tombstone(t *testing.T) { dir := MustTempDir() defer os.RemoveAll(dir) f := MustTempFile(dir) defer f.Close() w, err := tsm1.NewTSMWriter(f) if err != nil { t.Fatalf("unexpected error creating writer: %v", err) } values := []tsm1.Value{tsm1.NewValue(time.Unix(0, 0), 1.0)} if err := w.Write("cpu", values); err != nil { t.Fatalf("unexpected error writing: %v", err) } if err := w.Write("mem", values); err != nil { t.Fatalf("unexpected error writing: %v", err) } if err := w.WriteIndex(); err != nil { t.Fatalf("unexpected error writing index: %v", err) } if err := w.Close(); err != nil { t.Fatalf("unexpected error closing: %v", err) } f, err = os.Open(f.Name()) if err != nil { t.Fatalf("unexpected error open file: %v", err) } r, err := tsm1.NewTSMReaderWithOptions( tsm1.TSMReaderOptions{ MMAPFile: f, }) if err != nil { t.Fatalf("unexpected error created reader: %v", err) } if err := r.Delete([]string{"mem"}); err != nil { t.Fatalf("unexpected error deleting: %v", err) } r, err = tsm1.NewTSMReaderWithOptions( tsm1.TSMReaderOptions{ MMAPFile: f, }) if err != nil { t.Fatalf("unexpected error created reader: %v", err) } defer r.Close() if got, exp := len(r.Keys()), 1; got != exp { t.Fatalf("key length mismatch: got %v, exp %v", got, exp) } }
func TestTSMReader_MMAP_TombstoneMultipleRanges(t *testing.T) { dir := MustTempDir() defer os.RemoveAll(dir) f := MustTempFile(dir) defer f.Close() w, err := tsm1.NewTSMWriter(f) if err != nil { t.Fatalf("unexpected error creating writer: %v", err) } expValues := []tsm1.Value{ tsm1.NewValue(1, 1.0), tsm1.NewValue(2, 2.0), tsm1.NewValue(3, 3.0), tsm1.NewValue(4, 4.0), tsm1.NewValue(5, 5.0), } if err := w.Write("cpu", expValues); err != nil { t.Fatalf("unexpected error writing: %v", err) } if err := w.WriteIndex(); err != nil { t.Fatalf("unexpected error writing index: %v", err) } if err := w.Close(); err != nil { t.Fatalf("unexpected error closing: %v", err) } f, err = os.Open(f.Name()) if err != nil { t.Fatalf("unexpected error open file: %v", err) } r, err := tsm1.NewTSMReader(f) if err != nil { t.Fatalf("unexpected error created reader: %v", err) } defer r.Close() if err := r.DeleteRange([]string{"cpu"}, 2, 2); err != nil { t.Fatalf("unexpected error deleting: %v", err) } if err := r.DeleteRange([]string{"cpu"}, 4, 4); err != nil { t.Fatalf("unexpected error deleting: %v", err) } values, err := r.ReadAll("cpu") if err != nil { t.Fatalf("unexpected error reading all: %v", err) } if got, exp := len(values), 3; got != exp { t.Fatalf("values length mismatch: got %v, exp %v", got, exp) } }
// Tests that writing keys in reverse is able to read them back. func TestTSMWriter_Write_SameKey(t *testing.T) { var b bytes.Buffer w, err := tsm1.NewTSMWriter(&b) if err != nil { t.Fatalf("unexpected error creating writer: %v", err) } var data = []struct { key string values []tsm1.Value }{ {"cpu", []tsm1.Value{ tsm1.NewValue(0, 1.0), tsm1.NewValue(1, 2.0)}, }, {"cpu", []tsm1.Value{ tsm1.NewValue(2, 3.0), tsm1.NewValue(3, 4.0)}, }, } for _, d := range data { if err := w.Write(d.key, d.values); err != nil { t.Fatalf("unexpected error writing: %v", err) } } if err := w.WriteIndex(); err != nil { t.Fatalf("unexpected error closing: %v", err) } if err := w.Close(); err != nil { t.Fatalf("unexpected error closing: %v", err) } r, err := tsm1.NewTSMReader(bytes.NewReader(b.Bytes())) if err != nil { t.Fatalf("unexpected error created reader: %v", err) } values := append(data[0].values, data[1].values...) readValues, err := r.ReadAll("cpu") if err != nil { t.Fatalf("unexpected error readin: %v", err) } if exp := len(values); exp != len(readValues) { t.Fatalf("read values length mismatch: got %v, exp %v", len(readValues), exp) } for i, v := range values { if v.Value() != readValues[i].Value() { t.Fatalf("read value mismatch(%d): got %v, exp %d", i, readValues[i].Value(), v.Value()) } } }
func TestBlockIterator_Single(t *testing.T) { var b bytes.Buffer w, err := tsm1.NewTSMWriter(&b) if err != nil { t.Fatalf("unexpected error creating writer: %v", err) } values := []tsm1.Value{tsm1.NewValue(time.Unix(0, 0), int64(1))} if err := w.Write("cpu", values); err != nil { t.Fatalf("unexpected error writing: %v", err) } if err := w.WriteIndex(); err != nil { t.Fatalf("unexpected error closing: %v", err) } if err := w.Close(); err != nil { t.Fatalf("unexpected error closing: %v", err) } r, err := tsm1.NewTSMReader(bytes.NewReader(b.Bytes())) if err != nil { t.Fatalf("unexpected error created reader: %v", err) } var count int iter := r.BlockIterator() for iter.Next() { key, minTime, maxTime, buf, err := iter.Read() if err != nil { t.Fatalf("unexpected error creating iterator: %v", err) } if got, exp := key, "cpu"; got != exp { t.Fatalf("key mismatch: got %v, exp %v", got, exp) } if got, exp := minTime, time.Unix(0, 0); got != exp { t.Fatalf("min time mismatch: got %v, exp %v", got, exp) } if got, exp := maxTime, time.Unix(0, 0); got != exp { t.Fatalf("max time mismatch: got %v, exp %v", got, exp) } if len(buf) == 0 { t.Fatalf("buf length = 0") } count++ } if got, exp := count, len(values); got != exp { t.Fatalf("value count mismatch: got %v, exp %v", got, exp) } }
func TestTSMWriter_Write_Empty(t *testing.T) { var b bytes.Buffer w, err := tsm1.NewTSMWriter(&b) if err != nil { t.Fatalf("unexpected error created writer: %v", err) } if err := w.WriteIndex(); err != tsm1.ErrNoValues { t.Fatalf("unexpected error closing: %v", err) } if got, exp := len(b.Bytes()), 0; got < exp { t.Fatalf("file size mismatch: got %v, exp %v", got, exp) } }
func TestTSMWriter_Write_Single(t *testing.T) { var b bytes.Buffer w, err := tsm1.NewTSMWriter(&b) if err != nil { t.Fatalf("unexpected error creating writer: %v", err) } values := []tsm1.Value{tsm1.NewValue(0, 1.0)} if err := w.Write("cpu", values); err != nil { t.Fatalf("unexpected error writing: %v", err) } if err := w.WriteIndex(); err != nil { t.Fatalf("unexpected error writing index: %v", err) } if err := w.Close(); err != nil { t.Fatalf("unexpected error closing: %v", err) } if got, exp := len(b.Bytes()), 5; got < exp { t.Fatalf("file size mismatch: got %v, exp %v", got, exp) } if got := binary.BigEndian.Uint32(b.Bytes()[0:4]); got != tsm1.MagicNumber { t.Fatalf("magic number mismatch: got %v, exp %v", got, tsm1.MagicNumber) } r, err := tsm1.NewTSMReader(bytes.NewReader(b.Bytes())) if err != nil { t.Fatalf("unexpected error created reader: %v", err) } readValues, err := r.ReadAll("cpu") if err != nil { t.Fatalf("unexpected error readin: %v", err) } if len(readValues) != len(values) { t.Fatalf("read values length mismatch: got %v, exp %v", len(readValues), len(values)) } for i, v := range values { if v.Value() != readValues[i].Value() { t.Fatalf("read value mismatch(%d): got %v, exp %d", i, readValues[i].Value(), v.Value()) } } }
func TestCompacted_NotFull(t *testing.T) { dir := MustTempDir() defer os.RemoveAll(dir) f := MustTempFile(dir) w, err := tsm1.NewTSMWriter(f) if err != nil { t.Fatalf("unexpected error creating writer: %v", err) } values := []tsm1.Value{tsm1.NewValue(0, 1.0)} if err := w.Write("cpu", values); err != nil { t.Fatalf("unexpected error writing: %v", err) } if err := w.WriteIndex(); err != nil { t.Fatalf("unexpected error writing index: %v", err) } if err := w.Close(); err != nil { t.Fatalf("unexpected error closing: %v", err) } fd, err := os.Open(f.Name()) if err != nil { t.Fatalf("unexpected error open file: %v", err) } r, err := tsm1.NewTSMReader(fd) if err != nil { t.Fatalf("unexpected error created reader: %v", err) } iter := r.BlockIterator() if !iter.Next() { t.Fatalf("expected next, got false") } _, _, _, _, block, err := iter.Read() if err != nil { t.Fatalf("unexpected error reading block: %v", err) } if got, exp := tsm1.BlockCount(block), 1; got != exp { t.Fatalf("block count mismatch: got %v, exp %v", got, exp) } }
// nextTSMWriter returns the next TSMWriter for the Converter. func (c *Converter) nextTSMWriter() (tsm1.TSMWriter, error) { c.sequence++ fileName := filepath.Join(c.path, fmt.Sprintf("%09d-%09d.%s", 1, c.sequence, tsm1.TSMFileExtension)) fd, err := os.OpenFile(fileName, os.O_CREATE|os.O_RDWR, 0666) if err != nil { return nil, err } // Create the writer for the new TSM file. w, err := tsm1.NewTSMWriter(fd) if err != nil { return nil, err } c.tracker.IncrTSMFileCount() return w, nil }
func TestTSMWriter_Write_MaxKey(t *testing.T) { dir := MustTempDir() defer os.RemoveAll(dir) f := MustTempFile(dir) defer f.Close() w, err := tsm1.NewTSMWriter(f) if err != nil { t.Fatalf("unexpected error created writer: %v", err) } var key string for i := 0; i < 100000; i++ { key += "a" } if err := w.Write(key, []tsm1.Value{tsm1.NewValue(0, 1.0)}); err != tsm1.ErrMaxKeyLengthExceeded { t.Fatalf("expected max key length error writing key: %v", err) } }
func MustWriteTSM(dir string, gen int, values map[string][]tsm1.Value) string { f := MustTempFile(dir) oldName := f.Name() // Windows can't rename a file while it's open. Close first, rename and // then re-open if err := f.Close(); err != nil { panic(fmt.Sprintf("close temp file: %v", err)) } newName := filepath.Join(filepath.Dir(oldName), tsmFileName(gen)) if err := os.Rename(oldName, newName); err != nil { panic(fmt.Sprintf("create tsm file: %v", err)) } var err error f, err = os.OpenFile(newName, os.O_RDWR, 0666) if err != nil { panic(fmt.Sprintf("open tsm files: %v", err)) } w, err := tsm1.NewTSMWriter(f) if err != nil { panic(fmt.Sprintf("create TSM writer: %v", err)) } for k, v := range values { if err := w.Write(k, v); err != nil { panic(fmt.Sprintf("write TSM value: %v", err)) } } if err := w.WriteIndex(); err != nil { panic(fmt.Sprintf("write TSM index: %v", err)) } if err := w.Close(); err != nil { panic(fmt.Sprintf("write TSM close: %v", err)) } return newName }
func TestTSMReader_Type(t *testing.T) { dir := MustTempDir() defer os.RemoveAll(dir) f := MustTempFile(dir) w, err := tsm1.NewTSMWriter(f) if err != nil { t.Fatalf("unexpected error creating writer: %v", err) } values := []tsm1.Value{tsm1.NewValue(0, int64(1))} if err := w.Write("cpu", values); err != nil { t.Fatalf("unexpected error writing: %v", err) } if err := w.WriteIndex(); err != nil { t.Fatalf("unexpected error closing: %v", err) } if err := w.Close(); err != nil { t.Fatalf("unexpected error closing: %v", err) } f, err = os.Open(f.Name()) if err != nil { t.Fatalf("unexpected error opening: %v", err) } r, err := tsm1.NewTSMReader(f) if err != nil { t.Fatalf("unexpected error created reader: %v", err) } typ, err := r.Type("cpu") if err != nil { fatal(t, "reading type", err) } if got, exp := typ, tsm1.BlockInteger; got != exp { t.Fatalf("type mismatch: got %v, exp %v", got, exp) } }
func TestCompacted_NotFull(t *testing.T) { var b bytes.Buffer w, err := tsm1.NewTSMWriter(&b) if err != nil { t.Fatalf("unexpected error creating writer: %v", err) } values := []tsm1.Value{tsm1.NewValue(time.Unix(0, 0), 1.0)} if err := w.Write("cpu", values); err != nil { t.Fatalf("unexpected error writing: %v", err) } if err := w.WriteIndex(); err != nil { t.Fatalf("unexpected error writing index: %v", err) } if err := w.Close(); err != nil { t.Fatalf("unexpected error closing: %v", err) } r, err := tsm1.NewTSMReader(bytes.NewReader(b.Bytes())) if err != nil { t.Fatalf("unexpected error created reader: %v", err) } iter := r.BlockIterator() if !iter.Next() { t.Fatalf("expected next, got false") } _, _, _, block, err := iter.Read() if err != nil { t.Fatalf("unexpected error reading block: %v", err) } if got, exp := tsm1.BlockCount(block), 1; got != exp { t.Fatalf("block count mismatch: got %v, exp %v", got, exp) } }
func TestTSMReader_MMAP_Stats(t *testing.T) { dir := MustTempDir() defer os.RemoveAll(dir) f := MustTempFile(dir) defer f.Close() w, err := tsm1.NewTSMWriter(f) if err != nil { t.Fatalf("unexpected error creating writer: %v", err) } values1 := []tsm1.Value{tsm1.NewValue(time.Unix(0, 0), 1.0)} if err := w.Write("cpu", values1); err != nil { t.Fatalf("unexpected error writing: %v", err) } values2 := []tsm1.Value{tsm1.NewValue(time.Unix(1, 0), 1.0)} if err := w.Write("mem", values2); err != nil { t.Fatalf("unexpected error writing: %v", err) } if err := w.WriteIndex(); err != nil { t.Fatalf("unexpected error writing index: %v", err) } if err := w.Close(); err != nil { t.Fatalf("unexpected error closing: %v", err) } f, err = os.Open(f.Name()) if err != nil { t.Fatalf("unexpected error open file: %v", err) } r, err := tsm1.NewTSMReaderWithOptions( tsm1.TSMReaderOptions{ MMAPFile: f, }) if err != nil { t.Fatalf("unexpected error created reader: %v", err) } defer r.Close() stats := r.Stats() if got, exp := stats.MinKey, "cpu"; got != exp { t.Fatalf("min key mismatch: got %v, exp %v", got, exp) } if got, exp := stats.MaxKey, "mem"; got != exp { t.Fatalf("max key mismatch: got %v, exp %v", got, exp) } if got, exp := stats.MinTime, values1[0].Time(); got != exp { t.Fatalf("min time mismatch: got %v, exp %v", got, exp) } if got, exp := stats.MaxTime, values2[0].Time(); got != exp { t.Fatalf("max time mismatch: got %v, exp %v", got, exp) } if got, exp := len(r.Keys()), 2; got != exp { t.Fatalf("key length mismatch: got %v, exp %v", got, exp) } }
func TestTSMReader_MMAP_ReadAll(t *testing.T) { dir := MustTempDir() defer os.RemoveAll(dir) f := MustTempFile(dir) defer f.Close() w, err := tsm1.NewTSMWriter(f) if err != nil { t.Fatalf("unexpected error creating writer: %v", err) } var data = []struct { key string values []tsm1.Value }{ {"float", []tsm1.Value{ tsm1.NewValue(1, 1.0)}, }, {"int", []tsm1.Value{ tsm1.NewValue(1, int64(1))}, }, {"bool", []tsm1.Value{ tsm1.NewValue(1, true)}, }, {"string", []tsm1.Value{ tsm1.NewValue(1, "foo")}, }, } for _, d := range data { if err := w.Write(d.key, d.values); err != nil { t.Fatalf("unexpected error writing: %v", err) } } if err := w.WriteIndex(); err != nil { t.Fatalf("unexpected error writing index: %v", err) } if err := w.Close(); err != nil { t.Fatalf("unexpected error closing: %v", err) } f, err = os.Open(f.Name()) if err != nil { t.Fatalf("unexpected error open file: %v", err) } r, err := tsm1.NewTSMReader(f) if err != nil { t.Fatalf("unexpected error created reader: %v", err) } defer r.Close() var count int for _, d := range data { readValues, err := r.ReadAll(d.key) if err != nil { t.Fatalf("unexpected error readin: %v", err) } if exp := len(d.values); exp != len(readValues) { t.Fatalf("read values length mismatch: got %v, exp %v", len(readValues), exp) } for i, v := range d.values { if v.Value() != readValues[i].Value() { t.Fatalf("read value mismatch(%d): got %v, exp %d", i, readValues[i].Value(), v.Value()) } } count++ } if got, exp := count, len(data); got != exp { t.Fatalf("read values count mismatch: got %v, exp %v", got, exp) } }
// Write TSMPoints data to TSM files func (migrationData *MigrationData) WriteTSMPoints(filename string, tsmPoints []TsmPoint) error { if len(tsmPoints) == 0 { return nil } // Open tsm file for writing f, err := os.OpenFile(filename, os.O_CREATE|os.O_RDWR, 0666) if err != nil { fmt.Println(err) return err } defer f.Close() //Create TSMWriter with filehandle tsmWriter, err := tsm1.NewTSMWriter(f) if err != nil { panic(fmt.Sprintf("create TSM writer: %v", err)) } //Write the points in batch writes := 0 for _, tsmPoint := range tsmPoints { //fmt.Println(i, tsmPoint.key) if len(tsmPoint.values) > 0 { if err := tsmWriter.Write(tsmPoint.key, tsmPoint.values); err != nil { panic(fmt.Sprintf("write TSM value: %v", err)) } writes = writes + 1 } } // Should not write index if there are no writes if writes == 0 { return nil } //Write index if err := tsmWriter.WriteIndex(); err != nil { panic(fmt.Sprintf("write TSM index: %v", err)) } if err := tsmWriter.Close(); err != nil { panic(fmt.Sprintf("write TSM close: %v", err)) } // Opening the file again, just to check size f1, err := os.OpenFile(filename, os.O_RDWR, 0666) if err != nil { fmt.Println(err) return err } defer f1.Close() fileinfo1, err := f1.Stat() if err != nil { fmt.Println("Could not read filestat", err) return err } migrationData.tsmFileSize = migrationData.tsmFileSize + fileinfo1.Size() fmt.Println("TSM File ", filename, "Size ", fileinfo1.Size()) return err }
func TestBlockIterator_MultipleBlocks(t *testing.T) { dir := MustTempDir() defer os.RemoveAll(dir) f := MustTempFile(dir) w, err := tsm1.NewTSMWriter(f) if err != nil { t.Fatalf("unexpected error creating writer: %v", err) } values1 := []tsm1.Value{tsm1.NewValue(0, int64(1))} if err := w.Write("cpu", values1); err != nil { t.Fatalf("unexpected error writing: %v", err) } values2 := []tsm1.Value{tsm1.NewValue(1, int64(2))} if err := w.Write("cpu", values2); err != nil { t.Fatalf("unexpected error writing: %v", err) } if err := w.WriteIndex(); err != nil { t.Fatalf("unexpected error closing: %v", err) } if err := w.Close(); err != nil { t.Fatalf("unexpected error closing: %v", err) } fd, err := os.Open(f.Name()) if err != nil { t.Fatalf("unexpected error opening: %v", err) } r, err := tsm1.NewTSMReader(fd) if err != nil { t.Fatalf("unexpected error created reader: %v", err) } var count int expData := []tsm1.Values{values1, values2} iter := r.BlockIterator() var i int for iter.Next() { key, minTime, maxTime, _, buf, err := iter.Read() if err != nil { t.Fatalf("unexpected error creating iterator: %v", err) } if got, exp := key, "cpu"; got != exp { t.Fatalf("key mismatch: got %v, exp %v", got, exp) } if got, exp := minTime, expData[i][0].UnixNano(); got != exp { t.Fatalf("min time mismatch: got %v, exp %v", got, exp) } if got, exp := maxTime, expData[i][0].UnixNano(); got != exp { t.Fatalf("max time mismatch: got %v, exp %v", got, exp) } if len(buf) == 0 { t.Fatalf("buf length = 0") } count++ i++ } if got, exp := count, 2; got != exp { t.Fatalf("value count mismatch: got %v, exp %v", got, exp) } }
func TestTSMWriter_WriteBlock_Multiple(t *testing.T) { dir := MustTempDir() defer os.RemoveAll(dir) f := MustTempFile(dir) w, err := tsm1.NewTSMWriter(f) if err != nil { t.Fatalf("unexpected error creating writer: %v", err) } var data = []struct { key string values []tsm1.Value }{ {"cpu", []tsm1.Value{tsm1.NewValue(0, 1.0)}}, {"mem", []tsm1.Value{tsm1.NewValue(1, 2.0)}}, } for _, d := range data { if err := w.Write(d.key, d.values); err != nil { t.Fatalf("unexpected error writing: %v", err) } } if err := w.WriteIndex(); err != nil { t.Fatalf("unexpected error closing: %v", err) } if err := w.Close(); err != nil { t.Fatalf("unexpected error closing: %v", err) } fd, err := os.Open(f.Name()) if err != nil { t.Fatalf("unexpected error open file: %v", err) } defer fd.Close() b, err := ioutil.ReadAll(fd) if err != nil { t.Fatalf("unexpected error read all: %v", err) } if got, exp := len(b), 5; got < exp { t.Fatalf("file size mismatch: got %v, exp %v", got, exp) } if got := binary.BigEndian.Uint32(b[0:4]); got != tsm1.MagicNumber { t.Fatalf("magic number mismatch: got %v, exp %v", got, tsm1.MagicNumber) } if _, err := fd.Seek(0, os.SEEK_SET); err != nil { t.Fatalf("error seeking: %v", err) } // Create reader for that file r, err := tsm1.NewTSMReader(fd) if err != nil { t.Fatalf("unexpected error created reader: %v", err) } f = MustTempFile(dir) w, err = tsm1.NewTSMWriter(f) if err != nil { t.Fatalf("unexpected error creating writer: %v", err) } iter := r.BlockIterator() for iter.Next() { key, minTime, maxTime, _, b, err := iter.Read() if err != nil { t.Fatalf("unexpected error reading block: %v", err) } if err := w.WriteBlock(key, minTime, maxTime, b); err != nil { t.Fatalf("unexpected error writing block: %v", err) } } if err := w.WriteIndex(); err != nil { t.Fatalf("unexpected error closing: %v", err) } if err := w.Close(); err != nil { t.Fatalf("unexpected error closing: %v", err) } fd, err = os.Open(f.Name()) if err != nil { t.Fatalf("unexpected error open file: %v", err) } // Now create a reader to verify the written blocks matches the originally // written file using Write r, err = tsm1.NewTSMReader(fd) if err != nil { t.Fatalf("unexpected error created reader: %v", err) } defer r.Close() for _, d := range data { readValues, err := r.ReadAll(d.key) if err != nil { t.Fatalf("unexpected error readin: %v", err) } if exp := len(d.values); exp != len(readValues) { t.Fatalf("read values length mismatch: got %v, exp %v", len(readValues), exp) } for i, v := range d.values { if v.Value() != readValues[i].Value() { t.Fatalf("read value mismatch(%d): got %v, exp %d", i, readValues[i].Value(), v.Value()) } } } }
func TestTSMWriter_Write_Single(t *testing.T) { dir := MustTempDir() defer os.RemoveAll(dir) f := MustTempFile(dir) w, err := tsm1.NewTSMWriter(f) if err != nil { t.Fatalf("unexpected error creating writer: %v", err) } values := []tsm1.Value{tsm1.NewValue(0, 1.0)} if err := w.Write("cpu", values); err != nil { t.Fatalf("unexpected error writing: %v", err) } if err := w.WriteIndex(); err != nil { t.Fatalf("unexpected error writing index: %v", err) } if err := w.Close(); err != nil { t.Fatalf("unexpected error closing: %v", err) } fd, err := os.Open(f.Name()) if err != nil { t.Fatalf("unexpected error open file: %v", err) } b, err := ioutil.ReadAll(fd) if err != nil { t.Fatalf("unexpected error reading: %v", err) } if got, exp := len(b), 5; got < exp { t.Fatalf("file size mismatch: got %v, exp %v", got, exp) } if got := binary.BigEndian.Uint32(b[0:4]); got != tsm1.MagicNumber { t.Fatalf("magic number mismatch: got %v, exp %v", got, tsm1.MagicNumber) } if _, err := fd.Seek(0, os.SEEK_SET); err != nil { t.Fatalf("unexpected error seeking: %v", err) } r, err := tsm1.NewTSMReader(fd) if err != nil { t.Fatalf("unexpected error created reader: %v", err) } defer r.Close() readValues, err := r.ReadAll("cpu") if err != nil { t.Fatalf("unexpected error readin: %v", err) } if len(readValues) != len(values) { t.Fatalf("read values length mismatch: got %v, exp %v", len(readValues), len(values)) } for i, v := range values { if v.Value() != readValues[i].Value() { t.Fatalf("read value mismatch(%d): got %v, exp %d", i, readValues[i].Value(), v.Value()) } } }
func TestBlockIterator_Sorted(t *testing.T) { dir := MustTempDir() defer os.RemoveAll(dir) f := MustTempFile(dir) w, err := tsm1.NewTSMWriter(f) if err != nil { t.Fatalf("unexpected error creating writer: %v", err) } values := map[string][]tsm1.Value{ "mem": []tsm1.Value{tsm1.NewValue(0, int64(1))}, "cpu": []tsm1.Value{tsm1.NewValue(1, float64(2))}, "disk": []tsm1.Value{tsm1.NewValue(1, true)}, "load": []tsm1.Value{tsm1.NewValue(1, "string")}, } for k, v := range values { if err := w.Write(k, v); err != nil { t.Fatalf("unexpected error writing: %v", err) } } if err := w.WriteIndex(); err != nil { t.Fatalf("unexpected error closing: %v", err) } if err := w.Close(); err != nil { t.Fatalf("unexpected error closing: %v", err) } fd, err := os.Open(f.Name()) if err != nil { t.Fatalf("unexpected error opening: %v", err) } r, err := tsm1.NewTSMReader(fd) if err != nil { t.Fatalf("unexpected error created reader: %v", err) } var count int iter := r.BlockIterator() var lastKey string for iter.Next() { key, _, _, _, buf, err := iter.Read() if key < lastKey { t.Fatalf("keys not sorted: got %v, last %v", key, lastKey) } lastKey = key if err != nil { t.Fatalf("unexpected error creating iterator: %v", err) } if len(buf) == 0 { t.Fatalf("buf length = 0") } count++ } if got, exp := count, len(values); got != exp { t.Fatalf("value count mismatch: got %v, exp %v", got, exp) } }
// Tests that calling Read returns all the values for block matching the key // and timestamp func TestTSMWriter_Read_Multiple(t *testing.T) { var b bytes.Buffer w, err := tsm1.NewTSMWriter(&b) if err != nil { t.Fatalf("unexpected error creating writer: %v", err) } var data = []struct { key string values []tsm1.Value }{ {"cpu", []tsm1.Value{ tsm1.NewValue(0, 1.0), tsm1.NewValue(1, 2.0)}, }, {"cpu", []tsm1.Value{ tsm1.NewValue(2, 3.0), tsm1.NewValue(3, 4.0)}, }, } for _, d := range data { if err := w.Write(d.key, d.values); err != nil { t.Fatalf("unexpected error writing: %v", err) } } if err := w.WriteIndex(); err != nil { t.Fatalf("unexpected error closing: %v", err) } if err := w.Close(); err != nil { t.Fatalf("unexpected error closing: %v", err) } r, err := tsm1.NewTSMReader(bytes.NewReader(b.Bytes())) if err != nil { t.Fatalf("unexpected error created reader: %v", err) } for _, values := range data { // Try the first timestamp readValues, err := r.Read("cpu", values.values[0].UnixNano()) if err != nil { t.Fatalf("unexpected error readin: %v", err) } if exp := len(values.values); exp != len(readValues) { t.Fatalf("read values length mismatch: got %v, exp %v", len(readValues), exp) } for i, v := range values.values { if v.Value() != readValues[i].Value() { t.Fatalf("read value mismatch(%d): got %v, exp %d", i, readValues[i].Value(), v.Value()) } } // Try the last timestamp too readValues, err = r.Read("cpu", values.values[1].UnixNano()) if err != nil { t.Fatalf("unexpected error readin: %v", err) } if exp := len(values.values); exp != len(readValues) { t.Fatalf("read values length mismatch: got %v, exp %v", len(readValues), exp) } for i, v := range values.values { if v.Value() != readValues[i].Value() { t.Fatalf("read value mismatch(%d): got %v, exp %d", i, readValues[i].Value(), v.Value()) } } } }
func TestTSMWriter_WriteBlock_Multiple(t *testing.T) { // Write a new TSM file var b bytes.Buffer w, err := tsm1.NewTSMWriter(&b) if err != nil { t.Fatalf("unexpected error creating writer: %v", err) } var data = []struct { key string values []tsm1.Value }{ {"cpu", []tsm1.Value{tsm1.NewValue(0, 1.0)}}, {"mem", []tsm1.Value{tsm1.NewValue(1, 2.0)}}, } for _, d := range data { if err := w.Write(d.key, d.values); err != nil { t.Fatalf("unexpected error writing: %v", err) } } if err := w.WriteIndex(); err != nil { t.Fatalf("unexpected error closing: %v", err) } if err := w.Close(); err != nil { t.Fatalf("unexpected error closing: %v", err) } if got, exp := len(b.Bytes()), 5; got < exp { t.Fatalf("file size mismatch: got %v, exp %v", got, exp) } if got := binary.BigEndian.Uint32(b.Bytes()[0:4]); got != tsm1.MagicNumber { t.Fatalf("magic number mismatch: got %v, exp %v", got, tsm1.MagicNumber) } // Create reader for that file r, err := tsm1.NewTSMReader(bytes.NewReader(b.Bytes())) if err != nil { t.Fatalf("unexpected error created reader: %v", err) } // Using the reader, write a new file using WriteBlocks b.Reset() w, err = tsm1.NewTSMWriter(&b) if err != nil { t.Fatalf("unexpected error creating writer: %v", err) } iter := r.BlockIterator() for iter.Next() { key, minTime, maxTime, b, err := iter.Read() if err != nil { t.Fatalf("unexpected error reading block: %v", err) } if err := w.WriteBlock(key, minTime, maxTime, b); err != nil { t.Fatalf("unexpected error writing block: %v", err) } } if err := w.WriteIndex(); err != nil { t.Fatalf("unexpected error closing: %v", err) } if err := w.Close(); err != nil { t.Fatalf("unexpected error closing: %v", err) } // Now create a reader to verify the written blocks matches the originally // written file using Write r, err = tsm1.NewTSMReader(bytes.NewReader(b.Bytes())) if err != nil { t.Fatalf("unexpected error created reader: %v", err) } for _, d := range data { readValues, err := r.ReadAll(d.key) if err != nil { t.Fatalf("unexpected error readin: %v", err) } if exp := len(d.values); exp != len(readValues) { t.Fatalf("read values length mismatch: got %v, exp %v", len(readValues), exp) } for i, v := range d.values { if v.Value() != readValues[i].Value() { t.Fatalf("read value mismatch(%d): got %v, exp %d", i, readValues[i].Value(), v.Value()) } } } }
func TestTSMReader_File_Read(t *testing.T) { dir := MustTempDir() defer os.RemoveAll(dir) f := MustTempFile(dir) defer f.Close() w, err := tsm1.NewTSMWriter(f) if err != nil { t.Fatalf("unexpected error creating writer: %v", err) } var data = []struct { key string values []tsm1.Value }{ {"float", []tsm1.Value{ tsm1.NewValue(time.Unix(1, 0), 1.0)}, }, {"int", []tsm1.Value{ tsm1.NewValue(time.Unix(1, 0), int64(1))}, }, {"bool", []tsm1.Value{ tsm1.NewValue(time.Unix(1, 0), true)}, }, {"string", []tsm1.Value{ tsm1.NewValue(time.Unix(1, 0), "foo")}, }, } for _, d := range data { if err := w.Write(d.key, d.values); err != nil { t.Fatalf("unexpected error writing: %v", err) } } if err := w.WriteIndex(); err != nil { t.Fatalf("unexpected error writing index: %v", err) } if err := w.Close(); err != nil { t.Fatalf("unexpected error closing: %v", err) } f, err = os.Open(f.Name()) if err != nil { t.Fatalf("unexpected error open file: %v", err) } r, err := tsm1.NewTSMReaderWithOptions( tsm1.TSMReaderOptions{ Reader: f, }) if err != nil { t.Fatalf("unexpected error created reader: %v", err) } defer r.Close() var count int for _, d := range data { readValues, err := r.Read(d.key, d.values[0].Time()) if err != nil { t.Fatalf("unexpected error readin: %v", err) } if exp, got := len(d.values), len(readValues); exp != got { t.Fatalf("read values length mismatch: exp %v, got %v", exp, len(readValues)) } for i, v := range d.values { if v.Value() != readValues[i].Value() { t.Fatalf("read value mismatch(%d): exp %v, got %d", i, v.Value(), readValues[i].Value()) } } count++ } if exp, got := count, len(data); exp != got { t.Fatalf("read values count mismatch: exp %v, got %v", exp, got) } }
func TestBlockIterator_Sorted(t *testing.T) { var b bytes.Buffer w, err := tsm1.NewTSMWriter(&b) if err != nil { t.Fatalf("unexpected error creating writer: %v", err) } values := map[string][]tsm1.Value{ "mem": []tsm1.Value{tsm1.NewValue(time.Unix(0, 0), int64(1))}, "cpu": []tsm1.Value{tsm1.NewValue(time.Unix(1, 0), float64(2))}, "disk": []tsm1.Value{tsm1.NewValue(time.Unix(1, 0), true)}, "load": []tsm1.Value{tsm1.NewValue(time.Unix(1, 0), "string")}, } for k, v := range values { if err := w.Write(k, v); err != nil { t.Fatalf("unexpected error writing: %v", err) } } if err := w.WriteIndex(); err != nil { t.Fatalf("unexpected error closing: %v", err) } if err := w.Close(); err != nil { t.Fatalf("unexpected error closing: %v", err) } r, err := tsm1.NewTSMReader(bytes.NewReader(b.Bytes())) if err != nil { t.Fatalf("unexpected error created reader: %v", err) } var count int iter := r.BlockIterator() var lastKey string for iter.Next() { key, _, _, buf, err := iter.Read() if key < lastKey { t.Fatalf("keys not sorted: got %v, last %v", key, lastKey) } lastKey = key if err != nil { t.Fatalf("unexpected error creating iterator: %v", err) } if len(buf) == 0 { t.Fatalf("buf length = 0") } count++ } if got, exp := count, len(values); got != exp { t.Fatalf("value count mismatch: got %v, exp %v", got, exp) } }