~bigbes/sr-ht-dolt

ref: 93e699101e297244802590365e96da638404b579 sr-ht-dolt/browse/table_hash_test.go -rw-r--r-- 2.9 KiB
93e69910 — Eugene Blikh storage: create databases empty so the first push needs no --force 3 days ago
                                                                                
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
package browse

import (
	"context"
	"testing"

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

// tableHash is a helper for the common "the table must exist here" case.
func tableHash(t *testing.T, db *DB, ctx context.Context, refStr, table string) string {
	t.Helper()
	h, ok, err := db.TableHash(ctx, refStr, table)
	require.NoError(t, err)
	require.True(t, ok, "table %q must exist at %q", table, refStr)
	require.NotEmpty(t, h)
	return h
}

func TestTableHashStable(t *testing.T) {
	db := openFixture(t)
	ctx := context.Background()

	first := tableHash(t, db, ctx, "main", "users")
	second := tableHash(t, db, ctx, "main", "users")
	assert.Equal(t, first, second, "the same table at the same ref must hash the same")

	// A branch and the commit hash it points at are the same root, so they must
	// produce the same table hash. dev's head is C2.
	byBranch := tableHash(t, db, ctx, "dev", "users")
	byCommit := tableHash(t, db, ctx, commitHash(t, msgInsert), "users")
	assert.Equal(t, byBranch, byCommit, "branch and its head commit must agree")
}

// TestTableHashDetectsChange is the property the whole history walk rests on:
// the hash changes exactly when the table does.
func TestTableHashDetectsChange(t *testing.T) {
	db := openFixture(t)
	ctx := context.Background()

	atInsert := tableHash(t, db, ctx, commitHash(t, msgInsert), "users") // C2
	atModify := tableHash(t, db, ctx, commitHash(t, msgModify), "users") // C3: rows changed
	atAddItem := tableHash(t, db, ctx, commitHash(t, msgAddItem), "users")

	assert.NotEqual(t, atInsert, atModify, "C3 changed users rows, hash must differ")
	// C4 created items and docs and left users alone: a walk must be able to
	// skip it without reading a row.
	assert.Equal(t, atAddItem, atModify, "C4 did not touch users, hash must be unchanged")
}

func TestTableHashMissingTable(t *testing.T) {
	db := openFixture(t)
	ctx := context.Background()

	// items is created by C4, so it does not exist at C2 — an ordinary answer
	// for a backwards walk, not an error.
	h, ok, err := db.TableHash(ctx, commitHash(t, msgInsert), "items")
	require.NoError(t, err)
	assert.False(t, ok)
	assert.Empty(t, h)

	// A table that never existed behaves the same way.
	h, ok, err = db.TableHash(ctx, "main", "no-such-table")
	require.NoError(t, err)
	assert.False(t, ok)
	assert.Empty(t, h)
}

func TestTableHashRefNotFound(t *testing.T) {
	db := openFixture(t)
	ctx := context.Background()

	_, ok, err := db.TableHash(ctx, "no-such-ref", "users")
	require.ErrorIs(t, err, ErrRefNotFound)
	assert.False(t, ok)
}

func TestTableHashDistinctTables(t *testing.T) {
	db := openFixture(t)
	ctx := context.Background()

	users := tableHash(t, db, ctx, "main", "users")
	items := tableHash(t, db, ctx, "main", "items")
	docs := tableHash(t, db, ctx, "main", "docs")

	assert.NotEqual(t, users, items)
	assert.NotEqual(t, users, docs)
	assert.NotEqual(t, items, docs, "an empty table must not collide with another table")
}