Class RealJenkinsRule

  • All Implemented Interfaces:
    org.junit.rules.TestRule

    public final class RealJenkinsRule
    extends Object
    implements org.junit.rules.TestRule
    Like JenkinsSessionRule but running Jenkins in a more realistic environment.

    Though Jenkins is run in a separate JVM using Winstone (java -jar jenkins.war), you can still do “whitebox” testing: directly calling Java API methods, starting from JenkinsRule or not. This is because the test code gets sent to the remote JVM and loaded and run there. (Thus when using Maven, there are at least three JVMs involved: Maven itself; the Surefire booter with your top-level test code; and the Jenkins controller with test bodies.) Just as with JenkinsRule, all plugins found in the test classpath will be enabled, but with more realistic behavior: class loaders in a graph, pluginFirstClassLoader and maskClasses, etc.

    “Compile-on-save” style development works for classes and resources in the current plugin: with a suitable IDE, you can edit a source file, have it be sent to target/classes/, and rerun a test without needing to go through a full Maven build cycle. This is because target/test-classes/the.hpl is used to load unpacked plugin resources.

    Like JenkinsRule, the controller is started in “development mode”: the setup wizard is suppressed, the update center is not checked, etc.

    Known limitations:

    • Execution is a bit slower due to the overhead of launching a new JVM; and class loading overhead cannot be shared between test cases. More memory is needed.
    • Remote thunks must be serializable. If they need data from the test JVM, you will need to create a static nested class to package that.
    • static state cannot be shared between the top-level test code and test bodies (though the compiler will not catch this mistake).
    • When using a snapshot dep on Jenkins core, you must build jenkins.war to test core changes (there is no “compile-on-save” support for this).
    • Assume is not available.
    • TestExtension is not available.
    • LoggerRule is not available, however additional loggers can be configured via withLogger(Class, Level)}.
    • BuildWatcher is not available, but you can use TailLog instead.
    • There is not currently enough flexibility in how the controller is launched.

    Systems not yet tested:

    • Possibly Timeout can be used.
    • Possibly ExtensionList.add(Object) can be used as an alternative to TestExtension.
    • Constructor Detail

      • RealJenkinsRule

        public RealJenkinsRule()
    • Method Detail

      • addPlugins

        public RealJenkinsRule addPlugins​(String... plugins)
        Add some plugins to the test classpath.
        Parameters:
        plugins - Filenames of the plugins to install. These are expected to be absolute test classpath resources, such as plugins/workflow-job.hpi for example.

        Committing that file to SCM (say, src/test/resources/sample.jpi) is reasonable for small fake plugins built for this purpose and exercising some bit of code. If you wish to test with larger archives of real plugins, this is possible for example by binding dependency:copy to the process-test-resources phase.

        In most cases you do not need this method. Simply add whatever plugins you are interested in testing against to your POM in test scope. These, and their transitive dependencies, will be loaded in all RealJenkinsRule tests. This method is useful if only a particular test may load the tested plugin, or if the tested plugin is not available in a repository for use as a test dependency.

      • omitPlugins

        public RealJenkinsRule omitPlugins​(String... plugins)
        Omit some plugins in the test classpath.
        Parameters:
        plugins - one or more code names, like token-macro
      • javaOptions

        public RealJenkinsRule javaOptions​(String... options)
        Add some JVM startup options.
        Parameters:
        options - one or more options, like -Dorg.jenkinsci.Something.FLAG=true
      • extraEnv

        public RealJenkinsRule extraEnv​(String key,
                                        String value)
        Set an extra environment variable.
        Parameters:
        value - null to cancel a previously set variable
      • withHost

        public RealJenkinsRule withHost​(String host)
        Sets a custom host name for the Jenkins root URL.

        By default, this is just localhost. But you may wish to set it to something else that resolves to localhost, such as some-id.127.0.0.1.nip.io. This is particularly useful when running multiple copies of Jenkins (and/or other services) in one test case, since browser cookies are sensitive to host but not port and so otherwise HttpServletRequest.getSession(boolean) might accidentally be shared across otherwise distinct services.

        Calling this method does not change the fact that Jenkins will be configured to listen only on localhost for security reasons (so others in the same network cannot access your system under test, especially if it lacks authentication).

      • withWar

        public RealJenkinsRule withWar​(File war)
        Sets a custom WAR file to be used by the rule instead of the one in the path or war/target/jenkins.war in case of core.
      • withName

        public RealJenkinsRule withName​(String name)
        Sets a name for this instance, which will be prefixed to log messages to simplify debugging.
      • getName

        public String getName()
      • includeTestClasspathPlugins

        public RealJenkinsRule includeTestClasspathPlugins​(boolean includeTestClasspathPlugins)
        The intended use case for this is to use the plugins bundled into the war withWar(File) instead of the plugins in the pom. A typical scenario for this feature is a test which does not live inside a plugin's src/test/java
        Parameters:
        includeTestClasspathPlugins - false if plugins from pom should not be used (default true)
      • apply

        public org.junit.runners.model.Statement apply​(org.junit.runners.model.Statement base,
                                                       org.junit.runner.Description description)
        Specified by:
        apply in interface org.junit.rules.TestRule
      • getHome

        public File getHome()
        Obtains the Jenkins home directory. Normally it will suffice to use LocalData to populate files.
      • stopJenkins

        public void stopJenkins()
                         throws Throwable
        Stops Jenkins and releases any system resources associated with it. If Jenkins is already stopped then invoking this method has no effect.
        Throws:
        Throwable
      • runRemotely

        public void runRemotely​(RealJenkinsRule.Step... steps)
                         throws Throwable
        Runs one or more steps on the remote system. (Compared to multiple calls, passing a series of steps is slightly more efficient as only one network call is made.)
        Throws:
        Throwable