aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAleksandr Nogikh <nogikh@google.com>2025-03-11 21:38:10 +0100
committerAleksandr Nogikh <nogikh@google.com>2025-03-11 21:04:55 +0000
commitee70e6dbc377b7957fe85c173da580f033ee93a3 (patch)
treeb5b30a5a6af477b1de5c4775f51e9efcef71d4ed
parentf9a86f79173ee73cd60ab4b2ff04d49764e53644 (diff)
syz-cluster: display and filter by Cc list
For each series, display the Cc'd email list and let users filter the patch series list by those addresses.
-rw-r--r--syz-cluster/controller/processor_test.go2
-rw-r--r--syz-cluster/dashboard/handler.go11
-rw-r--r--syz-cluster/dashboard/templates/index.html1
-rw-r--r--syz-cluster/dashboard/templates/series.html8
-rw-r--r--syz-cluster/pkg/db/series_repo.go14
-rw-r--r--syz-cluster/pkg/db/series_repo_test.go16
-rw-r--r--syz-cluster/pkg/db/session_repo_test.go2
7 files changed, 43 insertions, 11 deletions
diff --git a/syz-cluster/controller/processor_test.go b/syz-cluster/controller/processor_test.go
index ff85ebec9..00f2c471b 100644
--- a/syz-cluster/controller/processor_test.go
+++ b/syz-cluster/controller/processor_test.go
@@ -85,7 +85,7 @@ func awaitFinishedSessions(t *testing.T, seriesRepo *db.SeriesRepository, wantFi
for i := 0; i < int(deadline/interval); i++ {
time.Sleep(interval)
- list, err := seriesRepo.ListLatest(context.Background(), time.Time{}, 0)
+ list, err := seriesRepo.ListLatest(context.Background(), db.SeriesFilter{}, time.Time{}, 0)
assert.NoError(t, err)
withFinishedSeries := 0
for _, item := range list {
diff --git a/syz-cluster/dashboard/handler.go b/syz-cluster/dashboard/handler.go
index 2df0ed37f..c20d2225f 100644
--- a/syz-cluster/dashboard/handler.go
+++ b/syz-cluster/dashboard/handler.go
@@ -79,11 +79,16 @@ func (h *dashboardHandler) seriesList(w http.ResponseWriter, r *http.Request) er
type MainPageData struct {
// It's probably not the best idea to expose db entities here,
// but so far redefining the entity would just duplicate the code.
- List []*db.SeriesWithSession
+ List []*db.SeriesWithSession
+ Filter db.SeriesFilter
+ }
+ data := MainPageData{
+ Filter: db.SeriesFilter{
+ Cc: r.FormValue("cc"),
+ },
}
- var data MainPageData
var err error
- data.List, err = h.seriesRepo.ListLatest(r.Context(), time.Time{}, 0)
+ data.List, err = h.seriesRepo.ListLatest(r.Context(), data.Filter, time.Time{}, 0)
if err != nil {
return fmt.Errorf("failed to query the list: %w", err)
}
diff --git a/syz-cluster/dashboard/templates/index.html b/syz-cluster/dashboard/templates/index.html
index d3e60cfce..fb8fde0f3 100644
--- a/syz-cluster/dashboard/templates/index.html
+++ b/syz-cluster/dashboard/templates/index.html
@@ -1,4 +1,5 @@
{{define "content"}}
+ {{if .Filter.Cc}}<div class="alert alert-dark"><b>Filter: Cc={{.Filter.Cc}}</b></div>{{end}}
<table class="table">
<thead class="thead-light">
<tr>
diff --git a/syz-cluster/dashboard/templates/series.html b/syz-cluster/dashboard/templates/series.html
index c160c0a71..5d7ba6693 100644
--- a/syz-cluster/dashboard/templates/series.html
+++ b/syz-cluster/dashboard/templates/series.html
@@ -55,6 +55,14 @@
<th>Version</th>
<td>{{.Version}}</td>
</tr>
+ <tr>
+ <th>Cc</th>
+ <td>
+ {{range .Cc}}
+ <a href="/?cc={{.}}">{{.}}</a>
+ {{end}}
+ </td>
+ </tr>
</tbody>
</table>
diff --git a/syz-cluster/pkg/db/series_repo.go b/syz-cluster/pkg/db/series_repo.go
index 018d32d8f..affe7f9cf 100644
--- a/syz-cluster/pkg/db/series_repo.go
+++ b/syz-cluster/pkg/db/series_repo.go
@@ -130,20 +130,28 @@ type SeriesWithSession struct {
Session *Session
}
+type SeriesFilter struct {
+ Cc string
+}
+
// ListLatest() returns the list of series ordered by the decreasing PublishedAt value.
-func (repo *SeriesRepository) ListLatest(ctx context.Context,
+func (repo *SeriesRepository) ListLatest(ctx context.Context, filter SeriesFilter,
maxPublishedAt time.Time, limit int) ([]*SeriesWithSession, error) {
ro := repo.client.ReadOnlyTransaction()
defer ro.Close()
stmt := spanner.Statement{
- SQL: "SELECT * FROM Series",
+ SQL: "SELECT * FROM Series WHERE 1=1",
Params: map[string]interface{}{},
}
if !maxPublishedAt.IsZero() {
- stmt.SQL += " WHERE PublishedAt < @toTime"
+ stmt.SQL += " AND PublishedAt < @toTime"
stmt.Params["toTime"] = maxPublishedAt
}
+ if filter.Cc != "" {
+ stmt.SQL += " AND @cc IN UNNEST(Cc)"
+ stmt.Params["cc"] = filter.Cc
+ }
stmt.SQL += " ORDER BY PublishedAt DESC"
if limit > 0 {
stmt.SQL += " LIMIT @limit"
diff --git a/syz-cluster/pkg/db/series_repo_test.go b/syz-cluster/pkg/db/series_repo_test.go
index c01049e5c..f9462dd90 100644
--- a/syz-cluster/pkg/db/series_repo_test.go
+++ b/syz-cluster/pkg/db/series_repo_test.go
@@ -58,16 +58,19 @@ func TestSeriesRepositoryList(t *testing.T) {
ExtID: "series-3",
Title: "Series 3",
PublishedAt: time.Date(2020, time.January, 1, 3, 0, 0, 0, time.UTC),
+ Cc: []string{"a"},
},
{
ExtID: "series-1",
Title: "Series 1",
PublishedAt: time.Date(2020, time.January, 1, 1, 0, 0, 0, time.UTC),
+ Cc: []string{"a", "b"},
},
{
ExtID: "series-2",
Title: "Series 2",
PublishedAt: time.Date(2020, time.January, 1, 2, 0, 0, 0, time.UTC),
+ Cc: []string{"c"},
},
} {
err := repo.Insert(ctx, series, func() ([]*Patch, error) { return nil, nil })
@@ -81,13 +84,13 @@ func TestSeriesRepositoryList(t *testing.T) {
})
t.Run("all", func(t *testing.T) {
- list, err := repo.ListLatest(ctx, time.Time{}, 0)
+ list, err := repo.ListLatest(ctx, SeriesFilter{}, time.Time{}, 0)
assert.NoError(t, err)
assert.Len(t, list, 3)
})
t.Run("with_limit", func(t *testing.T) {
- list, err := repo.ListLatest(ctx, time.Time{}, 2)
+ list, err := repo.ListLatest(ctx, SeriesFilter{}, time.Time{}, 2)
assert.NoError(t, err)
assert.Len(t, list, 2)
assert.Equal(t, "Series 3", list[0].Series.Title)
@@ -96,12 +99,19 @@ func TestSeriesRepositoryList(t *testing.T) {
t.Run("with_from", func(t *testing.T) {
// Skips the latest series.
- list, err := repo.ListLatest(ctx, time.Date(2020, time.January, 1, 3, 0, 0, 0, time.UTC), 0)
+ list, err := repo.ListLatest(ctx, SeriesFilter{}, time.Date(2020, time.January, 1, 3, 0, 0, 0, time.UTC), 0)
assert.NoError(t, err)
assert.Len(t, list, 2)
assert.Equal(t, "Series 2", list[0].Series.Title)
assert.Equal(t, "Series 1", list[1].Series.Title)
})
+
+ t.Run("filter_by_cc", func(t *testing.T) {
+ list, err := repo.ListLatest(ctx,
+ SeriesFilter{Cc: "a"}, time.Time{}, 0)
+ assert.NoError(t, err)
+ assert.Len(t, list, 2)
+ })
}
func TestSeriesRepositoryUpdate(t *testing.T) {
diff --git a/syz-cluster/pkg/db/session_repo_test.go b/syz-cluster/pkg/db/session_repo_test.go
index 2a3b9bd69..c6f79f975 100644
--- a/syz-cluster/pkg/db/session_repo_test.go
+++ b/syz-cluster/pkg/db/session_repo_test.go
@@ -20,7 +20,7 @@ func TestSeriesInsertSession(t *testing.T) {
assert.NoError(t, err)
withSession := func(need int) {
- list, err := seriesRepo.ListLatest(ctx, time.Time{}, 10)
+ list, err := seriesRepo.ListLatest(ctx, SeriesFilter{}, time.Time{}, 10)
assert.NoError(t, err)
var cnt int
for _, item := range list {