Skip to content

Performance: Cross-test caching of loaded scripts #606

@reitzig

Description

@reitzig

What feature do you want to see added?

Currently, PipelineTestHelper#loadScript (or, more specifically, GroovyScriptEngine#loadScriptByName) accounts for roughly 95% of the running time of our test suite (>200 tests).
image

Now, I'm sure we've been working against anything that even closely resembles best practices, but still.

In a @BeforeEach method, we

  • run DelarativePipelineTestHelper#setUp,
  • set up some mocks,
  • register a shared library, and
  • load the pipeline script under test.

In the test class at hand, we have 27 tests, each of which performs a run of the pipeline (with different parameters, alas).

I see that GroovyScriptEngine has a cache, but that one is reset for every test.
I tried adding a cache for the class objects myself:

class CachingPipelineTestHelper extends PipelineTestHelper {
    private final static Map<String, Class> scriptClassCache = new HashMap<>()

    @Override
    Script loadScript(String scriptName, Binding binding) {
        Objects.requireNonNull(binding, "Binding cannot be null.");

        Class scriptClass;
        if (scriptClassCache.containsKey(scriptName)) {
            scriptClass = scriptClassCache.get(scriptName)
        } else {
            Objects.requireNonNull(gse,
                    "GroovyScriptEngine is not initialized: Initialize the helper by calling init().");
            scriptClass = gse.loadScriptByName(scriptName)
            scriptClassCache.put(scriptName, scriptClass)
        }

        setGlobalVars(binding)
        Script script = InvokerHelper.createScript(scriptClass, binding)
        InterceptingGCL.interceptClassMethods(script.getMetaClass(), this, binding)
        return script
    }
}

When I use that, I get java.lang.IllegalStateException: No agent description found in all but the first test; basically, they fail on the first expression inside pipeline { ... }.

I don't really understand what's going on, so I'll go ahead and phrase it as a feature request: Please provide facilities that allow us to load pipeline scripts only once per test run (or at least test class).

Upstream changes

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions