this.lockFilePath = directory.resolve(LOCK_FILE_NAME).toAbsolutePath();
}
- public String getFileLockName() {
- return LOCK_FILE_NAME;
- }
-
- public void lock() {
- try {
- lockRandomAccessFile = new RandomAccessFile(lockFilePath.toFile(), "rw");
- lockChannel = lockRandomAccessFile.getChannel();
- lockFile = lockChannel.lock(0, 1024, false);
- } catch (IOException e) {
- throw new IllegalStateException("Failed to create lock in " + lockFilePath.toString(), e);
- }
- }
-
public boolean tryLock() {
try {
lockRandomAccessFile = new RandomAccessFile(lockFilePath.toFile(), "rw");
import java.util.jar.JarOutputStream;
import java.util.jar.Pack200;
import java.util.zip.GZIPInputStream;
-import javax.annotation.CheckForNull;
/**
* This class is responsible for managing Sonar batch file cache. You can put file into cache and
return cacheDir;
}
- /**
- * Look for a file in the cache by its filename and md5 checksum. If the file is not
- * present then return null.
- */
- @CheckForNull
- public File get(String filename, String hash) {
- File cachedFile = new File(new File(cacheDir, hash), filename);
- if (cachedFile.exists()) {
- return cachedFile;
- }
- logger.debug(String.format("No file found in the cache with name %s and hash %s", filename, hash));
- return null;
- }
-
public interface Downloader {
void download(String filename, File toFile) throws IOException;
}
+ /**
+ * Look for a file in the cache by its filename and md5 checksum. If the file is not
+ * present then try to download it. In case of error or if the file is not found
+ * an exception is thrown. {@code null} is never returned.
+ */
public File get(String filename, String hash, Downloader downloader) {
// Does not fail if another process tries to create the directory at the same time.
File hashDir = hashDir(hash);
this.logger = logger;
}
- public FileCacheBuilder setUserHome(File d) {
- this.userHome = d;
- return this;
- }
-
- public FileCacheBuilder setUserHome(@Nullable String path) {
- this.userHome = (path == null) ? null : new File(path);
+ public FileCacheBuilder setUserHome(@Nullable File dir) {
+ this.userHome = dir;
return this;
}
*/
package org.sonar.home.cache;
-import static org.mockito.Mockito.mock;
-import static org.assertj.core.api.Assertions.assertThat;
-
-import org.junit.rules.ExpectedException;
-
-import java.nio.channels.OverlappingFileLockException;
import java.nio.file.Paths;
-
-import org.junit.Test;
import org.junit.Before;
import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+
public class DirectoryLockTest {
@Rule
public TemporaryFolder temp = new TemporaryFolder();
@Rule
- public ExpectedException exception = ExpectedException.none();
+ public ExpectedException expectedException = ExpectedException.none();
private DirectoryLock lock;
@Before
lock = new DirectoryLock(temp.getRoot().toPath(), mock(Logger.class));
}
- @Test
- public void lock() {
- assertThat(temp.getRoot().list()).isEmpty();
- lock.lock();
- assertThat(temp.getRoot().toPath().resolve(".sonar_lock")).exists();
- lock.unlock();
- }
-
@Test
public void tryLock() {
assertThat(temp.getRoot().list()).isEmpty();
lock.unlock();
}
- @Test(expected = OverlappingFileLockException.class)
- public void error_2locks() {
- assertThat(temp.getRoot().list()).isEmpty();
- lock.lock();
- lock.lock();
- }
-
@Test
public void unlockWithoutLock() {
lock.unlock();
}
- @Test
- public void errorCreatingLock() {
- lock = new DirectoryLock(Paths.get("non", "existing", "path"), mock(Logger.class));
-
- exception.expect(IllegalStateException.class);
- exception.expectMessage("Failed to create lock");
- lock.lock();
- }
-
@Test
public void errorTryLock() {
lock = new DirectoryLock(Paths.get("non", "existing", "path"), mock(Logger.class));
- exception.expect(IllegalStateException.class);
- exception.expectMessage("Failed to create lock");
+ expectedException.expect(IllegalStateException.class);
+ expectedException.expectMessage("Failed to create lock");
+
lock.tryLock();
}
}
@Test
public void user_home_property_can_be_null() {
- FileCache cache = new FileCacheBuilder(mock(Logger.class)).setUserHome((String) null).build();
+ FileCache cache = new FileCacheBuilder(mock(Logger.class)).setUserHome(null).build();
// does not fail. It uses default path or env variable
assertThat(cache.getDir()).isDirectory().exists();
import static org.mockito.Mockito.when;
public class FileCacheTest {
- private FileHashes fileHashes;
- private FileCache cache;
-
- @Before
- public void setUp() throws IOException {
- fileHashes = mock(FileHashes.class);
- cache = new FileCache(tempFolder.getRoot(), fileHashes, mock(Logger.class));
- }
@Rule
public TemporaryFolder tempFolder = new TemporaryFolder();
-
@Rule
- public ExpectedException thrown = ExpectedException.none();
-
- @Test
- public void not_in_cache() throws IOException {
- assertThat(cache.get("sonar-foo-plugin-1.5.jar", "ABCDE")).isNull();
- }
+ public ExpectedException expectedException = ExpectedException.none();
- @Test
- public void found_in_cache() throws IOException {
- // populate the cache. Assume that hash is correct.
- File cachedFile = new File(new File(cache.getDir(), "ABCDE"), "sonar-foo-plugin-1.5.jar");
- FileUtils.write(cachedFile, "body");
+ private FileHashes fileHashes = mock(FileHashes.class);
+ private FileCache cache;
- assertThat(cache.get("sonar-foo-plugin-1.5.jar", "ABCDE")).isNotNull().exists().isEqualTo(cachedFile);
+ @Before
+ public void setUp() {
+ cache = new FileCache(tempFolder.getRoot(), fileHashes, mock(Logger.class));
}
@Test
public void fail_to_download() {
when(fileHashes.of(any(File.class))).thenReturn("ABCDE");
- FileCache.Downloader downloader = new FileCache.Downloader() {
- public void download(String filename, File toFile) throws IOException {
- throw new IOException("fail");
- }
+ FileCache.Downloader downloader = (filename, toFile) -> {
+ throw new IOException("fail");
};
- thrown.expect(IllegalStateException.class);
- thrown.expectMessage("Fail to download");
+ expectedException.expect(IllegalStateException.class);
+ expectedException.expectMessage("Fail to download");
cache.get("sonar-foo-plugin-1.5.jar", "ABCDE", downloader);
}
@Test
public void fail_create_hash_dir() throws IOException {
File file = tempFolder.newFile();
- thrown.expect(IllegalStateException.class);
- thrown.expectMessage("Unable to create user cache");
+ expectedException.expect(IllegalStateException.class);
+ expectedException.expectMessage("Unable to create user cache");
cache = new FileCache(file, fileHashes, mock(Logger.class));
}
File hashDir = new File(cache.getDir(), "ABCDE");
hashDir.createNewFile();
- thrown.expect(IllegalStateException.class);
- thrown.expectMessage("Fail to create cache directory");
+ expectedException.expect(IllegalStateException.class);
+ expectedException.expectMessage("Fail to create cache directory");
cache.get("sonar-foo-plugin-1.5.jar", "ABCDE", mock(FileCache.Downloader.class));
}
public void download_and_add_to_cache() throws IOException {
when(fileHashes.of(any(File.class))).thenReturn("ABCDE");
- FileCache.Downloader downloader = new FileCache.Downloader() {
- public void download(String filename, File toFile) throws IOException {
- FileUtils.write(toFile, "body");
- }
- };
+ FileCache.Downloader downloader = (filename, toFile) -> FileUtils.write(toFile, "body");
File cachedFile = cache.get("sonar-foo-plugin-1.5.jar", "ABCDE", downloader);
assertThat(cachedFile).isNotNull().exists().isFile();
assertThat(cachedFile.getName()).isEqualTo("sonar-foo-plugin-1.5.jar");
}
@Test
- public void download_and_add_to_cache_compressed_file() throws IOException {
+ public void download_and_add_to_cache_compressed_file() {
when(fileHashes.of(any(File.class))).thenReturn("ABCDE");
- FileCache.Downloader downloader = new FileCache.Downloader() {
- public void download(String filename, File toFile) throws IOException {
- FileUtils.copyFile(compressedFile(), toFile);
- }
- };
+ FileCache.Downloader downloader = (filename, toFile) -> FileUtils.copyFile(compressedFile(), toFile);
File cachedFile = cache.getCompressed("sonar-foo-plugin-1.5.pack.gz", "ABCDE", downloader);
assertThat(cachedFile).isNotNull().exists().isFile();
}
@Test
- public void download_corrupted_file() throws IOException {
- thrown.expect(IllegalStateException.class);
- thrown.expectMessage("INVALID HASH");
+ public void download_corrupted_file() {
+ expectedException.expect(IllegalStateException.class);
+ expectedException.expectMessage("INVALID HASH");
when(fileHashes.of(any(File.class))).thenReturn("VWXYZ");
- FileCache.Downloader downloader = new FileCache.Downloader() {
- public void download(String filename, File toFile) throws IOException {
- FileUtils.write(toFile, "corrupted body");
- }
- };
+ FileCache.Downloader downloader = (filename, toFile) -> FileUtils.write(toFile, "corrupted body");
cache.get("sonar-foo-plugin-1.5.jar", "ABCDE", downloader);
}
public void concurrent_download() throws IOException {
when(fileHashes.of(any(File.class))).thenReturn("ABCDE");
- FileCache.Downloader downloader = new FileCache.Downloader() {
- public void download(String filename, File toFile) throws IOException {
- // Emulate a concurrent download that adds file to cache before
- File cachedFile = new File(new File(cache.getDir(), "ABCDE"), "sonar-foo-plugin-1.5.jar");
- FileUtils.write(cachedFile, "downloaded by other");
+ FileCache.Downloader downloader = (filename, toFile) -> {
+ // Emulate a concurrent download that adds file to cache before
+ File cachedFile = new File(new File(cache.getDir(), "ABCDE"), "sonar-foo-plugin-1.5.jar");
+ FileUtils.write(cachedFile, "downloaded by other");
- FileUtils.write(toFile, "downloaded by me");
- }
+ FileUtils.write(toFile, "downloaded by me");
};
// do not fail
public class FileHashesTest {
- SecureRandom secureRandom = new SecureRandom();
+ private SecureRandom secureRandom = new SecureRandom();
@Rule
- public ExpectedException thrown = ExpectedException.none();
+ public ExpectedException expectedException = ExpectedException.none();
@Rule
public TemporaryFolder temp = new TemporaryFolder();
File file = temp.newFile("does_not_exist");
FileUtils.forceDelete(file);
- thrown.expect(IllegalStateException.class);
- thrown.expectMessage("Fail to compute hash of: " + file.getAbsolutePath());
+ expectedException.expect(IllegalStateException.class);
+ expectedException.expectMessage("Fail to compute hash of: " + file.getAbsolutePath());
new FileHashes().of(file);
}
@Test
public void fail_if_stream_is_closed() throws Exception {
- thrown.expect(IllegalStateException.class);
- thrown.expectMessage("Fail to compute hash");
+ expectedException.expect(IllegalStateException.class);
+ expectedException.expectMessage("Fail to compute hash");
InputStream input = mock(InputStream.class);
when(input.read(any(byte[].class), anyInt(), anyInt())).thenThrow(new IllegalThreadStateException());
*/
package org.sonar.scanner.bootstrap;
+import java.io.File;
import org.picocontainer.injectors.ProviderAdapter;
import org.sonar.api.config.Configuration;
import org.sonar.home.cache.FileCache;
public FileCache provide(Configuration settings) {
if (cache == null) {
- String home = settings.get("sonar.userHome").orElse(null);
+ File home = settings.get("sonar.userHome")
+ .map(File::new)
+ .orElse(null);
cache = new FileCacheBuilder(new Slf4jLogger()).setUserHome(home).build();
}
return cache;
@ClassRule
public static TemporaryFolder temp = new TemporaryFolder();
- File userHome;
- ScannerPluginJarExploder underTest;
+ private File userHome;
+ private ScannerPluginJarExploder underTest;
@Before
public void setUp() throws IOException {
assertThat(exploded.getKey()).isEqualTo("checkstyle");
assertThat(exploded.getMain()).isFile().exists();
- assertThat(exploded.getLibs()).extracting("name").containsOnly("antlr-2.7.6.jar", "checkstyle-5.1.jar", "commons-cli-1.0.jar");
+ assertThat(exploded.getLibs()).extracting(File::getName).containsExactlyInAnyOrder("antlr-2.7.6.jar", "checkstyle-5.1.jar", "commons-cli-1.0.jar");
assertThat(new File(fileFromCache.getParent(), "sonar-checkstyle-plugin-2.8.jar")).exists();
assertThat(new File(fileFromCache.getParent(), "sonar-checkstyle-plugin-2.8.jar_unzip/META-INF/lib/checkstyle-5.1.jar")).exists();
}
assertThat(new File(fileFromCache.getParent(), "sonar-checkstyle-plugin-2.8.jar_unzip/org/sonar/plugins/checkstyle/CheckstyleVersion.class")).doesNotExist();
}
- File getFileFromCache(String filename) throws IOException {
+ private File getFileFromCache(String filename) throws IOException {
File src = FileUtils.toFile(getClass().getResource(this.getClass().getSimpleName() + "/" + filename));
File destFile = new File(new File(userHome, "" + filename.hashCode()), filename);
FileUtils.copyFile(src, destFile);