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

Function TestPartialReplay

tempodb/encoding/vparquet5/wal_block_test.go:64–134  ·  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

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