Skip to content

Commit

Permalink
- [FIXED JENKINS-22005]
Browse files Browse the repository at this point in the history
- Adding ManualCondition Test Cases and making a few changes for supporting them.
  • Loading branch information
cvarjao committed Mar 1, 2014
1 parent 419e0c5 commit 8a3928a
Show file tree
Hide file tree
Showing 5 changed files with 348 additions and 24 deletions.
Expand Up @@ -16,6 +16,7 @@
import hudson.model.JobPropertyDescriptor;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;
import org.kohsuke.stapler.Ancestor;
import org.kohsuke.stapler.StaplerRequest;
Expand Down Expand Up @@ -312,7 +313,16 @@ public Action getJobAction(AbstractProject<?,?> job) {

@Extension
public static final class DescriptorImpl extends JobPropertyDescriptor {
public String getDisplayName() {

public DescriptorImpl() {
super();
}

public DescriptorImpl(Class<? extends JobProperty<?>> clazz) {
super(clazz);
}

public String getDisplayName() {
return "Promote Builds When...";
}

Expand Down
36 changes: 21 additions & 15 deletions src/main/java/hudson/plugins/promoted_builds/PromotionProcess.java
Expand Up @@ -299,8 +299,13 @@ public boolean considerPromotion(AbstractBuild<?,?> build) throws IOException {
*
* @return
* null if the build was not promoted, otherwise Future that kicks in when the build is completed.
* @throws IOException
*/
public Future<Promotion> considerPromotion2(AbstractBuild<?,?> build) throws IOException {
public Future<Promotion> considerPromotion2(AbstractBuild<?, ?> build) throws IOException {
return considerPromotion2(build, (List<ParameterValue>)null);
}

public Future<Promotion> considerPromotion2(AbstractBuild<?,?> build, List<ParameterValue> params) throws IOException {
if (!isActive())
return null; // not active

Expand All @@ -316,7 +321,7 @@ public Future<Promotion> considerPromotion2(AbstractBuild<?,?> build) throws IOE
return null; // not this time

LOGGER.fine("Promotion condition of "+build+" is met: "+qualification);
Future<Promotion> f = promote2(build, new UserCause(), qualification); // TODO: define promotion cause
Future<Promotion> f = promote2(build, new UserCause(), qualification, params); // TODO: define promotion cause
if (f==null)
LOGGER.warning(build+" qualifies for a promotion but the queueing failed.");
return f;
Expand All @@ -343,6 +348,9 @@ public void promote(AbstractBuild<?,?> build, Cause cause, Status qualification)
* Future to track the completion of the promotion.
*/
public Future<Promotion> promote2(AbstractBuild<?,?> build, Cause cause, Status qualification) throws IOException {
return promote2(build, cause, qualification, null);
}
public Future<Promotion> promote2(AbstractBuild<?,?> build, Cause cause, Status qualification, List<ParameterValue> params) throws IOException {
PromotedBuildAction a = build.getAction(PromotedBuildAction.class);
// build is qualified for a promotion.
if(a!=null) {
Expand All @@ -353,7 +361,7 @@ public Future<Promotion> promote2(AbstractBuild<?,?> build, Cause cause, Status
}

// schedule promotion activity.
return scheduleBuild2(build,cause);
return scheduleBuild2(build,cause, params);
}

/**
Expand All @@ -379,26 +387,20 @@ public boolean scheduleBuild(AbstractBuild<?,?> build, Cause cause) {
public Future<Promotion> scheduleBuild2(AbstractBuild<?,?> build, Cause cause, List<ParameterValue> params) {
assert build.getProject()==getOwner();

List<Action> actions = new ArrayList<Action>();
Promotion.buildParametersAction(actions, build, params);

List<Action> actions = new ArrayList<Action>();
if (params!=null){
Promotion.buildParametersAction(actions, build, params);
}
actions.add(new PromotionTargetAction(build));

// remember what build we are promoting
return super.scheduleBuild2(0, cause, actions.toArray(new Action[actions.size()]));
}

public Future<Promotion> scheduleBuild2(AbstractBuild<?,?> build, Cause cause) {
List<ParameterValue> params=new ArrayList<ParameterValue>();
List<ManualApproval> approvals = build.getActions(ManualApproval.class);
if (approvals!=null){
for(ManualApproval approval : approvals) {
params.addAll(approval.badge.getParameterValues());
}
}

// remember what build we are promoting
return scheduleBuild2(build, cause, params);
public Future<Promotion> scheduleBuild2(AbstractBuild<?,?> build, Cause cause) {
return scheduleBuild2(build, cause, null);
}

public boolean isInQueue(AbstractBuild<?,?> build) {
Expand Down Expand Up @@ -591,4 +593,8 @@ public FormValidation doCheckName(@QueryParameter String name) {

private static final Logger LOGGER = Logger.getLogger(PromotionProcess.class.getName());

public Future<Promotion> considerPromotion2(AbstractBuild<?, ?> build, ManualApproval approval) throws IOException {
return considerPromotion2(build, approval.badge.getParameterValues());
}

}
Expand Up @@ -7,6 +7,7 @@
import hudson.model.Descriptor;
import hudson.model.Hudson;
import hudson.model.InvisibleAction;
import hudson.model.SimpleParameterDefinition;
import hudson.model.ParameterDefinition;
import hudson.model.ParameterValue;
import hudson.model.User;
Expand All @@ -15,15 +16,26 @@
import hudson.plugins.promoted_builds.PromotionConditionDescriptor;
import hudson.plugins.promoted_builds.Promotion;
import hudson.plugins.promoted_builds.PromotionProcess;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import javax.servlet.ServletException;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.acegisecurity.GrantedAuthority;
import org.kohsuke.stapler.AncestorInPath;
import org.kohsuke.stapler.StaplerRequest;
Expand Down Expand Up @@ -135,6 +147,32 @@ private boolean isInGroupList() {
}
return false;
}
public Future<Promotion> approve(AbstractBuild<?,?> build, PromotionProcess promotionProcess, List<ParameterValue> paramValues) throws IOException{
if (canApprove(promotionProcess, build)) {
// add approval to build
ManualApproval approval=new ManualApproval(promotionProcess.getName(), paramValues);
build.addAction(approval);
build.save();

// check for promotion
return promotionProcess.considerPromotion2(build, approval);
}
return null;
}
public List<ParameterValue> createDefaultValues(){
List<ParameterValue> paramValues = new ArrayList<ParameterValue>();

if (parameterDefinitions != null && !parameterDefinitions.isEmpty()) {
for (ParameterDefinition d:parameterDefinitions){
paramValues.add(d.getDefaultParameterValue());
}
}
return paramValues;
}
public Future<Promotion> approve(AbstractBuild<?,?> build, PromotionProcess promotionProcess) throws IOException{
List<ParameterValue> paramValues = createDefaultValues();
return approve(build, promotionProcess, paramValues);
}

/**
* Web method to handle the approval action submitted by the user.
Expand All @@ -158,17 +196,11 @@ public void doApprove(StaplerRequest req, StaplerResponse rsp,
ParameterDefinition d = getParameterDefinition(name);
if (d==null)
throw new IllegalArgumentException("No such parameter definition: " + name);

paramValues.add(d.createValue(req, jo));
}
}

// add approval to build
build.addAction(new ManualApproval(promotionProcess.getName(), paramValues));
build.save();

// check for promotion
promotionProcess.considerPromotion2(build);
approve(build, promotionProcess, paramValues);
}

rsp.sendRedirect2("../../../..");
Expand Down
@@ -0,0 +1,111 @@
package hudson.plugins.promoted_builds.conditions;

import hudson.ExtensionList;
import hudson.model.FreeStyleBuild;
import hudson.model.Descriptor;
import hudson.model.FreeStyleProject;
import hudson.model.ParameterDefinition;
import hudson.model.StringParameterDefinition;
import hudson.plugins.promoted_builds.Status;
import hudson.plugins.promoted_builds.JobPropertyImpl;
import hudson.plugins.promoted_builds.PromotedBuildAction;
import hudson.plugins.promoted_builds.Promotion;
import hudson.plugins.promoted_builds.PromotionProcess;
import hudson.plugins.promoted_builds.conditions.ManualCondition.ManualApproval;

import java.io.IOException;
import java.util.List;

import jenkins.model.Jenkins;

import org.jvnet.hudson.test.Bug;
import org.jvnet.hudson.test.HudsonTestCase;

import com.gargoylesoftware.htmlunit.html.HtmlElement;
import com.gargoylesoftware.htmlunit.html.HtmlForm;
import com.gargoylesoftware.htmlunit.html.HtmlPage;

@Bug(22005)
public class ManualConditionBug22005 extends HudsonTestCase {
private PromotionProcess createPromotionProcess(JobPropertyImpl parent, String name) throws IOException{
PromotionProcess prom0 = parent.addProcess(name);
ManualCondition prom0ManualCondition=new ManualCondition();
prom0ManualCondition.getParameterDefinitions().add(new StringParameterDefinition("param1", prom0.getName()+"_value_1", "Parameter 1"));
prom0ManualCondition.getParameterDefinitions().add(new StringParameterDefinition("param2", prom0.getName()+"_value_2", "Parameter 2"));
prom0.conditions.add(prom0ManualCondition);
return prom0;
}

public void testPromotionProcess() throws Exception {
FreeStyleProject p = createFreeStyleProject();

ExtensionList<Descriptor> list=Jenkins.getInstance().getExtensionList(Descriptor.class);
list.add(new JobPropertyImpl.DescriptorImpl(JobPropertyImpl.class));
JobPropertyImpl base = new JobPropertyImpl(p);
p.addProperty(base);
PromotionProcess prom0=createPromotionProcess(base, "PROM0");
ManualCondition prom0Condition=prom0.conditions.get(ManualCondition.class);
PromotionProcess prom1=createPromotionProcess(base, "PROM1");
ManualCondition prom1Condition=prom1.conditions.get(ManualCondition.class);
PromotionProcess prom2=createPromotionProcess(base, "PROM2");
ManualCondition prom2Condition=prom2.conditions.get(ManualCondition.class);

FreeStyleBuild b1 = assertBuildStatusSuccess(p.scheduleBuild2(0));
Promotion p0b1=assertBuildStatusSuccess(prom0Condition.approve(b1, prom0));
assertEquals(2,p0b1.getParameterValues().size());
assertEquals(2,p0b1.getParameterDefinitionsWithValue().size());

Promotion p1b1=assertBuildStatusSuccess(prom1Condition.approve(b1, prom1));
assertEquals(2,p1b1.getParameterValues().size());
assertEquals(2,p1b1.getParameterDefinitionsWithValue().size());

Promotion p2b1=assertBuildStatusSuccess(prom2Condition.approve(b1, prom2));
assertEquals(2,p2b1.getParameterValues().size());
assertEquals(2,p2b1.getParameterDefinitionsWithValue().size());

List<ManualApproval> approvals=b1.getActions(ManualApproval.class);
assertEquals(3, approvals.size());

PromotedBuildAction promBuildAction=b1.getAction(PromotedBuildAction.class);
List<Status> statuses=promBuildAction.getPromotions();
assertEquals(3, statuses.size());

for (Status status:statuses){
Promotion lastBuild=status.getLast();
List<ParameterDefinition> lastBuildParameters=lastBuild.getParameterDefinitionsWithValue();
assertEquals(2, lastBuildParameters.size());
}

}
public void testPromotionProcessViaWebClient() throws Exception {
FreeStyleProject p = createFreeStyleProject();

ExtensionList<Descriptor> list=Jenkins.getInstance().getExtensionList(Descriptor.class);
list.add(new JobPropertyImpl.DescriptorImpl(JobPropertyImpl.class));
JobPropertyImpl base = new JobPropertyImpl(p);
p.addProperty(base);
createPromotionProcess(base, "PROM0");
createPromotionProcess(base, "PROM1");
createPromotionProcess(base, "PROM2");


FreeStyleBuild b1 = assertBuildStatusSuccess(p.scheduleBuild2(0));
assertNull(b1.getAction(ManualApproval.class));
HtmlPage page=createWebClient().getPage(b1, "promotion");
//Approve Promotion
List<HtmlForm> forms=ManualConditionTest.getFormsByName(page, "approve");
assertFalse(forms.isEmpty());
assertEquals(3, forms.size());
for (HtmlForm form:forms){
submit(form);
}

//reload promotions page
page=createWebClient().getPage(b1, "promotion");
forms=ManualConditionTest.getFormsByName(page,"build");
for (HtmlForm form:forms){
List<HtmlElement> parameters=ManualConditionTest.getFormParameters(form);
assertEquals(2, parameters.size());
}
}
}

0 comments on commit 8a3928a

Please sign in to comment.