1 year ago

#381726

test-img

Laiv

Why my Jenkins JUnit test no longer works?

A bit of context.

I'm developing an extensi贸n for Jenkins, that consists of a new WEB API aimed to provide our ALM tooling with customized endpoints and features. The starting point for me was this guide, which I have reproduced step by step.

After some manual tests of a bare minimum API, I concluded that the extension was ready for further development. However, I wanted to make the test automatic during the build phase, so I implemented a canary test following the previous guide and this other to feed test with @LocalData.

The firsts times I run the JUnit, everything went as expected. Test passed. I was able to run mvn clean packge and complete the tests.

Today, I did open the IDE, run the same maven goals to ensure that everything was ok, but all my test failed due to an 404 Not Found

=== Starting test_ping(net.corp.jenkins.plugins.almapirest.AlmApiTest)
   0.132 [id=17]    INFO    o.jvnet.hudson.test.WarExploder#explode: Picking up existing exploded jenkins.war at /home/*****/Desarrollo/workspace-11/jenkins-plugins/imi-alm-jenkinsplugin-almapirest/target/jenkins-for-test
   0.493 [id=17]    INFO    o.jvnet.hudson.test.JenkinsRule#createWebServer: Running on http://localhost:37423/jenkins/
   1.011 [id=31]    INFO    jenkins.InitReactorRunner$1#onAttained: Started initialization
   2.381 [id=29]    INFO    hudson.PluginManager#considerDetachedPlugin: Loading a detached plugin as a dependency: /tmp/jenkins14603157886504547615/plugins/bouncycastle-api.jpi
   2.488 [id=29]    INFO    hudson.PluginManager#considerDetachedPlugin: Loading a detached plugin as a dependency: /tmp/jenkins14603157886504547615/plugins/command-launcher.jpi
   2.501 [id=29]    INFO    hudson.PluginManager#considerDetachedPlugin: Loading a detached plugin as a dependency: /tmp/jenkins14603157886504547615/plugins/jdk-tool.jpi
   2.521 [id=29]    INFO    hudson.PluginManager#considerDetachedPlugin: Loading a detached plugin as a dependency: /tmp/jenkins14603157886504547615/plugins/jaxb.jpi
   2.774 [id=33]    INFO    jenkins.InitReactorRunner$1#onAttained: Listed all plugins
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.google.inject.internal.cglib.core.$ReflectUtils$2 (file:/home/*****/.m2/repository/com/google/inject/guice/4.0/guice-4.0.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain)
WARNING: Please consider reporting this to the maintainers of com.google.inject.internal.cglib.core.$ReflectUtils$2
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
   6.059 [id=35]    INFO    jenkins.InitReactorRunner$1#onAttained: Prepared all plugins
   6.086 [id=29]    INFO    jenkins.InitReactorRunner$1#onAttained: Started all plugins
   6.096 [id=29]    INFO    jenkins.InitReactorRunner$1#onAttained: Augmented all extensions
   7.084 [id=31]    INFO    jenkins.InitReactorRunner$1#onAttained: System config loaded
   7.085 [id=31]    INFO    jenkins.InitReactorRunner$1#onAttained: System config adapted
   7.085 [id=35]    INFO    jenkins.InitReactorRunner$1#onAttained: Loaded all jobs
   7.087 [id=33]    INFO    jenkins.InitReactorRunner$1#onAttained: Configuration for all jobs updated
   7.176 [id=35]    INFO    jenkins.InitReactorRunner$1#onAttained: Completed initialization
   9.127 [id=17]    INFO    n.o.j.p.almapirest.AlmApiTest#logJenkinsWebResponse: <html><body>
**<h1>404 Not Found</h1>**
<p>Stapler processed this HTTP request as follows, but couldn't find the resource to consume the request
<pre>
-&gt; evaluate(&lt;hudson.model.Hudson@15789a13&gt; :hudson.model.Hudson,"/alm-api/ping")
-&gt; evaluate(((StaplerProxy)&lt;hudson.model.Hudson@15789a13&gt;).getTarget(),"/alm-api/ping")
-&gt; evaluate(&lt;hudson.model.Hudson@15789a13&gt;.getDynamic("alm-api",...),"/ping")
            hudson.model.Hudson@15789a13.getDynamic("alm-api",...)==null. Back tracking.
-&gt; evaluate(((StaplerFallback)&lt;hudson.model.Hudson@15789a13&gt;).getStaplerFallback(),"/alm-api/ping")
-&gt; evaluate(&lt;hudson.model.AllView@52446fb2[view/all/]&gt; :hudson.model.AllView,"/alm-api/ping")
-&gt; evaluate(&lt;hudson.model.AllView@52446fb2[view/all/]&gt;.getDynamic("alm-api",...),"/ping")
            hudson.model.AllView@52446fb2[view/all/].getDynamic("alm-api",...)==null. Back tracking.
<font color=red>-&gt; No matching rule was found on &lt;hudson.model.AllView@52446fb2[view/all/]&gt; for "/alm-api/ping"</font>
</pre>
<p>&lt;hudson.model.AllView@52446fb2[view/all/]&gt; has the following URL mappings, in the order of preference:<ol>
<li>
If path ends without '/' insert it
<li>
hudson.model.View.doChildrenContextMenu(...) for url=/childrenContextMenu/...
<li>
hudson.model.AllView.doCreateItem(...) for url=/createItem/...
<li>
hudson.model.View.doConfigSubmit(...) for url=/configSubmit/...
<li>
hudson.model.View.doCheckJobName(...) for url=/checkJobName/...
<li>
hudson.model.View.doItemCategories(...) for url=/itemCategories/...
<li>
hudson.model.View.doConfigDotXml(...) for url=/config.xml/...
<li>
hudson.model.View.doDoDelete(...) for url=/doDelete/...
<li>
hudson.model.View.doSubmitDescription(...) for url=/submitDescription/...
<li>
hudson.model.View.doRssAll(...) for url=/rssAll/...
<li>
hudson.model.View.doRssFailed(...) for url=/rssFailed/...
<li>
hudson.model.View.doRssLatest(...) for url=/rssLatest/...
<li>
VIEW.groovy for url=/VIEW
<li>
VIEW.gsp for url=/VIEW
<li>
VIEW.jelly for url=/VIEW
<li>
index view of org.kohsuke.stapler.jelly.groovy.GroovyFacet@5a1e412f for url=/
<li>
index view of org.kohsuke.stapler.jelly.JellyFacet@5b7c0578 for url=/
<li>
BLOCKED: class java.lang.String hudson.model.AllView.DEFAULT_VIEW_NAME for url=/DEFAULT_VIEW_NAME/...
<li>
BLOCKED: class hudson.util.DescriptorList hudson.model.View.LIST for url=/LIST/...
<li>
BLOCKED: interface java.util.Comparator hudson.model.View.SORTER for url=/SORTER/...
<li>
BLOCKED: class hudson.security.PermissionGroup hudson.model.View.PERMISSIONS for url=/PERMISSIONS/...
<li>
BLOCKED: class hudson.security.Permission hudson.model.View.CREATE for url=/CREATE/...
<li>
BLOCKED: class hudson.security.Permission hudson.model.View.DELETE for url=/DELETE/...
<li>
BLOCKED: class hudson.security.Permission hudson.model.View.CONFIGURE for url=/CONFIGURE/...
<li>
BLOCKED: class hudson.security.Permission hudson.model.View.READ for url=/READ/...
<li>
BLOCKED: class hudson.util.AlternativeUiTextProvider$Message hudson.model.View.NEW_PRONOUN for url=/NEW_PRONOUN/...
<li>
BLOCKED: hudson.security.ACL hudson.model.View.getACL() for url=/aCL/...
<li>
hudson.model.ViewDescriptor hudson.model.View.getDescriptor() for url=/descriptor/...
<li>
BLOCKED: java.lang.String hudson.model.AllView.getDisplayName() for url=/displayName/...
<li>
BLOCKED: hudson.search.SearchIndex hudson.model.AbstractModelObject.getSearchIndex() for url=/searchIndex/...
<li>
BLOCKED: java.lang.String hudson.model.AbstractModelObject.getSearchName() for url=/searchName/...
<li>
BLOCKED: java.lang.String hudson.model.View.getSearchUrl() for url=/searchUrl/...
<li>
hudson.search.Search hudson.model.AbstractModelObject.getSearch() for url=/search/...
<li>
BLOCKED: java.util.Collection hudson.model.AllView.getItems() for url=/items/...
<li>
BLOCKED: hudson.Indenter hudson.model.View.getIndenter() for url=/indenter/...
<li>
hudson.model.Api hudson.model.View.getApi() for url=/api/...
<li>
hudson.model.BuildTimelineWidget hudson.model.View.getTimeline() for url=/timeline/...
<li>
hudson.model.View$AsynchPeople hudson.model.View.getAsynchPeople() for url=/asynchPeople/...
<li>
hudson.model.View$People hudson.model.View.getPeople() for url=/people/...
<li>
hudson.model.ViewGroup hudson.model.View.getOwner() for url=/owner/...
<li>
hudson.util.DescribableList hudson.model.View.getProperties() for url=/properties/...
<li>
BLOCKED: hudson.util.RunList hudson.model.View.getBuilds() for url=/builds/...
<li>
BLOCKED: java.lang.Iterable hudson.model.View.getColumns() for url=/columns/...
<li>
BLOCKED: java.lang.String hudson.model.View.getAbsoluteUrl() for url=/absoluteUrl/...
<li>
BLOCKED: java.lang.String hudson.model.View.getDescription() for url=/description/...
<li>
BLOCKED: java.lang.String hudson.model.View.getNewPronoun() for url=/newPronoun/...
<li>
BLOCKED: java.lang.String hudson.model.AllView.getPostConstructLandingPage() for url=/postConstructLandingPage/...
<li>
BLOCKED: java.lang.String hudson.model.View.getUrl() for url=/url/...
<li>
BLOCKED: java.lang.String hudson.model.View.getViewName() for url=/viewName/...
<li>
BLOCKED: java.lang.String hudson.model.View.getViewUrl() for url=/viewUrl/...
<li>
BLOCKED: java.util.Collection hudson.model.View.getAllItems() for url=/allItems/...
<li>
BLOCKED: java.util.List hudson.model.View.getActions() for url=/actions/...
<li>
BLOCKED: java.util.List hudson.model.View.getAllProperties() for url=/allProperties/...
<li>
BLOCKED: java.util.List hudson.model.View.getApplicablePropertyDescriptors() for url=/applicablePropertyDescriptors/...
<li>
BLOCKED: java.util.List hudson.model.View.getComputers() for url=/computers/...
<li>
BLOCKED: java.util.List hudson.model.View.getQueueItems() for url=/queueItems/...
<li>
BLOCKED: java.util.List hudson.model.View.getVisiblePropertyDescriptors() for url=/visiblePropertyDescriptors/...
<li>
BLOCKED: java.util.List hudson.model.View.getWidgets() for url=/widgets/...
<li>
BLOCKED: hudson.security.Permission hudson.model.View.getItemCreatePermission() for url=/itemCreatePermission/...
<li>
hudson.model.ItemGroup hudson.model.View.getOwnerItemGroup() for url=/ownerItemGroup/...
<li>
hudson.model.View hudson.model.View.getOwnerPrimaryView() for url=/ownerPrimaryView/...
<li>
BLOCKED: java.util.List hudson.model.View.getApproximateQueueItemsQuickly() for url=/approximateQueueItemsQuickly/...
<li>
BLOCKED: java.util.List hudson.model.View.getOwnerViewActions() for url=/ownerViewActions/...
<li>
hudson.model.Descriptor hudson.model.DescriptorByNameOwner.getDescriptorByName(String) for url=/descriptorByName/TOKEN/...
<li>
hudson.model.TopLevelItem hudson.model.View.getJob(String) for url=/job/TOKEN/...
<li>
hudson.model.TopLevelItem hudson.model.View.getItem(String) for url=/item/TOKEN/...
<li>
BLOCKED: java.lang.Object hudson.model.View.getDynamic(String) for url=/dynamic/TOKEN/...
<li>
java.lang.Object hudson.model.View.getDynamic(String,StaplerRequest,StaplerResponse) for url=/TOKEN/...
</ol>
</body></html>

   9.440 [id=17]    INFO    jenkins.model.Jenkins#cleanUp: Stopping Jenkins
   9.727 [id=17]    INFO    jenkins.model.Jenkins#cleanUp: Jenkins stopped

Does anyone know why my test' no longer finds my API? It looks like the plugin was not loaded. If I run mvn hpi:run, the plugin creates work in my project's root dir and I can see the plugin installed in work/plugins/. So, I tested again, this time manually, if the API that caused the previous 404 was accessible and it was.

It should be something related to my local environment or workspace, but I don't know what could have changed since the last time tests worked.

This is the source code of the test

@Rule
public JenkinsRule jenkinsRule = new JenkinsRule();

public void test_ping() throws Exception {

   JenkinsRule.WebClient webClient = jenkinsRule.createWebClient();
   JenkinsRule.JSONWebResponse response = webClient.getJSON("alm-api/ping");
   logJenkinsWebResponse(response);
        
   assertThat(response.getStatusCode(), is(200));
   assertThat(response.getJSONObject().get("pong"), notNullValue());
    
}
private static void logJenkinsWebResponse(JenkinsRule.JSONWebResponse response) {
   try {
    LOG.info(response.getJSONObject().toString(2,2));
   }catch(JSONException ex) {
    LOG.info(response.getContentAsString());
   }
}

And this's the production code

@Extension
public class AlmApi implements RootAction {

    protected static final String ALM_API_NAME = "alm-api";

    @Override
    public String getIconFileName() {
        return null;
    }

    @Override
    public String getDisplayName() {
        return null;
    }

    @Override
    public String getUrlName() {
        return ALM_API_NAME;
    }

    @GET
    @WebMethod(name = "ping")
    public JsonHttpResponse ping() {
        JSONObject response = JSONObject.fromObject(new PongDTO(Instant.now()));
        return new JsonHttpResponse(response, 200);
    }
}

PongDTO: Plain old java object

Observations: I have realised that Jenkins Test, creates target/jenkins-for-test but everything I see in there is a very small version of Jenkins but I don't find any plugin/ folder. I guess, during the test phase, my extensions get injected into the classloader on-the-fly.

My code is being committed in a GitLab repository every time something in the source code changes. So, I have checked out previous commits (proven to work and pass tests) and tried to run tests again. No test passed. The problem has been the same: 404 Not Found.

I have also tried ending endpoints with a trailing slash (/) in all the calls from JUnit tests. It didn't work either.

unit-testing

jenkins-plugins

0 Answers

Your Answer

Accepted video resources