package hudson.model;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;

import java.io.IOException;

import hudson.EnvVars;
import hudson.matrix.MatrixProject;
import hudson.maven.MavenModuleSet;
import hudson.tasks.Maven.MavenInstallation;
import hudson.util.StreamTaskListener;

import jenkins.model.Jenkins;

import org.jvnet.hudson.test.Issue;
import org.jvnet.hudson.test.ExtractResourceSCM;
import org.jvnet.hudson.test.HudsonTestCase;
import org.jvnet.hudson.test.ToolInstallations;

/**
 * Tests that getEnvironment() calls outside of builds are safe.
 *
 * @author kutzi
 */
@Issue("JENKINS-11592")
public class GetEnvironmentOutsideBuildTest extends HudsonTestCase {

    private int oldExecNum;

    @Override
    protected void runTest() throws Throwable {
        // Disable tests

        // It's unfortunately not working, yet, as whenJenkinsMasterHasNoExecutors is not working as expected
    }

    public void setUp() throws Exception {
        super.setUp();

        this.oldExecNum = Jenkins.getInstance().getNumExecutors();
    }

    public void tearDown() throws Exception {
        restoreOldNumExecutors();
        super.tearDown();
    }

    private void restoreOldNumExecutors() throws IOException {
        Jenkins.getInstance().setNumExecutors(this.oldExecNum);
        assertNotNull(Jenkins.getInstance().toComputer());
    }

    private MavenModuleSet createSimpleMavenProject() throws Exception {
        MavenModuleSet project = jenkins.createProject(MavenModuleSet.class, "mms");
        MavenInstallation mi = ToolInstallations.configureMaven3();
        project.setScm(new ExtractResourceSCM(getClass().getResource(
                "/simple-projects.zip")));
        project.setMaven(mi.getName());
        project.setGoals("validate");
        return project;
    }

    private void whenJenkinsMasterHasNoExecutors() throws IOException {
        Jenkins.getInstance().setNumExecutors(0);
        assertNull(Jenkins.getInstance().toComputer());
    }

    public void testMaven() throws Exception {
        MavenModuleSet m = createSimpleMavenProject();

        assertGetEnvironmentCallOutsideBuildWorks(m);
    }

    public void testFreestyle() throws Exception {
        FreeStyleProject project = createFreeStyleProject();

        assertGetEnvironmentCallOutsideBuildWorks(project);
    }

    public void testMatrix() throws Exception {
        MatrixProject createMatrixProject = jenkins.createProject(MatrixProject.class, "mp");

        assertGetEnvironmentCallOutsideBuildWorks(createMatrixProject);
    }

    @SuppressWarnings({"rawtypes", "unchecked"})
    private void assertGetEnvironmentCallOutsideBuildWorks(AbstractProject job) throws Exception {
        AbstractBuild build = buildAndAssertSuccess(job);

        assertGetEnvironmentWorks(build);
    }

    @SuppressWarnings("rawtypes")
    private void assertGetEnvironmentWorks(Run build) throws IOException, InterruptedException {
        whenJenkinsMasterHasNoExecutors();
        // and getEnvironment is called outside of build
        EnvVars envVars =  build.getEnvironment(StreamTaskListener.fromStdout());
        // then it should still succeed - i.e. no NPE o.s.l.t.
        assertNotNull(envVars);
    }
}

@@ -158,16 +158,50 @@
 nvVars;%0A
+import hudson.matrix.MatrixBuild;%0A
 import h
@@ -264,16 +264,57 @@
 uleSet;%0A
+import hudson.maven.MavenModuleSetBuild;%0A
 import h
@@ -2196,32 +2196,101 @@
 avenProject();%0A%0A
+        final MavenModuleSetBuild build = buildAndAssertSuccess(m);%0A%0A
         assertGe
@@ -2305,31 +2305,19 @@
 ment
-CallOutsideBuild
 Works(
-m
+build
 );%0A 
@@ -2447,57 +2447,109 @@
     
-assertGetEnvironmentCallOutsideBuildWorks(project
+final FreeStyleBuild build = buildAndAssertSuccess(project);%0A%0A        assertGetEnvironmentWorks(build
 );%0A 
@@ -2709,243 +2709,20 @@
     
-assertGetEnvironmentCallOutsideBuildWorks(createMatrixProject);%0A    %7D%0A%0A    @SuppressWarnings(%7B%22rawtypes%22, %22unchecked%22%7D)%0A    private void assertGetEnvironmentCallOutsideBuildWorks(AbstractProject job) throws Exception %7B%0A        Abstract
+final Matrix
 Buil
@@ -2757,11 +2757,27 @@
 ess(
-job
+createMatrixProject
 );%0A%0A

Fix generics ambiguity