aboutsummaryrefslogtreecommitdiffstats
path: root/syz-cluster/pkg/controller
diff options
context:
space:
mode:
authorAleksandr Nogikh <nogikh@google.com>2025-02-13 11:57:14 +0100
committerAleksandr Nogikh <nogikh@google.com>2025-02-14 13:40:12 +0000
commitf20e88b2468bdcdb631b14e384f1f9a67e984013 (patch)
treed2758c08ab9deea9354a91237a3d9234de0efce3 /syz-cluster/pkg/controller
parenteaf86f3f4dc8a7190abf09fe840e20bcf83709d8 (diff)
syz-cluster: report session results
Provide an API to set up the reporting of finished sessions for which syz-cluster collected reportable findings. The actual sending of the results is to be done in a separate component that would: 1) Call Next() to get the next report to send. 2) Call Confirm() to confirm that the report has been sent. 3) Call Upstream() if the report has been moderated and needs to be sent to e.g. public mailing lists.
Diffstat (limited to 'syz-cluster/pkg/controller')
-rw-r--r--syz-cluster/pkg/controller/api.go53
-rw-r--r--syz-cluster/pkg/controller/api_test.go4
2 files changed, 14 insertions, 43 deletions
diff --git a/syz-cluster/pkg/controller/api.go b/syz-cluster/pkg/controller/api.go
index 270803c3b..85910bb06 100644
--- a/syz-cluster/pkg/controller/api.go
+++ b/syz-cluster/pkg/controller/api.go
@@ -1,14 +1,13 @@
// 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.
-// nolint: dupl // The methods look similar, but extracting the common parts will only make the code worse.
+// Package controller provides the server part of the *api.Client interface.
+// nolint: dupl
package controller
import (
- "encoding/json"
"errors"
"fmt"
- "io"
"net/http"
"github.com/google/syzkaller/syz-cluster/pkg/api"
@@ -57,7 +56,7 @@ func (c APIServer) getSessionSeries(w http.ResponseWriter, r *http.Request) {
http.Error(w, fmt.Sprint(err), http.StatusInternalServerError)
return
}
- reply(w, resp)
+ api.ReplyJSON(w, resp)
}
func (c APIServer) skipSession(w http.ResponseWriter, r *http.Request) {
@@ -73,7 +72,7 @@ func (c APIServer) skipSession(w http.ResponseWriter, r *http.Request) {
http.Error(w, fmt.Sprint(err), http.StatusInternalServerError)
return
}
- reply[interface{}](w, nil)
+ api.ReplyJSON[interface{}](w, nil)
}
func (c APIServer) getSeries(w http.ResponseWriter, r *http.Request) {
@@ -85,7 +84,7 @@ func (c APIServer) getSeries(w http.ResponseWriter, r *http.Request) {
http.Error(w, fmt.Sprint(err), http.StatusInternalServerError)
return
}
- reply(w, resp)
+ api.ReplyJSON(w, resp)
}
func (c APIServer) uploadBuild(w http.ResponseWriter, r *http.Request) {
@@ -99,7 +98,7 @@ func (c APIServer) uploadBuild(w http.ResponseWriter, r *http.Request) {
http.Error(w, fmt.Sprint(err), http.StatusInternalServerError)
return
}
- reply(w, resp)
+ api.ReplyJSON(w, resp)
}
func (c APIServer) uploadTest(w http.ResponseWriter, r *http.Request) {
@@ -113,11 +112,11 @@ func (c APIServer) uploadTest(w http.ResponseWriter, r *http.Request) {
http.Error(w, fmt.Sprint(err), http.StatusInternalServerError)
return
}
- reply[interface{}](w, nil)
+ api.ReplyJSON[interface{}](w, nil)
}
func (c APIServer) uploadFinding(w http.ResponseWriter, r *http.Request) {
- req := api.ParseJSON[api.Finding](w, r)
+ req := api.ParseJSON[api.NewFinding](w, r)
if req == nil {
return
}
@@ -127,7 +126,7 @@ func (c APIServer) uploadFinding(w http.ResponseWriter, r *http.Request) {
http.Error(w, fmt.Sprint(err), http.StatusInternalServerError)
return
}
- reply[interface{}](w, nil)
+ api.ReplyJSON[interface{}](w, nil)
}
func (c APIServer) getLastBuild(w http.ResponseWriter, r *http.Request) {
@@ -140,7 +139,7 @@ func (c APIServer) getLastBuild(w http.ResponseWriter, r *http.Request) {
http.Error(w, fmt.Sprint(err), http.StatusInternalServerError)
return
}
- reply[*api.Build](w, resp)
+ api.ReplyJSON[*api.Build](w, resp)
}
func (c APIServer) uploadSeries(w http.ResponseWriter, r *http.Request) {
@@ -153,7 +152,7 @@ func (c APIServer) uploadSeries(w http.ResponseWriter, r *http.Request) {
http.Error(w, fmt.Sprint(err), http.StatusInternalServerError)
return
}
- reply[*api.UploadSeriesResp](w, resp)
+ api.ReplyJSON[*api.UploadSeriesResp](w, resp)
}
func (c APIServer) uploadSession(w http.ResponseWriter, r *http.Request) {
@@ -166,33 +165,5 @@ func (c APIServer) uploadSession(w http.ResponseWriter, r *http.Request) {
http.Error(w, fmt.Sprint(err), http.StatusInternalServerError)
return
}
- reply[*api.UploadSessionResp](w, resp)
-}
-
-func reply[T any](w http.ResponseWriter, resp T) {
- w.Header().Set("Content-Type", "application/json")
- err := json.NewEncoder(w).Encode(resp)
- if err != nil {
- http.Error(w, "failed to serialize the response", http.StatusInternalServerError)
- return
- }
-}
-
-func parseBody[T any](w http.ResponseWriter, r *http.Request) *T {
- if r.Method != http.MethodPost {
- http.Error(w, "must be called via POST", http.StatusMethodNotAllowed)
- return nil
- }
- body, err := io.ReadAll(r.Body)
- if err != nil {
- http.Error(w, "failed to read body", http.StatusBadRequest)
- return nil
- }
- var data T
- err = json.Unmarshal(body, &data)
- if err != nil {
- http.Error(w, "invalid body", http.StatusBadRequest)
- return nil
- }
- return &data
+ api.ReplyJSON[*api.UploadSessionResp](w, resp)
}
diff --git a/syz-cluster/pkg/controller/api_test.go b/syz-cluster/pkg/controller/api_test.go
index 2e3483414..f3954d4f3 100644
--- a/syz-cluster/pkg/controller/api_test.go
+++ b/syz-cluster/pkg/controller/api_test.go
@@ -57,7 +57,7 @@ func TestAPISaveFinding(t *testing.T) {
assert.NoError(t, err)
t.Run("not existing test", func(t *testing.T) {
- err = client.UploadFinding(ctx, &api.Finding{
+ err = client.UploadFinding(ctx, &api.NewFinding{
SessionID: sessionID,
TestName: "unknown test",
})
@@ -65,7 +65,7 @@ func TestAPISaveFinding(t *testing.T) {
})
t.Run("must succeed", func(t *testing.T) {
- finding := &api.Finding{
+ finding := &api.NewFinding{
SessionID: sessionID,
TestName: "test",
Report: []byte("report"),