From 02543954761705087a63c178a70d46b56095eecc Mon Sep 17 00:00:00 2001 From: jgrant216 Date: Sat, 6 Mar 2021 16:00:58 -0500 Subject: [PATCH] #298: Prevent NullPointerException when branch with cancelled analysis is rescanned When a background task for a pull request analysis is cancelled, a subsequent attempt to re-scan the pull request fails in the scanner since the `analysisDate` field is no longer present against the pull request. This change handles this missing date in a better manner, defaulting to having a `0` analysis date in the same way an error parsing the analysis date would. --- .../CommunityProjectPullRequestsLoader.java | 9 ++++++-- ...ommunityProjectPullRequestsLoaderTest.java | 22 +++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/github/mc1arke/sonarqube/plugin/scanner/CommunityProjectPullRequestsLoader.java b/src/main/java/com/github/mc1arke/sonarqube/plugin/scanner/CommunityProjectPullRequestsLoader.java index 1fd876e5f..c3fe6a6c5 100644 --- a/src/main/java/com/github/mc1arke/sonarqube/plugin/scanner/CommunityProjectPullRequestsLoader.java +++ b/src/main/java/com/github/mc1arke/sonarqube/plugin/scanner/CommunityProjectPullRequestsLoader.java @@ -70,8 +70,13 @@ private static JsonDeserializer createPullRequestInfoJsonDeseri JsonObject jsonObject = jsonElement.getAsJsonObject(); long parsedDate = 0; try { - parsedDate = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ") - .parse(jsonObject.get("analysisDate").getAsString()).getTime(); + String analysisDate = Optional.ofNullable(jsonObject.get("analysisDate")).map(JsonElement::getAsString).orElse(null); + if(analysisDate == null) { + LOGGER.warn("Analysis Date not provided in Pull Requests API response. Will use '0' date"); + } else { + parsedDate = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ") + .parse(analysisDate).getTime(); + } } catch (ParseException e) { LOGGER.warn("Could not parse date from Pull Requests API response. Will use '0' date", e); } diff --git a/src/test/java/com/github/mc1arke/sonarqube/plugin/scanner/CommunityProjectPullRequestsLoaderTest.java b/src/test/java/com/github/mc1arke/sonarqube/plugin/scanner/CommunityProjectPullRequestsLoaderTest.java index d0f3dca5f..be73aeb68 100644 --- a/src/test/java/com/github/mc1arke/sonarqube/plugin/scanner/CommunityProjectPullRequestsLoaderTest.java +++ b/src/test/java/com/github/mc1arke/sonarqube/plugin/scanner/CommunityProjectPullRequestsLoaderTest.java @@ -138,6 +138,28 @@ public void testAllPullRequestsFromNonEmptyServerResponseWithoutBase() { assertEquals("101", responseInfo.getKey()); } + @Test + public void testAllPullRequestsFromNonEmptyServerResponseWithoutAnalysisDateAndQualityGateStatusForCancelledPr() throws ParseException { + WsResponse mockResponse = mock(WsResponse.class); + when(scannerWsClient.call(any())).thenReturn(mockResponse); + + StringReader stringReader = new StringReader( + "{\"pullRequests\":[{\"key\":\"101\",\"title\":\"dummybranch\",\"branch\":\"dummybranch\",\"base\":\"master\",\"status\":{\"bugs\":0,\"vulnerabilities\":0,\"codeSmells\":0}}]}"); + when(mockResponse.contentReader()).thenReturn(stringReader); + + CommunityProjectPullRequestsLoader testCase = new CommunityProjectPullRequestsLoader(scannerWsClient); + ProjectPullRequests response = testCase.load("key"); + assertFalse(response.isEmpty()); + + PullRequestInfo responseInfo = response.get("dummybranch"); + assertNotNull(responseInfo); + assertEquals(0, + responseInfo.getAnalysisDate()); + assertEquals("master", responseInfo.getBase()); + assertEquals("dummybranch", responseInfo.getBranch()); + assertEquals("101", responseInfo.getKey()); + } + @Test public void testMessageExceptionOnIOException() { WsResponse mockResponse = mock(WsResponse.class);