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
|
package helper
import (
"context"
"encoding/base64"
"encoding/json"
"strings"
"testing"
"github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/gitaly/v14/internal/storage"
"gitlab.com/gitlab-org/gitaly/v14/internal/testhelper"
"google.golang.org/grpc/metadata"
)
func TestExtractGitalyServers(t *testing.T) {
ctxOuter, cancel := testhelper.Context()
defer cancel()
testCases := []struct {
desc string
metadata metadata.MD
info storage.GitalyServers
}{
{
desc: "no gitaly-servers metadata",
metadata: metadata.Pairs("not-gitaly-servers", "definitely not JSON camouflaging in base64"),
},
{
desc: "metadata not encoded in base64",
metadata: metadata.Pairs("gitaly-servers", "definitely not base64"),
},
{
desc: "encoded metadata is not JSON",
metadata: metadata.Pairs("gitaly-servers", base64.StdEncoding.EncodeToString([]byte("definitely not JSON"))),
},
{
desc: "encoded JSON is not of the expected format",
metadata: metadata.Pairs("gitaly-servers", base64.StdEncoding.EncodeToString([]byte(`{"default":"string"}`))),
},
{
desc: "properly-encoded string",
metadata: metadata.Pairs("gitaly-servers", base64.StdEncoding.EncodeToString([]byte(`{"default":{"address":"unix:///tmp/sock","token":"hunter1"}}`))),
info: storage.GitalyServers{"default": storage.ServerInfo{Address: "unix:///tmp/sock", Token: "hunter1"}},
},
}
for _, testCase := range testCases {
t.Run(testCase.desc, func(t *testing.T) {
ctx := metadata.NewIncomingContext(ctxOuter, testCase.metadata)
info, err := ExtractGitalyServers(ctx)
if testCase.info == nil {
require.Error(t, err)
} else {
require.NoError(t, err)
require.Equal(t, testCase.info, info)
}
})
}
}
func TestInjectGitalyServers(t *testing.T) {
check := func(t *testing.T, ctx context.Context) {
t.Helper()
newCtx, err := InjectGitalyServers(ctx, "gitaly-1", "1.1.1.1", "secret")
require.NoError(t, err)
md, found := metadata.FromOutgoingContext(newCtx)
require.True(t, found)
gs, found := md["gitaly-servers"]
require.True(t, found)
require.Len(t, gs, 1)
var servers map[string]interface{}
require.NoError(t, json.NewDecoder(base64.NewDecoder(base64.StdEncoding, strings.NewReader(gs[0]))).Decode(&servers), "received %s", gs[0])
require.EqualValues(t, map[string]interface{}{"gitaly-1": map[string]interface{}{"address": "1.1.1.1", "token": "secret"}}, servers)
}
t.Run("brand new context", func(t *testing.T) {
ctx := context.Background()
check(t, ctx)
})
t.Run("context with existing outgoing metadata should not be re-written", func(t *testing.T) {
existing := metadata.New(map[string]string{"foo": "bar"})
ctx := metadata.NewOutgoingContext(context.Background(), existing)
check(t, ctx)
md, found := metadata.FromOutgoingContext(ctx)
require.True(t, found)
require.Equal(t, []string{"bar"}, md["foo"])
})
}
func TestOutgoingToIncoming(t *testing.T) {
ctx := context.Background()
ctx, err := InjectGitalyServers(ctx, "a", "b", "c")
require.NoError(t, err)
_, err = ExtractGitalyServer(ctx, "a")
require.Equal(t, ErrEmptyMetadata, err,
"server should not be found in the incoming context")
ctx = OutgoingToIncoming(ctx)
info, err := ExtractGitalyServer(ctx, "a")
require.NoError(t, err)
require.Equal(t, storage.ServerInfo{Address: "b", Token: "c"}, info)
}
|