Skip to content

Commit 87b60d5

Browse files
committed
syz-cluster: display the number of findings per series
It will help identify the series to highlight.
1 parent cb870a1 commit 87b60d5

File tree

3 files changed

+100
-36
lines changed

3 files changed

+100
-36
lines changed

syz-cluster/dashboard/templates/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
<td>{{.Series.AuthorEmail}}</td>
5555
<td>
5656
{{if .Session}}
57-
{{.Session.Status}}
57+
{{.Session.Status}} {{if gt .Findings 0}}<b>[{{.Findings}} findings]</b>{{end}}
5858
{{else}}
5959
-
6060
{{end}}

syz-cluster/pkg/db/series_repo.go

Lines changed: 85 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,9 @@ func (repo *SeriesRepository) Count(ctx context.Context) (int, error) {
127127
}
128128

129129
type SeriesWithSession struct {
130-
Series *Series
131-
Session *Session
130+
Series *Series
131+
Session *Session
132+
Findings int
132133
}
133134

134135
type SeriesFilter struct {
@@ -191,37 +192,96 @@ func (repo *SeriesRepository) ListLatest(ctx context.Context, filter SeriesFilte
191192
}
192193

193194
// Now query Sessions.
194-
var keys []string
195195
var ret []*SeriesWithSession
196-
idToSeries := map[string]*SeriesWithSession{}
197196
for _, series := range seriesList {
197+
obj := &SeriesWithSession{Series: series}
198+
ret = append(ret, obj)
199+
}
200+
201+
// And the rest of the data.
202+
err = repo.querySessions(ctx, ro, ret)
203+
if err != nil {
204+
return nil, fmt.Errorf("failed to query sessions: %w", err)
205+
}
206+
err = repo.queryFindingCounts(ctx, ro, ret)
207+
if err != nil {
208+
return nil, fmt.Errorf("failed to query finding counts: %w", err)
209+
}
210+
return ret, nil
211+
}
212+
213+
func (repo *SeriesRepository) querySessions(ctx context.Context, ro *spanner.ReadOnlyTransaction,
214+
seriesList []*SeriesWithSession) error {
215+
idToSeries := map[string]*SeriesWithSession{}
216+
var keys []string
217+
for _, item := range seriesList {
218+
series := item.Series
219+
idToSeries[series.ID] = item
198220
if !series.LatestSessionID.IsNull() {
199221
keys = append(keys, series.LatestSessionID.String())
200222
}
201-
obj := &SeriesWithSession{Series: series}
202-
ret = append(ret, obj)
203-
idToSeries[series.ID] = obj
204-
}
205-
if len(keys) > 0 {
206-
iter := ro.Query(ctx, spanner.Statement{
207-
SQL: "SELECT * FROM Sessions WHERE ID IN UNNEST(@ids)",
208-
Params: map[string]interface{}{
209-
"ids": keys,
210-
},
211-
})
212-
defer iter.Stop()
213-
sessions, err := readEntities[Session](iter)
214-
if err != nil {
215-
return nil, err
223+
}
224+
if len(keys) == 0 {
225+
return nil
226+
}
227+
iter := ro.Query(ctx, spanner.Statement{
228+
SQL: "SELECT * FROM Sessions WHERE ID IN UNNEST(@ids)",
229+
Params: map[string]interface{}{
230+
"ids": keys,
231+
},
232+
})
233+
defer iter.Stop()
234+
sessions, err := readEntities[Session](iter)
235+
if err != nil {
236+
return err
237+
}
238+
for _, session := range sessions {
239+
obj := idToSeries[session.SeriesID]
240+
if obj != nil {
241+
obj.Session = session
216242
}
217-
for _, session := range sessions {
218-
obj := idToSeries[session.SeriesID]
219-
if obj != nil {
220-
obj.Session = session
221-
}
243+
}
244+
return nil
245+
}
246+
247+
func (repo *SeriesRepository) queryFindingCounts(ctx context.Context, ro *spanner.ReadOnlyTransaction,
248+
seriesList []*SeriesWithSession) error {
249+
var keys []string
250+
sessionToSeries := map[string]*SeriesWithSession{}
251+
for _, series := range seriesList {
252+
if series.Session == nil || series.Session.Status() != SessionStatusFinished {
253+
continue
222254
}
255+
keys = append(keys, series.Session.ID)
256+
sessionToSeries[series.Session.ID] = series
223257
}
224-
return ret, nil
258+
if len(keys) == 0 {
259+
return nil
260+
}
261+
262+
type findingCount struct {
263+
SessionID string `spanner:"SessionID"`
264+
Count int64 `spanner:"Count"`
265+
}
266+
267+
stmt := spanner.Statement{
268+
SQL: "SELECT `SessionID`, COUNT(`ID`) as `Count` FROM `Findings` " +
269+
"WHERE `SessionID` IN UNNEST(@ids) GROUP BY `SessionID`",
270+
Params: map[string]interface{}{
271+
"ids": keys,
272+
},
273+
}
274+
iter := repo.client.Single().Query(ctx, stmt)
275+
defer iter.Stop()
276+
277+
list, err := readEntities[findingCount](iter)
278+
if err != nil {
279+
return err
280+
}
281+
for _, item := range list {
282+
sessionToSeries[item.SessionID].Findings = int(item.Count)
283+
}
284+
return nil
225285
}
226286

227287
// golint sees too much similarity with SessionRepository's ListForSeries, but in reality there's not.

syz-cluster/pkg/db/series_repo_test.go

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -125,30 +125,34 @@ func TestSeriesRepositoryList(t *testing.T) {
125125
})
126126

127127
// Start one session to test filtering by status.
128-
sessionRepo := NewSessionRepository(client)
129128
series2, err := repo.GetByExtID(ctx, "series-2")
130129
assert.NoError(t, err)
131-
session := &Session{
132-
SeriesID: series2.ID,
133-
CreatedAt: time.Now(),
134-
}
135-
err = sessionRepo.Insert(ctx, session)
136-
assert.NoError(t, err)
137130

131+
dtd := &dummyTestData{t, ctx, client}
132+
session := dtd.dummySession(series2)
133+
dtd.addSessionTest(session, "test")
138134
t.Run("filter_status_waiting", func(t *testing.T) {
139135
list, err := repo.ListLatest(ctx, SeriesFilter{Status: SessionStatusWaiting}, time.Time{})
140136
assert.NoError(t, err)
141137
assert.Len(t, list, 1)
142138
})
143139

144-
err = sessionRepo.Start(ctx, session.ID)
145-
assert.NoError(t, err)
146-
140+
dtd.startSession(session)
147141
t.Run("filter_status_in_progress", func(t *testing.T) {
148142
list, err := repo.ListLatest(ctx, SeriesFilter{Status: SessionStatusInProgress}, time.Time{})
149143
assert.NoError(t, err)
150144
assert.Len(t, list, 1)
151145
})
146+
147+
dtd.addSessionTest(session, "test")
148+
dtd.addFinding(session, "title", "test")
149+
dtd.finishSession(session)
150+
t.Run("query_finding_count", func(t *testing.T) {
151+
list, err := repo.ListLatest(ctx, SeriesFilter{Status: SessionStatusFinished}, time.Time{})
152+
assert.NoError(t, err)
153+
assert.Len(t, list, 1)
154+
assert.Equal(t, 1, list[0].Findings, "there must be just one finding")
155+
})
152156
}
153157

154158
func TestSeriesRepositoryUpdate(t *testing.T) {

0 commit comments

Comments
 (0)