diff options
author | Andrei Selkin <andreyselkin@gmail.com> | 2016-05-16 23:53:12 +0300 |
---|---|---|
committer | Roman Ivanov <romani@users.noreply.github.com> | 2016-05-16 13:53:12 -0700 |
commit | ecbeaa6e1df7cb021745e111b04395b9fbd509c7 (patch) | |
tree | 1eb411fa321220383c9456f92f9ea407beb43adb /src/test | |
parent | 8c6863abdf85264d2a5624e33384c9d57bf32968 (diff) | |
download | checkstyle-ecbeaa6e1df7cb021745e111b04395b9fbd509c7.tar.gz |
Issue #407: Fix cache usage in presence of modules which use external resources for configuration (#3092)
Diffstat (limited to 'src/test')
6 files changed, 451 insertions, 3 deletions
diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/CheckerTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/CheckerTest.java index 645d0da22..76d443d49 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/CheckerTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/CheckerTest.java @@ -38,6 +38,7 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Locale; +import java.util.Set; import java.util.SortedSet; import org.junit.Assume; @@ -48,11 +49,18 @@ import org.powermock.api.mockito.PowerMockito; import com.google.common.collect.Lists; import com.google.common.collect.Sets; +import com.puppycrawl.tools.checkstyle.api.AbstractFileSetCheck; +import com.puppycrawl.tools.checkstyle.api.AuditEvent; import com.puppycrawl.tools.checkstyle.api.CheckstyleException; import com.puppycrawl.tools.checkstyle.api.Configuration; +import com.puppycrawl.tools.checkstyle.api.ExternalResourceHolder; +import com.puppycrawl.tools.checkstyle.api.Filter; import com.puppycrawl.tools.checkstyle.api.LocalizedMessage; import com.puppycrawl.tools.checkstyle.checks.TranslationCheck; import com.puppycrawl.tools.checkstyle.checks.coding.HiddenFieldCheck; +import com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck; +import com.puppycrawl.tools.checkstyle.checks.header.RegexpHeaderCheck; +import com.puppycrawl.tools.checkstyle.filters.SuppressionFilter; import com.puppycrawl.tools.checkstyle.utils.CommonUtils; public class CheckerTest extends BaseCheckTestSupport { @@ -572,4 +580,214 @@ public class CheckerTest extends BaseCheckTestSupport { assertEquals(errorMessage, error.getCause().getCause().getMessage()); } } + + @Test + public void testExternalConfigurationResourceDoesNotExist() throws Exception { + final Checker mockChecker = createMockCheckerWithCacheForModule(DummyFileSetCheck.class); + + final String pathToEmptyFile = temporaryFolder.newFile("EmptyFile.java").getPath(); + final String[] expected = CommonUtils.EMPTY_STRING_ARRAY; + + // We invoke 'verify' twice to invalidate cache + // and have two identical exceptions which happen on the same line between runs + final int numberOfRuns = 2; + for (int i = 0; i < numberOfRuns; i++) { + verify(mockChecker, pathToEmptyFile, expected); + } + } + + @Test + public void testInvalidateCacheDueToDifferentExceptionsBetweenRuns() throws Exception { + final Checker mockChecker = createMockCheckerWithCacheForModule(DummyFileSetCheck.class); + + final String pathToEmptyFile = temporaryFolder.newFile("TestFile.java").getPath(); + final String[] expected = CommonUtils.EMPTY_STRING_ARRAY; + + verify(mockChecker, pathToEmptyFile, expected); + // Once again to invalidate cache because in the second run exception will happen + // on different line + verify(mockChecker, pathToEmptyFile, expected); + } + + @Test + public void testCacheIoExceptionWhenReadingExternalResource() throws Exception { + final SuppressionFilter mock = PowerMockito.mock(SuppressionFilter.class); + final Set<String> mockResourceLocations = new HashSet<>(1); + mockResourceLocations.add("http://mock.sourceforge.net/suppressions_none.xml"); + when(mock.getExternalResourceLocations()).thenReturn(mockResourceLocations); + + final DefaultConfiguration checkerConfig = new DefaultConfiguration("checkstyle_checks"); + checkerConfig.addAttribute("cacheFile", temporaryFolder.newFile().getPath()); + + final Checker checker = new Checker(); + checker.addFilter(mock); + checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader()); + checker.configure(checkerConfig); + + final String pathToEmptyFile = temporaryFolder.newFile("file.java").getPath(); + final String[] expected = CommonUtils.EMPTY_STRING_ARRAY; + + verify(checker, pathToEmptyFile, pathToEmptyFile, expected); + // One more time to use cahce. + verify(checker, pathToEmptyFile, pathToEmptyFile, expected); + } + + @Test + public void testMultipleConfigs() throws Exception { + final DefaultConfiguration headerCheckConfig = createCheckConfig(HeaderCheck.class); + headerCheckConfig.addAttribute("headerFile", + getPath("configs" + File.separator + "java.header")); + + final DefaultConfiguration dummyFileSetCheckConfig = + createCheckConfig(DummyFileSetCheck.class); + + final DefaultConfiguration regexpHeaderCheckConfig = + createCheckConfig(RegexpHeaderCheck.class); + regexpHeaderCheckConfig.addAttribute("headerFile", + getPath("checks" + File.separator + "header" + File.separator + "regexp.header")); + + final DefaultConfiguration checkerConfig = new DefaultConfiguration("checkstyle_checks"); + checkerConfig.addAttribute("cacheFile", temporaryFolder.newFile().getPath()); + checkerConfig.addChild(headerCheckConfig); + checkerConfig.addChild(dummyFileSetCheckConfig); + checkerConfig.addChild(regexpHeaderCheckConfig); + + final Checker checker = new Checker(); + checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader()); + checker.configure(checkerConfig); + checker.addListener(new BriefUtLogger(stream)); + + final String pathToEmptyFile = temporaryFolder.newFile("file.java").getPath(); + final String[] expected = { + "1: " + "Missing a header - not enough lines in file.", + }; + + verify(checker, pathToEmptyFile, expected); + // Once again to invalidate cache because in the second run IOException will happen + // on different line for DummyFileSetCheck and it will change the content + verify(checker, pathToEmptyFile, expected); + } + + @Test + public void testFilterWhichDoesNotImplementExternalResourceHolderInterface() throws Exception { + final DefaultConfiguration filterConfig = createCheckConfig(DummyFilter.class); + + final DefaultConfiguration checkerConfig = new DefaultConfiguration("checkstyle_checks"); + checkerConfig.addChild(filterConfig); + checkerConfig.addAttribute("cacheFile", temporaryFolder.newFile().getPath()); + + final Checker checker = new Checker(); + checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader()); + checker.configure(checkerConfig); + checker.addListener(new BriefUtLogger(stream)); + + final String[] expected = CommonUtils.EMPTY_STRING_ARRAY; + final String pathToEmptyFile = temporaryFolder.newFile("file.java").getPath(); + verify(checker, pathToEmptyFile, expected); + // One more time to use cache. + verify(checker, pathToEmptyFile, expected); + } + + @Test + public void testCheckAddsNewResourceLocationButKeepsSameCheckerInstance() throws Exception { + + // Use case (https://github.com/checkstyle/checkstyle/pull/3092#issuecomment-218162436): + // Imagine that cache exists in a file. New version of Checkstyle appear. + // New release contains update to a some check to have additional external resource. + // User update his configuration and run validation as usually. + // Cache should not be reused. + + final DynamicalResourceHolderCheck check = new DynamicalResourceHolderCheck(); + check.setFirstExternalResourceLocation(getPath("checks" + File.separator + + "imports" + File.separator + "import-control_one.xml")); + + final DefaultConfiguration checkerConfig = new DefaultConfiguration("checkstyle_checks"); + checkerConfig.addAttribute("cacheFile", temporaryFolder.newFile().getPath()); + + final Checker checker = new Checker(); + checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader()); + checker.addFileSetCheck(check); + checker.configure(checkerConfig); + checker.addListener(new BriefUtLogger(stream)); + + final String pathToEmptyFile = temporaryFolder.newFile("file.java").getPath(); + final String[] expected = CommonUtils.EMPTY_STRING_ARRAY; + + verify(checker, pathToEmptyFile, expected); + + // Change a list of external resources which are used by the check + check.setSecondExternalResourceLocation("checks" + File.separator + + "imports" + File.separator + "import-control_one-re.xml"); + + verify(checker, pathToEmptyFile, expected); + } + + private Checker createMockCheckerWithCacheForModule( + Class<? extends ExternalResourceHolder> mockClass) throws IOException, CheckstyleException { + + final DefaultConfiguration mockConfig = createCheckConfig(mockClass); + + final DefaultConfiguration defaultConfig = new DefaultConfiguration("defaultConfiguration"); + defaultConfig.addAttribute("cacheFile", temporaryFolder.newFile().getPath()); + defaultConfig.addChild(mockConfig); + + final Checker checker = new Checker(); + checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader()); + checker.addListener(new BriefUtLogger(stream)); + checker.configure(defaultConfig); + return checker; + } + + private static class DummyFilter implements Filter { + + @Override + public boolean accept(AuditEvent event) { + return false; + } + } + + private static class DummyFileSetCheck extends AbstractFileSetCheck + implements ExternalResourceHolder { + + @Override + protected void processFiltered(File file, List<String> lines) throws CheckstyleException { } + + @Override + public Set<String> getExternalResourceLocations() { + final Set<String> externalResourceLocation = new HashSet<>(1); + externalResourceLocation.add("non_existing_external_resource.xml"); + return externalResourceLocation; + } + } + + private static class DynamicalResourceHolderCheck extends AbstractFileSetCheck + implements ExternalResourceHolder { + + private String firstExternalResourceLocation; + private String secondExternalResourceLocation; + + public void setFirstExternalResourceLocation(String firstExternalResourceLocation) { + this.firstExternalResourceLocation = firstExternalResourceLocation; + } + + public void setSecondExternalResourceLocation(String secondExternalResourceLocation) { + this.secondExternalResourceLocation = secondExternalResourceLocation; + } + + @Override + protected void processFiltered(File file, List<String> lines) throws CheckstyleException { + // there is no need in implementation of the method + } + + @Override + public Set<String> getExternalResourceLocations() { + final Set<String> locations = new HashSet<>(); + locations.add(firstExternalResourceLocation); + // Attempt to change the behaviour of the check dynamically + if (secondExternalResourceLocation != null) { + locations.add(secondExternalResourceLocation); + } + return locations; + } + } } diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/PropertyCacheFileTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/PropertyCacheFileTest.java index 6aa8e3eed..527b34922 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/PropertyCacheFileTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/PropertyCacheFileTest.java @@ -209,7 +209,8 @@ public class PropertyCacheFileTest { final Class<?>[] param = new Class<?>[1]; param[0] = Serializable.class; - final Method method = PropertyCacheFile.class.getDeclaredMethod("getConfigHashCode", param); + final Method method = + PropertyCacheFile.class.getDeclaredMethod("getHashCodeBasedOnObjectContent", param); method.setAccessible(true); try { method.invoke(cache, config); diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/TreeWalkerTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/TreeWalkerTest.java index 2feb02fc5..b587bd1ac 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/TreeWalkerTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/TreeWalkerTest.java @@ -295,5 +295,4 @@ public class TreeWalkerTest extends BaseCheckTestSupport { return CommonUtils.EMPTY_INT_ARRAY; } } - } diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/checks/header/HeaderCheckTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/checks/header/HeaderCheckTest.java index 91633137a..0d21f98a5 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/checks/header/HeaderCheckTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/checks/header/HeaderCheckTest.java @@ -32,13 +32,17 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import org.apache.commons.beanutils.ConversionException; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TemporaryFolder; import org.junit.runner.RunWith; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import com.puppycrawl.tools.checkstyle.BaseFileSetCheckTestSupport; +import com.puppycrawl.tools.checkstyle.BriefUtLogger; +import com.puppycrawl.tools.checkstyle.Checker; import com.puppycrawl.tools.checkstyle.DefaultConfiguration; import com.puppycrawl.tools.checkstyle.api.CheckstyleException; import com.puppycrawl.tools.checkstyle.utils.CommonUtils; @@ -46,6 +50,10 @@ import com.puppycrawl.tools.checkstyle.utils.CommonUtils; @RunWith(PowerMockRunner.class) @PrepareForTest({ HeaderCheck.class, HeaderCheckTest.class, AbstractHeaderCheck.class }) public class HeaderCheckTest extends BaseFileSetCheckTestSupport { + + @Rule + public final TemporaryFolder temporaryFolder = new TemporaryFolder(); + @Override protected String getPath(String filename) throws IOException { return super.getPath("checks" + File.separator @@ -236,4 +244,28 @@ public class HeaderCheckTest extends BaseFileSetCheckTestSupport { + getPath("InputRegexpHeader1.java"), ex.getCause().getMessage()); } } + + @Test + public void testCacheHeaderFile() throws Exception { + final DefaultConfiguration checkConfig = createCheckConfig(HeaderCheck.class); + checkConfig.addAttribute("headerFile", getConfigPath("java.header")); + + final DefaultConfiguration checkerConfig = new DefaultConfiguration("checkstyle_checks"); + checkerConfig.addChild(checkConfig); + checkerConfig.addAttribute("cacheFile", temporaryFolder.newFile().getPath()); + + final Checker checker = new Checker(); + checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader()); + checker.configure(checkerConfig); + checker.addListener(new BriefUtLogger(stream)); + + final String[] expected = { + "1: " + getCheckMessage(MSG_MISSING), + }; + + verify(checker, getPath("InputHeader.java"), expected); + // One more time to use cache. + verify(checker, getPath("InputHeader.java"), expected); + + } } diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/checks/imports/ImportControlCheckTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/checks/imports/ImportControlCheckTest.java index 889d0648d..44e259263 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/checks/imports/ImportControlCheckTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/checks/imports/ImportControlCheckTest.java @@ -30,15 +30,24 @@ import java.io.File; import java.io.IOException; import java.lang.reflect.InvocationTargetException; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TemporaryFolder; import com.puppycrawl.tools.checkstyle.BaseCheckTestSupport; +import com.puppycrawl.tools.checkstyle.BriefUtLogger; +import com.puppycrawl.tools.checkstyle.Checker; import com.puppycrawl.tools.checkstyle.DefaultConfiguration; +import com.puppycrawl.tools.checkstyle.TreeWalker; import com.puppycrawl.tools.checkstyle.api.CheckstyleException; import com.puppycrawl.tools.checkstyle.api.TokenTypes; import com.puppycrawl.tools.checkstyle.utils.CommonUtils; public class ImportControlCheckTest extends BaseCheckTestSupport { + + @Rule + public final TemporaryFolder temporaryFolder = new TemporaryFolder(); + @Override protected String getPath(String filename) throws IOException { return super.getPath("checks" + File.separator @@ -241,6 +250,52 @@ public class ImportControlCheckTest extends BaseCheckTestSupport { } } + @Test + public void testCacheWhenFileExternalResourceContentDoesNotChange() throws Exception { + final DefaultConfiguration checkConfig = createCheckConfig(ImportControlCheck.class); + checkConfig.addAttribute("file", getPath("import-control_one-re.xml")); + + final Checker checker = createMockCheckerWithCache(checkConfig); + + final String filePath = temporaryFolder.newFile("EmptyFile.java").getPath(); + final String[] expected = CommonUtils.EMPTY_STRING_ARRAY; + + verify(checker, filePath, filePath, expected); + // One more time to use cache. + verify(checker, filePath, filePath, expected); + } + + @Test + public void testCacheWhenUrlExternalResourceContentDoesNotChange() throws Exception { + final DefaultConfiguration checkConfig = createCheckConfig(ImportControlCheck.class); + checkConfig.addAttribute("url", getUriString("import-control_one.xml")); + + final Checker checker = createMockCheckerWithCache(checkConfig); + + final String pathToEmptyFile = temporaryFolder.newFile("TestFile.java").getPath(); + final String[] expected = CommonUtils.EMPTY_STRING_ARRAY; + + verify(checker, pathToEmptyFile, pathToEmptyFile, expected); + // One more time to use cache. + verify(checker, pathToEmptyFile, pathToEmptyFile, expected); + } + + private Checker createMockCheckerWithCache(DefaultConfiguration checkConfig) + throws IOException, CheckstyleException { + final DefaultConfiguration treeWalkerConfig = createCheckConfig(TreeWalker.class); + treeWalkerConfig.addChild(checkConfig); + + final DefaultConfiguration checkerConfig = new DefaultConfiguration("checkstyle_checks"); + checkerConfig.addChild(treeWalkerConfig); + checkerConfig.addAttribute("cacheFile", temporaryFolder.newFile().getPath()); + + final Checker checker = new Checker(); + checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader()); + checker.configure(checkerConfig); + checker.addListener(new BriefUtLogger(stream)); + return checker; + } + /** * Returns String message of original exception that was thrown in * ImportControlCheck.setUrl or ImportControlCheck.setFile diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/filters/SuppressionFilterTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/filters/SuppressionFilterTest.java index fe3502c2e..211740847 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/filters/SuppressionFilterTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/filters/SuppressionFilterTest.java @@ -23,12 +23,17 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.net.HttpURLConnection; import java.net.URI; import java.net.URL; +import org.junit.Assume; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TemporaryFolder; import org.junit.runner.RunWith; import org.mockito.BDDMockito; @@ -38,6 +43,11 @@ import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; +import com.google.common.io.Closeables; +import com.puppycrawl.tools.checkstyle.BaseCheckTestSupport; +import com.puppycrawl.tools.checkstyle.BriefUtLogger; +import com.puppycrawl.tools.checkstyle.Checker; +import com.puppycrawl.tools.checkstyle.DefaultConfiguration; import com.puppycrawl.tools.checkstyle.api.AuditEvent; import com.puppycrawl.tools.checkstyle.api.CheckstyleException; import com.puppycrawl.tools.checkstyle.utils.CommonUtils; @@ -47,7 +57,16 @@ import nl.jqno.equalsverifier.Warning; @RunWith(PowerMockRunner.class) @PrepareForTest({SuppressionFilter.class, CommonUtils.class}) -public class SuppressionFilterTest { +public class SuppressionFilterTest extends BaseCheckTestSupport { + + @Rule + public final TemporaryFolder temporaryFolder = new TemporaryFolder(); + + @Override + protected String getPath(String filename) throws IOException { + return super.getPath("filters" + File.separator + filename); + } + @Test public void testEqualsAndHashCode() { EqualsVerifier @@ -170,6 +189,130 @@ public class SuppressionFilterTest { assertTrue(filter.accept(ev)); } + @Test + public void testLocalFileExternalResourceContentDoesNotChange() throws Exception { + final DefaultConfiguration filterConfig = createCheckConfig(SuppressionFilter.class); + filterConfig.addAttribute("file", getPath("suppressions_none.xml")); + + final DefaultConfiguration checkerConfig = new DefaultConfiguration("checkstyle_checks"); + checkerConfig.addChild(filterConfig); + final String cacheFile = temporaryFolder.newFile().getPath(); + checkerConfig.addAttribute("cacheFile", cacheFile); + + final Checker checker = new Checker(); + checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader()); + checker.addListener(new BriefUtLogger(stream)); + checker.configure(checkerConfig); + + final String filePath = temporaryFolder.newFile("file.java").getPath(); + final String[] expected = CommonUtils.EMPTY_STRING_ARRAY; + + verify(checker, filePath, expected); + // One more time to use cache. + verify(checker, filePath, expected); + } + + @Test + public void testRemoteFileExternalResourceContentDoesNotChange() throws Exception { + final String[] urlCandidates = { + "http://checkstyle.sourceforge.net/files/suppressions_none.xml", + "https://raw.githubusercontent.com/checkstyle/checkstyle/master/src/site/resources/" + + "files/suppressions_none.xml", + }; + + String urlForTest = null; + for (String url : urlCandidates) { + if (isConnectionAvailableAndStable(url)) { + urlForTest = url; + break; + } + } + + // Run the test only if connection is available and url is reachable. + Assume.assumeFalse(urlForTest == null); + + final DefaultConfiguration firstFilterConfig = createCheckConfig(SuppressionFilter.class); + firstFilterConfig.addAttribute("file", urlForTest); + + final DefaultConfiguration firstCheckerConfig = + new DefaultConfiguration("checkstyle_checks"); + firstCheckerConfig.addChild(firstFilterConfig); + final String cacheFile = temporaryFolder.newFile().getPath(); + firstCheckerConfig.addAttribute("cacheFile", cacheFile); + + final Checker checker = new Checker(); + checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader()); + checker.configure(firstCheckerConfig); + checker.addListener(new BriefUtLogger(stream)); + + final String pathToEmptyFile = temporaryFolder.newFile("file.java").getPath(); + final String[] expected = CommonUtils.EMPTY_STRING_ARRAY; + + verify(checker, pathToEmptyFile, expected); + + // One more time to use cache. + final DefaultConfiguration secondFilterConfig = createCheckConfig(SuppressionFilter.class); + secondFilterConfig.addAttribute("file", urlForTest); + + final DefaultConfiguration secondCheckerConfig = + new DefaultConfiguration("checkstyle_checks"); + secondCheckerConfig.addAttribute("cacheFile", cacheFile); + secondCheckerConfig.addChild(secondFilterConfig); + + checker.configure(secondCheckerConfig); + + verify(checker, pathToEmptyFile, expected); + } + + private static boolean isConnectionAvailableAndStable(String url) throws Exception { + boolean available = false; + + if (isUrlReachable(url)) { + final int attemptLimit = 5; + int attemptCount = 0; + + while (attemptCount <= attemptLimit) { + final URL addres = new URL(url); + InputStream stream = null; + try { + stream = addres.openStream(); + // Attemt to read a byte in order to check wtether file content is available + available = stream.read() != -1; + break; + } + catch (IOException ex) { + // for some reason Travis CI failed some times (unstable) on reading the file + if (attemptCount < attemptLimit && ex.getMessage().contains("Unable to read")) { + attemptCount++; + available = false; + // wait for bad / disconnection time to pass + Thread.sleep(1000); + } + else { + Closeables.closeQuietly(stream); + throw ex; + } + } + finally { + Closeables.closeQuietly(stream); + } + } + } + return available; + } + + private static boolean isUrlReachable(String url) { + try { + final URL verifiableUrl = new URL(url); + final HttpURLConnection urlConnect = (HttpURLConnection) verifiableUrl.openConnection(); + urlConnect.getContent(); + } + catch (IOException ex) { + return false; + } + return true; + } + private static SuppressionFilter createSupressionFilter(String fileName, boolean optional) throws CheckstyleException { final SuppressionFilter suppressionFilter = new SuppressionFilter(); |