Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle case where last completed build does not have RebuildAction #158

Merged
merged 1 commit into from
Mar 31, 2024

Conversation

sghill
Copy link
Contributor

@sghill sghill commented Dec 5, 2023

This fixes a NPE introduced in #155. We've run into this issue while attempting to view job config history with the latest version, and have pinned to the previous version to avoid it.

Testing done

I attempted to create a tests with mockito that covered the logic of RebuildLastCompletedBuildAction#getUrlName(), but ran into issues with Jenkins.instance missing. Since the change here is straightforward, I wasn't sure it warranted creating JenkinsRule tests.

RebuildLastCompletedBuildActionTest.java
package com.sonyericsson.rebuild;

import hudson.model.AbstractProject;
import hudson.model.FreeStyleBuild;
import hudson.model.FreeStyleProject;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.mockito.BDDMockito.given;

@RunWith(MockitoJUnitRunner.class)
public class RebuildLastCompletedBuildActionTest {
    @Mock
    private AbstractProject project;
    @Mock
    private FreeStyleBuild lastCompletedBuild;
    @Mock
    private RebuildAction rebuildAction;
    private RebuildLastCompletedBuildAction action;

    @Before
    public void setUp() {
        action = new RebuildLastCompletedBuildAction(project);
    }

    @Test
    public void shouldReturnNullIfNotBuildable() {
        given(project.isBuildable()).willReturn(false);
        String actual = action.getUrlName();
        assertNull(actual);
    }

    @Test
    public void shouldReturnNullIfNoLastCompletedBuild() {
        given(project.isBuildable()).willReturn(true);
        given(project.getLastCompletedBuild()).willReturn(null);
        String actual = action.getUrlName();
        assertNull(actual);
    }

    @Test
    public void shouldReturnNullIfNoRebuildActionOnLastCompletedBuild() {
        given(project.isBuildable()).willReturn(true);
        given(project.getLastCompletedBuild()).willReturn(lastCompletedBuild);
        given(lastCompletedBuild.getAction(RebuildAction.class)).willReturn(null);
        String actual = action.getUrlName();
        assertNull(actual);
    }

    @Test
    public void shouldReturnUrlName() {
        given(project.isBuildable()).willReturn(true);
        given(project.getLastCompletedBuild()).willReturn(lastCompletedBuild);
        given(rebuildAction.getUrlName()).willReturn("expected-task-url");
        given(lastCompletedBuild.getAction(RebuildAction.class)).willReturn(rebuildAction);
        String expected = "lastCompletedBuild/expected-task-url";
        String actual = action.getUrlName();
        assertEquals(expected, actual);
    }
}

Submitter checklist

Preview Give feedback

@sghill sghill requested a review from a team as a code owner December 5, 2023 17:43
@daniel-beck
Copy link
Member

I would not expect this to happen with RebuildActionFactory. What's the affected job type?

@sghill
Copy link
Contributor Author

sghill commented Dec 5, 2023

@daniel-beck it's a hudson.model.FreeStyleProject that was created before the upgrade. Loading up {buildUrl}/jobConfigHistory/ showed this stacktrace:

Caused by: java.lang.NullPointerException: Cannot invoke "com.sonyericsson.rebuild.RebuildAction.getTaskUrl()" because "action" is null
        at com.sonyericsson.rebuild.RebuildLastCompletedBuildAction.getUrlName(RebuildLastCompletedBuildAction.java:61)
        at hudson.model.Actionable.getDynamic(Actionable.java:345)
        at hudson.model.Job.getDynamic(Job.java:864)
        at java.base/java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:732)
        at org.kohsuke.stapler.Function$MethodFunction.invoke(Function.java:397)

@daniel-beck
Copy link
Member

daniel-beck commented Dec 5, 2023

My guess is you have a plugin installed that provides an implementation of RebuildValidator, like gerrit-trigger. That's a case I didn't test for as I was unaware this existed.

@GLundh
Copy link
Member

GLundh commented Dec 5, 2023

@daniel-beck: I don't see much risk for this PR. But before I merge & close, do you see a risk?

@daniel-beck
Copy link
Member

daniel-beck commented Dec 6, 2023

@GLundh Untested but seems fine if it works. Feedback was exclusively about understanding how this situation occurs.

@sghill
Copy link
Contributor Author

sghill commented Dec 6, 2023

Confirming I do have another implementation of RebuildValidator.

Thanks for the review!

@pci-mthompson
Copy link

FYI, this can also occur with inheritance builds (Project Inheritance Plugin) after recent updates. I manually patched a version of rebuild and this PR fixes it.

@shemuwel
Copy link

Hello! Any chance to get this PR merged?
Thank you

Copy link
Member

@hagzag hagzag left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@timotei
Copy link

timotei commented Mar 29, 2024

@hagzag can we make use of this fix in a released version? We're currently blocked from rolling out the latest update because of this issue.

@hagzag hagzag merged commit a1ee476 into jenkinsci:master Mar 31, 2024
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants