Repository: jenkinsci/jenkins
File: test/src/test/java/jenkins/triggers/ReverseBuildTriggerTest.java (Java)

Code before:
                .getAuthenticators()
                .replace(new MockQueueItemAuthenticator()
                        .authenticate(upstreamName, User.get("bob").impersonate2())
                        .authenticate(downstreamName, User.get("alice").impersonate2()));
        b = r.buildAndAssertSuccess(upstream);
        r.assertLogNotContains(downstreamName, b);
        r.waitUntilNoActivity();
        assertEquals(3, downstream.getLastBuild().number);

        // A QIA is configured but does not specify any authentication for downstream, anonymous can only DISCOVER upstream
        // so no message is printed about it, and no Exception neither (JENKINS-42707)
        auth.grant(Item.READ).onItems(upstream).to("bob");
        auth.grant(Item.DISCOVER).onItems(upstream).to("anonymous");
        QueueItemAuthenticatorConfiguration.get()
                .getAuthenticators()
                .replace(new MockQueueItemAuthenticator()
                        .authenticate(upstreamName, User.get("bob").impersonate2())
                        .authenticate(downstreamName, Jenkins.ANONYMOUS2));
        b = r.buildAndAssertSuccess(upstream);
        r.assertLogNotContains(downstreamName, b);
        r.assertLogNotContains("Please login to access job " + upstreamName, b);
        r.waitUntilNoActivity();
        assertEquals(3, downstream.getLastBuild().number);
    }

    @Issue({"JENKINS-29876", "JENKINS-39044"})
    @Test
    void nullJobInTriggerNotCausesNPE() throws Exception {
        final FreeStyleProject upstreamJob = r.createFreeStyleProject("upstream");

        //job with trigger.job == null
        final FreeStyleProject downstreamJob1 = r.createFreeStyleProject("downstream1");
        final ReverseBuildTrigger reverseBuildTrigger = new ReverseBuildTrigger("upstream");
        downstreamJob1.addTrigger(reverseBuildTrigger);
        downstreamJob1.save();

        //job with trigger.job != null
        final FreeStyleProject downstreamJob2 = r.createFreeStyleProject("downstream2");
        final ReverseBuildTrigger reverseBuildTrigger2 = new ReverseBuildTrigger("upstream");
        downstreamJob2.addTrigger(reverseBuildTrigger2);
        downstreamJob2.save();
        r.configRoundtrip(downstreamJob2);

        r.jenkins.rebuildDependencyGraph();

        // JENKINS-39044 - NPE if trigger threshold is null
        ReverseBuildTrigger trigger = downstreamJob2.getTrigger(ReverseBuildTrigger.class);
        trigger.setThreshold(null);

        final FreeStyleBuild build = r.buildAndAssertSuccess(upstreamJob);
        r.waitUntilNoActivity();

Review comment (suggestion):
The PR title and description reference issue #17611, but this annotation references JENKINS-39044. These should be consistent - either both should reference the same issue number, or if they're related issues, the PR description should clarify the relationship between #17611 and JENKINS-39044.

Code after:
                .getAuthenticators()
                .replace(new MockQueueItemAuthenticator()
                        .authenticate(upstreamName, User.get("bob").impersonate2())
                        .authenticate(downstreamName, User.get("alice").impersonate2()));
        b = r.buildAndAssertSuccess(upstream);
        r.assertLogNotContains(downstreamName, b);
        r.waitUntilNoActivity();
        assertEquals(3, downstream.getLastBuild().number);

        // A QIA is configured but does not specify any authentication for downstream, anonymous can only DISCOVER upstream
        // so no message is printed about it, and no Exception neither (JENKINS-42707)
        auth.grant(Item.READ).onItems(upstream).to("bob");
        auth.grant(Item.DISCOVER).onItems(upstream).to("anonymous");
        QueueItemAuthenticatorConfiguration.get()
                .getAuthenticators()
                .replace(new MockQueueItemAuthenticator()
                        .authenticate(upstreamName, User.get("bob").impersonate2())
                        .authenticate(downstreamName, Jenkins.ANONYMOUS2));
        b = r.buildAndAssertSuccess(upstream);
        r.assertLogNotContains(downstreamName, b);
        r.assertLogNotContains("Please login to access job " + upstreamName, b);
        r.waitUntilNoActivity();
        assertEquals(3, downstream.getLastBuild().number);
    }

    @Issue({"JENKINS-29876", "JENKINS-39044", "https://github.com/jenkinsci/jenkins/issues/17611"})
    @Test
    void nullJobInTriggerNotCausesNPE() throws Exception {
        final FreeStyleProject upstreamJob = r.createFreeStyleProject("upstream");

        //job with trigger.job == null
        final FreeStyleProject downstreamJob1 = r.createFreeStyleProject("downstream1");
        final ReverseBuildTrigger reverseBuildTrigger = new ReverseBuildTrigger("upstream");
        downstreamJob1.addTrigger(reverseBuildTrigger);
        downstreamJob1.save();

        //job with trigger.job != null
        final FreeStyleProject downstreamJob2 = r.createFreeStyleProject("downstream2");
        final ReverseBuildTrigger reverseBuildTrigger2 = new ReverseBuildTrigger("upstream");
        downstreamJob2.addTrigger(reverseBuildTrigger2);
        downstreamJob2.save();
        r.configRoundtrip(downstreamJob2);

        r.jenkins.rebuildDependencyGraph();

        // JENKINS-39044 - NPE if trigger threshold is null
        ReverseBuildTrigger trigger = downstreamJob2.getTrigger(ReverseBuildTrigger.class);
        trigger.setThreshold(null);

        final FreeStyleBuild build = r.buildAndAssertSuccess(upstreamJob);
        r.waitUntilNoActivity();