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
|
// Copyright 2025 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 service
import (
"bytes"
"context"
"fmt"
"io"
"time"
"cloud.google.com/go/spanner"
"github.com/google/syzkaller/syz-cluster/pkg/api"
"github.com/google/syzkaller/syz-cluster/pkg/app"
"github.com/google/syzkaller/syz-cluster/pkg/blob"
"github.com/google/syzkaller/syz-cluster/pkg/db"
)
type SessionTestService struct {
testRepo *db.SessionTestRepository
blobStorage blob.Storage
}
func NewSessionTestService(env *app.AppEnvironment) *SessionTestService {
return &SessionTestService{
testRepo: db.NewSessionTestRepository(env.Spanner),
blobStorage: env.BlobStorage,
}
}
func (s *SessionTestService) Save(ctx context.Context, req *api.TestResult) error {
entity, err := s.testRepo.Get(ctx, req.SessionID, req.TestName)
if err != nil {
return fmt.Errorf("failed to query the test: %w", err)
} else if entity == nil {
entity = &db.SessionTest{
SessionID: req.SessionID,
TestName: req.TestName,
}
}
logURI := entity.LogURI
if len(req.Log) > 0 {
logURI, err = s.blobStorage.Write(bytes.NewReader(req.Log),
"Session", req.SessionID, "Test", req.TestName, "log")
if err != nil {
return fmt.Errorf("failed to save the log: %w", err)
}
}
return s.testRepo.InsertOrUpdate(ctx, entity, func(test *db.SessionTest) {
test.Result = req.Result
test.UpdatedAt = time.Now()
test.LogURI = logURI
if req.BaseBuildID != "" {
test.BaseBuildID = spanner.NullString{StringVal: req.BaseBuildID, Valid: true}
}
if req.PatchedBuildID != "" {
test.PatchedBuildID = spanner.NullString{StringVal: req.PatchedBuildID, Valid: true}
}
})
}
func (s *SessionTestService) SaveArtifacts(ctx context.Context, sessionID, testName string, reader io.Reader) error {
entity, err := s.testRepo.Get(ctx, sessionID, testName)
if err != nil {
return fmt.Errorf("failed to query the test: %w", err)
} else if entity == nil {
return fmt.Errorf("the test has not been submitted yet")
}
archiveURI, err := s.blobStorage.Write(reader, "Session", sessionID, "Test", testName, "artifacts")
if err != nil {
return fmt.Errorf("failed to save the artifacts archive: %w", err)
}
return s.testRepo.InsertOrUpdate(ctx, entity, func(test *db.SessionTest) {
test.ArtifactsArchiveURI = archiveURI
})
}
|