TestSnapshotUnknownEncodingFallsBackToWAL verifies that a snapshot containing an unknown chunk encoding causes the entire snapshot load to fail and fall back to full WAL replay, recovering all series without data loss.
(t *testing.T)
| 5015 | // an unknown chunk encoding causes the entire snapshot load to fail and fall back |
| 5016 | // to full WAL replay, recovering all series without data loss. |
| 5017 | func TestSnapshotUnknownEncodingFallsBackToWAL(t *testing.T) { |
| 5018 | head, _ := newTestHead(t, 120*4, compression.None, false) |
| 5019 | defer func() { |
| 5020 | head.opts.EnableMemorySnapshotOnShutdown = false |
| 5021 | require.NoError(t, head.Close()) |
| 5022 | }() |
| 5023 | |
| 5024 | floatHist := tsdbutil.GenerateTestGaugeFloatHistograms(1)[0] |
| 5025 | lblsFloatHist := labels.FromStrings("floathist", "bar") |
| 5026 | lblsFloat := labels.FromStrings("foo", "bar") |
| 5027 | |
| 5028 | app := head.Appender(context.Background()) |
| 5029 | _, err := app.AppendHistogram(0, lblsFloatHist, 99, nil, floatHist) |
| 5030 | require.NoError(t, err) |
| 5031 | _, err = app.Append(0, lblsFloat, 99, 99.0) |
| 5032 | require.NoError(t, err) |
| 5033 | require.NoError(t, app.Commit()) |
| 5034 | |
| 5035 | head.opts.EnableMemorySnapshotOnShutdown = true |
| 5036 | require.NoError(t, head.Close()) |
| 5037 | |
| 5038 | // Find the snapshot and corrupt the encoding byte of the float histogram series. |
| 5039 | snapDir, _, _, err := LastChunkSnapshot(head.opts.ChunkDirRoot) |
| 5040 | require.NoError(t, err) |
| 5041 | |
| 5042 | sr, err := wlog.NewSegmentsReader(snapDir) |
| 5043 | require.NoError(t, err) |
| 5044 | r := wlog.NewReader(sr) |
| 5045 | syms := labels.NewSymbolTable() |
| 5046 | rdec := record.NewDecoder(syms, promslog.NewNopLogger()) |
| 5047 | var ( |
| 5048 | records [][]byte |
| 5049 | mutated bool |
| 5050 | ) |
| 5051 | for r.Next() { |
| 5052 | rec := append([]byte(nil), r.Record()...) |
| 5053 | if rec[0] == chunkSnapshotRecordTypeSeries { |
| 5054 | buf := encoding.Decbuf{B: rec} |
| 5055 | _ = buf.Byte() // flag |
| 5056 | _ = buf.Be64() // ref |
| 5057 | lset := rdec.DecodeLabels(&buf) |
| 5058 | _ = buf.Be64int64() // chunkRange |
| 5059 | if buf.Uvarint() == 1 && lset.Get("floathist") == "bar" { |
| 5060 | _ = buf.Be64int64() // minTime |
| 5061 | _ = buf.Be64int64() // maxTime |
| 5062 | encPos := len(rec) - buf.Len() |
| 5063 | require.Equal(t, byte(chunkenc.EncFloatHistogram), rec[encPos], |
| 5064 | "expected float histogram encoding at computed offset") |
| 5065 | rec[encPos] = 0xFF |
| 5066 | mutated = true |
| 5067 | } |
| 5068 | } |
| 5069 | records = append(records, rec) |
| 5070 | } |
| 5071 | require.NoError(t, r.Err()) |
| 5072 | require.NoError(t, sr.Close()) |
| 5073 | require.True(t, mutated, "expected to find and corrupt the float histogram series record") |
| 5074 |
nothing calls this directly
no test coverage detected
searching dependent graphs…