From ad281adc97b4e1fa9cd1ac32c9e92bfb0efd91c2 Mon Sep 17 00:00:00 2001 From: Martin van Zijl Date: Wed, 4 Sep 2019 14:43:59 +1200 Subject: [PATCH] Unit tests and fixes. Fixed issue with getCodeFrequency() where it would occasionally throw an exception when the statistics were still being generated. Added comment about throwing an exception as a possibility when 202 is returned. --- .../java/org/kohsuke/github/GHRepository.java | 34 ++++--- .../java/org/kohsuke/github/Requester.java | 1 + .../org/kohsuke/github/StatisticsTest.java | 91 +++++++++++++++++++ 3 files changed, 113 insertions(+), 13 deletions(-) create mode 100644 src/test/java/org/kohsuke/github/StatisticsTest.java diff --git a/src/main/java/org/kohsuke/github/GHRepository.java b/src/main/java/org/kohsuke/github/GHRepository.java index d06b808b5..c0b87964d 100644 --- a/src/main/java/org/kohsuke/github/GHRepository.java +++ b/src/main/java/org/kohsuke/github/GHRepository.java @@ -26,6 +26,7 @@ package org.kohsuke.github; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.exc.MismatchedInputException; import com.infradna.tool.bridge_method_injector.WithBridgeMethods; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import org.apache.commons.lang3.StringUtils; @@ -1739,22 +1740,29 @@ public class GHRepository extends GHObject { public List getCodeFrequency() throws IOException { // Map to ArrayLists first, since there are no field names in the // returned JSON. - InputStream stream = root.retrieve().asStream(getApiTailUrl("stats/code_frequency")); + try { + InputStream stream = root.retrieve().asStream(getApiTailUrl("stats/code_frequency")); - ObjectMapper mapper = new ObjectMapper(); - TypeReference > > typeRef = - new TypeReference > >() {}; - ArrayList > list = mapper.readValue(stream, typeRef); + ObjectMapper mapper = new ObjectMapper(); + TypeReference > > typeRef = + new TypeReference > >() {}; + ArrayList > list = mapper.readValue(stream, typeRef); - // Convert to proper objects. - ArrayList returnList = new ArrayList(); - for(ArrayList item: list) - { - CodeFrequency cf = new CodeFrequency(item); - returnList.add(cf); + // Convert to proper objects. + ArrayList returnList = new ArrayList(); + for(ArrayList item: list) + { + CodeFrequency cf = new CodeFrequency(item); + returnList.add(cf); + } + + return returnList; + } catch (MismatchedInputException e) { + // This sometimes happens when retrieving code frequency statistics + // for a repository for the first time. It is probably still being + // generated, so return null. + return null; } - - return returnList; } public static class CodeFrequency { diff --git a/src/main/java/org/kohsuke/github/Requester.java b/src/main/java/org/kohsuke/github/Requester.java index ff8f12243..e415b915a 100644 --- a/src/main/java/org/kohsuke/github/Requester.java +++ b/src/main/java/org/kohsuke/github/Requester.java @@ -626,6 +626,7 @@ class Requester { // See https://developer.github.com/v3/repos/statistics/#a-word-about-caching if (responseCode == 202) { LOGGER.log(INFO, "The statistics are still being generated. Please try again in 5 seconds."); + // Maybe throw an exception instead? return null; } diff --git a/src/test/java/org/kohsuke/github/StatisticsTest.java b/src/test/java/org/kohsuke/github/StatisticsTest.java new file mode 100644 index 000000000..ab878285e --- /dev/null +++ b/src/test/java/org/kohsuke/github/StatisticsTest.java @@ -0,0 +1,91 @@ +package org.kohsuke.github; + +import org.junit.Test; + +import java.io.IOException; + +public class StatisticsTest extends AbstractGitHubApiTestBase { + + public static final String REPOSITORY = "martinvanzijl/sandbox"; + public static int MAX_ITERATIONS = 3; + public static int SLEEP_INTERVAL = 5000; + + private GitHub github; + private GHRepository repo; + + @Override + public void setUp() throws Exception { + github = GitHub.connect(); + repo = github.getRepository(REPOSITORY); + } + + @Test + @SuppressWarnings("SleepWhileInLoop") + public void testContributorStats() throws IOException, InterruptedException { + for (int i = 0; i < MAX_ITERATIONS; i += 1) { + if(repo.getContributorStats() == null) { + Thread.sleep(SLEEP_INTERVAL); + } + else { + return; + } + } + fail("Statistics took too long to retrieve."); + } + + @Test + @SuppressWarnings("SleepWhileInLoop") + public void testCommitActivity() throws IOException, InterruptedException { + for (int i = 0; i < MAX_ITERATIONS; i += 1) { + if(repo.getCommitActivity() == null) { + Thread.sleep(SLEEP_INTERVAL); + } + else { + return; + } + } + fail("Statistics took too long to retrieve."); + } + + @Test + @SuppressWarnings("SleepWhileInLoop") + public void testCodeFrequency() throws IOException, InterruptedException { + for (int i = 0; i < MAX_ITERATIONS; i += 1) { + if(repo.getCodeFrequency() == null) { + Thread.sleep(SLEEP_INTERVAL); + } + else { + return; + } + } + fail("Statistics took too long to retrieve."); + } + + @Test + @SuppressWarnings("SleepWhileInLoop") + public void testParticipation() throws IOException, InterruptedException { + for (int i = 0; i < MAX_ITERATIONS; i += 1) { + if(repo.getParticipation() == null) { + Thread.sleep(SLEEP_INTERVAL); + } + else { + return; + } + } + fail("Statistics took too long to retrieve."); + } + + @Test + @SuppressWarnings("SleepWhileInLoop") + public void testPunchCard() throws IOException, InterruptedException { + for (int i = 0; i < MAX_ITERATIONS; i += 1) { + if(repo.getPunchCard() == null) { + Thread.sleep(SLEEP_INTERVAL); + } + else { + return; + } + } + fail("Statistics took too long to retrieve."); + } +}