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
124
125
126
|
// Copyright 2024 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
package coveragedb
import (
"encoding/json"
"io"
"strings"
"testing"
"time"
"cloud.google.com/go/spanner"
"github.com/google/syzkaller/pkg/coveragedb/mocks"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)
type spannerMockTune func(*testing.T, *mocks.SpannerClient)
func TestSaveMergeResult(t *testing.T) {
tests := []struct {
name string
jsonl io.Reader
descr *HistoryRecord
mockTune spannerMockTune
wantErr bool
wantRows int
}{
{
name: "empty jsonl",
jsonl: strings.NewReader(`{}`),
wantErr: true,
},
{
name: "wrong jsonl content",
jsonl: strings.NewReader(`{a}`),
wantErr: true,
},
// nolint: dupl
{
name: "1 MCR record, Ok",
jsonl: strings.NewReader(`{"MCR":{"FileData":{}}}`),
descr: &HistoryRecord{},
wantRows: 2, // 1 in files and 1 in merge_history
mockTune: func(t *testing.T, m *mocks.SpannerClient) {
m.
On("Apply", mock.Anything, mock.Anything).
Return(time.Now(), nil).
Once()
},
},
// nolint: dupl
{
name: "1 FC record, Ok",
jsonl: strings.NewReader(`{"FL":{}}`),
descr: &HistoryRecord{},
wantRows: 2, // 1 in functions and 1 in merge_history
mockTune: func(t *testing.T, m *mocks.SpannerClient) {
m.
On("Apply", mock.Anything, mock.Anything).
Return(time.Now(), nil).
Once()
},
},
{
name: "2 records, Ok",
jsonl: strings.NewReader(` {"MCR":{"FileData":{}}}
{"MCR":{"FileData":{}}}`),
descr: &HistoryRecord{},
wantRows: 3,
mockTune: func(t *testing.T, m *mocks.SpannerClient) {
m.
On("Apply",
mock.Anything,
mock.MatchedBy(func(ms []*spanner.Mutation) bool {
// 2 in files and 1 in merge_history
return len(ms) == 3
})).
Return(time.Now(), nil).
Once()
},
},
{
name: "2k records, Ok",
jsonl: strings.NewReader(strings.Repeat("{\"MCR\":{\"FileData\":{}}}\n", 2000)),
descr: &HistoryRecord{},
wantRows: 2001,
mockTune: func(t *testing.T, m *mocks.SpannerClient) {
m.
On("Apply",
mock.Anything,
mock.MatchedBy(func(ms []*spanner.Mutation) bool {
// 2k in files
return len(ms) == 1000
})).
Return(time.Now(), nil).
Times(2).
On("Apply",
mock.Anything,
mock.MatchedBy(func(ms []*spanner.Mutation) bool {
// And 1 in merge_history.
return len(ms) == 1
})).
Return(time.Now(), nil).
Once()
},
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
t.Parallel()
spannerMock := mocks.NewSpannerClient(t)
if test.mockTune != nil {
test.mockTune(t, spannerMock)
}
gotRows, err := SaveMergeResult(t.Context(), spannerMock, test.descr, json.NewDecoder(test.jsonl))
if test.wantErr {
assert.Error(t, err)
} else {
assert.NoError(t, err)
}
assert.Equal(t, test.wantRows, gotRows)
})
}
}
|