package com.cloudbees.jenkins; import com.github.tomakehurst.wiremock.common.Slf4jNotifier; import com.github.tomakehurst.wiremock.junit.WireMockRule; import hudson.Launcher; import hudson.model.AbstractBuild; import hudson.model.Build; import hudson.model.BuildListener; import hudson.model.Cause; import hudson.model.FreeStyleProject; import hudson.model.Result; import hudson.plugins.git.GitSCM; import hudson.plugins.git.Revision; import hudson.plugins.git.util.BuildData; import hudson.util.VersionNumber; import org.eclipse.jgit.lib.ObjectId; import org.jenkinsci.plugins.github.config.GitHubPluginConfig; import org.jenkinsci.plugins.github.test.GHMockRule; import org.jenkinsci.plugins.github.test.GHMockRule.FixedGHRepoNameTestContributor; import org.jenkinsci.plugins.github.test.InjectJenkinsMembersRule; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExternalResource; import org.junit.rules.RuleChain; import org.junit.runner.RunWith; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.TestBuilder; import org.jvnet.hudson.test.TestExtension; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import javax.inject.Inject; import static com.cloudbees.jenkins.GitHubSetCommitStatusBuilderTest.SOME_SHA; import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor; import static com.github.tomakehurst.wiremock.client.WireMock.urlPathMatching; import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; import static org.jenkinsci.plugins.github.util.Messages.BuildDataHelper_NoBuildDataError; import static org.jenkinsci.plugins.github.util.Messages.BuildDataHelper_NoLastRevisionError; import static org.mockito.Mockito.when; /** * Tests for {@link GitHubCommitNotifier}. * * @author Oleg Nenashev <o.v.nenashev@gmail.com> */ @RunWith(MockitoJUnitRunner.class) public class GitHubCommitNotifierTest { @Mock public BuildData data; @Mock public Revision rev; @Inject public GitHubPluginConfig config; public JenkinsRule jRule = new JenkinsRule(); @Rule public RuleChain chain = RuleChain.outerRule(jRule).around(new InjectJenkinsMembersRule(jRule, this)); @Rule public GHMockRule github = new GHMockRule( new WireMockRule( wireMockConfig().dynamicPort().notifier(new Slf4jNotifier(true)) )) .stubUser() .stubRepo() .stubStatuses(); @Rule public ExternalResource prep = new ExternalResource() { @Override protected void before() throws Throwable { when(data.getLastBuiltRevision()).thenReturn(rev); data.lastBuild = new hudson.plugins.git.util.Build(rev, rev, 0, Result.SUCCESS); when(rev.getSha1()).thenReturn(ObjectId.fromString(SOME_SHA)); } }; @Test @Issue("JENKINS-23641") public void testNoBuildData() throws Exception { FreeStyleProject prj = jRule.createFreeStyleProject("23641_noBuildData"); prj.getPublishersList().add(new GitHubCommitNotifier()); Build b = prj.scheduleBuild2(0).get(); jRule.assertBuildStatus(Result.FAILURE, b); jRule.assertLogContains(BuildDataHelper_NoBuildDataError(), b); } @Test @Issue("JENKINS-23641") public void testNoBuildRevision() throws Exception { FreeStyleProject prj = jRule.createFreeStyleProject(); prj.setScm(new GitSCM("http://non.existent.git.repo.nowhere/repo.git")); prj.getPublishersList().add(new GitHubCommitNotifier()); //Git plugin 2.4.1 + does not include BuildData if checkout fails, so we add it if needed Build b = safelyGenerateBuild(prj); jRule.assertBuildStatus(Result.FAILURE, b); jRule.assertLogContains(BuildDataHelper_NoLastRevisionError(), b); } @Test @Issue("JENKINS-25312") public void testMarkUnstableOnCommitNotifierFailure() throws Exception { FreeStyleProject prj = jRule.createFreeStyleProject(); prj.getPublishersList().add(new GitHubCommitNotifier(Result.UNSTABLE.toString())); Build b = prj.scheduleBuild2(0).get(); jRule.assertBuildStatus(Result.UNSTABLE, b); } @Test @Issue("JENKINS-25312") public void testMarkSuccessOnCommitNotifierFailure() throws Exception { FreeStyleProject prj = jRule.createFreeStyleProject(); prj.getPublishersList().add(new GitHubCommitNotifier(Result.SUCCESS.toString())); Build b = prj.scheduleBuild2(0).get(); jRule.assertBuildStatus(Result.SUCCESS, b); } @Test public void shouldWriteStatusOnGH() throws Exception { config.getConfigs().add(github.serverConfig()); FreeStyleProject prj = jRule.createFreeStyleProject(); prj.getBuildersList().add(new TestBuilder() { @Override public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) { build.addAction(data); return true; } }); prj.getPublishersList().add(new GitHubCommitNotifier(Result.SUCCESS.toString())); prj.scheduleBuild2(0).get(); github.service().verify(1, postRequestedFor(urlPathMatching(".*/" + SOME_SHA))); } private Build safelyGenerateBuild(FreeStyleProject prj) throws InterruptedException, java.util.concurrent.ExecutionException { Build b; if (jRule.getPluginManager().getPlugin("git").getVersionNumber().isNewerThan(new VersionNumber("2.4.0"))) { b = prj.scheduleBuild2(0, new Cause.UserIdCause(), new BuildData()).get(); } else { b = prj.scheduleBuild2(0).get(); } return b; } @TestExtension public static final FixedGHRepoNameTestContributor CONTRIBUTOR = new FixedGHRepoNameTestContributor(); }