@ -57,35 +57,42 @@ var (
} {
{
headBlockFmt : OrderedHeadBlockFmt ,
chunkFormat : c hunkFormatV2,
chunkFormat : C hunkFormatV2,
} ,
{
headBlockFmt : OrderedHeadBlockFmt ,
chunkFormat : c hunkFormatV3,
chunkFormat : C hunkFormatV3,
} ,
{
headBlockFmt : UnorderedHeadBlockFmt ,
chunkFormat : c hunkFormatV3,
chunkFormat : C hunkFormatV3,
} ,
{
headBlockFmt : UnorderedWithNonIndexedLabelsHeadBlockFmt ,
chunkFormat : c hunkFormatV4,
chunkFormat : C hunkFormatV4,
} ,
}
)
const DefaultTestHeadBlockFmt = Default HeadBlockFmt
const DefaultTestHeadBlockFmt = UnorderedWithNonIndexedLabels HeadBlockFmt
func TestBlocksInclusive ( t * testing . T ) {
chk := NewMemChunk ( EncNone , DefaultTestHeadBlockFmt , testBlockSize , testTargetSize )
err := chk . Append ( logprotoEntry ( 1 , "1" ) )
require . Nil ( t , err )
err = chk . cut ( )
require . Nil ( t , err )
for _ , enc := range testEncoding {
enc := enc
for _ , format := range allPossibleFormats {
chunkfmt , headfmt := format . chunkFormat , format . headBlockFmt
chk := NewMemChunk ( chunkfmt , enc , headfmt , testBlockSize , testTargetSize )
err := chk . Append ( logprotoEntry ( 1 , "1" ) )
require . Nil ( t , err )
err = chk . cut ( )
require . Nil ( t , err )
blocks := chk . Blocks ( time . Unix ( 0 , 1 ) , time . Unix ( 0 , 1 ) )
require . Equal ( t , 1 , len ( blocks ) )
require . Equal ( t , 1 , blocks [ 0 ] . Entries ( ) )
}
}
blocks := chk . Blocks ( time . Unix ( 0 , 1 ) , time . Unix ( 0 , 1 ) )
require . Equal ( t , 1 , len ( blocks ) )
require . Equal ( t , 1 , blocks [ 0 ] . Entries ( ) )
}
func TestBlock ( t * testing . T ) {
@ -182,7 +189,7 @@ func TestBlock(t *testing.T) {
require . Equal ( t , cases [ idx ] . ts , e . Timestamp . UnixNano ( ) )
require . Equal ( t , cases [ idx ] . str , e . Line )
require . Empty ( t , e . NonIndexedLabels )
if chunkFormat < c hunkFormatV4 {
if chunkFormat < C hunkFormatV4 {
require . Equal ( t , labels . EmptyLabels ( ) . String ( ) , it . Labels ( ) )
} else {
expectedLabels := logproto . FromLabelAdaptersToLabels ( cases [ idx ] . lbs ) . String ( )
@ -240,43 +247,47 @@ func TestBlock(t *testing.T) {
func TestCorruptChunk ( t * testing . T ) {
for _ , enc := range testEncoding {
enc := enc
t . Run ( enc . String ( ) , func ( t * testing . T ) {
t . Parallel ( )
for _ , format := range allPossibleFormats {
chunkfmt , headfmt := format . chunkFormat , format . headBlockFmt
chk := NewMemChunk ( enc , DefaultTestHeadBlockFmt , testBlockSize , testTargetSize )
cases := [ ] struct {
data [ ] byte
} {
// Data that should not decode as lines from a chunk in any encoding.
{ data : [ ] byte { 0 } } ,
{ data : [ ] byte { 1 } } ,
{ data : [ ] byte ( "asdfasdfasdfqwyteqwtyeq" ) } ,
}
t . Run ( enc . String ( ) , func ( t * testing . T ) {
t . Parallel ( )
chk := NewMemChunk ( chunkfmt , enc , headfmt , testBlockSize , testTargetSize )
cases := [ ] struct {
data [ ] byte
} {
// Data that should not decode as lines from a chunk in any encoding.
{ data : [ ] byte { 0 } } ,
{ data : [ ] byte { 1 } } ,
{ data : [ ] byte ( "asdfasdfasdfqwyteqwtyeq" ) } ,
}
ctx , start , end := context . Background ( ) , time . Unix ( 0 , 0 ) , time . Unix ( 0 , math . MaxInt64 )
for i , c := range cases {
chk . blocks = [ ] block { { b : c . data } }
it , err := chk . Iterator ( ctx , start , end , logproto . FORWARD , noopStreamPipeline )
require . NoError ( t , err , "case %d" , i )
ctx , start , end := context . Background ( ) , time . Unix ( 0 , 0 ) , time . Unix ( 0 , math . MaxInt64 )
for i , c := range cases {
chk . blocks = [ ] block { { b : c . data } }
it , err := chk . Iterator ( ctx , start , end , logproto . FORWARD , noopStreamPipeline )
require . NoError ( t , err , "case %d" , i )
idx := 0
for it . Next ( ) {
idx ++
idx := 0
for it . Next ( ) {
idx ++
}
require . Error ( t , it . Error ( ) , "case %d" , i )
require . NoError ( t , it . Close ( ) )
}
require . Error ( t , it . Error ( ) , "case %d" , i )
require . NoError ( t , it . Close ( ) )
}
} )
} )
}
}
}
func TestReadFormatV1 ( t * testing . T ) {
t . Parallel ( )
c := NewMemChunk ( EncGZIP , DefaultTestHeadBlockFmt , testBlockSize , testTargetSize )
c := NewMemChunk ( ChunkFormatV3 , EncGZIP , DefaultTestHeadBlockFmt , testBlockSize , testTargetSize )
fillChunk ( c )
// overrides default v2 format
c . format = c hunkFormatV1
// overrides to v1 for testing that specific version.
c . format = C hunkFormatV1
b , err := c . Bytes ( )
if err != nil {
@ -369,14 +380,14 @@ func testNameWithFormats(enc Encoding, chunkFormat byte, headBlockFmt HeadBlockF
}
func TestRoundtripV3 ( t * testing . T ) {
for _ , f := range HeadBlockFmts {
for _ , enc := range testEncoding {
enc := enc
t . Run ( fmt . Sprintf ( "%v-%v" , f , enc ) , func ( t * testing . T ) {
for _ , enc := range testEncoding {
enc := enc
for _ , format := range allPossibleFormats {
chunkfmt , headfmt := format . chunkFormat , format . headBlockFmt
t . Run ( fmt . Sprintf ( "%v-%v" , format , enc ) , func ( t * testing . T ) {
t . Parallel ( )
c := NewMemChunk ( enc , f , testBlockSize , testTargetSize )
c . format = chunkFormatV3
c := NewMemChunk ( chunkfmt , enc , headfmt , testBlockSize , testTargetSize )
_ = fillChunk ( c )
b , err := c . Bytes ( )
@ -408,7 +419,7 @@ func TestSerialization(t *testing.T) {
t . Run ( testName , func ( t * testing . T ) {
t . Parallel ( )
chk := NewMemChunk ( enc , testData . headBlockFmt , testBlockSize , testTargetSize )
chk := NewMemChunk ( testData . chunkFormat , enc , testData . headBlockFmt , testBlockSize , testTargetSize )
chk . format = testData . chunkFormat
numSamples := 50000
var entry * logproto . Entry
@ -437,7 +448,7 @@ func TestSerialization(t *testing.T) {
require . Equal ( t , int64 ( i ) , e . Timestamp . UnixNano ( ) )
require . Equal ( t , strconv . Itoa ( i ) , e . Line )
require . Nil ( t , e . NonIndexedLabels )
if appendWithNonIndexedLabels && testData . chunkFormat >= c hunkFormatV4 {
if appendWithNonIndexedLabels && testData . chunkFormat >= C hunkFormatV4 {
require . Equal ( t , labels . FromStrings ( "foo" , strconv . Itoa ( i ) ) . String ( ) , it . Labels ( ) )
} else {
require . Equal ( t , labels . EmptyLabels ( ) . String ( ) , it . Labels ( ) )
@ -460,7 +471,7 @@ func TestSerialization(t *testing.T) {
s := sampleIt . Sample ( )
require . Equal ( t , int64 ( i ) , s . Timestamp )
require . Equal ( t , 1. , s . Value )
if appendWithNonIndexedLabels && testData . chunkFormat >= c hunkFormatV4 {
if appendWithNonIndexedLabels && testData . chunkFormat >= C hunkFormatV4 {
require . Equal ( t , labels . FromStrings ( "foo" , strconv . Itoa ( i ) ) . String ( ) , sampleIt . Labels ( ) )
} else {
require . Equal ( t , labels . EmptyLabels ( ) . String ( ) , sampleIt . Labels ( ) )
@ -525,7 +536,7 @@ func TestChunkFilling(t *testing.T) {
func TestGZIPChunkTargetSize ( t * testing . T ) {
t . Parallel ( )
chk := NewMemChunk ( EncGZIP , DefaultTestHeadBlockFmt , testBlockSize , testTargetSize )
chk := NewMemChunk ( ChunkFormatV3 , EncGZIP , DefaultTestHeadBlockFmt , testBlockSize , testTargetSize )
lineSize := 512
entry := & logproto . Entry {
@ -622,7 +633,7 @@ func TestMemChunk_AppendOutOfOrder(t *testing.T) {
t . Run ( testName , func ( t * testing . T ) {
t . Parallel ( )
tester ( t , NewMemChunk ( EncGZIP , f , testBlockSize , testTargetSize ) )
tester ( t , NewMemChunk ( ChunkFormatV3 , EncGZIP , f , testBlockSize , testTargetSize ) )
} )
}
}
@ -667,7 +678,7 @@ func TestChunkSize(t *testing.T) {
}
func TestChunkStats ( t * testing . T ) {
c := NewMemChunk ( EncSnappy , DefaultTestHeadBlockFmt , testBlockSize , 0 )
c := NewMemChunk ( ChunkFormatV4 , EncSnappy , DefaultTestHeadBlockFmt , testBlockSize , 0 )
first := time . Now ( )
entry := & logproto . Entry {
Timestamp : first ,
@ -793,7 +804,7 @@ func BenchmarkWrite(b *testing.B) {
b . Run ( name , func ( b * testing . B ) {
uncompressedBytes , compressedBytes := 0 , 0
for n := 0 ; n < b . N ; n ++ {
c := NewMemChunk ( enc , f , testBlockSize , testTargetSize )
c := NewMemChunk ( ChunkFormatV3 , enc , f , testBlockSize , testTargetSize )
// adds until full so we trigger cut which serialize using gzip
for c . SpaceFor ( entry ) {
_ = c . Append ( entry )
@ -885,7 +896,7 @@ func BenchmarkBackwardIterator(b *testing.B) {
for _ , bs := range testBlockSizes {
b . Run ( humanize . Bytes ( uint64 ( bs ) ) , func ( b * testing . B ) {
b . ReportAllocs ( )
c := NewMemChunk ( EncSnappy , DefaultTestHeadBlockFmt , bs , testTargetSize )
c := NewMemChunk ( ChunkFormatV3 , EncSnappy , DefaultTestHeadBlockFmt , bs , testTargetSize )
_ = fillChunk ( c )
b . ResetTimer ( )
for n := 0 ; n < b . N ; n ++ {
@ -996,7 +1007,7 @@ func BenchmarkHeadBlockSampleIterator(b *testing.B) {
func TestMemChunk_IteratorBounds ( t * testing . T ) {
createChunk := func ( ) * MemChunk {
t . Helper ( )
c := NewMemChunk ( EncNone , DefaultTestHeadBlockFmt , 1e6 , 1e6 )
c := NewMemChunk ( ChunkFormatV3 , EncNone , DefaultTestHeadBlockFmt , 1e6 , 1e6 )
if err := c . Append ( & logproto . Entry {
Timestamp : time . Unix ( 0 , 1 ) ,
@ -1060,7 +1071,7 @@ func TestMemchunkLongLine(t *testing.T) {
t . Run ( enc . String ( ) , func ( t * testing . T ) {
t . Parallel ( )
c := NewMemChunk ( enc , DefaultTestHeadBlockFmt , testBlockSize , testTargetSize )
c := NewMemChunk ( ChunkFormatV3 , enc , DefaultTestHeadBlockFmt , testBlockSize , testTargetSize )
for i := 1 ; i <= 10 ; i ++ {
require . NoError ( t , c . Append ( & logproto . Entry { Timestamp : time . Unix ( 0 , int64 ( i ) ) , Line : strings . Repeat ( "e" , 200000 ) } ) )
}
@ -1078,9 +1089,9 @@ func TestMemchunkLongLine(t *testing.T) {
func TestBytesWith ( t * testing . T ) {
t . Parallel ( )
exp , err := NewMemChunk ( EncNone , DefaultTestHeadBlockFmt , testBlockSize , testTargetSize ) . BytesWith ( nil )
exp , err := NewMemChunk ( ChunkFormatV3 , EncNone , DefaultTestHeadBlockFmt , testBlockSize , testTargetSize ) . BytesWith ( nil )
require . Nil ( t , err )
out , err := NewMemChunk ( EncNone , DefaultTestHeadBlockFmt , testBlockSize , testTargetSize ) . BytesWith ( [ ] byte { 1 , 2 , 3 } )
out , err := NewMemChunk ( ChunkFormatV3 , EncNone , DefaultTestHeadBlockFmt , testBlockSize , testTargetSize ) . BytesWith ( [ ] byte { 1 , 2 , 3 } )
require . Nil ( t , err )
require . Equal ( t , exp , out )
@ -1125,7 +1136,7 @@ func TestCheckpointEncoding(t *testing.T) {
cpy , err = MemchunkFromCheckpoint ( chk . Bytes ( ) , head . Bytes ( ) , f . headBlockFmt , blockSize , targetSize )
require . Nil ( t , err )
if f . chunkFormat <= c hunkFormatV2 {
if f . chunkFormat <= C hunkFormatV2 {
for i := range c . blocks {
c . blocks [ i ] . uncompressedSize = 0
}
@ -1154,7 +1165,7 @@ func TestCheckpointEncoding(t *testing.T) {
cpy , err = MemchunkFromCheckpoint ( chk . Bytes ( ) , head . Bytes ( ) , f . headBlockFmt , blockSize , targetSize )
require . Nil ( t , err )
if f . chunkFormat <= c hunkFormatV2 {
if f . chunkFormat <= C hunkFormatV2 {
for i := range c . blocks {
c . blocks [ i ] . uncompressedSize = 0
}
@ -1173,7 +1184,7 @@ var (
func BenchmarkBufferedIteratorLabels ( b * testing . B ) {
for _ , f := range HeadBlockFmts {
b . Run ( f . String ( ) , func ( b * testing . B ) {
c := NewMemChunk ( EncSnappy , f , testBlockSize , testTargetSize )
c := NewMemChunk ( ChunkFormatV3 , EncSnappy , f , testBlockSize , testTargetSize )
_ = fillChunk ( c )
labelsSet := [ ] labels . Labels {
@ -1387,7 +1398,7 @@ func TestMemChunk_Rebound(t *testing.T) {
}
func buildTestMemChunk ( t * testing . T , from , through time . Time ) * MemChunk {
chk := NewMemChunk ( EncGZIP , DefaultTestHeadBlockFmt , defaultBlockSize , 0 )
chk := NewMemChunk ( ChunkFormatV3 , EncGZIP , DefaultTestHeadBlockFmt , defaultBlockSize , 0 )
for ; from . Before ( through ) ; from = from . Add ( time . Second ) {
err := chk . Append ( & logproto . Entry {
Line : from . String ( ) ,
@ -1466,7 +1477,7 @@ func TestMemChunk_ReboundAndFilter_with_filter(t *testing.T) {
}
func buildFilterableTestMemChunk ( t * testing . T , from , through time . Time , matchingFrom , matchingTo * time . Time ) * MemChunk {
chk := NewMemChunk ( EncGZIP , DefaultTestHeadBlockFmt , defaultBlockSize , 0 )
chk := NewMemChunk ( ChunkFormatV3 , EncGZIP , DefaultTestHeadBlockFmt , defaultBlockSize , 0 )
t . Logf ( "from : %v" , from . String ( ) )
t . Logf ( "through: %v" , through . String ( ) )
for from . Before ( through ) {
@ -1598,7 +1609,7 @@ func TestMemChunk_SpaceFor(t *testing.T) {
expectFunc : func ( chunkFormat byte , _ HeadBlockFmt ) bool {
// Succeed unless we're using chunk format v4, which should
// take the non-indexed labels into account.
return chunkFormat < c hunkFormatV4
return chunkFormat < C hunkFormatV4
} ,
} ,
} {
@ -1633,7 +1644,7 @@ func TestMemChunk_IteratorWithNonIndexedLabels(t *testing.T) {
streamLabels := labels . Labels {
{ Name : "job" , Value : "fake" } ,
}
chk := newMemChunkWithFormat ( c hunkFormatV4, enc , UnorderedWithNonIndexedLabelsHeadBlockFmt , testBlockSize , testTargetSize )
chk := newMemChunkWithFormat ( C hunkFormatV4, enc , UnorderedWithNonIndexedLabelsHeadBlockFmt , testBlockSize , testTargetSize )
require . NoError ( t , chk . Append ( logprotoEntryWithNonIndexedLabels ( 1 , "lineA" , [ ] logproto . LabelAdapter {
{ Name : "traceID" , Value : "123" } ,
{ Name : "user" , Value : "a" } ,
@ -1843,7 +1854,7 @@ func TestMemChunk_IteratorWithNonIndexedLabels(t *testing.T) {
}
func TestMemChunk_IteratorOptions ( t * testing . T ) {
chk := newMemChunkWithFormat ( c hunkFormatV4, EncNone , UnorderedWithNonIndexedLabelsHeadBlockFmt , testBlockSize , testTargetSize )
chk := newMemChunkWithFormat ( C hunkFormatV4, EncNone , UnorderedWithNonIndexedLabelsHeadBlockFmt , testBlockSize , testTargetSize )
require . NoError ( t , chk . Append ( logprotoEntryWithNonIndexedLabels ( 0 , "0" , logproto . FromLabelsToLabelAdapters (
labels . FromStrings ( "a" , "0" ) ,
) ) ) )