@Test public void testCacheRemainsWhenExternalResourceTheSame() throws IOException { final Configuration config = new DefaultConfiguration("myName"); final String externalResourcePath = temporaryFolder.newFile().getPath(); final String filePath = temporaryFolder.newFile().getPath(); final PropertyCacheFile cache = new PropertyCacheFile(config, filePath); // pre-populate with cache with resources cache.load(); final Set<String> resources = new HashSet<>(); resources.add(externalResourcePath); cache.putExternalResources(resources); cache.persist(); // test cache with same resources and new file cache.load(); cache.put("myFile", 1); cache.putExternalResources(resources); assertTrue("Should return true in file is in cache", cache.isInCache("myFile", 1)); }
@Test public void testConfigHashOnReset() throws IOException { final Configuration config = new DefaultConfiguration("myName"); final String filePath = temporaryFolder.newFile().getPath(); final PropertyCacheFile cache = new PropertyCacheFile(config, filePath); cache.load(); final String hash = cache.get(PropertyCacheFile.CONFIG_HASH_KEY); assertNotNull("Config hash key should not be null", hash); cache.reset(); assertEquals("Invalid config hash key", hash, cache.get(PropertyCacheFile.CONFIG_HASH_KEY)); }
/** * Puts external resources in cache. * If at least one external resource changed, clears the cache. * @param locations locations of external resources. */ public void putExternalResources(Set<String> locations) { final Set<ExternalResource> resources = loadExternalResources(locations); if (areExternalResourcesChanged(resources)) { reset(); fillCacheWithExternalResources(resources); } }
/** * Sets cache file. * @param fileName the cache file. * @throws IOException if there are some problems with file loading. */ public void setCacheFile(String fileName) throws IOException { final Configuration configuration = getConfiguration(); cacheFile = new PropertyCacheFile(configuration, fileName); cacheFile.load(); }
/** * Load cached values from file. * @throws IOException when there is a problems with file read */ public void load() throws IOException { // get the current config so if the file isn't found // the first time the hash will be added to output file configHash = getHashCodeBasedOnObjectContent(config); final File file = new File(fileName); if (file.exists()) { try (InputStream inStream = Files.newInputStream(file.toPath())) { details.load(inStream); final String cachedConfigHash = details.getProperty(CONFIG_HASH_KEY); if (!configHash.equals(cachedConfigHash)) { // Detected configuration change - clear cache reset(); } } } else { // put the hash in the file if the file is going to be created reset(); } }
@Test public void testExternalResourceIsSavedInCache() throws Exception { final Configuration config = new DefaultConfiguration("myName"); final String filePath = temporaryFolder.newFile().getPath(); final PropertyCacheFile cache = new PropertyCacheFile(config, filePath); cache.load(); final Set<String> resources = new HashSet<>(); final String pathToResource = getPath("InputPropertyCacheFileExternal.properties"); resources.add(pathToResource); cache.putExternalResources(resources); final MessageDigest digest = MessageDigest.getInstance("SHA-1"); final URI uri = CommonUtil.getUriByFilename(pathToResource); final byte[] input = ByteStreams.toByteArray(new BufferedInputStream(uri.toURL().openStream())); final ByteArrayOutputStream out = new ByteArrayOutputStream(); try (ObjectOutputStream oos = new ObjectOutputStream(out)) { oos.writeObject(input); } digest.update(out.toByteArray()); final String expected = BaseEncoding.base16().upperCase().encode(digest.digest()); assertEquals("Hashes are not equal", expected, cache.get("module-resource*?:" + pathToResource)); }
@Test public void testConfigHashRemainsOnResetExternalResources() throws IOException { final Configuration config = new DefaultConfiguration("myName"); final String filePath = temporaryFolder.newFile().getPath(); final PropertyCacheFile cache = new PropertyCacheFile(config, filePath); // create cache with one file cache.load(); cache.put("myFile", 1); final String hash = cache.get(PropertyCacheFile.CONFIG_HASH_KEY); assertNotNull("Config hash key should not be null", hash); // apply new external resource to clear cache final Set<String> resources = new HashSet<>(); resources.add("dummy"); cache.putExternalResources(resources); assertEquals("Invalid config hash key", hash, cache.get(PropertyCacheFile.CONFIG_HASH_KEY)); assertFalse("Should return false in file is not in cache", cache.isInCache("myFile", 1)); }
@Test public void testInCache() throws IOException { final Configuration config = new DefaultConfiguration("myName"); final String filePath = temporaryFolder.newFile().getPath(); final PropertyCacheFile cache = new PropertyCacheFile(config, filePath); cache.put("myFile", 1); assertTrue("Should return true when file is in cache", cache.isInCache("myFile", 1)); assertFalse("Should return false when file is not in cache", cache.isInCache("myFile", 2)); assertFalse("Should return false when file is not in cache", cache.isInCache("myFile1", 1)); }
@Test public void testFlushAndCloseCacheFileOutputStream() throws IOException { mockStatic(Closeables.class); doNothing().when(Closeables.class); Closeables.close(any(OutputStream.class), ArgumentMatchers.eq(false)); mockStatic(Flushables.class); doNothing().when(Flushables.class); Flushables.flush(any(OutputStream.class), ArgumentMatchers.eq(false)); final Configuration config = new DefaultConfiguration("myName"); final PropertyCacheFile cache = new PropertyCacheFile(config, temporaryFolder.newFile().getPath()); cache.put("CheckedFileName.java", System.currentTimeMillis()); cache.persist(); verifyStatic(Closeables.class, times(1)); Closeables.close(any(OutputStream.class), ArgumentMatchers.eq(false)); verifyStatic(Flushables.class, times(1)); Flushables.flush(any(OutputStream.class), ArgumentMatchers.eq(false)); }
@Test public void testResetIfFileDoesNotExist() throws IOException { final Configuration config = new DefaultConfiguration("myName"); final PropertyCacheFile cache = new PropertyCacheFile(config, "fileDoesNotExist.txt"); cache.load(); assertNotNull("Config hash key should not be null", cache.get(PropertyCacheFile.CONFIG_HASH_KEY)); }
@Test public void testPathToCacheContainsOnlyFileName() throws IOException { final Configuration config = new DefaultConfiguration("myName"); final String filePath = "temp.cache"; final PropertyCacheFile cache = new PropertyCacheFile(config, filePath); // no exception expected cache.persist(); assertTrue("Cache file does not exist", Files.exists(Paths.get(filePath))); Files.delete(Paths.get(filePath)); }
@Test public void testExceptionNoSuchAlgorithmException() throws Exception { final Configuration config = new DefaultConfiguration("myName"); final String filePath = temporaryFolder.newFile().getPath(); final PropertyCacheFile cache = new PropertyCacheFile(config, filePath); cache.put("myFile", 1); mockStatic(MessageDigest.class); when(MessageDigest.getInstance("SHA-1")) .thenThrow(NoSuchAlgorithmException.class); final Class<?>[] param = new Class<?>[1]; param[0] = Serializable.class; final Method method = PropertyCacheFile.class.getDeclaredMethod("getHashCodeBasedOnObjectContent", param); method.setAccessible(true); try { method.invoke(cache, config); fail("InvocationTargetException is expected"); } catch (InvocationTargetException ex) { assertTrue("Invalid exception cause", ex.getCause().getCause() instanceof NoSuchAlgorithmException); assertEquals("Invalid exception message", "Unable to calculate hashcode.", ex.getCause().getMessage()); } }
@Override public void destroy() { listeners.clear(); fileSetChecks.clear(); beforeExecutionFileFilters.clear(); filters.clear(); if (cacheFile != null) { try { cacheFile.persist(); } catch (IOException ex) { throw new IllegalStateException("Unable to persist cache file.", ex); } } }
/** * Clears the cache. */ public void clearCache() { if (cacheFile != null) { cacheFile.reset(); } }
@Override public int process(List<File> files) throws CheckstyleException { if (cacheFile != null) { cacheFile.putExternalResources(getExternalResourceLocations()); } // Prepare to start fireAuditStarted(); for (final FileSetCheck fsc : fileSetChecks) { fsc.beginProcessing(charset); } final List<File> targetFiles = files.stream() .filter(file -> CommonUtil.matchesFileExtension(file, fileExtensions)) .collect(Collectors.toList()); processFiles(targetFiles); // Finish up // It may also log!!! fileSetChecks.forEach(FileSetCheck::finishProcessing); // It may also log!!! fileSetChecks.forEach(FileSetCheck::destroy); final int errorCount = counter.getCount(); fireAuditFinished(); return errorCount; }
@Test public void testCtor() { try { final Object test = new PropertyCacheFile(null, ""); fail("exception expected but got " + test); } catch (IllegalArgumentException ex) { assertEquals("Invalid exception message", "config can not be null", ex.getMessage()); } try { final Configuration config = new DefaultConfiguration("myName"); final Object test = new PropertyCacheFile(config, null); fail("exception expected but got " + test); } catch (IllegalArgumentException ex) { assertEquals("Invalid exception message", "fileName can not be null", ex.getMessage()); } }
/** * Serializes object to output stream. * @param object object to be serialized * @param outputStream serialization stream * @throws IOException if an error occurs */ private static void serialize(Serializable object, OutputStream outputStream) throws IOException { final ObjectOutputStream oos = new ObjectOutputStream(outputStream); try { oos.writeObject(object); } finally { flushAndCloseOutStream(oos); } }
@Test public void testChangeInConfig() throws Exception { final DefaultConfiguration config = new DefaultConfiguration("myConfig"); config.addAttribute("attr", "value"); final File cacheFile = temporaryFolder.newFile(); final PropertyCacheFile cache = new PropertyCacheFile(config, cacheFile.getPath()); cache.load(); final String expectedInitialConfigHash = "91753B970AFDF9F5F3DFA0D258064841949D3C6B"; final String actualInitialConfigHash = cache.get(PropertyCacheFile.CONFIG_HASH_KEY); assertEquals("Invalid config hash", expectedInitialConfigHash, actualInitialConfigHash); cache.persist(); final Properties details = new Properties(); details.load(Files.newBufferedReader(cacheFile.toPath())); assertEquals("Invalid details size", 1, details.size()); // change in config config.addAttribute("newAttr", "newValue"); final PropertyCacheFile cacheAfterChangeInConfig = new PropertyCacheFile(config, cacheFile.getPath()); cacheAfterChangeInConfig.load(); final String expectedConfigHashAfterChange = "4CF5EC78955B81D76153ACC2CA6D60CB77FDCB2A"; final String actualConfigHashAfterChange = cacheAfterChangeInConfig.get(PropertyCacheFile.CONFIG_HASH_KEY); assertEquals("Invalid config hash", expectedConfigHashAfterChange, actualConfigHashAfterChange); cacheAfterChangeInConfig.persist(); final Properties detailsAfterChangeInConfig = new Properties(); detailsAfterChangeInConfig.load(Files.newBufferedReader(cacheFile.toPath())); assertEquals("Invalid cache size", 1, detailsAfterChangeInConfig.size()); }
/** * This SuppressWarning("unchecked") required to suppress * "Unchecked generics array creation for varargs parameter" during mock. * @throws IOException when smth wrong with file creation or cache.load */ @Test public void testNonExistentResource() throws IOException { final Configuration config = new DefaultConfiguration("myName"); final String filePath = temporaryFolder.newFile().getPath(); final PropertyCacheFile cache = new PropertyCacheFile(config, filePath); // create cache with one file cache.load(); final String myFile = "myFile"; cache.put(myFile, 1); final String hash = cache.get(PropertyCacheFile.CONFIG_HASH_KEY); assertNotNull("Config hash key should not be null", hash); mockStatic(ByteStreams.class); when(ByteStreams.toByteArray(any(BufferedInputStream.class))) .thenThrow(IOException.class); // apply new external resource to clear cache final Set<String> resources = new HashSet<>(); final String resource = getPath("InputPropertyCacheFile.header"); resources.add(resource); cache.putExternalResources(resources); assertFalse("Should return false in file is not in cache", cache.isInCache(myFile, 1)); assertFalse("Should return false in file is not in cache", cache.isInCache(resource, 1)); }