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

     1  // Copyright 2024 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 db
     5  
     6  import (
     7  	"time"
     8  
     9  	"cloud.google.com/go/spanner"
    10  )
    11  
    12  type Series struct {
    13  	ID          string `spanner:"ID"`
    14  	ExtID       string `spanner:"ExtID"`
    15  	AuthorName  string `spanner:"AuthorName"`
    16  	AuthorEmail string `spanner:"AuthorEmail"`
    17  	Title       string `spanner:"Title"`
    18  	Link        string `spanner:"Link"`
    19  	Version     int64  `spanner:"Version"`
    20  	// In LKML patches, there are often hints at the target tree for the patch.
    21  	SubjectTags []string  `spanner:"SubjectTags"`
    22  	PublishedAt time.Time `spanner:"PublishedAt"`
    23  	// TODO: we could ger rid of the field by using slightly more complicated SQL queries.
    24  	LatestSessionID spanner.NullString `spanner:"LatestSessionID"`
    25  	Cc              []string           `spanner:"Cc"`
    26  }
    27  
    28  func (s *Series) SetLatestSession(session *Session) {
    29  	s.LatestSessionID = spanner.NullString{StringVal: session.ID, Valid: true}
    30  }
    31  
    32  type Patch struct {
    33  	ID       string `spanner:"ID"`
    34  	Seq      int64  `spanner:"Seq"`
    35  	SeriesID string `spanner:"SeriesID"`
    36  	Title    string `spanner:"Title"`
    37  	Link     string `spanner:"Link"`
    38  	BodyURI  string `spanner:"BodyURI"`
    39  }
    40  
    41  type Build struct {
    42  	ID         string             `spanner:"ID"`
    43  	TreeName   string             `spanner:"TreeName"`
    44  	TreeURL    string             `spanner:"TreeURL"`
    45  	CommitHash string             `spanner:"CommitHash"`
    46  	CommitDate time.Time          `spanner:"CommitDate"`
    47  	SeriesID   spanner.NullString `spanner:"SeriesID"`
    48  	Arch       string             `spanner:"Arch"`
    49  	ConfigName string             `spanner:"ConfigName"`
    50  	ConfigURI  string             `spanner:"ConfigURI"`
    51  	LogURI     string             `spanner:"LogURI"`
    52  	Status     string             `spanner:"Status"`
    53  	Compiler   string             `spanner:"Compiler"`
    54  }
    55  
    56  func (b *Build) SetSeriesID(val string) {
    57  	b.SeriesID = spanner.NullString{StringVal: val, Valid: true}
    58  }
    59  
    60  const (
    61  	BuildFailed string = "build_failed"
    62  	//	BuiltNotTested  string = "built"
    63  	//	BuildTestFailed string = "tests_failed"
    64  	BuildSuccess string = "success"
    65  )
    66  
    67  type Session struct {
    68  	ID           string             `spanner:"ID"`
    69  	SeriesID     string             `spanner:"SeriesID"`
    70  	CreatedAt    time.Time          `spanner:"CreatedAt"`
    71  	StartedAt    spanner.NullTime   `spanner:"StartedAt"`
    72  	FinishedAt   spanner.NullTime   `spanner:"FinishedAt"`
    73  	SkipReason   spanner.NullString `spanner:"SkipReason"`
    74  	LogURI       string             `spanner:"LogURI"`
    75  	TriageLogURI string             `spanner:"TriageLogURI"`
    76  	Tags         []string           `spanner:"Tags"`
    77  	// TODO: to accept more specific fuzzing assignment,
    78  	// add Triager, BaseRepo, BaseCommit, Config fields.
    79  }
    80  
    81  type SessionStatus string
    82  
    83  const (
    84  	SessionStatusWaiting    SessionStatus = "waiting"
    85  	SessionStatusInProgress SessionStatus = "in progress"
    86  	SessionStatusFinished   SessionStatus = "finished"
    87  	SessionStatusSkipped    SessionStatus = "skipped"
    88  	// To be used in filters.
    89  	SessionStatusAny SessionStatus = ""
    90  )
    91  
    92  // It could have been a calculated field in Spanner, but the Go library for Spanner currently
    93  // does not support read-only fields.
    94  func (s *Session) Status() SessionStatus {
    95  	if s.StartedAt.IsNull() {
    96  		return SessionStatusWaiting
    97  	} else if s.FinishedAt.IsNull() {
    98  		return SessionStatusInProgress
    99  	} else if !s.SkipReason.IsNull() {
   100  		return SessionStatusSkipped
   101  	}
   102  	return SessionStatusFinished
   103  }
   104  
   105  func (s *Session) Duration() time.Duration {
   106  	if s.FinishedAt.IsNull() {
   107  		return 0
   108  	}
   109  	return s.FinishedAt.Time.Sub(s.StartedAt.Time).Truncate(time.Minute)
   110  }
   111  
   112  func (s *Session) SetStartedAt(t time.Time) {
   113  	s.StartedAt = spanner.NullTime{Time: t, Valid: true}
   114  }
   115  
   116  func (s *Session) SetFinishedAt(t time.Time) {
   117  	s.FinishedAt = spanner.NullTime{Time: t, Valid: true}
   118  }
   119  
   120  func (s *Session) SetSkipReason(reason string) {
   121  	s.SkipReason = spanner.NullString{StringVal: reason, Valid: true}
   122  }
   123  
   124  type SessionTest struct {
   125  	SessionID           string             `spanner:"SessionID"`
   126  	BaseBuildID         spanner.NullString `spanner:"BaseBuildID"`
   127  	PatchedBuildID      spanner.NullString `spanner:"PatchedBuildID"`
   128  	UpdatedAt           time.Time          `spanner:"UpdatedAt"`
   129  	TestName            string             `spanner:"TestName"`
   130  	Result              string             `spanner:"Result"`
   131  	LogURI              string             `spanner:"LogURI"`
   132  	ArtifactsArchiveURI string             `spanner:"ArtifactsArchiveURI"`
   133  }
   134  
   135  type Finding struct {
   136  	ID              string           `spanner:"ID"`
   137  	SessionID       string           `spanner:"SessionID"`
   138  	TestName        string           `spanner:"TestName"`
   139  	Title           string           `spanner:"Title"`
   140  	ReportURI       string           `spanner:"ReportURI"`
   141  	LogURI          string           `spanner:"LogURI"`
   142  	SyzReproURI     string           `spanner:"SyzReproURI"`
   143  	SyzReproOptsURI string           `spanner:"SyzReproOptsURI"`
   144  	CReproURI       string           `spanner:"CReproURI"`
   145  	InvalidatedAt   spanner.NullTime `spanner:"InvalidatedAt"`
   146  }
   147  
   148  func (f *Finding) SetInvalidatedAt(t time.Time) {
   149  	f.InvalidatedAt = spanner.NullTime{Time: t, Valid: true}
   150  }
   151  
   152  type SessionReport struct {
   153  	ID         string           `spanner:"ID"`
   154  	SessionID  string           `spanner:"SessionID"`
   155  	ReportedAt spanner.NullTime `spanner:"ReportedAt"`
   156  	Moderation bool             `spanner:"Moderation"`
   157  	Reporter   string           `spanner:"Reporter"`
   158  }
   159  
   160  func (s *SessionReport) SetReportedAt(t time.Time) {
   161  	s.ReportedAt = spanner.NullTime{Time: t, Valid: true}
   162  }
   163  
   164  type ReportReply struct {
   165  	MessageID string    `spanner:"MessageID"`
   166  	ReportID  string    `spanner:"ReportID"`
   167  	Time      time.Time `spanner:"Time"`
   168  }
   169  
   170  // BaseFinding collects all crashes observed on the base kernel tree.
   171  // It will be used to avoid unnecessary bug reproduction attempts.
   172  type BaseFinding struct {
   173  	CommitHash string `spanner:"CommitHash"`
   174  	Config     string `spanner:"Config"`
   175  	Arch       string `spanner:"Arch"`
   176  	Title      string `spanner:"Title"`
   177  }