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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
// +build postgres
package datastore
import (
"fmt"
"strings"
"testing"
"github.com/prometheus/client_golang/prometheus/testutil"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/gitaly/v14/internal/testhelper"
)
func TestRepositoryStoreCollector(t *testing.T) {
ctx, cancel := testhelper.Context()
defer cancel()
db := getDB(t)
rs := NewPostgresRepositoryStore(db, nil)
state := map[string]map[string]map[string]int{
"some-read-only": {
"read-only": {
"vs-primary": 0,
"repo-primary": 0,
"secondary": 1,
},
"writable": {
"vs-primary": 1,
"repo-primary": 1,
"secondary": 1,
},
"repo-writable": {
"vs-primary": 0,
"repo-primary": 1,
"secondary": 1,
},
},
"all-writable": {
"writable": {
"vs-primary": 0,
"repo-primary": 0,
},
},
"unconfigured": {
"read-only": {
"secondary": 1,
},
},
"no-records": {},
"no-primary": {
"read-only": {
"secondary": 0,
},
},
}
for virtualStorage, relativePaths := range state {
demoted := false
if virtualStorage == "no-primary" {
demoted = true
}
_, err := db.ExecContext(ctx, `
INSERT INTO shard_primaries (shard_name, node_name, elected_by_praefect, elected_at, demoted)
VALUES ($1, 'vs-primary', 'not-needed', now(), $2)
`, virtualStorage, demoted,
)
require.NoError(t, err)
for relativePath, storages := range relativePaths {
if virtualStorage != "no-primary" {
_, err := db.ExecContext(ctx, `
INSERT INTO repositories (virtual_storage, relative_path, "primary")
VALUES ($1, $2, 'repo-primary')
`, virtualStorage, relativePath,
)
require.NoError(t, err)
}
for storage, generation := range storages {
require.NoError(t, rs.SetGeneration(ctx, virtualStorage, relativePath, storage, generation))
}
}
}
var virtualStorages []string
for vs := range state {
if vs == "unconfigured" {
continue
}
virtualStorages = append(virtualStorages, vs)
}
for _, tc := range []struct {
desc string
repositoryScoped bool
someReadOnlyCount int
}{
{
desc: "repository scoped",
someReadOnlyCount: 1,
repositoryScoped: true,
},
{
desc: "virtual storage scoped",
someReadOnlyCount: 2,
},
} {
t.Run(tc.desc, func(t *testing.T) {
c := NewRepositoryStoreCollector(logrus.New(), virtualStorages, db, tc.repositoryScoped)
require.NoError(t, testutil.CollectAndCompare(c, strings.NewReader(fmt.Sprintf(`
# HELP gitaly_praefect_read_only_repositories Number of repositories in read-only mode within a virtual storage.
# TYPE gitaly_praefect_read_only_repositories gauge
gitaly_praefect_read_only_repositories{virtual_storage="all-writable"} 0
gitaly_praefect_read_only_repositories{virtual_storage="no-records"} 0
gitaly_praefect_read_only_repositories{virtual_storage="no-primary"} 1
gitaly_praefect_read_only_repositories{virtual_storage="some-read-only"} %d
`, tc.someReadOnlyCount))))
})
}
}
|