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 }