go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/milo/ui/src/monitoring/util/server_json.ts (about) 1 // Copyright 2024 The LUCI Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 import { IssueJson } from '@/common/hooks/gapi_query/corp_issuetracker'; 16 import { TestCulprit } from '@/proto/go.chromium.org/luci/bisection/proto/v1/analyses.pb'; 17 18 export type TreesJson = TreeJson[]; 19 20 export interface TreeJson { 21 name: string; 22 display_name: string; 23 default_monorail_project_name?: string; // default to 'chromium' if undefined. 24 bug_queue_label?: string; 25 hotlistId?: string; 26 } 27 28 export const treeJsonFromName = (treeName: string): TreeJson | null => { 29 // trees-json is a string containing json, so we need one parse to get the string, and another to get the structure. 30 const text = document.getElementById('trees-json')?.innerText; 31 if (!text) return null; 32 const trees = JSON.parse(JSON.parse(text)); 33 return trees.filter((t: TreeJson) => t.name === treeName)?.[0]; 34 }; 35 36 // TODO: AlertJson fields were added based on example data. There may be missing or incorrect fields. 37 export interface AlertJson { 38 key: string; 39 title: string; 40 body: string; 41 severity: number; 42 time: number; 43 start_time: number; 44 links: null; 45 tags: null; 46 type: string; 47 extension: AlertExtensionJson; 48 resolved: boolean; 49 } 50 51 // TODO: AlertExtensionJson fields were added based on example data. There may be missing or incorrect fields. 52 export interface AlertExtensionJson { 53 builders: AlertBuilderJson[]; 54 culprits: null; 55 has_findings: boolean; 56 is_finished: boolean; 57 is_supported: boolean; 58 reason: AlertReasonJson; 59 regression_ranges: RegressionRangeJson[]; 60 suspected_cls: null; 61 tree_closer: false; 62 luci_bisection_result?: LuciBisectionResult; 63 } 64 65 // TODO: AlertBuilderJson fields were added based on example data. There may be missing or incorrect fields. 66 export interface AlertBuilderJson { 67 bucket: string; 68 build_status: string; 69 builder_group: string; 70 count: number; 71 failing_tests_trunc: string; 72 first_failing_rev: RevisionJson; 73 first_failure: number; 74 first_failure_build_number: number; 75 first_failure_url: string; 76 last_passing_rev: RevisionJson; 77 latest_failure: number; 78 latest_failure_build_number: number; 79 latest_failure_url: string; 80 latest_passing: number; 81 name: string; 82 project: string; 83 start_time: number; 84 url: string; 85 } 86 87 // TODO: RevisionJson fields were added based on example data. There may be missing or incorrect fields. 88 export interface RevisionJson { 89 author: string; 90 branch: string; 91 commit_position: number; 92 description: string; 93 git_hash: string; 94 host: string; 95 link: string; 96 repo: string; 97 when: number; 98 } 99 100 // TODO: AlertReasonJson fields were added based on example data. There may be missing or incorrect fields. 101 export interface AlertReasonJson { 102 num_failing_tests: number; 103 step: string; 104 tests: AlertReasonTestJson[]; 105 } 106 107 // TODO: AlertReasonTestJson fields were added based on example data. There may be missing or incorrect fields. 108 export interface AlertReasonTestJson { 109 test_name: string; 110 test_id: string; 111 realm: string; 112 variant_hash: string; 113 cluster_name: string; 114 cur_counts: TestResultCountsJson; 115 prev_counts: TestResultCountsJson; 116 cur_start_hour: string; 117 prev_end_hour: string; 118 ref_hash: string; 119 regression_end_position: number; 120 regression_start_position: number; 121 luci_bisection_result?: LuciBisectionTestAnalysisResult; 122 } 123 124 export interface TestResultCountsJson { 125 total_results: number; 126 unexpected_results: number; 127 } 128 129 // TODO: RegressionRangeJson fields were added based on example data. There may be missing or incorrect fields. 130 export interface RegressionRangeJson { 131 host: string; 132 positions: string[]; 133 repo: string; 134 revisions: string[]; 135 revisions_with_results: null; 136 url: string; 137 } 138 139 // TODO: AnnotationJson fields were added based on example data. There may be missing or incorrect fields. 140 export interface AnnotationJson { 141 KeyDigest: string; 142 ModificationTime: string; 143 Tree: string; 144 bug_data: { [id: number]: AnnotationBugDataJson }; 145 bugs: BugId[]; 146 comments: null; 147 group_id: string; 148 key: string; 149 snoozeTime: number | null; 150 } 151 152 export interface BugId { 153 id: number; 154 projectId: string; 155 } 156 157 export interface AnnotationBugDataJson { 158 id: string; 159 projectId: string; 160 status: string; 161 summary: string; 162 } 163 164 export interface LuciBisectionResult { 165 analysis?: LuciBisectionAnalysis; 166 is_supported?: boolean; 167 failed_bbid?: string; 168 } 169 170 export interface LuciBisectionTestAnalysisResult { 171 analysis_id: string; 172 status: string; 173 culprit?: TestCulprit; 174 } 175 176 export interface LuciBisectionAnalysis { 177 analysis_id: string; 178 heuristic_result?: HeuristicAnalysis; 179 nth_section_result?: NthSectionAnalysis; 180 culprits?: Culprit[]; 181 } 182 183 export interface HeuristicAnalysis { 184 suspects: HeuristicSuspect[]; 185 } 186 187 export interface HeuristicSuspect { 188 // TODO (nqmtuan): Also display if a verification is in progress. 189 reviewUrl: string; 190 justification: string; 191 score: number; 192 confidence_level: number; 193 } 194 195 export interface NthSectionAnalysis { 196 suspect?: NthSectionSuspect; 197 remaining_nth_section_range?: RegressionRange; 198 } 199 200 export interface NthSectionSuspect { 201 reviewUrl: string; 202 reviewTitle: string; 203 } 204 205 export interface RegressionRange { 206 last_passed: GitilesCommit; 207 first_failed: GitilesCommit; 208 } 209 210 export interface GitilesCommit { 211 host: string; 212 project: string; 213 ref: string; 214 id: string; 215 } 216 217 export interface Culprit { 218 review_url: string; 219 review_title: string; 220 } 221 222 export interface Bug { 223 number: string; 224 link: string; 225 summary: string | undefined; 226 priority: number | undefined; 227 status: string | undefined; 228 labels: string[]; 229 } 230 231 export const bugFromJson = (issue: IssueJson): Bug => { 232 const number = issue.issueId; 233 return { 234 number: number, 235 link: `http://b/${number}`, 236 summary: issue.issueState.title, 237 priority: parseInt(issue.issueState.priority.substring(1)), 238 status: 239 issue.issueState.status[0] + 240 issue.issueState.status.substring(1).toLowerCase(), 241 labels: [], // FIXME: what is the equivalent of labels for the UI? 242 }; 243 }; 244 245 export const bugFromId = (bug: string): Bug => { 246 return { 247 number: bug, 248 labels: [], 249 link: `http://b/${bug}`, 250 priority: undefined, 251 status: undefined, 252 summary: undefined, 253 }; 254 };