Last active
October 3, 2018 01:12
-
-
Save robert-milan/20d87f10456b23f297c9eb9e7d730190 to your computer and use it in GitHub Desktop.
Evict Memory Leak Testing (before and after fix) (master / cebc212)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package cache | |
import ( | |
"bytes" | |
"encoding/binary" | |
"fmt" | |
"runtime" | |
"sync" | |
"testing" | |
"time" | |
"github.com/grafana/metrictank/mdata/chunk" | |
"github.com/grafana/metrictank/test" | |
"github.com/raintank/schema" | |
) | |
// getItgen returns an IterGen which holds a chunk which has directly encoded all values | |
// it assumes the data has step=1, deriving the span as len(values) | |
func getItgen(t testing.TB, values []uint32, ts uint32, spanaware bool) chunk.IterGen { | |
var b []byte | |
buf := new(bytes.Buffer) | |
if spanaware { | |
binary.Write(buf, binary.LittleEndian, uint8(chunk.FormatStandardGoTszWithSpan)) | |
span := uint32(len(values)) | |
spanCode, ok := chunk.RevChunkSpans[span] | |
if !ok { | |
t.Fatalf("invalid chunk span provided (%d)", span) | |
} | |
binary.Write(buf, binary.LittleEndian, spanCode) | |
} else { | |
binary.Write(buf, binary.LittleEndian, uint8(chunk.FormatStandardGoTsz)) | |
} | |
for _, val := range values { | |
binary.Write(buf, binary.LittleEndian, uint32(val)) | |
} | |
buf.Write(b) | |
itgen, _ := chunk.NewGen(buf.Bytes(), ts) | |
return *itgen | |
} | |
func getConnectedChunks(t *testing.T, metric schema.AMKey) *CCache { | |
cc := NewCCache() | |
values := []uint32{1, 2, 3, 4, 5} | |
itgen1 := getItgen(t, values, 1000, false) | |
itgen2 := getItgen(t, values, 1005, false) | |
itgen3 := getItgen(t, values, 1010, false) | |
itgen4 := getItgen(t, values, 1015, false) | |
itgen5 := getItgen(t, values, 1020, false) | |
cc.Add(metric, 0, itgen1) | |
cc.Add(metric, 1000, itgen2) | |
cc.Add(metric, 1005, itgen3) | |
cc.Add(metric, 1010, itgen4) | |
cc.Add(metric, 1015, itgen5) | |
return cc | |
} | |
func printMemUsage(wg *sync.WaitGroup) { | |
var m runtime.MemStats | |
runtime.ReadMemStats(&m) | |
fmt.Printf("HeapAlloc = %v MB\t %v KB\t %v B\n", (m.HeapAlloc / 1024 / 1024), (m.HeapAlloc / 1024), m.HeapAlloc) | |
fmt.Printf("TotalAlloc = %v MB\t %v KB\t %v B\n", (m.HeapAlloc / 1024 / 1024), (m.TotalAlloc / 1024), m.HeapAlloc) | |
fmt.Printf("Sys = %v MB\t %v KB\t %v B\n", (m.Sys / 1024 / 1024), (m.Sys / 1024), m.Sys) | |
fmt.Printf("Live Heap Objects = %v\n", (m.Mallocs - m.Frees)) | |
fmt.Printf("NumGC = %v\n\n\n", m.NumGC) | |
wg.Done() | |
} | |
// test if evict has a memory leak under certain conditions | |
func TestEvictMemoryLeak(t *testing.T) { | |
wg := sync.WaitGroup{} | |
fmt.Println("Starting mem stats") | |
wg.Add(1) | |
printMemUsage(&wg) | |
wg.Wait() | |
metric1 := test.GetAMKey(1) | |
cc := NewCCache() | |
maxVals := 5 | |
values := make([]uint32, 0, maxVals) | |
for i := 1; i <= maxVals; i++ { | |
values = append(values, uint32(i)) | |
} | |
maxItgens := 50000 | |
step := 5 | |
initial := 1000 | |
maxMinusOneItgens := (maxItgens * step) + (initial - step) | |
fmt.Println("maxItgens:", maxItgens) | |
fmt.Println("") | |
itgens1 := make([]chunk.IterGen, 0, maxItgens) | |
for i := initial; i < ((maxItgens * step) + initial); i += step { | |
itgens1 = append(itgens1, getItgen(t, values, uint32(i), true)) | |
} | |
cc.AddRange(metric1, 0, itgens1) | |
runtime.GC() | |
mc, ok := cc.metricCache[metric1] | |
if !ok { | |
t.Fatal("metric doesn't exist in cc.metricCache") | |
} | |
fmt.Printf("len(mc.chunks): %v\n", len(mc.chunks)) | |
time.Sleep(3 * time.Second) | |
fmt.Println("Stats after AddRange and values allocation") | |
wg.Add(1) | |
printMemUsage(&wg) | |
wg.Wait() | |
for i := initial; i < maxMinusOneItgens; i += step { | |
mc.Del(uint32(i)) | |
} | |
fmt.Printf("len(mc.chunks): %v\n", len(mc.chunks)) | |
runtime.GC() | |
time.Sleep(3 * time.Second) | |
wg.Add(1) | |
fmt.Println("Stats after deleted most chunks") | |
printMemUsage(&wg) | |
wg.Wait() | |
for _, chnk := range mc.chunks { | |
mc.Del(chnk.Ts) | |
} | |
fmt.Printf("len(mc.chunks): %v\n", len(mc.chunks)) | |
runtime.GC() | |
time.Sleep(3 * time.Second) | |
fmt.Println("Stats after deleting all chunks") | |
wg.Add(1) | |
printMemUsage(&wg) | |
wg.Wait() | |
delete(cc.metricCache, metric1) | |
runtime.GC() | |
time.Sleep(3 * time.Second) | |
fmt.Println("Stats after deleting *CCacheMetric from *CCache") | |
wg.Add(1) | |
printMemUsage(&wg) | |
wg.Wait() | |
} | |
// test AddIfHot method without passing a previous timestamp on a hot metric | |
func TestAddIfHotWithoutPrevTsOnHotMetric(t *testing.T) { | |
metric := test.GetAMKey(1) | |
cc := NewCCache() | |
values := []uint32{1, 2, 3, 4, 5} | |
itgen1 := getItgen(t, values, 1000, false) | |
itgen2 := getItgen(t, values, 1005, false) | |
itgen3 := getItgen(t, values, 1010, false) | |
cc.Add(metric, 0, itgen1) | |
cc.Add(metric, 1000, itgen2) | |
cc.AddIfHot(metric, 0, itgen3) | |
mc := cc.metricCache[metric] | |
chunk, ok := mc.chunks[1010] | |
if !ok { | |
t.Fatalf("expected cache chunk to have been cached") | |
} | |
if itgen3.Ts != chunk.Ts { | |
t.Fatalf("cached chunk wasn't the expected one") | |
} | |
if chunk.Prev != 1005 { | |
t.Fatalf("expected cache chunk's previous ts to be 1005, but got %d", chunk.Prev) | |
} | |
if mc.chunks[chunk.Prev].Next != chunk.Ts { | |
t.Fatalf("previous cache chunk didn't point at this one as it's next, got %d", mc.chunks[chunk.Prev].Next) | |
} | |
} | |
// test AddIfHot method without passing a previous timestamp on a cold metric | |
func TestAddIfHotWithoutPrevTsOnColdMetric(t *testing.T) { | |
metric := test.GetAMKey(1) | |
cc := NewCCache() | |
values := []uint32{1, 2, 3, 4, 5} | |
itgen1 := getItgen(t, values, 1000, false) | |
itgen3 := getItgen(t, values, 1010, false) | |
cc.Add(metric, 0, itgen1) | |
cc.AddIfHot(metric, 0, itgen3) | |
mc := cc.metricCache[metric] | |
_, ok := mc.chunks[1010] | |
if ok { | |
t.Fatalf("expected cache chunk to not have been cached") | |
} | |
if mc.chunks[1000].Next != 0 { | |
t.Fatalf("previous cache chunk got wrongly connected with a following one, got %d", mc.chunks[1000].Next) | |
} | |
} | |
// test AddIfHot method on a hot metric | |
func TestAddIfHotWithPrevTsOnHotMetric(t *testing.T) { | |
metric := test.GetAMKey(1) | |
cc := NewCCache() | |
values := []uint32{1, 2, 3, 4, 5} | |
itgen1 := getItgen(t, values, 1000, false) | |
itgen2 := getItgen(t, values, 1005, false) | |
itgen3 := getItgen(t, values, 1010, false) | |
cc.Add(metric, 0, itgen1) | |
cc.Add(metric, 1000, itgen2) | |
cc.AddIfHot(metric, 1005, itgen3) | |
mc := cc.metricCache[metric] | |
chunk, ok := mc.chunks[1010] | |
if !ok { | |
t.Fatalf("expected cache chunk to have been cached") | |
} | |
if itgen3.Ts != chunk.Ts { | |
t.Fatalf("cached chunk wasn't the expected one") | |
} | |
if chunk.Prev != 1005 { | |
t.Fatalf("expected cache chunk's previous ts to be 1005, but got %d", chunk.Prev) | |
} | |
if mc.chunks[chunk.Prev].Next != chunk.Ts { | |
t.Fatalf("previous cache chunk didn't point at this one as it's next, got %d", mc.chunks[chunk.Prev].Next) | |
} | |
} | |
// test AddIfHot method on a cold metric | |
func TestAddIfHotWithPrevTsOnColdMetric(t *testing.T) { | |
metric := test.GetAMKey(1) | |
cc := NewCCache() | |
values := []uint32{1, 2, 3, 4, 5} | |
itgen1 := getItgen(t, values, 1000, false) | |
itgen3 := getItgen(t, values, 1010, false) | |
cc.Add(metric, 0, itgen1) | |
cc.AddIfHot(metric, 1005, itgen3) | |
mc := cc.metricCache[metric] | |
_, ok := mc.chunks[1010] | |
if ok { | |
t.Fatalf("expected cache chunk to not have been cached") | |
} | |
if mc.chunks[1000].Next != 0 { | |
t.Fatalf("previous cache chunk got wrongly connected with a following one, got %d", mc.chunks[1000].Next) | |
} | |
} | |
func TestConsecutiveAdding(t *testing.T) { | |
metric := test.GetAMKey(1) | |
cc := NewCCache() | |
values := []uint32{1, 2, 3, 4, 5} | |
itgen1 := getItgen(t, values, 1000, false) | |
itgen2 := getItgen(t, values, 1005, false) | |
cc.Add(metric, 0, itgen1) | |
cc.Add(metric, 1000, itgen2) | |
mc := cc.metricCache[metric] | |
chunk1, ok := mc.chunks[1000] | |
if !ok { | |
t.Fatalf("expected cache chunk 1000 not found") | |
} | |
chunk2, ok := mc.chunks[1005] | |
if !ok { | |
t.Fatalf("expected cache chunk 2000 not found") | |
} | |
if chunk1.Prev != 0 { | |
t.Fatalf("Expected previous chunk to be 0, got %d", chunk1.Prev) | |
} | |
if chunk1.Next != 1005 { | |
t.Fatalf("Expected next chunk to be 2000, got %d", chunk1.Next) | |
} | |
if chunk2.Prev != 1000 { | |
t.Fatalf("Expected previous chunk to be 1000, got %d", chunk2.Prev) | |
} | |
if chunk2.Next != 0 { | |
t.Fatalf("Expected next chunk to be 0, got %d", chunk2.Next) | |
} | |
} | |
// tests if chunks get connected to previous even if it is is not specified, based on span | |
func TestDisconnectedAdding(t *testing.T) { | |
metric := test.GetAMKey(1) | |
cc := NewCCache() | |
values := []uint32{1, 2, 3, 4, 5} | |
itgen1 := getItgen(t, values, 1000, true) | |
itgen2 := getItgen(t, values, 1005, true) | |
itgen3 := getItgen(t, values, 1010, true) | |
cc.Add(metric, 0, itgen1) | |
cc.Add(metric, 0, itgen2) | |
cc.Add(metric, 0, itgen3) | |
res, err := cc.Search(test.NewContext(), metric, 900, 1015) | |
if err != nil { | |
t.Fatalf("expected err nil, got %v", err) | |
} | |
if res.Complete { | |
t.Fatalf("complete is expected to be false") | |
} | |
if len(res.Start) != 0 { | |
t.Fatalf("expected to get 0 itergens in Start, got %d", len(res.Start)) | |
} | |
if len(res.End) != 3 { | |
t.Fatalf("expected to get 3 itergens in End, got %d", len(res.End)) | |
} | |
if res.End[0].Ts != 1010 || res.End[len(res.End)-1].Ts != 1000 { | |
t.Fatalf("result set is wrong") | |
} | |
} | |
// tests if chunks get connected to previous even if it is is not specified, | |
// basesd on a span which is the result of a guess that's based on the distance to the previous chunk | |
func TestDisconnectedAddingByGuessing(t *testing.T) { | |
metric := test.GetAMKey(1) | |
cc := NewCCache() | |
values := []uint32{1, 2, 3, 4, 5} | |
itgen1 := getItgen(t, values, 1000, false) | |
itgen2 := getItgen(t, values, 1005, false) | |
itgen3 := getItgen(t, values, 1010, false) | |
cc.Add(metric, 0, itgen1) | |
cc.Add(metric, 1000, itgen2) | |
cc.Add(metric, 0, itgen3) | |
res, err := cc.Search(test.NewContext(), metric, 900, 1015) | |
if err != nil { | |
t.Fatalf("expected err nil, got %v", err) | |
} | |
if res.Complete { | |
t.Fatalf("complete is expected to be false") | |
} | |
if len(res.Start) != 0 { | |
t.Fatalf("expected to get 0 itergens in Start, got %d", len(res.Start)) | |
} | |
if len(res.End) != 3 { | |
t.Fatalf("expected to get 3 itergens in End, got %d", len(res.End)) | |
} | |
if res.End[0].Ts != 1010 || res.End[len(res.End)-1].Ts != 1000 { | |
t.Fatalf("result set is wrong") | |
} | |
mc, ok := cc.metricCache[metric] | |
if !ok { | |
t.Fatalf("cannot find metric that should be present") | |
} | |
lastChunk, ok := mc.chunks[1010] | |
if !ok { | |
t.Fatalf("cannot find chunk that should be present") | |
} | |
if lastChunk.Prev != 1005 { | |
t.Fatalf("Add() method failed to correctly guess previous chunk") | |
} | |
} | |
func TestSearchFromBeginningComplete(t *testing.T) { | |
metric := test.GetAMKey(1) | |
cc := getConnectedChunks(t, metric) | |
res, err := cc.Search(test.NewContext(), metric, 1006, 1025) | |
if err != nil { | |
t.Fatalf("expected err nil, got %v", err) | |
} | |
if !res.Complete { | |
t.Fatalf("complete is expected to be true") | |
} | |
if len(res.Start) != 4 { | |
t.Fatalf("expected to get 4 itergens, got %d", len(res.Start)) | |
} | |
if res.Start[0].Ts != 1005 || res.Start[len(res.Start)-1].Ts != 1020 { | |
t.Fatalf("result set is wrong") | |
} | |
} | |
func TestSearchFromBeginningIncompleteEnd(t *testing.T) { | |
metric := test.GetAMKey(1) | |
cc := getConnectedChunks(t, metric) | |
res, err := cc.Search(test.NewContext(), metric, 1006, 1030) | |
if err != nil { | |
t.Fatalf("expected err nil, got %v", err) | |
} | |
if res.Complete { | |
t.Fatalf("complete is expected to be false") | |
} | |
if len(res.Start) != 4 { | |
t.Fatalf("expected to get 4 itergens, got %d", len(res.Start)) | |
} | |
if res.Start[0].Ts != 1005 || res.Start[len(res.Start)-1].Ts != 1020 { | |
t.Fatalf("result set is wrong") | |
} | |
} | |
func TestSearchFromEnd(t *testing.T) { | |
metric := test.GetAMKey(1) | |
cc := getConnectedChunks(t, metric) | |
res, err := cc.Search(test.NewContext(), metric, 500, 1025) | |
if err != nil { | |
t.Fatalf("expected err nil, got %v", err) | |
} | |
if res.Complete { | |
t.Fatalf("complete is expected to not be true") | |
} | |
if res.From != 500 { | |
t.Fatalf("From is expected to remain the original value") | |
} | |
if len(res.End) != 5 { | |
t.Fatalf("expected to get 5 itergens, got %d", len(res.End)) | |
} | |
if res.Until != 1000 { | |
t.Fatalf("Until is expected to be 1000, got %d", res.Until) | |
} | |
if res.End[0].Ts != 1020 || res.End[len(res.End)-1].Ts != 1000 { | |
t.Fatalf("result set is wrong") | |
} | |
} | |
func TestSearchDisconnectedStartEndSpanawareAscending(t *testing.T) { | |
testSearchDisconnectedStartEnd(t, true, true) | |
} | |
func TestSearchDisconnectedStartEndSpanawareDescending(t *testing.T) { | |
testSearchDisconnectedStartEnd(t, true, false) | |
} | |
func TestSearchDisconnectedStartEndNonSpanaware(t *testing.T) { | |
testSearchDisconnectedStartEnd(t, false, true) | |
} | |
func testSearchDisconnectedStartEnd(t *testing.T, spanaware, ascending bool) { | |
metric := test.GetAMKey(1) | |
values := []uint32{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} | |
itgen1 := getItgen(t, values, 1000, spanaware) | |
itgen2 := getItgen(t, values, 1010, spanaware) | |
itgen3 := getItgen(t, values, 1020, spanaware) | |
itgen4 := getItgen(t, values, 1030, spanaware) | |
itgen5 := getItgen(t, values, 1040, spanaware) | |
itgen6 := getItgen(t, values, 1050, spanaware) | |
cc := NewCCache() | |
for from := uint32(1000); from < 1010; from++ { | |
// the end of ranges is exclusive, so we go up to 1060 | |
for until := uint32(1051); until < 1061; until++ { | |
cc.Reset() | |
if ascending { | |
cc.Add(metric, 0, itgen1) | |
cc.Add(metric, 1000, itgen2) | |
cc.Add(metric, 1010, itgen3) | |
cc.Add(metric, 0, itgen4) | |
cc.Add(metric, 1030, itgen5) | |
cc.Add(metric, 1040, itgen6) | |
} else { | |
cc.Add(metric, 0, itgen6) | |
cc.Add(metric, 0, itgen5) | |
cc.Add(metric, 0, itgen4) | |
cc.Add(metric, 0, itgen3) | |
cc.Add(metric, 0, itgen2) | |
cc.Add(metric, 0, itgen1) | |
} | |
res, err := cc.Search(test.NewContext(), metric, from, until) | |
if err != nil { | |
t.Fatalf("expected err nil, got %v", err) | |
} | |
if !res.Complete { | |
t.Fatalf("from %d, until %d: complete is expected to be true", from, until) | |
} | |
if len(res.Start) != 6 { | |
t.Fatalf("from %d, until %d: expected to get %d itergens at start, got %d", from, until, 6, len(res.Start)) | |
} | |
if res.Start[0].Ts != 1000 || res.Start[len(res.Start)-1].Ts != 1050 { | |
t.Fatalf("from %d, until %d: result set at Start is wrong", from, until) | |
} | |
if res.From != 1060 { | |
t.Fatalf("from %d, until %d: expected From to be %d, got %d", from, until, 1060, res.From) | |
} | |
if len(res.End) != 0 { | |
t.Fatalf("from %d, until %d: expected to get %d itergens at end, got %d", from, until, 0, len(res.End)) | |
} | |
if res.Until != until { | |
t.Fatalf("from %d, until %d: expected Until to be %d, got %d", from, until, 1055, res.Until) | |
} | |
} | |
} | |
} | |
func TestSearchDisconnectedWithGapStartEndSpanawareAscending(t *testing.T) { | |
testSearchDisconnectedWithGapStartEnd(t, true, true) | |
} | |
func TestSearchDisconnectedWithGapStartEndSpanawareDescending(t *testing.T) { | |
testSearchDisconnectedWithGapStartEnd(t, true, false) | |
} | |
func TestSearchDisconnectedWithGapStartEndNonSpanaware(t *testing.T) { | |
testSearchDisconnectedWithGapStartEnd(t, false, true) | |
} | |
func testSearchDisconnectedWithGapStartEnd(t *testing.T, spanaware, ascending bool) { | |
metric := test.GetAMKey(1) | |
values := []uint32{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} | |
itgen1 := getItgen(t, values, 1000, spanaware) | |
itgen2 := getItgen(t, values, 1010, spanaware) | |
itgen3 := getItgen(t, values, 1020, spanaware) | |
// missing chunk | |
itgen4 := getItgen(t, values, 1040, spanaware) | |
itgen5 := getItgen(t, values, 1050, spanaware) | |
itgen6 := getItgen(t, values, 1060, spanaware) | |
cc := NewCCache() | |
for from := uint32(1000); from < 1010; from++ { | |
// the end of ranges is exclusive, so we go up to 1060 | |
for until := uint32(1061); until < 1071; until++ { | |
cc.Reset() | |
if ascending { | |
cc.Add(metric, 0, itgen1) | |
cc.Add(metric, 1000, itgen2) | |
cc.Add(metric, 1010, itgen3) | |
cc.Add(metric, 0, itgen4) | |
cc.Add(metric, 1040, itgen5) | |
cc.Add(metric, 1050, itgen6) | |
} else { | |
cc.Add(metric, 0, itgen6) | |
cc.Add(metric, 0, itgen5) | |
cc.Add(metric, 0, itgen4) | |
cc.Add(metric, 0, itgen3) | |
cc.Add(metric, 0, itgen2) | |
cc.Add(metric, 0, itgen1) | |
} | |
res, err := cc.Search(test.NewContext(), metric, from, until) | |
if err != nil { | |
t.Fatalf("expected err nil, got %v", err) | |
} | |
if res.Complete { | |
t.Fatalf("from %d, until %d: complete is expected to be false", from, until) | |
} | |
if len(res.Start) != 3 { | |
t.Fatalf("from %d, until %d: expected to get 3 itergens at start, got %d", from, until, len(res.Start)) | |
} | |
if res.Start[0].Ts != 1000 || res.Start[len(res.Start)-1].Ts != 1020 { | |
t.Fatalf("from %d, until %d: result set at Start is wrong", from, until) | |
} | |
if res.From != 1030 { | |
t.Fatalf("from %d, until %d: expected From to be %d but got %d", from, until, 1030, res.From) | |
} | |
if len(res.End) != 3 { | |
t.Fatalf("from %d, until %d: expected to get 3 itergens at end, got %d", from, until, len(res.End)) | |
} | |
if res.End[0].Ts != 1060 || res.End[len(res.End)-1].Ts != 1040 { | |
t.Fatalf("from %d, until %d: result set at End is wrong", from, until) | |
} | |
if res.Until != 1040 { | |
t.Fatalf("from %d, until %d: expected Until to be %d but got %d", from, until, 1030, res.Until) | |
} | |
} | |
} | |
} | |
func TestReset(t *testing.T) { | |
cc := NewCCache() | |
// .Reset() is being called at the end of testMetricDelete() | |
testMetricDelete(t, cc) | |
testMetricDelete(t, cc) | |
testMetricDelete(t, cc) | |
} | |
func TestMetricDelete(t *testing.T) { | |
cc := NewCCache() | |
testMetricDelete(t, cc) | |
} | |
func testMetricDelete(t *testing.T, cc *CCache) { | |
rawMetric1 := test.GetAMKey(1) | |
metric1_1 := schema.GetAMKey(rawMetric1.MKey, schema.Cnt, 600) | |
metric1_2 := schema.GetAMKey(rawMetric1.MKey, schema.Sum, 600) | |
rawMetric2 := test.GetMKey(2) | |
metric2_1 := schema.GetAMKey(rawMetric2, schema.Cnt, 6000) | |
values := []uint32{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} | |
itgenCount := 10 | |
itgens := make([]chunk.IterGen, 0, itgenCount) | |
for i := 1000; i < 1000+itgenCount*len(values); i = i + len(values) { | |
itgens = append(itgens, getItgen(t, values, uint32(i), true)) | |
} | |
// add two metrics with itgenCount chunks each | |
for _, itgen := range itgens { | |
cc.Add(metric1_1, 0, itgen) | |
cc.Add(metric1_2, 0, itgen) | |
cc.Add(metric2_1, 0, itgen) | |
} | |
// check if Search returns them all for metric1_1 | |
res, err := cc.Search(test.NewContext(), metric1_1, 1000, uint32(1000+itgenCount*len(values))) | |
if err != nil { | |
t.Fatalf("expected err nil, got %v", err) | |
} | |
if len(res.Start) != itgenCount { | |
t.Fatalf("Expected to have %d values, got %d", itgenCount, len(res.Start)) | |
} | |
// check if Search returns them all for metric1_2 | |
res, err = cc.Search(test.NewContext(), metric1_2, 1000, uint32(1000+itgenCount*len(values))) | |
if err != nil { | |
t.Fatalf("expected err nil, got %v", err) | |
} | |
if len(res.Start) != itgenCount { | |
t.Fatalf("Expected to have %d values, got %d", itgenCount, len(res.Start)) | |
} | |
// check if Search returns them all for metric2_1 | |
res, err = cc.Search(test.NewContext(), metric2_1, 1000, uint32(1000+itgenCount*len(values))) | |
if err != nil { | |
t.Fatalf("expected err nil, got %v", err) | |
} | |
if len(res.Start) != itgenCount { | |
t.Fatalf("Expected to have %d values, got %d", itgenCount, len(res.Start)) | |
} | |
// now delete metric1_1, but leave metric2_1 | |
delSeries, delArchives := cc.DelMetric(rawMetric1.MKey) | |
expectDelSeries := 1 | |
if delSeries != expectDelSeries { | |
t.Fatalf("Expected exactly %d deleted series, but got %d", expectDelSeries, delSeries) | |
} | |
expectDelArchives := 2 | |
if delArchives != expectDelArchives { | |
t.Fatalf("Expected exactly %d deleted archives, but got %d", expectDelArchives, delArchives) | |
} | |
// check if metric1_1 returns no results anymore | |
res, err = cc.Search(test.NewContext(), metric1_1, 1000, uint32(1000+itgenCount*len(values))) | |
if err != nil { | |
t.Fatalf("expected err nil, got %v", err) | |
} | |
if len(res.Start) != 0 { | |
t.Fatalf("Expected to have %d values, got %d", 0, len(res.Start)) | |
} | |
// check if metric1_2 returns no results anymore | |
res, err = cc.Search(test.NewContext(), metric1_2, 1000, uint32(1000+itgenCount*len(values))) | |
if err != nil { | |
t.Fatalf("expected err nil, got %v", err) | |
} | |
if len(res.Start) != 0 { | |
t.Fatalf("Expected to have %d values, got %d", 0, len(res.Start)) | |
} | |
// but metric2_1 should still be there | |
res, err = cc.Search(test.NewContext(), metric2_1, 1000, uint32(1000+itgenCount*len(values))) | |
if err != nil { | |
t.Fatalf("expected err nil, got %v", err) | |
} | |
if len(res.Start) != itgenCount { | |
t.Fatalf("Expected to have %d values, got %d", itgenCount, len(res.Start)) | |
} | |
// now add metric1_1 and metric1_2 again | |
for _, itgen := range itgens { | |
cc.Add(metric1_1, 0, itgen) | |
cc.Add(metric1_2, 0, itgen) | |
} | |
// and check if it gets returned by Search again | |
res, err = cc.Search(test.NewContext(), metric1_1, 1000, uint32(1000+itgenCount*len(values))) | |
if err != nil { | |
t.Fatalf("expected err nil, got %v", err) | |
} | |
if len(res.Start) != itgenCount { | |
t.Fatalf("Expected to have %d values, got %d", itgenCount, len(res.Start)) | |
} | |
// now reset the whole metric cache | |
delSeries, delArchives = cc.Reset() | |
expectDelSeries = 2 | |
if delSeries != expectDelSeries { | |
t.Fatalf("Expected exactly deleted %d series, but got %d", expectDelSeries, delSeries) | |
} | |
expectDelArchives = 3 | |
if delArchives != expectDelArchives { | |
t.Fatalf("Expected exactly deleted %d archives, but got %d", expectDelArchives, delArchives) | |
} | |
// check if metric1_1 returns no results anymore | |
res, err = cc.Search(test.NewContext(), metric1_1, 1000, uint32(1000+itgenCount*len(values))) | |
if err != nil { | |
t.Fatalf("expected err nil, got %v", err) | |
} | |
if len(res.Start) != 0 { | |
t.Fatalf("Expected to have %d values, got %d", 0, len(res.Start)) | |
} | |
// check if metric1_1 returns no results anymore | |
res, err = cc.Search(test.NewContext(), metric1_2, 1000, uint32(1000+itgenCount*len(values))) | |
if err != nil { | |
t.Fatalf("expected err nil, got %v", err) | |
} | |
if len(res.Start) != 0 { | |
t.Fatalf("Expected to have %d values, got %d", 0, len(res.Start)) | |
} | |
// check if metric2_1 returns no results anymore | |
res, err = cc.Search(test.NewContext(), metric2_1, 1000, uint32(1000+itgenCount*len(values))) | |
if err != nil { | |
t.Fatalf("expected err nil, got %v", err) | |
} | |
if len(res.Start) != 0 { | |
t.Fatalf("Expected to have %d values, got %d", 0, len(res.Start)) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
=== RUN TestEvictMemoryLeak | |
Starting mem stats | |
HeapAlloc = 1 MB 1502 KB 1538616 B | |
TotalAlloc = 1 MB 1502 KB 1538616 B | |
Sys = 68 MB 69694 KB 71366904 B | |
Live Heap Objects = 1189 | |
NumGC = 0 | |
maxItgens: 50000 | |
len(mc.chunks): 50000 | |
Stats after AddRange and values allocation | |
HeapAlloc = 23 MB 24474 KB 25062304 B | |
TotalAlloc = 23 MB 30823 KB 25062304 B | |
Sys = 68 MB 70142 KB 71825656 B | |
Live Heap Objects = 205693 | |
NumGC = 4 | |
len(mc.chunks): 1 | |
Stats after deleted most chunks | |
HeapAlloc = 13 MB 13387 KB 13709216 B | |
TotalAlloc = 13 MB 5093251 KB 13709216 B | |
Sys = 68 MB 70654 KB 72349944 B | |
Live Heap Objects = 103587 | |
NumGC = 298 | |
len(mc.chunks): 0 | |
Stats after deleting all chunks | |
HeapAlloc = 13 MB 13387 KB 13709032 B | |
TotalAlloc = 13 MB 5093252 KB 13709032 B | |
Sys = 68 MB 70654 KB 72349944 B | |
Live Heap Objects = 103583 | |
NumGC = 299 | |
Stats after deleting *CCacheMetric from *CCache | |
HeapAlloc = 12 MB 12346 KB 12642648 B | |
TotalAlloc = 12 MB 5093253 KB 12642648 B | |
Sys = 68 MB 70654 KB 72349944 B | |
Live Heap Objects = 102763 | |
NumGC = 300 | |
--- PASS: TestEvictMemoryLeak (256.52s) | |
PASS | |
ok github.com/grafana/metrictank/mdata/cache 256.540s | |
************************************************************************************************* | |
=== RUN TestEvictMemoryLeak | |
Starting mem stats | |
HeapAlloc = 1 MB 1501 KB 1537712 B | |
TotalAlloc = 1 MB 1501 KB 1537712 B | |
Sys = 68 MB 69694 KB 71366904 B | |
Live Heap Objects = 1190 | |
NumGC = 0 | |
maxItgens: 50000 | |
len(mc.chunks): 50000 | |
Stats after AddRange and values allocation | |
HeapAlloc = 23 MB 24497 KB 25085064 B | |
TotalAlloc = 23 MB 30843 KB 25085064 B | |
Sys = 68 MB 70398 KB 72087800 B | |
Live Heap Objects = 205773 | |
NumGC = 4 | |
len(mc.chunks): 1 | |
Stats after deleted most chunks | |
HeapAlloc = 13 MB 13396 KB 13718088 B | |
TotalAlloc = 13 MB 5093273 KB 13718088 B | |
Sys = 68 MB 70654 KB 72349944 B | |
Live Heap Objects = 103608 | |
NumGC = 298 | |
len(mc.chunks): 0 | |
Stats after deleting all chunks | |
HeapAlloc = 13 MB 13396 KB 13717976 B | |
TotalAlloc = 13 MB 5093274 KB 13717976 B | |
Sys = 68 MB 70654 KB 72349944 B | |
Live Heap Objects = 103606 | |
NumGC = 299 | |
Stats after deleting *CCacheMetric from *CCache | |
HeapAlloc = 12 MB 12357 KB 12653848 B | |
TotalAlloc = 12 MB 5093275 KB 12653848 B | |
Sys = 68 MB 70654 KB 72349944 B | |
Live Heap Objects = 102807 | |
NumGC = 300 | |
--- PASS: TestEvictMemoryLeak (255.20s) | |
PASS | |
ok github.com/grafana/metrictank/mdata/cache 255.326s | |
************************************************************************************************* | |
=== RUN TestEvictMemoryLeak | |
Starting mem stats | |
HeapAlloc = 1 MB 1500 KB 1536352 B | |
TotalAlloc = 1 MB 1500 KB 1536352 B | |
Sys = 68 MB 69694 KB 71366904 B | |
Live Heap Objects = 1181 | |
NumGC = 0 | |
maxItgens: 50000 | |
len(mc.chunks): 50000 | |
Stats after AddRange and values allocation | |
HeapAlloc = 23 MB 24481 KB 25069016 B | |
TotalAlloc = 23 MB 30831 KB 25069016 B | |
Sys = 68 MB 70654 KB 72349944 B | |
Live Heap Objects = 205713 | |
NumGC = 4 | |
len(mc.chunks): 1 | |
Stats after deleted most chunks | |
HeapAlloc = 13 MB 13353 KB 13673968 B | |
TotalAlloc = 13 MB 5093225 KB 13673968 B | |
Sys = 68 MB 70654 KB 72349944 B | |
Live Heap Objects = 103598 | |
NumGC = 298 | |
len(mc.chunks): 0 | |
Stats after deleting all chunks | |
HeapAlloc = 13 MB 13353 KB 13673792 B | |
TotalAlloc = 13 MB 5093226 KB 13673792 B | |
Sys = 68 MB 70654 KB 72349944 B | |
Live Heap Objects = 103595 | |
NumGC = 299 | |
Stats after deleting *CCacheMetric from *CCache | |
HeapAlloc = 12 MB 12308 KB 12604160 B | |
TotalAlloc = 12 MB 5093227 KB 12604160 B | |
Sys = 68 MB 70654 KB 72349944 B | |
Live Heap Objects = 102746 | |
NumGC = 300 | |
--- PASS: TestEvictMemoryLeak (248.36s) | |
PASS | |
ok github.com/grafana/metrictank/mdata/cache 248.379s | |
************************************************************************************************* | |
=== RUN TestEvictMemoryLeak | |
Starting mem stats | |
HeapAlloc = 1 MB 1500 KB 1536336 B | |
TotalAlloc = 1 MB 1500 KB 1536336 B | |
Sys = 68 MB 69694 KB 71366904 B | |
Live Heap Objects = 1186 | |
NumGC = 0 | |
maxItgens: 50000 | |
len(mc.chunks): 50000 | |
Stats after AddRange and values allocation | |
HeapAlloc = 23 MB 24475 KB 25063000 B | |
TotalAlloc = 23 MB 30821 KB 25063000 B | |
Sys = 68 MB 70398 KB 72087800 B | |
Live Heap Objects = 205657 | |
NumGC = 4 | |
len(mc.chunks): 1 | |
Stats after deleted most chunks | |
HeapAlloc = 13 MB 13370 KB 13691192 B | |
TotalAlloc = 13 MB 5093235 KB 13691192 B | |
Sys = 68 MB 70654 KB 72349944 B | |
Live Heap Objects = 103548 | |
NumGC = 297 | |
len(mc.chunks): 0 | |
Stats after deleting all chunks | |
HeapAlloc = 13 MB 13370 KB 13691016 B | |
TotalAlloc = 13 MB 5093236 KB 13691016 B | |
Sys = 68 MB 70654 KB 72349944 B | |
Live Heap Objects = 103545 | |
NumGC = 298 | |
Stats after deleting *CCacheMetric from *CCache | |
HeapAlloc = 12 MB 12326 KB 12622728 B | |
TotalAlloc = 12 MB 5093236 KB 12622728 B | |
Sys = 68 MB 70654 KB 72349944 B | |
Live Heap Objects = 102708 | |
NumGC = 299 | |
--- PASS: TestEvictMemoryLeak (251.36s) | |
PASS | |
ok github.com/grafana/metrictank/mdata/cache 251.379s |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
=== RUN TestEvictMemoryLeak | |
Starting mem stats | |
HeapAlloc = 1 MB 1501 KB 1537296 B | |
TotalAlloc = 1 MB 1501 KB 1537296 B | |
Sys = 68 MB 69694 KB 71366904 B | |
Live Heap Objects = 1181 | |
NumGC = 0 | |
maxItgens: 50000 | |
len(mc.chunks): 50000 | |
Stats after AddRange and values allocation | |
HeapAlloc = 23 MB 24462 KB 25049264 B | |
TotalAlloc = 23 MB 30809 KB 25049264 B | |
Sys = 68 MB 70398 KB 72087800 B | |
Live Heap Objects = 155605 | |
NumGC = 4 | |
len(mc.chunks): 1 | |
Stats after deleted most chunks | |
HeapAlloc = 20 MB 21203 KB 21712592 B | |
TotalAlloc = 20 MB 5093243 KB 21712592 B | |
Sys = 68 MB 70654 KB 72349944 B | |
Live Heap Objects = 153552 | |
NumGC = 260 | |
len(mc.chunks): 0 | |
Stats after deleting all chunks | |
HeapAlloc = 13 MB 13390 KB 13712336 B | |
TotalAlloc = 13 MB 5093244 KB 13712336 B | |
Sys = 68 MB 70654 KB 72349944 B | |
Live Heap Objects = 103551 | |
NumGC = 261 | |
Stats after deleting *CCacheMetric from *CCache | |
HeapAlloc = 12 MB 12346 KB 12642808 B | |
TotalAlloc = 12 MB 5093245 KB 12642808 B | |
Sys = 68 MB 70654 KB 72349944 B | |
Live Heap Objects = 102702 | |
NumGC = 262 | |
--- PASS: TestEvictMemoryLeak (260.05s) | |
PASS | |
ok github.com/grafana/metrictank/mdata/cache 260.074s | |
************************************************************************************************* | |
=== RUN TestEvictMemoryLeak | |
Starting mem stats | |
HeapAlloc = 1 MB 1500 KB 1536960 B | |
TotalAlloc = 1 MB 1500 KB 1536960 B | |
Sys = 68 MB 69694 KB 71366904 B | |
Live Heap Objects = 1182 | |
NumGC = 0 | |
maxItgens: 50000 | |
len(mc.chunks): 50000 | |
Stats after AddRange and values allocation | |
HeapAlloc = 23 MB 24205 KB 24786424 B | |
TotalAlloc = 23 MB 30837 KB 24786424 B | |
Sys = 68 MB 70398 KB 72087800 B | |
Live Heap Objects = 155464 | |
NumGC = 4 | |
len(mc.chunks): 1 | |
Stats after deleted most chunks | |
HeapAlloc = 20 MB 21187 KB 21696400 B | |
TotalAlloc = 20 MB 5093252 KB 21696400 B | |
Sys = 68 MB 70654 KB 72349944 B | |
Live Heap Objects = 153587 | |
NumGC = 260 | |
len(mc.chunks): 0 | |
Stats after deleting all chunks | |
HeapAlloc = 13 MB 13375 KB 13696120 B | |
TotalAlloc = 13 MB 5093253 KB 13696120 B | |
Sys = 68 MB 70654 KB 72349944 B | |
Live Heap Objects = 103584 | |
NumGC = 261 | |
Stats after deleting *CCacheMetric from *CCache | |
HeapAlloc = 12 MB 12330 KB 12626904 B | |
TotalAlloc = 12 MB 5093254 KB 12626904 B | |
Sys = 68 MB 70654 KB 72349944 B | |
Live Heap Objects = 102740 | |
NumGC = 262 | |
--- PASS: TestEvictMemoryLeak (257.12s) | |
PASS | |
ok github.com/grafana/metrictank/mdata/cache 257.138s | |
************************************************************************************************* | |
=== RUN TestEvictMemoryLeak | |
Starting mem stats | |
HeapAlloc = 1 MB 1501 KB 1537488 B | |
TotalAlloc = 1 MB 1501 KB 1537488 B | |
Sys = 68 MB 69694 KB 71366904 B | |
Live Heap Objects = 1193 | |
NumGC = 0 | |
maxItgens: 50000 | |
len(mc.chunks): 50000 | |
Stats after AddRange and values allocation | |
HeapAlloc = 23 MB 24482 KB 25070432 B | |
TotalAlloc = 23 MB 30828 KB 25070432 B | |
Sys = 68 MB 70398 KB 72087800 B | |
Live Heap Objects = 155676 | |
NumGC = 4 | |
len(mc.chunks): 1 | |
Stats after deleted most chunks | |
HeapAlloc = 20 MB 21225 KB 21735168 B | |
TotalAlloc = 20 MB 5093274 KB 21735168 B | |
Sys = 68 MB 70654 KB 72349944 B | |
Live Heap Objects = 153590 | |
NumGC = 260 | |
len(mc.chunks): 0 | |
Stats after deleting all chunks | |
HeapAlloc = 13 MB 13412 KB 13734896 B | |
TotalAlloc = 13 MB 5093275 KB 13734896 B | |
Sys = 68 MB 70654 KB 72349944 B | |
Live Heap Objects = 103588 | |
NumGC = 261 | |
Stats after deleting *CCacheMetric from *CCache | |
HeapAlloc = 12 MB 12372 KB 12669408 B | |
TotalAlloc = 12 MB 5093276 KB 12669408 B | |
Sys = 68 MB 70654 KB 72349944 B | |
Live Heap Objects = 102776 | |
NumGC = 262 | |
--- PASS: TestEvictMemoryLeak (256.27s) | |
PASS | |
ok github.com/grafana/metrictank/mdata/cache 256.301s | |
************************************************************************************************* | |
=== RUN TestEvictMemoryLeak | |
Starting mem stats | |
HeapAlloc = 1 MB 1501 KB 1537144 B | |
TotalAlloc = 1 MB 1501 KB 1537144 B | |
Sys = 68 MB 69694 KB 71366904 B | |
Live Heap Objects = 1187 | |
NumGC = 0 | |
maxItgens: 50000 | |
len(mc.chunks): 50000 | |
Stats after AddRange and values allocation | |
HeapAlloc = 23 MB 24471 KB 25058712 B | |
TotalAlloc = 23 MB 30817 KB 25058712 B | |
Sys = 68 MB 70398 KB 72087800 B | |
Live Heap Objects = 155612 | |
NumGC = 4 | |
len(mc.chunks): 1 | |
Stats after deleted most chunks | |
HeapAlloc = 20 MB 21202 KB 21711304 B | |
TotalAlloc = 20 MB 5093244 KB 21711304 B | |
Sys = 68 MB 70654 KB 72349944 B | |
Live Heap Objects = 153558 | |
NumGC = 260 | |
len(mc.chunks): 0 | |
Stats after deleting all chunks | |
HeapAlloc = 13 MB 13389 KB 13711024 B | |
TotalAlloc = 13 MB 5093244 KB 13711024 B | |
Sys = 68 MB 70654 KB 72349944 B | |
Live Heap Objects = 103555 | |
NumGC = 261 | |
Stats after deleting *CCacheMetric from *CCache | |
HeapAlloc = 12 MB 12349 KB 12645536 B | |
TotalAlloc = 12 MB 5093245 KB 12645536 B | |
Sys = 68 MB 70654 KB 72349944 B | |
Live Heap Objects = 102743 | |
NumGC = 262 | |
--- PASS: TestEvictMemoryLeak (257.20s) | |
PASS | |
ok github.com/grafana/metrictank/mdata/cache 257.217s |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment