github.com/google/syzkaller@v0.0.0-20251211124644-a066d2bc4b02/syz-cluster/pkg/service/sessiontest.go (about)

     1  // Copyright 2025 syzkaller project authors. All rights reserved.
     2  // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
     3  
     4  package service
     5  
     6  import (
     7  	"bytes"
     8  	"context"
     9  	"fmt"
    10  	"io"
    11  	"time"
    12  
    13  	"cloud.google.com/go/spanner"
    14  	"github.com/google/syzkaller/syz-cluster/pkg/api"
    15  	"github.com/google/syzkaller/syz-cluster/pkg/app"
    16  	"github.com/google/syzkaller/syz-cluster/pkg/blob"
    17  	"github.com/google/syzkaller/syz-cluster/pkg/db"
    18  )
    19  
    20  type SessionTestService struct {
    21  	testRepo    *db.SessionTestRepository
    22  	blobStorage blob.Storage
    23  }
    24  
    25  func NewSessionTestService(env *app.AppEnvironment) *SessionTestService {
    26  	return &SessionTestService{
    27  		testRepo:    db.NewSessionTestRepository(env.Spanner),
    28  		blobStorage: env.BlobStorage,
    29  	}
    30  }
    31  
    32  func (s *SessionTestService) Save(ctx context.Context, req *api.TestResult) error {
    33  	entity, err := s.testRepo.Get(ctx, req.SessionID, req.TestName)
    34  	if err != nil {
    35  		return fmt.Errorf("failed to query the test: %w", err)
    36  	} else if entity == nil {
    37  		entity = &db.SessionTest{
    38  			SessionID: req.SessionID,
    39  			TestName:  req.TestName,
    40  		}
    41  	}
    42  	logURI := entity.LogURI
    43  	if len(req.Log) > 0 {
    44  		logURI, err = s.blobStorage.Write(bytes.NewReader(req.Log),
    45  			"Session", req.SessionID, "Test", req.TestName, "log")
    46  		if err != nil {
    47  			return fmt.Errorf("failed to save the log: %w", err)
    48  		}
    49  	}
    50  	return s.testRepo.InsertOrUpdate(ctx, entity, func(test *db.SessionTest) {
    51  		test.Result = req.Result
    52  		test.UpdatedAt = time.Now()
    53  		test.LogURI = logURI
    54  		if req.BaseBuildID != "" {
    55  			test.BaseBuildID = spanner.NullString{StringVal: req.BaseBuildID, Valid: true}
    56  		}
    57  		if req.PatchedBuildID != "" {
    58  			test.PatchedBuildID = spanner.NullString{StringVal: req.PatchedBuildID, Valid: true}
    59  		}
    60  	})
    61  }
    62  
    63  func (s *SessionTestService) SaveArtifacts(ctx context.Context, sessionID, testName string, reader io.Reader) error {
    64  	entity, err := s.testRepo.Get(ctx, sessionID, testName)
    65  	if err != nil {
    66  		return fmt.Errorf("failed to query the test: %w", err)
    67  	} else if entity == nil {
    68  		return fmt.Errorf("the test has not been submitted yet")
    69  	}
    70  	archiveURI, err := s.blobStorage.Write(reader, "Session", sessionID, "Test", testName, "artifacts")
    71  	if err != nil {
    72  		return fmt.Errorf("failed to save the artifacts archive: %w", err)
    73  	}
    74  	return s.testRepo.InsertOrUpdate(ctx, entity, func(test *db.SessionTest) {
    75  		test.ArtifactsArchiveURI = archiveURI
    76  	})
    77  }