File: command_surgery_freelist_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 (103 lines) | stat: -rw-r--r-- 2,689 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
92
93
94
95
96
97
98
99
100
101
102
103
package main_test

import (
	"path/filepath"
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"

	bolt "go.etcd.io/bbolt"
	main "go.etcd.io/bbolt/cmd/bbolt"
	"go.etcd.io/bbolt/internal/btesting"
	"go.etcd.io/bbolt/internal/common"
)

func TestSurgery_Freelist_Abandon(t *testing.T) {
	pageSize := 4096
	db := btesting.MustCreateDBWithOption(t, &bolt.Options{PageSize: pageSize})
	srcPath := db.Path()

	defer requireDBNoChange(t, dbData(t, srcPath), srcPath)

	rootCmd := main.NewRootCommand()
	output := filepath.Join(t.TempDir(), "db")
	rootCmd.SetArgs([]string{
		"surgery", "freelist", "abandon", srcPath,
		"--output", output,
	})
	err := rootCmd.Execute()
	require.NoError(t, err)

	meta0 := loadMetaPage(t, output, 0)
	assert.Equal(t, common.PgidNoFreelist, meta0.Freelist())
	meta1 := loadMetaPage(t, output, 1)
	assert.Equal(t, common.PgidNoFreelist, meta1.Freelist())
}

func TestSurgery_Freelist_Rebuild(t *testing.T) {
	testCases := []struct {
		name          string
		hasFreelist   bool
		expectedError error
	}{
		{
			name:          "normal operation",
			hasFreelist:   false,
			expectedError: nil,
		},
		{
			name:          "already has freelist",
			hasFreelist:   true,
			expectedError: main.ErrSurgeryFreelistAlreadyExist,
		},
	}

	for _, tc := range testCases {
		tc := tc
		t.Run(tc.name, func(t *testing.T) {
			pageSize := 4096
			db := btesting.MustCreateDBWithOption(t, &bolt.Options{
				PageSize:       pageSize,
				NoFreelistSync: !tc.hasFreelist,
			})
			srcPath := db.Path()

			err := db.Update(func(tx *bolt.Tx) error {
				// do nothing
				return nil
			})
			require.NoError(t, err)

			defer requireDBNoChange(t, dbData(t, srcPath), srcPath)

			// Verify the freelist isn't synced in the beginning
			meta := readMetaPage(t, srcPath)
			if tc.hasFreelist {
				if meta.Freelist() <= 1 || meta.Freelist() >= meta.Pgid() {
					t.Fatalf("freelist (%d) isn't in the valid range (1, %d)", meta.Freelist(), meta.Pgid())
				}
			} else {
				require.Equal(t, common.PgidNoFreelist, meta.Freelist())
			}

			// Execute `surgery freelist rebuild` command
			rootCmd := main.NewRootCommand()
			output := filepath.Join(t.TempDir(), "db")
			rootCmd.SetArgs([]string{
				"surgery", "freelist", "rebuild", srcPath,
				"--output", output,
			})
			err = rootCmd.Execute()
			require.Equal(t, tc.expectedError, err)

			if tc.expectedError == nil {
				// Verify the freelist has already been rebuilt.
				meta = readMetaPage(t, output)
				if meta.Freelist() <= 1 || meta.Freelist() >= meta.Pgid() {
					t.Fatalf("freelist (%d) isn't in the valid range (1, %d)", meta.Freelist(), meta.Pgid())
				}
			}
		})
	}
}