Skip to content

Commit

Permalink
Add parameter expansion for custom labels
Browse files Browse the repository at this point in the history
- deprecate verified/code-review minimum vote calculation
methods
- create string based label methods for minimum voting calcs
and aggregate all categories (verified & code-review included) into
the templated command allowing them to be expanded later all together
- remove redundant test (in which the scenario was testing the min.
voting calculation for the Verified label by using its associated method
instead of testing the scenario via getBuildCompletedCommand)
- update tests to check for the newly added custom label
  • Loading branch information
shemuwel committed Feb 19, 2024
1 parent 446a306 commit 2edfb6f
Show file tree
Hide file tree
Showing 9 changed files with 303 additions and 153 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,22 @@ public void setVerdictVote(BuildStatus status, Integer vote) {
}
}

/**
* Returns the value formatted as a placeholder.
* @return the value formatted as a placeholder.
*/
public String getPlaceholderValue() {
return verdictValue.toUpperCase().replace("-", "_");
}

/**
* Returns the original verdict category name
* @param placeholderValue the value to convert
* @return original verdict category name
*/
public static String fromPlaceholderValue(String placeholderValue) {
return placeholderValue.toLowerCase().replace("_", "-");
}

/**
* The Descriptor for a VerdictCategory.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@
import java.util.concurrent.TimeUnit;

//CS IGNORE LineLength FOR NEXT 11 LINES. REASON: static import.
import static com.sonyericsson.hudson.plugins.gerrit.trigger.config.Constants.CODE_REVIEW_LABEL;
import static com.sonyericsson.hudson.plugins.gerrit.trigger.config.Constants.VERIFIED_LABEL;
import static com.sonyericsson.hudson.plugins.gerrit.trigger.config.Constants.*;
import static com.sonymobile.tools.gerrit.gerritevents.GerritDefaultValues.DEFAULT_BUILD_SCHEDULE_DELAY;
import static com.sonymobile.tools.gerrit.gerritevents.GerritDefaultValues.DEFAULT_GERRIT_AUTH_KEY_FILE;
import static com.sonymobile.tools.gerrit.gerritevents.GerritDefaultValues.DEFAULT_GERRIT_AUTH_KEY_FILE_PASSWORD;
Expand Down Expand Up @@ -162,26 +161,6 @@ public class Config implements IGerritHudsonTriggerConfig {
/**
* Global default for notification level.
*/
public static final Notify DEFAULT_NOTIFICATION_LEVEL = Notify.ALL;

private static final String GERRIT_CMD_BUILD_STARTED_DEFAULT_VALUE = "gerrit review <CHANGE>,<PATCHSET> "
+ "--message 'Build Started <BUILDURL> <STARTED_STATS>' "
+ "--verified <VERIFIED> --code-review <CODE_REVIEW> --tag " + Constants.TAG_VALUE;
private static final String GERRIT_CMD_BUILD_SUCCESSFUL_DEFAULT_VALUE = "gerrit review <CHANGE>,<PATCHSET> "
+ "--message 'Build Successful <BUILDS_STATS>' "
+ "--verified <VERIFIED> --code-review <CODE_REVIEW> --tag " + Constants.TAG_VALUE;
private static final String GERRIT_CMD_BUILD_FAILED_DEFAULT_VALUE = "gerrit review <CHANGE>,<PATCHSET> "
+ "--message 'Build Failed <BUILDS_STATS>' "
+ "--verified <VERIFIED> --code-review <CODE_REVIEW> --tag " + Constants.TAG_VALUE;
private static final String GERRIT_CMD_BUILD_UNSTABLE_DEFAULT_VALUE = "gerrit review <CHANGE>,<PATCHSET> "
+ "--message 'Build Unstable <BUILDS_STATS>' "
+ "--verified <VERIFIED> --code-review <CODE_REVIEW> --tag " + Constants.TAG_VALUE;
private static final String GERRIT_CMD_BUILD_NOT_BUILT_DEFAULT_VALUE = "gerrit review <CHANGE>,<PATCHSET> "
+ "--message 'No Builds Executed <BUILDS_STATS>' "
+ "--verified <VERIFIED> --code-review <CODE_REVIEW> --tag " + Constants.TAG_VALUE;
private static final String GERRIT_CMD_BUILD_ABORTED_DEFAULT_VALUE = "gerrit review <CHANGE>,<PATCHSET> "
+ "--message 'Build Aborted <BUILDS_STATS>' "
+ "--verified <VERIFIED> --code-review <CODE_REVIEW> --tag " + Constants.TAG_VALUE;

private String gerritHostName;
private int gerritSshPort;
Expand Down Expand Up @@ -305,7 +284,7 @@ public void setValues(JSONObject formData) {
gerritUserName = formData.optString("gerritUserName", DEFAULT_GERRIT_USERNAME);
gerritEMail = formData.optString("gerritEMail", "");
notificationLevel = Notify.valueOf(formData.optString("notificationLevel",
Config.DEFAULT_NOTIFICATION_LEVEL.toString()));
Constants.DEFAULT_NOTIFICATION_LEVEL.toString()));
String file = formData.optString("gerritAuthKeyFile", null);
if (file != null) {
gerritAuthKeyFile = new File(file);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
*/
package com.sonyericsson.hudson.plugins.gerrit.trigger.config;

import com.sonymobile.tools.gerrit.gerritevents.dto.rest.Notify;

/**
* Global constants.
*/
Expand All @@ -42,6 +44,27 @@ public final class Constants {
* Verified review label
*/
public static final String VERIFIED_LABEL = "Verified";

public static final Notify DEFAULT_NOTIFICATION_LEVEL = Notify.ALL;

public static final String GERRIT_CMD_BUILD_STARTED_DEFAULT_VALUE = "gerrit review <CHANGE>,<PATCHSET> "
+ "--message 'Build Started <BUILDURL> <STARTED_STATS>' "
+ "--verified <VERIFIED> --code-review <CODE_REVIEW> --tag " + Constants.TAG_VALUE;
public static final String GERRIT_CMD_BUILD_SUCCESSFUL_DEFAULT_VALUE = "gerrit review <CHANGE>,<PATCHSET> "
+ "--message 'Build Successful <BUILDS_STATS>' "
+ "--verified <VERIFIED> --code-review <CODE_REVIEW> --tag " + Constants.TAG_VALUE;
public static final String GERRIT_CMD_BUILD_FAILED_DEFAULT_VALUE = "gerrit review <CHANGE>,<PATCHSET> "
+ "--message 'Build Failed <BUILDS_STATS>' "
+ "--verified <VERIFIED> --code-review <CODE_REVIEW> --tag " + Constants.TAG_VALUE;
public static final String GERRIT_CMD_BUILD_UNSTABLE_DEFAULT_VALUE = "gerrit review <CHANGE>,<PATCHSET> "
+ "--message 'Build Unstable <BUILDS_STATS>' "
+ "--verified <VERIFIED> --code-review <CODE_REVIEW> --tag " + Constants.TAG_VALUE;
public static final String GERRIT_CMD_BUILD_NOT_BUILT_DEFAULT_VALUE = "gerrit review <CHANGE>,<PATCHSET> "
+ "--message 'No Builds Executed <BUILDS_STATS>' "
+ "--verified <VERIFIED> --code-review <CODE_REVIEW> --tag " + Constants.TAG_VALUE;
public static final String GERRIT_CMD_BUILD_ABORTED_DEFAULT_VALUE = "gerrit review <CHANGE>,<PATCHSET> "
+ "--message 'Build Aborted <BUILDS_STATS>' "
+ "--verified <VERIFIED> --code-review <CODE_REVIEW> --tag " + Constants.TAG_VALUE;
/** Internal */
private Constants() {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@

import static com.sonyericsson.hudson.plugins.gerrit.trigger.config.Constants.CODE_REVIEW_LABEL;
import static com.sonyericsson.hudson.plugins.gerrit.trigger.config.Constants.VERIFIED_LABEL;
import static com.sonyericsson.hudson.plugins.gerrit.trigger.config.Constants.DEFAULT_NOTIFICATION_LEVEL;
import static com.sonyericsson.hudson.plugins.gerrit.trigger.utils.Logic.shouldSkip;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
Expand Down Expand Up @@ -112,16 +113,7 @@ public String getBuildStartedCommand(Run r, TaskListener taskListener,

GerritTrigger trigger = GerritTrigger.getTrigger(r.getParent());
String gerritCmd = config.getGerritCmdBuildStarted();
Map<String, String> parameters = createStandardParameters(r, event,
getBuildStartedCodeReviewValue(r),
getBuildStartedVerifiedValue(r),
Notify.ALL.name());

for (VerdictCategory category : config.getCategories()) {
String value = category.getVerdictValue();
String voteValue = String.valueOf(getBuildStatusVote(r, value, BuildStatus.STARTED));
parameters.put(category.getVerdictValue(), voteValue);
}
Map<String, String> parameters = createStartedCommandParameters(r, event, Notify.ALL.name());

StringBuilder startedStats = new StringBuilder();
if (stats.getTotalBuildsToStart() > 1) {
Expand Down Expand Up @@ -256,13 +248,10 @@ public Integer getBuildStatusVote(Run r, String gerritLabel, BuildStatus buildSt
* </ul>
* @param r the build.
* @param gerritEvent the event.
* @param codeReview the code review vote.
* @param verified the verified vote.
* @param notifyLevel the notify level.
* @return the parameters and their values.
*/
private Map<String, String> createStandardParameters(Run r, GerritTriggeredEvent gerritEvent,
Integer codeReview, Integer verified, String notifyLevel) {
private Map<String, String> createStandardParameters(Run r, GerritTriggeredEvent gerritEvent, String notifyLevel) {
//<GERRIT_NAME> <BRANCH> <CHANGE> <PATCHSET> <PATCHSET_REVISION> <REFSPEC> <BUILDURL> VERIFIED CODE_REVIEW
Map<String, String> map = new HashMap<String, String>(DEFAULT_PARAMETERS_COUNT);
if (gerritEvent instanceof ChangeBasedEvent) {
Expand All @@ -283,13 +272,30 @@ private Map<String, String> createStandardParameters(Run r, GerritTriggeredEvent
if (r != null) {
map.put("BUILDURL", jenkins.getRootUrl() + r.getUrl());
}
map.put("VERIFIED", String.valueOf(verified));
map.put("CODE_REVIEW", String.valueOf(codeReview));
map.put("NOTIFICATION_LEVEL", notifyLevel);

return map;
}

/**
* Creates a map of parameters and their values for a started command.
* @param r the build.
* @param gerritEvent the event.
* @param notifyLevel the notify level.
* @return the parameters and their values.
*/
private Map<String, String> createStartedCommandParameters(Run r, GerritTriggeredEvent gerritEvent, String notifyLevel) {
Map<String, String> standardParameters = createStandardParameters(r, gerritEvent, notifyLevel);

for (VerdictCategory category : config.getCategories()) {
System.out.println("Adding verdict category: " + category.getVerdictValue() + " into started command parameters map");
String voteValue = String.valueOf(getBuildStatusVote(r, category.getVerdictValue(), BuildStatus.STARTED));
standardParameters.put(category.getPlaceholderValue(), voteValue);
}

return standardParameters;
}

/**
* Expands all types of parameters in the string and returns the "replaced" string.
* Both types means both $ENV_VARS and &lt;PLUGIN_VARS&gt;
Expand All @@ -312,17 +318,63 @@ private String expandParameters(String gerritCommand, Run r, TaskListener taskLi
}

for (Map.Entry<String, String> param : parameters.entrySet()) {
command = command.replace("<" + param.getKey() + ">", param.getValue());
if (param.getValue().equals("null") || param.getValue().equals(String.valueOf(Integer.MAX_VALUE))) {
String labelName = VerdictCategory.fromPlaceholderValue(param.getKey());
command = command.replace("--" + labelName, "");
command = command.replace("<" + param.getKey() + ">", "");
} else {
command = command.replace("<" + param.getKey() + ">", param.getValue());
}
}
//replace null and Integer.MAX_VALUE code review value
command = command.replace("--code-review null", "");
command = command.replace("--code-review " + Integer.MAX_VALUE, "");
command = command.replace("--verified null", "");
command = command.replace("--verified " + Integer.MAX_VALUE, "");

return command;
}

/**
* Returns the minimum of the given label vote value for the build results in the memory.
* If no builds have contributed to label's value, this method returns null
*
* @param memoryImprint the memory.
* @param onlyBuilt only count builds that completed (no NOT_BUILT builds)
* @param label the label to get the vote value for.
* @return the lowest verified value.
*/
@CheckForNull
public Integer getMinimumLabelVoteValue(MemoryImprint memoryImprint,
boolean onlyBuilt,
String label) {
Integer minVoteValue = Integer.MAX_VALUE;
for (Entry entry : memoryImprint.getEntries()) {
if (entry == null) {
continue;
}

Run build = entry.getBuild();
if (build == null) {
continue;
}
Result result = build.getResult();
if (onlyBuilt && result == Result.NOT_BUILT) {
continue;
}

GerritTrigger trigger = GerritTrigger.getTrigger(entry.getProject());
if (shouldSkip(trigger.getSkipVote(), result)) {
continue;
}
Integer labelVoteValue = getLabelVoteValue(result, trigger, label);
if (labelVoteValue != null) {
minVoteValue = Math.min(minVoteValue, labelVoteValue);
}
}

if (minVoteValue == Integer.MAX_VALUE) {
return null;
}

return minVoteValue;
}

/**
* Finds the vote value for the specified label and build result on the configured trigger.
* @param result the build result.
Expand Down Expand Up @@ -351,8 +403,10 @@ protected Integer getLabelVoteValue(Result result,
* @param onlyBuilt only count builds that completed (no NOT_BUILT builds)
* @param maxAllowedVerifiedValue Upper boundary on verified value.
* @return the lowest verified value.
* @deprecated use {@link #getMinimumLabelVoteValue(MemoryImprint, boolean, String)}} instead.
*/
@CheckForNull
@Deprecated
public Integer getMinimumVerifiedValue(MemoryImprint memoryImprint, boolean onlyBuilt,
Integer maxAllowedVerifiedValue) {
Integer verified = Integer.MAX_VALUE;
Expand Down Expand Up @@ -392,8 +446,10 @@ public Integer getMinimumVerifiedValue(MemoryImprint memoryImprint, boolean only
* @param memoryImprint the memory
* @param onlyBuilt only count builds that completed (no NOT_BUILT builds)
* @return the lowest code review value.
* @deprecated use {@link #getMinimumLabelVoteValue(MemoryImprint, boolean, String)}} instead.
*/
@CheckForNull
@Deprecated
public Integer getMinimumCodeReviewValue(MemoryImprint memoryImprint, boolean onlyBuilt) {
Integer codeReview = Integer.MAX_VALUE;
for (Entry entry : memoryImprint.getEntries()) {
Expand Down Expand Up @@ -473,7 +529,7 @@ public Notify getNotificationLevel(GerritTrigger trigger) {
if (serverLevel != null) {
return serverLevel;
}
return Config.DEFAULT_NOTIFICATION_LEVEL;
return DEFAULT_NOTIFICATION_LEVEL;
}

/**
Expand Down Expand Up @@ -520,17 +576,27 @@ public String getBuildCompletedCommand(MemoryImprint memoryImprint, TaskListener
maxAllowedVerifiedValue = config.getLabelVote(VERIFIED_LABEL, BuildStatus.FAILED);
}

Integer verified = null;
Integer codeReview = null;
Notify notifyLevel = Notify.ALL;
if (memoryImprint.getEvent().isScorable()) {
verified = getMinimumVerifiedValue(memoryImprint, onlyCountBuilt, maxAllowedVerifiedValue);
codeReview = getMinimumCodeReviewValue(memoryImprint, onlyCountBuilt);
notifyLevel = getHighestNotificationLevel(memoryImprint, onlyCountBuilt);
}

Map<String, String> parameters = createStandardParameters(null, event,
codeReview, verified, notifyLevel.name());
Map<String, String> parameters = createStandardParameters(null, event, notifyLevel.name());
for (VerdictCategory category : config.getCategories()) {
if (!memoryImprint.getEvent().isScorable()) {
parameters.put(category.getPlaceholderValue(), "null");
continue;
}

System.out.println("Adding verdict category: " + category.getVerdictValue() + " into completed build parameters map");

Integer voteValue = getMinimumLabelVoteValue(memoryImprint, onlyCountBuilt, category.getVerdictValue());
if (category.getVerdictValue().equals(Constants.VERIFIED_LABEL) && voteValue != null) {
voteValue = Math.min(voteValue, maxAllowedVerifiedValue);
}

parameters.put(category.getPlaceholderValue(), String.valueOf(voteValue));
}

// escapes ' as '"'"' in order to avoid breaking command line param
// Details: http://stackoverflow.com/a/26165123/99834
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.sonyericsson.hudson.plugins.gerrit.trigger.Messages;
import com.sonyericsson.hudson.plugins.gerrit.trigger.PluginImpl;
import com.sonyericsson.hudson.plugins.gerrit.trigger.config.Config;
import com.sonyericsson.hudson.plugins.gerrit.trigger.config.Constants;
import com.sonyericsson.hudson.plugins.gerrit.trigger.config.ReplicationConfig;
import com.sonyericsson.hudson.plugins.gerrit.trigger.dependency.DependencyQueueTaskDispatcher;
import com.sonyericsson.hudson.plugins.gerrit.trigger.hudsontrigger.data.CompareType;
Expand Down Expand Up @@ -317,7 +318,7 @@ private static ListBoxModel.Option getOptionForNotificationLevelDefault(
}

// fall back to global default
String defaultText = levelTextsById.get(Config.DEFAULT_NOTIFICATION_LEVEL);
String defaultText = levelTextsById.get(Constants.DEFAULT_NOTIFICATION_LEVEL);
return new ListBoxModel.Option(Messages.NotificationLevel_DefaultValueFromServer(defaultText), "");
}

Expand Down
Loading

0 comments on commit 2edfb6f

Please sign in to comment.