LCOV - code coverage report
Current view: top level - entities - LabelFunction.java (source / functions) Hit Total Coverage
Test: _coverage_report.dat Lines: 43 44 97.7 %
Date: 2022-11-19 15:00:39 Functions: 8 9 88.9 %

          Line data    Source code
       1             : // Copyright (C) 2017 The Android Open Source Project
       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             : package com.google.gerrit.entities;
      16             : 
      17             : import com.google.gerrit.common.Nullable;
      18             : import com.google.gerrit.entities.SubmitRecord.Label;
      19             : import java.util.Collections;
      20             : import java.util.LinkedHashMap;
      21             : import java.util.Map;
      22             : import java.util.Optional;
      23             : 
      24             : /**
      25             :  * Functions for determining submittability based on label votes.
      26             :  *
      27             :  * <p>Only describes built-in label functions. Admins can extend the logic arbitrarily using Prolog
      28             :  * rules, in which case the choice of function in the project config is ignored.
      29             :  *
      30             :  * <p>Function semantics are documented in {@code config-labels.txt}, and actual behavior is
      31             :  * implemented both in Prolog in {@code gerrit_common.pl} and in the {@link #check} method.
      32             :  */
      33         154 : public enum LabelFunction {
      34         154 :   ANY_WITH_BLOCK("AnyWithBlock", true, false, false),
      35         154 :   MAX_WITH_BLOCK("MaxWithBlock", true, true, true),
      36         154 :   MAX_NO_BLOCK("MaxNoBlock", false, true, true),
      37         154 :   NO_BLOCK("NoBlock"),
      38         154 :   NO_OP("NoOp"),
      39         154 :   PATCH_SET_LOCK("PatchSetLock");
      40             : 
      41             :   public static final Map<String, LabelFunction> ALL;
      42             : 
      43             :   static {
      44         154 :     Map<String, LabelFunction> all = new LinkedHashMap<>();
      45         154 :     for (LabelFunction f : values()) {
      46         154 :       all.put(f.getFunctionName(), f);
      47             :     }
      48         154 :     ALL = Collections.unmodifiableMap(all);
      49         154 :   }
      50             : 
      51             :   public static Optional<LabelFunction> parse(@Nullable String str) {
      52         151 :     return Optional.ofNullable(ALL.get(str));
      53             :   }
      54             : 
      55             :   private final String name;
      56             :   private final boolean isBlock;
      57             :   private final boolean isRequired;
      58             :   private final boolean requiresMaxValue;
      59             : 
      60             :   LabelFunction(String name) {
      61         154 :     this(name, false, false, false);
      62         154 :   }
      63             : 
      64         154 :   LabelFunction(String name, boolean isBlock, boolean isRequired, boolean requiresMaxValue) {
      65         154 :     this.name = name;
      66         154 :     this.isBlock = isBlock;
      67         154 :     this.isRequired = isRequired;
      68         154 :     this.requiresMaxValue = requiresMaxValue;
      69         154 :   }
      70             : 
      71             :   /** The function name as defined in documentation and {@code project.config}. */
      72             :   public String getFunctionName() {
      73         154 :     return name;
      74             :   }
      75             : 
      76             :   /** Whether the label is a "block" label, meaning a minimum vote will prevent submission. */
      77             :   public boolean isBlock() {
      78         103 :     return isBlock;
      79             :   }
      80             : 
      81             :   /** Whether the label is a mandatory label, meaning absence of votes will prevent submission. */
      82             :   public boolean isRequired() {
      83           3 :     return isRequired;
      84             :   }
      85             : 
      86             :   /** Whether the label requires a vote with the maximum value to allow submission. */
      87             :   public boolean isMaxValueRequired() {
      88           0 :     return requiresMaxValue;
      89             :   }
      90             : 
      91             :   public Label check(LabelType labelType, Iterable<PatchSetApproval> approvals) {
      92         104 :     Label submitRecordLabel = new Label();
      93         104 :     submitRecordLabel.label = labelType.getName();
      94             : 
      95         104 :     submitRecordLabel.status = SubmitRecord.Label.Status.MAY;
      96         104 :     if (isRequired) {
      97         104 :       submitRecordLabel.status = SubmitRecord.Label.Status.NEED;
      98             :     }
      99             : 
     100         104 :     for (PatchSetApproval a : approvals) {
     101          58 :       if (a.value() == 0) {
     102          14 :         continue;
     103             :       }
     104             : 
     105          58 :       if (isBlock && labelType.isMaxNegative(a)) {
     106          20 :         submitRecordLabel.appliedBy = a.accountId();
     107          20 :         submitRecordLabel.status = SubmitRecord.Label.Status.REJECT;
     108          20 :         return submitRecordLabel;
     109             :       }
     110             : 
     111          58 :       if (labelType.isMaxPositive(a) || !requiresMaxValue) {
     112          56 :         submitRecordLabel.appliedBy = a.accountId();
     113             : 
     114          56 :         submitRecordLabel.status = SubmitRecord.Label.Status.MAY;
     115          56 :         if (isRequired) {
     116          56 :           submitRecordLabel.status = SubmitRecord.Label.Status.OK;
     117             :         }
     118             :       }
     119          58 :     }
     120             : 
     121         104 :     return submitRecordLabel;
     122             :   }
     123             : }

Generated by: LCOV version 1.16+git.20220603.dfeb750