File: tx_check_test.go

package info (click to toggle)
golang-github-coreos-bbolt 1.4.2-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 1,300 kB
  • sloc: makefile: 87; sh: 57
file content (91 lines) | stat: -rw-r--r-- 3,020 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package tests_test

import (
	"fmt"
	"testing"

	"github.com/stretchr/testify/require"

	bolt "go.etcd.io/bbolt"
	"go.etcd.io/bbolt/internal/btesting"
	"go.etcd.io/bbolt/internal/guts_cli"
	"go.etcd.io/bbolt/internal/surgeon"
)

func TestTx_RecursivelyCheckPages_MisplacedPage(t *testing.T) {
	db := btesting.MustCreateDB(t)
	db.ForceDisableStrictMode()
	require.NoError(t,
		db.Fill([]byte("data"), 1, 10000,
			func(tx int, k int) []byte { return []byte(fmt.Sprintf("%04d", k)) },
			func(tx int, k int) []byte { return make([]byte, 100) },
		))
	require.NoError(t, db.Close())

	xRay := surgeon.NewXRay(db.Path())

	path1, err := xRay.FindPathsToKey([]byte("0451"))
	require.NoError(t, err, "cannot find page that contains key:'0451'")
	require.Len(t, path1, 1, "Expected only one page that contains key:'0451'")

	path2, err := xRay.FindPathsToKey([]byte("7563"))
	require.NoError(t, err, "cannot find page that contains key:'7563'")
	require.Len(t, path2, 1, "Expected only one page that contains key:'7563'")

	srcPage := path1[0][len(path1[0])-1]
	targetPage := path2[0][len(path2[0])-1]
	require.NoError(t, surgeon.CopyPage(db.Path(), srcPage, targetPage))

	db.MustReopen()
	db.ForceDisableStrictMode()
	require.NoError(t, db.Update(func(tx *bolt.Tx) error {
		// Collect all the errors.
		var errors []error
		for err := range tx.Check() {
			errors = append(errors, err)
		}
		require.Len(t, errors, 1)
		require.ErrorContains(t, errors[0], fmt.Sprintf("leaf page(%v) needs to be >= the key in the ancestor", targetPage))
		return nil
	}))
	require.NoError(t, db.Close())
}

func TestTx_RecursivelyCheckPages_CorruptedLeaf(t *testing.T) {
	db := btesting.MustCreateDB(t)
	db.ForceDisableStrictMode()
	require.NoError(t,
		db.Fill([]byte("data"), 1, 10000,
			func(tx int, k int) []byte { return []byte(fmt.Sprintf("%04d", k)) },
			func(tx int, k int) []byte { return make([]byte, 100) },
		))
	require.NoError(t, db.Close())

	xray := surgeon.NewXRay(db.Path())

	path1, err := xray.FindPathsToKey([]byte("0451"))
	require.NoError(t, err, "cannot find page that contains key:'0451'")
	require.Len(t, path1, 1, "Expected only one page that contains key:'0451'")

	srcPage := path1[0][len(path1[0])-1]
	p, pbuf, err := guts_cli.ReadPage(db.Path(), uint64(srcPage))
	require.NoError(t, err)
	require.Positive(t, p.Count(), "page must be not empty")
	p.LeafPageElement(p.Count() / 2).Key()[0] = 'z'
	require.NoError(t, guts_cli.WritePage(db.Path(), pbuf))

	db.MustReopen()
	db.ForceDisableStrictMode()
	require.NoError(t, db.Update(func(tx *bolt.Tx) error {
		// Collect all the errors.
		var errors []error
		for err := range tx.Check() {
			errors = append(errors, err)
		}
		require.Len(t, errors, 2)
		require.ErrorContains(t, errors[0], fmt.Sprintf("leaf page(%v) needs to be < than key of the next element in ancestor", srcPage))
		require.ErrorContains(t, errors[1], fmt.Sprintf("leaf page(%v) needs to be > (found <) than previous element", srcPage))
		return nil
	}))
	require.NoError(t, db.Close())
}