go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/analysis/proto/config/project_config.proto (about) 1 // Copyright 2022 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 syntax = "proto3"; 16 17 package luci.analysis.config; 18 19 import "google/protobuf/timestamp.proto"; 20 21 import "go.chromium.org/luci/analysis/proto/config/test_variant_analysis_config.proto"; 22 23 option go_package = "go.chromium.org/luci/analysis/proto/config;configpb"; 24 25 // ProjectConfig is the project-specific configuration data for LUCI Analysis. 26 message ProjectConfig { 27 // The project metadata (eg. display name). 28 ProjectMetadata project_metadata = 6; 29 30 // The last time this project configuration was updated. 31 // LUCI Analysis sets and stores this value internally. Do not set 32 // in your project's configuration file, it will be ignored. 33 google.protobuf.Timestamp last_updated = 4; 34 35 // Configuration for how to cluster test results. 36 Clustering clustering = 5; 37 38 // Configuration for automatic bug management. 39 BugManagement bug_management = 9; 40 41 // Configuration related to metrics in LUCI Analysis. 42 Metrics metrics = 11; 43 44 // Configuration for when tests are considered stable enough 45 // to gate code changes. Only relevant for projects which integrate 46 // with the TestVariants.QueryStability RPC to exonerate 47 // unstable tests in presubmit. 48 TestStabilityCriteria test_stability_criteria = 12; 49 50 // Deprecated configuration follows. Setting these no longer 51 // has any effect. 52 53 // Per realm configurations. 54 repeated RealmConfig realms = 3; 55 56 // Deprecated. No longer has any effect. Retained for textproto 57 // compatibility only. Use bug_management.default_bug_system instead. 58 BugSystem bug_system = 7; 59 60 // Deprecated. No longer has any effect. Retained for textproto 61 // compatibility only. Use bug_management.monorail instead. 62 MonorailProject monorail = 1; 63 64 // Deprecated. No longer has any effect. Retained for textproto 65 // compatibility only. Use bug_management.buganizer instead. 66 BuganizerProject buganizer = 8; 67 68 // Deprecated. No longer has any effect. Retained for textproto 69 // compatibility only. Use bug_management.policies instead. 70 ImpactThreshold bug_filing_threshold = 2; 71 72 // Deprecated. No longer has any effect. Retained for textproto 73 // compatibility only. Use bug_management.policies instead. 74 repeated ImpactMetricThreshold bug_filing_thresholds = 10; 75 76 // Next ID: 13 77 } 78 79 80 // ProjectMetadata provides data about the project that are mostly used in ui. 81 message ProjectMetadata { 82 83 // Indicates the preferred display name for the project in the UI. 84 // Deprecated: not used anymore. 85 string display_name = 1; 86 } 87 88 // Settings related to metrics used to measure cluster impact. 89 message Metrics { 90 message MetricOverride { 91 // The id of the impact metric. 92 // 93 // Full list of available metrics here: 94 // https://source.chromium.org/chromium/infra/infra/+/main:go/src/go.chromium.org/luci/analysis/internal/analysis/metrics/metrics.go 95 string metric_id = 1; 96 97 // Whether the metric should be selected by default. 98 optional bool is_default = 2; 99 100 // Controls the default sort order between metrics. By default, 101 // a list will sort by the metric with the highest sort priority, 102 // followed by the metric with second highest sort priority, 103 // and so on. 104 optional int32 sort_priority = 3; 105 } 106 107 // Overrides to the default metrics configuration for a project. 108 repeated MetricOverride overrides = 1; 109 } 110 111 // Settings related to bug management. 112 message BugManagement { 113 // Disables creation of comments on bugs when LUCI Analysis successfully 114 // handles duplicate bugs by merging/updating failure association rules. 115 // 116 // This setting does not prevent the creation of comments in response 117 // to errors handling duplicate bugs. 118 bool disable_duplicate_bug_comments = 1; 119 120 // The set of policies which control the (re-)opening, closure and 121 // prioritization of bugs under the control of LUCI Analysis. 122 repeated BugManagementPolicy policies = 2; 123 124 // The default bug system to route new bugs to, when the bug system and 125 // component could not be automatically detected from a test metadata. 126 BugSystem default_bug_system = 3; 127 128 // Buganizer-specific bug filing configuration. 129 BuganizerProject buganizer = 4; 130 131 // Monorail-specific bug filing configuration. 132 MonorailProject monorail = 5; 133 } 134 135 // A bug management policy in LUCI Analysis. 136 // 137 // Bug management policies control when and how bugs are automatically 138 // opened, prioritised, and verified as fixed. Each policy has a user-visible 139 // identity in the UI and can post custom instructions on the bug. 140 // 141 // LUCI Analysis avoids filing multiple bugs for the same failures by 142 // allowing multiple policies to activate on the same failure association 143 // rule. The bug associated with a rule will only be verified if all policies 144 // have de-activated. 145 message BugManagementPolicy { 146 // A unique identifier for the bug management policy. 147 // 148 // Policies are stateful in that LUCI Analysis tracks which bugs have met the 149 // activation condition on the policy (and not since met the deactivation 150 // condition). 151 // 152 // Changing this value changes the identity of the policy and hence results in 153 // the activation state for the policy being lost for all bugs. 154 // 155 // Valid syntax: ^[a-z]([a-z0-9-]{0,62}[a-z0-9])?$. (Syntax designed to comply 156 // with google.aip.dev/122 for resource IDs.) 157 string id = 1; 158 159 // The owners of the policy, who can be contacted if there are issues/concerns 160 // about the policy. Each item in the list should be an @google.com email 161 // address. At least one owner (preferably a group) is required. 162 repeated string owners = 2; 163 164 // A short one-line description for the problem the policy identifies, which 165 // will appear on the UI and in bugs comments. This is a sentence fragment 166 // and not a sentence, so please do NOT include a full stop and or starting 167 // capital letter. 168 // 169 // For example, "test variant(s) are being exonerated in presubmit". 170 string human_readable_name = 3; 171 172 // The priority of the problem this policy defines. 173 // 174 // If: 175 // - the priority of the bug associated with a rule 176 // differs from this priority, and 177 // - the policy is activate on the rule (see `metrics`), and 178 // - LUCI Analysis is controlling the priority of the bug 179 // (the "Update bug priority" switch on the rule is enabled), 180 // the priority of the bug will be updated to match this priority. 181 // 182 // Where are there multiple policies active on the same rule, 183 // the highest priority (of all active policies) will be used. 184 // 185 // For monorail projects, the buganizer priority will be converted to the 186 // equivalent monorail priority (P0 is converted to Pri-0, P1 to Pri-1, 187 // P2 to Pri-2, etc.) until monorail is turned down. 188 BuganizerPriority priority = 4; 189 190 // The set of metrics which will control activation of the bug-filing policy. 191 // If a policy activates on a suggested cluster, a new bug will be filed. 192 // If a policy activates on an existing rule cluster, the bug will be 193 // updated. 194 // 195 // The policy will activate if the activation threshold is met on *ANY* 196 // metric, and will de-activate only if the deactivation threshold is met 197 // on *ALL* metrics. 198 // 199 // Activation on suggested clusters will be based on the metric values after 200 // excluding failures for which a bug has already been filed. This is to 201 // avoid duplicate bug filing. 202 repeated Metric metrics = 5; 203 204 // A metric used to control activation of a bug-filing policy. 205 message Metric { 206 // The identifier of the metric. 207 // 208 // Full list of available metrics here: 209 // https://source.chromium.org/chromium/infra/infra/+/main:go/src/go.chromium.org/luci/analysis/internal/analysis/metrics/metrics.go 210 string metric_id = 1; 211 212 // The level at which the policy activates. Activation occurs if the 213 // cluster impact meets or exceeds this threshold. 214 // MUST imply deactivation_threshold. 215 MetricThreshold activation_threshold = 2; 216 217 // The minimum metric level at which the policy remains active. 218 // Deactivation occcurs if the cluster impact is below the de-activation 219 // threshold. Deactivation_threshold should be set significantly lower 220 // than activation_threshold to prevent policies repeatedly activating 221 // and deactivating due to noise in the data, e.g. less tests executed 222 // on weekends. 223 MetricThreshold deactivation_threshold = 3; 224 } 225 226 // Expanatory text of the problem the policy identified, shown on the 227 // user interface when the user requests more information. Required. 228 Explanation explanation = 6; 229 230 // Content displayed on the user interface, to explain the problem and 231 // guide a developer to fix it. 232 message Explanation { 233 // A longer human-readable description of the problem this policy 234 // has identified, in HTML. 235 // 236 // For example, "Test variant(s) in this cluster are being exonerated 237 // (ignored) in presubmit because they are too flaky or failing. This 238 // means they are no longer effective at preventing the breakage of 239 // the functionality the test(s) cover.". 240 // 241 // MUST be sanitised by UI before rendering. Sanitisation is only 242 // required to support simple uses of the following tags: ul, li, a. 243 string problem_html = 1; 244 245 // A description of how a human should go about trying to fix the 246 // problem, in HTML. 247 // 248 // For example, "<ul> 249 // <li>View recent failures</li> 250 // <li><a href="http://goto.google.com/demote-from-cq">Demote</a> the test from CQ</li> 251 // </ul>" 252 // 253 // MUST be sanitised by UI before rendering. Sanitisation is only 254 // required to support simple uses of the following tags: ul, li, a. 255 string action_html = 2; 256 } 257 258 // Settings which affect the contents of a bug for a policy has activated. 259 BugTemplate bug_template = 7; 260 261 // Settings which affect the contents of a bug for a policy has activated. 262 message BugTemplate { 263 // Text to be included in the bug comment advising of the activation of the 264 // the policy. Leave blank to post no comment. 265 // 266 // The text here will be interpreted as a template by the golang 267 // template/text library (https://pkg.go.dev/text/template). The following 268 // fields are available: 269 // - RuleURL (string): The URL of the rule page. 270 // - BugID (BugID): The system-specific bug identifier. This type 271 // exposes the following methods with no arguments: 272 // - IsBuganizer returns (bool) indicating if the bug is a buganizer bug. 273 // - IsMonorail returns (bool) indicating if the bug is a monorail bug. 274 // - MonorailProject returns (string, error) indicating the monorail 275 // project, if the bug is a monorail bug, and errors otherwise. 276 // - MonorailBugID returns (string, error) indicating the monorail 277 // bug ID, if the bug is a monorail bug, and errors otherwise. 278 // - BuganizerBugID returns (string, error) indicating the buganizer 279 // bug ID, if the bug is a buganizer bug, and errors otherwise. 280 // 281 // Model usage of BugID in a template: 282 // ``` 283 // {{if .BugID.IsBuganizer}}Buganizer bug: {{.BugID.BuganizerBugID}}{{end}} 284 // {{if .BugID.IsMonorail}}Monorail bug: {{.BugID.MonorailProject}}/{{.BugID.MonorailBugID}}{{end}} 285 // ``` 286 // 287 // As for functions, only the standard global functions are available, see: 288 // https://pkg.go.dev/text/template#hdr-Functions 289 string comment_template = 1; 290 291 // Bug content options that are specific to Google issue tracker (Buganizer). 292 Buganizer buganizer = 2; 293 294 // Bug content options that are specific to monorail. 295 Monorail monorail = 3; 296 297 // TODO(meiring): Add assignee, cc list. 298 299 // Policy configuration that is specific to Google issue tracker (Buganizer). 300 message Buganizer { 301 // The numeric ID of the buganizer hotlist to add the issue to. Optional. 302 // The bug is added to the hostlist when the policy transitions to 303 // activated. The issue is not removed from the hotlist if the policy is 304 // deactivated, to avoid excessive bug updates. 305 repeated int64 hotlists = 1; 306 } 307 308 // Policy configuration that is specific to monorail issue tracker. 309 message Monorail { 310 // The labels to apply to the bug. 311 repeated string labels = 1; 312 } 313 } 314 } 315 316 // Deprecated. No longer has any effect. Retained for textproto 317 // compatibility only. 318 message ImpactThreshold { 319 MetricThreshold test_results_failed = 4; 320 MetricThreshold test_runs_failed = 5; 321 MetricThreshold presubmit_runs_failed = 6; 322 MetricThreshold critical_failures_exonerated = 7; 323 optional int64 unexpected_failures_1d = 1; 324 optional int64 unexpected_failures_3d = 2; 325 optional int64 unexpected_failures_7d = 3; 326 } 327 328 // ImpactMetricThreshold specifies a condition on a cluster's impact metric. 329 message ImpactMetricThreshold { 330 // The id of the impact metric. 331 // e.g. 332 // human-cls-failed-presubmit: The number of presubmit runs that failed. 333 // critical-failures-exonerated: The number of test failures on critical 334 // builders that were exonerated with an 335 // exoneration reason other than NOT_CRITICAL. 336 // test-runs-failed: The number of test runs that failed. 337 // A test run (also known as a 'shard' (chromium) or 338 // 'task' (Chrome OS)) is considered failed if all tries of 339 // test(s) in it unexpectedly failed. The failed test run is 340 // attributed to the last failure of each of the test(s) 341 // that failed on all tries. 342 // failures: The number of test results that were unexpected failures. 343 // 344 // Full list of available metrics here: 345 // https://source.chromium.org/chromium/infra/infra/+/main:go/src/go.chromium.org/luci/analysis/internal/analysis/metrics/metrics.go 346 string metric_id = 1; 347 348 // The thresholds against a metric. 349 MetricThreshold threshold = 2; 350 } 351 352 // MetricThreshold specifies thresholds for a particular metric. 353 // The threshold is considered satisfied if any of the individual metric 354 // thresholds is met or exceeded (i.e. if multiple thresholds are set, they 355 // are combined using an OR-semantic). If no threshold is set, the threshold 356 // as a whole is unsatisfiable. 357 message MetricThreshold { 358 // The threshold for one day. 359 optional int64 one_day = 1; 360 361 // The threshold for three day. 362 optional int64 three_day = 2; 363 364 // The threshold for seven days. 365 optional int64 seven_day = 3; 366 } 367 368 // MonorailProject describes the configuration to use when filing bugs 369 // into a given monorail project. 370 message MonorailProject { 371 // The monorail project being described. 372 // E.g. "chromium". 373 string project = 1; 374 375 // The field values to use when creating new bugs. 376 // For example, on chromium issue tracker, there is a manadatory 377 // issue type field (field 10), which must be set to "Bug". 378 repeated MonorailFieldValue default_field_values = 2; 379 380 // The ID of the issue's priority field. You can find this by visiting 381 // https://monorail-prod.appspot.com/p/<project>/adminLabels, scrolling 382 // down to Custom fields and finding the ID of the field you wish to set. 383 // 384 // This field must support the values: "Pri-0", "Pri-1", "Pri-2", "Pri-3". 385 int64 priority_field_id = 3; 386 387 // Deprecated. No longer has any effect. Retained for textproto 388 // compatibility only. Use bug_management.policies instead. 389 repeated MonorailPriority priorities = 4; 390 391 // Deprecated. No longer has any effect. Retained for textproto 392 // compatibility only. 393 int64 priority_hysteresis_percent = 5; 394 395 // The prefix that should appear when displaying bugs from the 396 // given bug tracking system. E.g. "crbug.com" or "fxbug.dev". 397 // If no prefix is specified, only the bug number will appear. 398 // Otherwise, the supplifed prefix will appear, followed by a 399 // forward slash ("/"), followed by the bug number. 400 // Valid prefixes match `^[a-z0-9\-.]{0,64}$`. 401 string display_prefix = 6; 402 403 // The preferred hostname to use in links to monorail. For example, 404 // "bugs.chromium.org" or "bugs.fuchsia.dev". 405 string monorail_hostname = 7; 406 407 // Whether the Restrict-View-Google tag should be omitted on new 408 // auto-filed bugs. This makes those bugs publically visible. 409 // If unset, defaults to filing with Restrict-View-Google. 410 bool file_without_restrict_view_google = 8; 411 } 412 413 // MonorailFieldValue describes a monorail field/value pair. 414 message MonorailFieldValue { 415 // The ID of the field to set. You can find this by visiting 416 // https://monorail-prod.appspot.com/p/<project>/adminLabels, scrolling 417 // down to Custom fields and finding the ID of the field you wish to set. 418 int64 field_id = 1; 419 420 // The field value. Values are encoded according to the field type: 421 // - Enumeration types: the string enumeration value (e.g. "Bug"). 422 // - Integer types: the integer, converted to a string (e.g. "1052"). 423 // - String types: the value, included verbatim. 424 // - User types: the user's resource name (e.g. "users/2627516260"). 425 // User IDs can be identified by looking at the people listing for a 426 // project: https://monorail-prod.appspot.com/p/<project>/people/list. 427 // The User ID is included in the URL as u=<number> when clicking into 428 // the page for a particular user. For example, "user/3816576959" is 429 // https://monorail-prod.appspot.com/p/chromium/people/detail?u=3816576959. 430 // - Date types: the number of seconds since epoch, as a string 431 // (e.g. "1609459200" for 1 January 2021). 432 // - URL type: the URL value, as a string (e.g. "https://www.google.com/"). 433 // 434 // The source of truth for mapping of field types to values is as 435 // defined in the Monorail v3 API, found here: 436 // https://source.chromium.org/chromium/infra/infra/+/main:appengine/monorail/api/v3/api_proto/issue_objects.proto?q=%22message%20FieldValue%22 437 string value = 2; 438 } 439 440 441 // Deprecated. No longer has any effect. Retained for textproto 442 // compatibility only. 443 message MonorailPriority { 444 string priority = 1; 445 ImpactThreshold threshold = 2; 446 repeated ImpactMetricThreshold thresholds = 3; 447 } 448 449 // Configurations per realm. 450 message RealmConfig { 451 // Name of the realm. 452 // 453 // Must match `^[a-z0-9_\.\-/]{1,400}$`. 454 // Must not contain the project part. I.e. for "chromium:ci" realm the value 455 // here must be "ci". 456 string name = 1; 457 458 // Test variant analysis configurations for the realm. 459 TestVariantAnalysisConfig test_variant_analysis = 2; 460 } 461 462 // Configuration for how test results are clustered. 463 message Clustering { 464 // Rules used to cluster test results by test name. 465 // The order of rules matters; the first matching rule will be used 466 // to cluster a given test result. 467 // 468 // If no rule matches, the test results will be clustered on the 469 // full test name. This corresponds approximately to the rule: 470 // { 471 // name: "Full test name" 472 // pattern: "^(?P<testname>.*)$" 473 // like_template: "${testname}" 474 // } 475 repeated TestNameClusteringRule test_name_rules = 1; 476 477 // Regular expressions used to mask out part of a failure reason 478 // prior to clustering. 479 // 480 // The process of generating the clustering key is: 481 // 1. All '%', '_' and '\' characters in the failure reason are 482 // escaped to generate a SQL LIKE expression that matches the 483 // failure reason literally. 484 // 2. Regular expressions are run over the escaped failure reason 485 // one by one to identify parts of the failure reason to mask 486 // out (replace by a SQL LIKE wildcard match). 487 // 3. The clustering key is used in the failure association rule 488 // of a newly field bug, or hashed to generate the clustering 489 // key. 490 // 491 // For regular expression run against the failure reason, 492 // the part of the reason that matches the first (capturing) 493 // subexpression is masked out in the reason cluster. 494 // All non-overlapping matches are replaced. 495 // 496 // For example, given the masking expression: 497 // "^\\[Fixture failure\\] (\\w+):" 498 // The failure reason: 499 // `[Fixture failure] myFixture: some_error` 500 // will be escaped to (in step 1): 501 // `[Fixture failure] myFixture: some\_error` 502 // and will yield the following output after masking (step 2): 503 // `[Fixture failure] %: some\_error` 504 // 505 // Masking expressions are applied in the order that they appear 506 // in the list. 507 repeated string reason_mask_patterns = 2; 508 } 509 510 // A rule used to cluster a test result by test name. 511 message TestNameClusteringRule { 512 // A human-readable name for the rule. This should be unique for each rule. 513 // This may be used by LUCI Analysis to explain why it chose to cluster the 514 // test name in this way. 515 string name = 1; 516 517 // The regular expression describing which test names should be clustered 518 // by this rule. 519 // 520 // Example. 521 // Assume our project uploads google test (gtest) results with the test 522 // name prefix "gtest://". 523 // If want to cluster value-parameterized google tests 524 // together based on the test suite and test case name (ignoring 525 // the value parameter), we may use a pattern like: 526 // "^gtest://(\w+/)?(?P<testcase>\w+\.\w+)/\w+$" 527 // 528 // This will allow us to cluster test names like: 529 // "gtest://InstantiationOne/ColorSpaceTest.testNullTransform/0" 530 // "gtest://InstantiationOne/ColorSpaceTest.testNullTransform/1" 531 // "gtest://InstantiationTwo/ColorSpaceTest.testNullTransform/0" 532 // together. 533 // 534 // See https://github.com/google/googletest/blob/main/docs/advanced.md#how-to-write-value-parameterized-tests 535 // to understand value-parameterised google tests. 536 // 537 // Use ?P<name> to name capture groups, so their values can be used in 538 // like_template below. 539 string pattern = 2; 540 541 // The template used to generate a LIKE expression on test names 542 // that defines the test name cluster identified by this rule. 543 // 544 // This like expression has two purposes: 545 // (1) If the test name cluster is large enough to justify the 546 // creation of a bug cluster, the like expression is used to 547 // generate a failure association rule of the following form: 548 // test LIKE "<evaluated like_template>" 549 // (2) A hash of the expression is used as the clustering key for the 550 // test name-based suggested cluster. This generally has the desired 551 // clustering behaviour, i.e. the parts of the test name which 552 // are important enough to included in the LIKE expression for (1) 553 // are also those on which clustering should occur. 554 // 555 // As is usual for LIKE expressions, the template can contain 556 // the following operators to do wildcard matching: 557 // * '%' for wildcard match of an arbitrary number of characters, and 558 // * '_' for single character wildcard match. 559 // 560 // To match literal '%' or '_', escape the operator with a '\', 561 // i.e. use "\%" or "\_" to match literal '%' and '_' respectively. 562 // To match literal '\', you should use "\\". 563 // 564 // The template can refer to parts of the test name matched by 565 // the rule pattern using ${name}, where name refers to the capture 566 // group (see pattern). To insert the literal '$', the sequence '$$' 567 // should be used. 568 // 569 // Example. 570 // Assume our project uploads google test (gtest) results with the test 571 // name prefix "gtest://". Further assume we used the pattern: 572 // "^gtest://(\w+/)?(?P<testcase>\w+\.\w+)/\w+$" 573 // 574 // We might use the following like_template: 575 // "gtest://%${testcase}%" 576 // 577 // When instantiated for a value-parameterised test, e.g. 578 // "gtest://InstantiationOne/ColorSpaceTest.testNullTransform/0", 579 // the result would be a failure association rule like: 580 // test LIKE "gtest://%ColorSpaceTest.testNullTransform%" 581 // 582 // Note the use of ${testcase} to refer to the testname capture group 583 // specified in the pattern example. 584 // 585 // See https://github.com/google/googletest/blob/main/docs/advanced.md#how-to-write-value-parameterized-tests 586 // to understand value-parameterised google tests. 587 // 588 // It is known that not all clusters can be precisely matched by 589 // a LIKE expression. Nonetheless, LUCI Analysis prefers LIKE expressions 590 // as they are easier to comprehend and modify by users, and in 591 // most cases, the added precision is not required. 592 // 593 // As such, your rule should try to ensure the generated LIKE statement 594 // captures your clustering logic as best it can. Your LIKE expression 595 // MUST match all test names matched by your regex pattern, and MAY 596 // capture additional test names (though this is preferably minimised, 597 // to reduce differences between the suggested clusters and eventual 598 // bug clusters). 599 // 600 // LUCI Analysis will automatically escape any '%' '_' and '\' in parts of 601 // the matched test name before substitution to ensure captured parts 602 // of the test name are matched literally and not interpreted. 603 string like_template = 3; 604 } 605 606 // An enum that represents the bug filing system that the project uses. 607 enum BugSystem { 608 // An unspecified bug system, Do not use, this will 609 // break LUCI Analysis bug filing functionality. 610 BUG_SYSTEM_UNSPECIFIED = 0; 611 // Use Monorail to file bugs. 612 MONORAIL = 1; 613 // Use Buganizer to file bugs. 614 BUGANIZER = 2; 615 } 616 617 // This enum represents the Buganizer priorities. 618 // It is equivalent to the one in Buganizer API. 619 enum BuganizerPriority { 620 // Priority unspecified, Do not use this value. 621 BUGANIZER_PRIORITY_UNSPECIFIED = 0; 622 // P0, Highest priority. 623 P0 = 1; 624 P1 = 2; 625 P2 = 3; 626 P3 = 4; 627 P4 = 5; 628 } 629 630 // Defines the required details for a Buganizer component. 631 message BuganizerComponent { 632 // The id of the component that we will use to file bugs in. 633 int64 id = 1; 634 } 635 636 // The Buganizer configuration, this should only be 637 // used when the bug tracking system ins Buganizer. 638 message BuganizerProject { 639 // The default Buganizer component. 640 // This component will be used if we failed to find 641 // a component for a cluster. 642 BuganizerComponent default_component = 1; 643 644 // Deprecated. No longer has any effect. Retained for textproto 645 // compatibility only. 646 int64 priority_hysteresis_percent = 2; 647 648 // Deprecated. No longer has any effect. Retained for textproto 649 // compatibility only. 650 message PriorityMapping { 651 BuganizerPriority priority = 1; 652 ImpactThreshold threshold = 2; 653 repeated ImpactMetricThreshold thresholds = 3; 654 } 655 656 // Deprecated. No longer has any effect. Retained for textproto 657 // compatibility only. Use bug_management.policies instead. 658 repeated PriorityMapping priority_mappings = 3; 659 660 // Whether the LIMIT_VIEW_TRUSTED access level should be omitted 661 // on new auto-filed bugs and LIMIT_NONE access level should be set. 662 // This makes those bugs visible to all those who can see bugs 663 // in a given component. 664 bool file_without_limit_view_trusted = 4; 665 } 666 667 // Criteria used to determine test stability. This criteria is used 668 // to inform test exoneration in presubmit via the 669 // TestVariants.QueryStability RPC. 670 // 671 // Criteria is applied using a data source which contains 672 // the last 14 days' of test result data for all test variants, 673 // with certain filterings applied. 674 // 675 // See go/luci-exoneration-v2 as well each criteria below for more details. 676 message TestStabilityCriteria { 677 // The failure rate criteria to apply. Mandatory. 678 FailureRateCriteria failure_rate = 1; 679 680 // The failure rate criteria detects consistently failing 681 // and highly flaky tests (e.g. 95%+ failing) by looking for 682 // a high number of failures at the queried position of the 683 // test's history. 684 // 685 // The criteria obtains from the last 14 days' of filtered test data 686 // a set of (up to) 20 test runs centered on the queried commit 687 // position (10 prior and 10 after) and applies criteria 688 // to this in various ways. 689 // The 20 test runs are sorted by commit position and then time. 690 // 691 // See go/luci-exoneration-v2 for more detail. 692 message FailureRateCriteria { 693 // The number of unexpected test runs that must be 694 // found in a sliding window of size 10 containing the 695 // queried position to begin exoneration. 696 // 6 is a good starting value. 697 // 698 // The criteria is applied over sliding windows of size 699 // 10 around the query position. Assuming the full 20 test 700 // runs are obtained, this means 11 window positions are considered. 701 // If any window satisifes the threshold, the criteria is met 702 // and the test is considered unstable. 703 // 704 // In the event that 10 test runs cannot be found in the last 705 // 14 days of test history, a window sized to the available 706 // test runs is used but the criteria is not scaled. 707 int32 failure_threshold = 1; 708 709 // The number of consecutive unexpected test runs, which if 710 // present at the leading or trailing part of the (up to) 20 711 // test verdicts, will trigger exoneration. 712 // 3 is a good starting value. 713 // 714 // The consecutive failures must also touch the query position. 715 // 716 // This is designed to create a fast path to exoneration for 717 // 100% failing tests which produce a strong and consistent 718 // failing signal, leveraging the statistical significance 719 // of consecutive failures. If this threshold is met, 720 // the failure_threshold above does NOT need to be met. 721 // 722 // E.g. the following scenario WILL trigger this criteria for 723 // a threshold of four or less. 724 // 725 // History: >F F F F< P P P P P P P 726 // ^ 727 // Query position 728 // 729 // The following scenario WILL NOT trigger this criteria: 730 // 731 // History:>P F F F F< P P P P P P P 732 // ^ 733 // Query position 734 // 735 // (N.B. Direction of history is irrelevant as criteria is 736 // applied symmetrically. Either the left or right could 737 // represent 'later' by commit position.) 738 int32 consecutive_failure_threshold = 2; 739 } 740 741 // The flake rate criteria to apply. Mandatory. 742 FlakeRateCriteria flake_rate = 2; 743 744 // The flake rate criteria detects flaky tests by looking for 745 // examples where a test has obtained expected and unexpected 746 // test runs for the same sources under test. 747 // 748 // If there are more flaky source verdicts found than a threshold, 749 // the test is considered flaky. 750 // 751 // The analysis window is all source verdicts for 7 days' worth 752 // of commit positions either side of the queried position. 753 // The conversion between time and commit position is discussed 754 // in go/luci-exoneration-v2. 755 // 756 // In the event that an unsatisfactory number of source positions 757 // are found using this method, the window is enlarged to possibly 758 // include any verdict in the last 14 days. This is to improve 759 // detection performance on tests with a low volume of results. 760 message FlakeRateCriteria { 761 // The minimum number of source verdicts desired 762 // for the analysis window. 763 // 764 // As standard, all source verdicts for sources 765 // +/- 7 days from the queried position are used. 766 // 767 // However, if the number of verdicts is not equal 768 // to or greater than min_window, all source verdicts 769 // from the last 14 days will be used. This is designed 770 // to prioritise adequate flake detection performance 771 // for test variants with low result volumes, at the 772 // cost of data recency. 773 // 774 // If the number of source verdicts in the last 14 days 775 // is less than min_window, then whatever source verdicts 776 // are available are still used. 777 // 778 // 100 is a good starting value. 779 int32 min_window = 1; 780 781 // The minimum number of flaky source verdicts required 782 // to trigger the criteria. 2 is a good starting value. 783 int32 flake_threshold = 2; 784 785 // The minimum flake rate required to trigger the criteria, 786 // as a proportion of all source verdicts. This must be a 787 // value between 0.0 and 1.0. 788 // 0.01 (1%) is a good starting value. 789 // 790 // Both flake_threshold AND the flake_rate_threshold must be met 791 // for a test to be considered unstable. 792 // 793 // Note that not even the most flaky (50% flaky) test would 794 // be expected to produce more than a 25% flake rate if 795 // failures are retried once. This is because its expected 796 // outcomes are: 797 // - Pass on first try = 50% 798 // - Fail on first try, pass on second try = 25% (flaky) 799 // - Fail on both tries = 25% 800 double flake_rate_threshold = 3; 801 } 802 }