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  };