MCPcopy
hub / github.com/grafana/tempo / TestPartialReplay

Function TestPartialReplay

tempodb/encoding/vparquet3/wal_block_test.go:65–135  ·  view source on GitHub ↗

TestPartialReplay verifies that we can best-effort replay a partial/corrupted WAL block. This test works by flushing a WAL block across a few pages, corrupting one, and then replaying it.

(t *testing.T)

Source from the content-addressed store, hash-verified

63// This test works by flushing a WAL block across a few pages, corrupting one, and then replaying
64// it.
65func TestPartialReplay(t *testing.T) {
66 decoder := model.MustNewSegmentDecoder(model.CurrentEncoding)
67 blockID := uuid.New()
68 basePath := t.TempDir()
69
70 meta := backend.NewBlockMeta("fake", blockID, VersionString)
71 w, err := createWALBlock(meta, basePath, model.CurrentEncoding, 0)
72 require.NoError(t, err)
73
74 // Flush a set of traces across 2 pages
75 count := 10
76 ids := make([]common.ID, count)
77 trs := make([]*tempopb.Trace, count)
78 for i := 0; i < count; i++ {
79 ids[i] = test.ValidTraceID(nil)
80 trs[i] = test.MakeTrace(10, ids[i])
81 trace.SortTrace(trs[i])
82
83 b1, err := decoder.PrepareForWrite(trs[i], 0, 0)
84 require.NoError(t, err)
85
86 b2, err := decoder.ToObject([][]byte{b1})
87 require.NoError(t, err)
88
89 err = w.Append(ids[i], b2, 0, 0, true)
90 require.NoError(t, err)
91
92 if i+1 == count/2 {
93 require.NoError(t, w.Flush())
94 }
95 }
96 require.NoError(t, w.Flush())
97
98 // Delete half of page 2
99 fpath := w.filepathOf(1)
100 info, err := os.Stat(fpath)
101 require.NoError(t, err)
102 require.NoError(t, os.Truncate(fpath, info.Size()/2))
103
104 // Replay, this has a warning on page 2
105 w2, warning, err := openWALBlock(filepath.Base(w.walPath()), filepath.Dir(w.walPath()), 0, 0)
106 require.NoError(t, err)
107 require.ErrorContains(t, warning, "invalid magic footer of parquet file")
108
109 // Verify we iterate only the records from the first flush
110 iter, err := w2.Iterator(context.Background())
111 require.NoError(t, err)
112
113 gotCount := 0
114 for ; ; gotCount++ {
115 id, tr, err := iter.Next(context.Background())
116 require.NoError(t, err)
117
118 if id == nil {
119 break
120 }
121
122 // Find trace in the input data

Callers

nothing calls this directly

Calls 15

MustNewSegmentDecoderFunction · 0.92
NewBlockMetaFunction · 0.92
ValidTraceIDFunction · 0.92
MakeTraceFunction · 0.92
SortTraceFunction · 0.92
createWALBlockFunction · 0.70
openWALBlockFunction · 0.70
PrepareForWriteMethod · 0.65
ToObjectMethod · 0.65
AppendMethod · 0.65
FlushMethod · 0.65
SizeMethod · 0.65

Tested by

no test coverage detected