/*
* Copyright 2013 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.jenkins.plugins.delegate;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Map;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.JenkinsRule;
import org.mockito.MockitoAnnotations;
import com.google.common.io.CharStreams;
import hudson.Extension;
import hudson.matrix.MatrixProject;
import hudson.model.AbstractBuild;
import hudson.model.FreeStyleProject;
import hudson.model.Result;
import hudson.model.Run;
import hudson.scm.NullSCM;
import hudson.tasks.Shell;
import jenkins.model.Jenkins;
/**
* Tests for {@link AbstractBranchAwareProject}.
*/
public class AbstractBranchAwareProjectTest {
@Rule
public JenkinsRule jenkins = new JenkinsRule();
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
/** */
public static class SemiNullSCM extends NullSCM {
public SemiNullSCM() {
;
}
/** {@inheritDoc} */
@Override
public void buildEnvVars(AbstractBuild<?, ?> build,
Map<String, String> env) {
env.put("HELLO", "WORLD");
}
/** */
@Extension
public static class DescriptorImpl extends NullSCM.DescriptorImpl {
}
}
// TODO(mattmoor): We need a TestSCM/TestBranch with which we can really
// exercise this stuff how I'd like.
@Test
public void testSimple() throws Exception {
TestBranchAwareProject topLevelProject =
Jenkins.getInstance().createProject(
TestBranchAwareProject.class, "topLevelProject");
FreeStyleProject leafProject = FreeStyleProject.DESCRIPTOR.newInstance(
topLevelProject, "foo");
leafProject.setScm(new DelegateSCM(TestBranchAwareProject.class));
topLevelProject.setItem(leafProject);
leafProject.onCreatedFromScratch();
// Run the outer job, which should delegate to our inner project
TestBuild outerBuild = topLevelProject.scheduleBuild2(0).get();
// Test that our outer job was a success
dumpLog(outerBuild);
assertEquals(Result.SUCCESS, outerBuild.getResult());
// Test that our inner job was a success
AbstractBuild innerBuild = leafProject.getBuildByNumber(1);
dumpLog(innerBuild);
assertEquals(Result.SUCCESS, innerBuild.getResult());
}
@Test
public void testNested() throws Exception {
TestBranchAwareProject topLevelProject =
Jenkins.getInstance().createProject(
TestBranchAwareProject.class, "topLevelProject");
TestBranchAwareProject middleProject =
topLevelProject.getDescriptor().newInstance(
topLevelProject, "malcolm");
middleProject.setScm(new DelegateSCM(TestBranchAwareProject.class));
topLevelProject.setItem(middleProject);
middleProject.onCreatedFromScratch();
FreeStyleProject leafProject = FreeStyleProject.DESCRIPTOR.newInstance(
middleProject, "foo");
leafProject.setScm(new DelegateSCM(TestBranchAwareProject.class));
middleProject.setItem(leafProject);
leafProject.onCreatedFromScratch();
// Run the outer job, which should delegate to our inner project
TestBuild outerBuild = topLevelProject.scheduleBuild2(0).get();
// Test that our outer job was a success
dumpLog(outerBuild);
assertEquals(Result.SUCCESS, outerBuild.getResult());
// Test that our middle job was a success
AbstractBuild middleBuild = middleProject.getBuildByNumber(1);
dumpLog(middleBuild);
assertEquals(Result.SUCCESS, middleBuild.getResult());
// Test that our inner job was a success
AbstractBuild innerBuild = leafProject.getBuildByNumber(1);
dumpLog(innerBuild);
assertEquals(Result.SUCCESS, innerBuild.getResult());
}
@Test
public void testMatrixNesting() throws Exception {
TestBranchAwareProject topLevelProject =
Jenkins.getInstance().createProject(
TestBranchAwareProject.class, "topLevelProject");
MatrixProject leafProject = MatrixProject.DESCRIPTOR.newInstance(
topLevelProject, "foo");
leafProject.setScm(new DelegateSCM(TestBranchAwareProject.class));
topLevelProject.setItem(leafProject);
leafProject.onCreatedFromScratch();
// Run the outer job, which should delegate to our inner project
TestBuild outerBuild = topLevelProject.scheduleBuild2(0).get();
// Test that our outer job was a success
dumpLog(outerBuild);
assertEquals(Result.SUCCESS, outerBuild.getResult());
// Test that our inner job was a success
AbstractBuild innerBuild = leafProject.getBuildByNumber(1);
dumpLog(innerBuild);
assertEquals(Result.SUCCESS, innerBuild.getResult());
}
@Test
public void testDirectTrigger() throws Exception {
TestBranchAwareProject topLevelProject =
Jenkins.getInstance().createProject(
TestBranchAwareProject.class, "topLevelProject");
FreeStyleProject leafProject = FreeStyleProject.DESCRIPTOR.newInstance(
topLevelProject, "foo");
leafProject.setScm(new DelegateSCM(TestBranchAwareProject.class));
topLevelProject.setItem(leafProject);
leafProject.onCreatedFromScratch();
// Run the inner job directly, which should die trying to find the parent
// build with a reasonable error message.
AbstractBuild build = leafProject.scheduleBuild2(0).get();
// Test that our job was a failure
dumpLog(build);
assertEquals(Result.FAILURE, build.getResult());
assertThat(CharStreams.toString(new InputStreamReader(
build.getLogInputStream())),
containsString("Unable to determine parent build"));
}
@Test
public void testSimpleDelegationWithoutEnvironment() throws Exception {
TestBranchAwareProject topLevelProject =
Jenkins.getInstance().createProject(
TestBranchAwareProject.class, "topLevelProject");
// NOTE: Without this, we expect $HELLO to resolve to nothing
// and the grep for WORLD to fail.
// topLevelProject.setScm(new SemiNullSCM());
FreeStyleProject leafProject = FreeStyleProject.DESCRIPTOR.newInstance(
topLevelProject, "foo");
leafProject.setScm(new DelegateSCM(TestBranchAwareProject.class));
topLevelProject.setItem(leafProject);
leafProject.onCreatedFromScratch();
leafProject.getBuildersList().add(
new Shell("echo $HELLO"));
// Run the outer job, which should delegate to our inner project
TestBuild outerBuild = topLevelProject.scheduleBuild2(0).get();
// Test that our outer job was a success
dumpLog(outerBuild);
assertEquals(Result.SUCCESS, outerBuild.getResult());
// Test that our inner job was a success
AbstractBuild innerBuild = leafProject.getBuildByNumber(1);
dumpLog(innerBuild);
assertEquals(Result.SUCCESS, innerBuild.getResult());
assertThat(CharStreams.toString(new InputStreamReader(
innerBuild.getLogInputStream())),
not(containsString("WORLD")));
}
@Test
public void testSimpleDelegationWithEnvironment() throws Exception {
TestBranchAwareProject topLevelProject =
Jenkins.getInstance().createProject(
TestBranchAwareProject.class, "topLevelProject");
topLevelProject.setScm(new SemiNullSCM());
FreeStyleProject leafProject = FreeStyleProject.DESCRIPTOR.newInstance(
topLevelProject, "foo");
leafProject.setScm(new DelegateSCM(TestBranchAwareProject.class));
topLevelProject.setItem(leafProject);
leafProject.onCreatedFromScratch();
leafProject.getBuildersList().add(
new Shell("echo $HELLO"));
// Run the outer job, which should delegate to our inner project
TestBuild outerBuild = topLevelProject.scheduleBuild2(0).get();
// Test that our outer job was a success
dumpLog(outerBuild);
assertEquals(Result.SUCCESS, outerBuild.getResult());
// Test that our inner job was a success
AbstractBuild innerBuild = leafProject.getBuildByNumber(1);
dumpLog(innerBuild);
assertEquals(Result.SUCCESS, innerBuild.getResult());
assertThat(CharStreams.toString(new InputStreamReader(
innerBuild.getLogInputStream())),
containsString("WORLD"));
}
private void dumpLog(Run run) throws IOException {
BufferedReader reader = new BufferedReader(run.getLogReader());
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
}
}