Skip to content

Commit

Permalink
Merge branch 'master' into JENKINS-49486-initial
Browse files Browse the repository at this point in the history
  • Loading branch information
Rick Liu authored May 11, 2018
2 parents 5394488 + bf55c17 commit 52a1215
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 10 deletions.
17 changes: 14 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
</parent>

<artifactId>promoted-builds</artifactId>
<version>3.0</version>
<version>3.2-SNAPSHOT</version>
<packaging>hpi</packaging>

<name>Jenkins promoted builds plugin</name>
Expand Down Expand Up @@ -39,7 +39,7 @@
<connection>scm:git:git://github.com/jenkinsci/${project.artifactId}-plugin.git</connection>
<developerConnection>scm:git:[email protected]:jenkinsci/${project.artifactId}-plugin.git</developerConnection>
<url>https://github.com/jenkinsci/${project.artifactId}-plugin</url>
<tag>promoted-builds-3.0</tag>
<tag>HEAD</tag>
</scm>
<licenses>
<license>
Expand Down Expand Up @@ -97,6 +97,11 @@
<version>1.25</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>structs</artifactId>
<version>1.7</version>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
Expand All @@ -112,7 +117,7 @@
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>token-macro</artifactId>
<version>1.12.1</version>
<version>2.0</version>
<optional>true</optional>
</dependency>
<dependency>
Expand All @@ -138,6 +143,12 @@
<version>1.4.7-jenkins-1</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>config-file-provider</artifactId>
<version>2.18</version>
<optional>true</optional>
</dependency>
<dependency>
<!-- TODO: it is something insane, no? -->
<groupId>org.jenkins-ci.plugins</groupId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package hudson.plugins.promoted_builds;

import hudson.Extension;
import hudson.model.ItemGroup;
import org.jenkinsci.plugins.configfiles.ConfigContextResolver;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;

@Extension(optional = true)
@Restricted(NoExternalUse.class)
public class JobPropertyImplConfigContextResolver extends ConfigContextResolver {

@Override
public ItemGroup getConfigContext(ItemGroup itemGroup) {
if (itemGroup instanceof JobPropertyImpl) {
return JobPropertyImpl.class.cast(itemGroup).getOwner().getParent();
}
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package hudson.plugins.promoted_builds;

import hudson.model.FreeStyleProject;
import hudson.model.Result;
import hudson.plugins.promoted_builds.conditions.SelfPromotionCondition;
import org.jenkinsci.plugins.configfiles.GlobalConfigFiles;
import org.jenkinsci.plugins.configfiles.builder.ConfigFileBuildStep;
import org.jenkinsci.plugins.configfiles.buildwrapper.ManagedFile;
import org.jenkinsci.plugins.configfiles.custom.CustomConfig;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.JenkinsRule;

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

import static org.junit.Assert.assertEquals;

public class PromotionConfigFilesTest {

private static final String CONFIG_ID = "ConfigFilesTestId";

@Rule
public JenkinsRule r = new JenkinsRule();

@Test
public void testPromotionConfigFilesAreRetrievedFromParentJobContext() throws Exception {
GlobalConfigFiles store = r.getInstance().getExtensionList(GlobalConfigFiles.class).get(GlobalConfigFiles.class);
Assert.assertTrue(store.getConfigs().isEmpty());

CustomConfig config = new CustomConfig(CONFIG_ID, "name", "comment", "content");
store.save(config);

FreeStyleProject p = r.createFreeStyleProject();

// promote if the downstream passes
JobPropertyImpl promotion = new JobPropertyImpl(p);
p.addProperty(promotion);

PromotionProcess promo1 = promotion.addProcess("promo1");
promo1.conditions.add(new SelfPromotionCondition(false));
List<ManagedFile> managedFiles = new ArrayList<>();
managedFiles.add(new ManagedFile(CONFIG_ID));
promo1.getBuildSteps().add(new ConfigFileBuildStep(managedFiles));

r.assertBuildStatusSuccess(p.scheduleBuild2(0));
// internally, the promotion is still an asynchronous process. It just happens
// right away after the build is complete.
Thread.sleep(1000);

Promotion pb = promo1.getBuilds().iterator().next();
assertEquals(Result.SUCCESS, pb.getResult());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ public void testManualPromotionPermissionsViaWebClient() throws Exception {
{
// Re-execute promotion as user without Promotion/Promote when no users are specified
wc.login("non-promoter", "non-promoter");
// Status#doBuild does a bare `return;` without scheduling the build in this case, which is why we use goTo with "" for the MIME type.
wc.goTo(String.format("job/%s/%d/promotion/%s/build?json={}", p.getName(), b.getNumber(), pp.getName()), "");
assertThat(pp.getBuildByNumber(2), nullValue());
}
Expand All @@ -301,10 +302,11 @@ public void testManualPromotionPermissionsViaWebClient() throws Exception {
wc.login("promoter", "promoter");
try {
wc.getPage(b, String.format("promotion/%s/build?json={}", pp.getName()));
fail();
} catch (FailingHttpStatusCodeException e) {
assertThat(e.getStatusCode(), equalTo(404)); // Redirect after the build is broken.
}
assertThat(pp.getBuildByNumber(2).getResult(), equalTo(Result.SUCCESS));
assertThat(waitForBuildByNumber(pp, 2).getResult(), equalTo(Result.SUCCESS));
}

{
Expand All @@ -313,24 +315,33 @@ public void testManualPromotionPermissionsViaWebClient() throws Exception {
wc.login("non-promoter", "non-promoter");
try {
wc.getPage(b, String.format("promotion/%s/build?json={}", pp.getName()));
fail();
} catch (FailingHttpStatusCodeException e) {
assertThat(e.getStatusCode(), equalTo(404)); // Redirect after the build is broken.
}
assertThat(pp.getBuildByNumber(3).getResult(), equalTo(Result.SUCCESS));
assertThat(waitForBuildByNumber(pp, 3).getResult(), equalTo(Result.SUCCESS));
}

{
// Re-execute promotion as unspecified user with Promotion/Promote
cond.setUsers("non-promoter");
wc.login("promoter", "promoter");
try {
wc.goTo(String.format("job/%s/%d/promotion/%s/build?json={}", p.getName(), b.getNumber(), pp.getName()), "");
} catch (FailingHttpStatusCodeException e) {
assertThat(e.getStatusCode(), equalTo(404)); // Redirect after the build is broken.
}
// Status#doBuild does a bare `return;` without scheduling the build in this case, which is why we use goTo with "" for the MIME type.
wc.goTo(String.format("job/%s/%d/promotion/%s/build?json={}", p.getName(), b.getNumber(), pp.getName()), "");
assertThat(pp.getBuildByNumber(4), nullValue());
}
}

private Promotion waitForBuildByNumber(PromotionProcess pp, int n) throws InterruptedException {
for(int i = 0; i < 100; i++){
Promotion promotion = pp.getBuildByNumber(n);
if(promotion != null && promotion.getResult() != null){
return promotion;
}
Thread.sleep(50);
}
throw new AssertionError("Timeout to retrieve the buildByNumber: " + n);
}

private PromotionProcess addPromotionProcess(AbstractProject<?,?> owner, String name) throws Exception {
ExtensionList<Descriptor> list = j.jenkins.getExtensionList(Descriptor.class);
Expand Down

0 comments on commit 52a1215

Please sign in to comment.