Skip to content
Permalink
Browse files

Merge pull request #45 from lanwen/anonymouse-cause

[FIXED JENKINS-28188] - Fix for plugin compatibility when used anonymous class cause
  • Loading branch information...
oleg-nenashev committed May 15, 2015
2 parents f6caad4 + 3d62b4f commit faea23f93513a83a1bdfddc1eb488a5a295ad195
@@ -40,8 +40,8 @@
<maven.compiler.target>1.6</maven.compiler.target>
<envinject.lib.version>1.21</envinject.lib.version>
<ivy.plugin.version>1.21</ivy.plugin.version>
<junit.version>4.9</junit.version>
<mockito.version>1.8.5</mockito.version>
<junit.version>4.12</junit.version>
<mockito.version>1.10.19</mockito.version>
</properties>

<scm>
@@ -5,7 +5,6 @@
import hudson.model.CauseAction;
import hudson.triggers.SCMTrigger;
import hudson.triggers.TimerTrigger;
import org.apache.commons.lang.StringUtils;

import java.util.ArrayList;
import java.util.Collection;
@@ -15,6 +14,10 @@
import java.util.Map;
import java.util.Set;

import static com.google.common.base.Joiner.on;
import static org.apache.commons.lang.StringUtils.isNotBlank;


/**
* @author Gregory Boissinot
*/
@@ -47,7 +50,7 @@ private static void insertRootCauseNames(Set<String> causeNames, Cause cause, in
if (depth == MAX_UPSTREAM_DEPTH) {
causeNames.add("DEEPLYNESTEDCAUSES");
} else {
Cause.UpstreamCause c = (Cause.UpstreamCause)cause;
Cause.UpstreamCause c = (Cause.UpstreamCause) cause;
List<Cause> upstreamCauses = c.getUpstreamCauses();
for (Cause upstreamCause : upstreamCauses)
insertRootCauseNames(causeNames, upstreamCause, depth + 1);
@@ -59,16 +62,15 @@ private static void insertRootCauseNames(Set<String> causeNames, Cause cause, in

private static Map<String, String> buildCauseEnvironmentVariables(String envBase, Collection<String> causeNames) {
Map<String, String> triggerVars = new HashMap<String, String>();
StringBuilder all = new StringBuilder();
List<String> nonEmptyNames = new ArrayList<String>();
for (String name : causeNames) {
if (!StringUtils.isBlank(name)) {
triggerVars.put(envBase + "_" + name, "true");
all.append(",");
all.append(name);
if (isNotBlank(name)) {
triggerVars.put(on("_").join(envBase, name), "true");
nonEmptyNames.add(name);
}
}
// add variable containing all the trigger names
triggerVars.put(envBase, all.toString().substring(1));
triggerVars.put(envBase, on(",").join(nonEmptyNames));
return triggerVars;
}

@@ -1,121 +1,145 @@
package org.jenkinsci.plugins.envinject;

import hudson.model.*;
import hudson.model.Cause;
import hudson.model.CauseAction;
import hudson.model.FreeStyleBuild;
import hudson.model.FreeStyleProject;
import hudson.model.Run;
import hudson.triggers.SCMTrigger;
import hudson.triggers.TimerTrigger;
import junit.framework.Assert;
import org.jenkinsci.lib.envinject.EnvInjectAction;
import org.jvnet.hudson.test.HudsonTestCase;

import java.util.HashMap;
import java.util.Map;
import org.junit.ClassRule;
import org.junit.Test;
import org.jvnet.hudson.test.Bug;
import org.jvnet.hudson.test.JenkinsRule;

import static com.google.common.base.Joiner.on;
import static hudson.model.Result.SUCCESS;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.jenkinsci.plugins.envinject.matchers.WithEnvInjectActionMatchers.withCause;
import static org.jenkinsci.plugins.envinject.matchers.WithEnvInjectActionMatchers.withCausesIsTrue;

/**
* @author Gregory Boissinot
*/
@SuppressWarnings("deprecation")
public class BuildCauseRetrieverTest extends HudsonTestCase {

private FreeStyleProject project;
public class BuildCauseRetrieverTest {

private static Map<Class<? extends Cause>, String> causeMatchingNames = new HashMap<Class<? extends Cause>, String>();
public static final String BUILD_CAUSE = "BUILD_CAUSE";
public static final String ROOT_BUILD_CAUSE = "ROOT_BUILD_CAUSE";

static {
causeMatchingNames.put(Cause.UserCause.class, "MANUALTRIGGER");
causeMatchingNames.put(SCMTrigger.SCMTriggerCause.class, "SCMTRIGGER");
causeMatchingNames.put(TimerTrigger.TimerTriggerCause.class, "TIMERTRIGGER");
causeMatchingNames.put(Cause.UpstreamCause.class, "UPSTREAMTRIGGER");
}
public static final String MANUAL_TRIGGER = "MANUALTRIGGER";
public static final String SCM_TRIGGER = "SCMTRIGGER";
public static final String TIMER_TRIGGER = "TIMERTRIGGER";
public static final String UPSTREAM_TRIGGER = "UPSTREAMTRIGGER";

@Override
public void setUp() throws Exception {
super.setUp();
project = createFreeStyleProject();
}
@ClassRule
public static JenkinsRule jenkins = new JenkinsRule();

@SuppressWarnings("deprecation")
public void testManualBuildCause() throws Exception {
checkCauseArguments(Cause.UserCause.class);
@Test
public void shouldWriteInfoAboutManualBuildCause() throws Exception {
Cause cause = Cause.UserCause.class.newInstance();
FreeStyleBuild build = jenkins.createFreeStyleProject().scheduleBuild2(0, cause).get();

assertThat(build.getResult(), is(SUCCESS));
assertThat(build, withCause(BUILD_CAUSE, MANUAL_TRIGGER));
assertThat(build, withCause(ROOT_BUILD_CAUSE, MANUAL_TRIGGER));
assertThat(build, withCausesIsTrue(sub(BUILD_CAUSE, MANUAL_TRIGGER), sub(ROOT_BUILD_CAUSE, MANUAL_TRIGGER)));
}

public void testSCMBuildCause() throws Exception {
checkCauseArguments(SCMTrigger.SCMTriggerCause.class);
@Test
public void shouldWriteInfoAboutSCMBuildCause() throws Exception {
Cause cause = SCMTrigger.SCMTriggerCause.class.newInstance();
FreeStyleBuild build = jenkins.createFreeStyleProject().scheduleBuild2(0, cause).get();

assertThat(build.getResult(), is(SUCCESS));
assertThat(build, withCause(BUILD_CAUSE, SCM_TRIGGER));
assertThat(build, withCause(ROOT_BUILD_CAUSE, SCM_TRIGGER));
assertThat(build, withCausesIsTrue(sub(BUILD_CAUSE, SCM_TRIGGER), sub(ROOT_BUILD_CAUSE, SCM_TRIGGER)));
}

public void testTIMERBuildCause() throws Exception {
checkCauseArguments(TimerTrigger.TimerTriggerCause.class);
@Test
public void shouldWriteInfoAboutTimerBuildCause() throws Exception {
Cause cause = TimerTrigger.TimerTriggerCause.class.newInstance();
FreeStyleBuild build = jenkins.createFreeStyleProject().scheduleBuild2(0, cause).get();

assertThat(build.getResult(), is(SUCCESS));

assertThat(build, withCause(BUILD_CAUSE, TIMER_TRIGGER));
assertThat(build, withCause(ROOT_BUILD_CAUSE, TIMER_TRIGGER));
assertThat(build, withCausesIsTrue(sub(BUILD_CAUSE, TIMER_TRIGGER), sub(ROOT_BUILD_CAUSE, TIMER_TRIGGER)));
}

public void testUPSTREAMBuildCause() throws Exception {
FreeStyleProject upProject = createFreeStyleProject();
@Test
public void shouldWriteInfoAboutUpstreamBuildCause() throws Exception {
FreeStyleProject upProject = jenkins.createFreeStyleProject();
FreeStyleBuild upBuild = upProject.scheduleBuild2(0, new Cause.UserCause()).get();

Cause.UpstreamCause upstreamCause = new Cause.UpstreamCause((Run) upBuild);
FreeStyleBuild build = project.scheduleBuild2(0, upstreamCause).get();
Assert.assertEquals(Result.SUCCESS, build.getResult());
checkBuildCauses(build, "UPSTREAMTRIGGER", "MANUALTRIGGER",
"BUILD_CAUSE_UPSTREAMTRIGGER" , "ROOT_BUILD_CAUSE_MANUALTRIGGER");
}
FreeStyleBuild build = jenkins.createFreeStyleProject().scheduleBuild2(0, upstreamCause).get();

public void testCustomBuildCause() throws Exception {
checkCauseArguments(CustomTestCause.class);
assertThat(build.getResult(), is(SUCCESS));

assertThat(build, withCause(BUILD_CAUSE, UPSTREAM_TRIGGER));
assertThat(build, withCause(ROOT_BUILD_CAUSE, MANUAL_TRIGGER));
assertThat(build, withCausesIsTrue(sub(BUILD_CAUSE, UPSTREAM_TRIGGER), sub(ROOT_BUILD_CAUSE, MANUAL_TRIGGER)));
}

public void testMultipleBuildCause() throws Exception {
@Test
public void shouldWriteInfoAboutCustomBuildCause() throws Exception {
Cause cause = CustomTestCause.class.newInstance();
FreeStyleBuild build = jenkins.createFreeStyleProject().scheduleBuild2(0, cause).get();

assertThat(build.getResult(), is(SUCCESS));

String customCauseName = CustomTestCause.class.getSimpleName().toUpperCase();

assertThat(build, withCause(BUILD_CAUSE, customCauseName));
assertThat(build, withCause(ROOT_BUILD_CAUSE, customCauseName));
assertThat(build, withCausesIsTrue(sub(BUILD_CAUSE, customCauseName), sub(ROOT_BUILD_CAUSE, customCauseName)));
}

@Test
public void shouldWriteInfoAboutMultipleBuildCauses() throws Exception {
Cause cause1 = new CustomTestCause();
Cause cause2 = new SCMTrigger.SCMTriggerCause("TEST");
CauseAction causeAction = new CauseAction(cause1);
causeAction.getCauses().add(cause2);

FreeStyleBuild build = project.scheduleBuild2(0, new Cause.UserCause(), causeAction).get();
Assert.assertEquals(Result.SUCCESS, build.getResult());
FreeStyleBuild build = jenkins.createFreeStyleProject().scheduleBuild2(0,
new Cause.UserCause(), causeAction).get();
assertThat(build.getResult(), is(SUCCESS));

String customCauseName = CustomTestCause.class.getSimpleName().toUpperCase();
checkBuildCauses(build, "CUSTOMTESTCAUSE,SCMTRIGGER", "CUSTOMTESTCAUSE,SCMTRIGGER",
"BUILD_CAUSE_" + customCauseName, "BUILD_CAUSE_SCMTRIGGER",
"ROOT_BUILD_CAUSE_" + customCauseName, "ROOT_BUILD_CAUSE_SCMTRIGGER");
}

private void checkCauseArguments(Class<? extends Cause> causeClass) throws Exception {
checkCauseArguments(causeClass.newInstance());
}

private void checkCauseArguments(Cause cause) throws Exception {
FreeStyleBuild build = project.scheduleBuild2(0, cause).get();
Assert.assertEquals(Result.SUCCESS, build.getResult());
checkCauseArgumentsWithBuild(build, causeMatchingNames.get(cause.getClass()));
assertThat(build, withCause(BUILD_CAUSE, on(",").join("CUSTOMTESTCAUSE", SCM_TRIGGER)));
assertThat(build, withCause(ROOT_BUILD_CAUSE, on(",").join("CUSTOMTESTCAUSE", SCM_TRIGGER)));
assertThat(build, withCausesIsTrue(
sub(BUILD_CAUSE, customCauseName),
sub(BUILD_CAUSE, SCM_TRIGGER),
sub(ROOT_BUILD_CAUSE, customCauseName),
sub(ROOT_BUILD_CAUSE, SCM_TRIGGER))
);
}

private void checkCauseArgumentsWithBuild(FreeStyleBuild build, String causeValue) throws Exception {
if (causeValue != null) {
checkBuildCauses(build, causeValue, causeValue, "BUILD_CAUSE_" + causeValue, "ROOT_BUILD_CAUSE_" + causeValue);
} else {
String customCauseName = CustomTestCause.class.getSimpleName().toUpperCase();
checkBuildCauses(build, customCauseName, customCauseName,
"BUILD_CAUSE_" + customCauseName, "ROOT_BUILD_CAUSE_" + customCauseName);
}
}

private void checkBuildCauses(FreeStyleBuild build, String expectedMainCauseValue,
String expectedRootMainCauseValue, String... expectedCauseKeys) {

EnvInjectAction envInjectAction = build.getAction(EnvInjectAction.class);
Assert.assertNotNull(envInjectAction);
@Test
@Bug(28188)
public void shouldWriteInfoAboutAnonymousClassCause() throws Exception {
FreeStyleBuild build = jenkins.createFreeStyleProject().scheduleBuild2(0, new Cause() {
@Override
public String getShortDescription() {
return "This build was started by a hobbit Bilbo. Bilbo Baggins";
}
}).get();

Map<String, String> envVars = envInjectAction.getEnvMap();
Assert.assertNotNull(envVars);
assertThat(build.getResult(), is(SUCCESS));

String causeValue = envVars.get("BUILD_CAUSE");
Assert.assertNotNull(causeValue);
Assert.assertEquals(expectedMainCauseValue, causeValue);

String rootCauseValue = envVars.get("ROOT_BUILD_CAUSE");
Assert.assertNotNull(rootCauseValue);
Assert.assertEquals(expectedRootMainCauseValue, rootCauseValue);

for (String causeKey : expectedCauseKeys) {
Assert.assertEquals("true", envVars.get(causeKey));
}
assertThat(build, withCause(BUILD_CAUSE, ""));
assertThat(build, withCause(ROOT_BUILD_CAUSE, ""));
}

private String sub(String first, String second) {
return on("_").join(first, second);
}
}
@@ -0,0 +1,77 @@
package org.jenkinsci.plugins.envinject.matchers;

import hudson.model.FreeStyleBuild;
import org.hamcrest.FeatureMatcher;
import org.hamcrest.Matcher;
import org.jenkinsci.lib.envinject.EnvInjectAction;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.hasEntry;

/**
* User: lanwen
* Date: 14.04.15
* Time: 21:56
*/
public final class WithEnvInjectActionMatchers {
private WithEnvInjectActionMatchers() {
// no instances
}

/**
* Gets the EnvInjectAction from build and wraps it with matcher
* @param matcher - matcher to match EnvInjectAction
* @return matcher to match FreeStyleBuild
*/
public static Matcher<FreeStyleBuild> withEnvInjectAction(Matcher<EnvInjectAction> matcher) {
return new FeatureMatcher<FreeStyleBuild, EnvInjectAction>(matcher, "envInject action", "envInject action") {
@Override
protected EnvInjectAction featureValueOf(FreeStyleBuild build) {
return build.getAction(EnvInjectAction.class);
}
};
}

/**
* Gets the env map from EnvInjectAction and wrap it with map-matcher
* @param matcher - matcher for Map of String, String
* @return matcher to match EnvInjectAction
*/
public static Matcher<EnvInjectAction> map(Matcher<Map<? extends String, ? extends String>> matcher) {
return new FeatureMatcher<EnvInjectAction, Map<? extends String, ? extends String>>(matcher, "env", "") {
@Override
protected Map<? extends String, ? extends String> featureValueOf(EnvInjectAction actual) {
return actual.getEnvMap();
}
};
}

/**
* Simple version of {@link #map(Matcher)}
* @param key - key to find in env map of EnvInjectAction causes
* @param value - value to find in env map of EnvInjectAction causes
* @return matcher to match FreeStyleBuild
*/
public static Matcher<FreeStyleBuild> withCause(String key, String value) {
return withEnvInjectAction(map(hasEntry(key, value)));
}

/**
* Same as {@link #withCause(String, String)} but with value "true"
* @param keys - vararg of keys to find
* @return matcher to match FreeStyleBuild
*/
@SuppressWarnings("unchecked")
public static Matcher<FreeStyleBuild> withCausesIsTrue(String... keys) {
List<Matcher> causes = new ArrayList<Matcher>();
for (String key : keys) {
causes.add(withCause(key, "true"));
}
return allOf((List)causes);
}

}

0 comments on commit faea23f

Please sign in to comment.
You can’t perform that action at this time.