aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-home
diff options
context:
space:
mode:
authorSimon Brandhof <simon.brandhof@sonarsource.com>2018-05-10 21:54:03 +0200
committerSonarTech <sonartech@sonarsource.com>2018-05-11 20:20:47 +0200
commita6f8921a959e5bc0a51d33b93eecd7c2667f1148 (patch)
tree5dc1f6a1bc975273bffb981af99da621a970b061 /sonar-home
parent01e1c69fe35fac0678130f5784ee0b70422c8536 (diff)
downloadsonarqube-a6f8921a959e5bc0a51d33b93eecd7c2667f1148.tar.gz
sonarqube-a6f8921a959e5bc0a51d33b93eecd7c2667f1148.zip
SONAR-10591 drop module sonar-home
Diffstat (limited to 'sonar-home')
-rw-r--r--sonar-home/src/main/java/org/sonar/home/cache/DirectoryLock.java80
-rw-r--r--sonar-home/src/main/java/org/sonar/home/cache/FileCache.java193
-rw-r--r--sonar-home/src/main/java/org/sonar/home/cache/FileCacheBuilder.java55
-rw-r--r--sonar-home/src/main/java/org/sonar/home/cache/FileHashes.java73
-rw-r--r--sonar-home/src/test/java/org/sonar/home/cache/DirectoryLockTest.java66
-rw-r--r--sonar-home/src/test/java/org/sonar/home/cache/FileCacheBuilderTest.java60
-rw-r--r--sonar-home/src/test/java/org/sonar/home/cache/FileCacheTest.java179
-rw-r--r--sonar-home/src/test/java/org/sonar/home/cache/FileHashesTest.java127
8 files changed, 0 insertions, 833 deletions
diff --git a/sonar-home/src/main/java/org/sonar/home/cache/DirectoryLock.java b/sonar-home/src/main/java/org/sonar/home/cache/DirectoryLock.java
deleted file mode 100644
index db61bac9bcd..00000000000
--- a/sonar-home/src/main/java/org/sonar/home/cache/DirectoryLock.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2018 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.home.cache;
-
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.nio.channels.FileChannel;
-import java.nio.channels.FileLock;
-import java.nio.file.Path;
-
-public class DirectoryLock {
- public static final String LOCK_FILE_NAME = ".sonar_lock";
- private final Path lockFilePath;
- private final Logger logger;
-
- private RandomAccessFile lockRandomAccessFile;
- private FileChannel lockChannel;
- private FileLock lockFile;
-
- public DirectoryLock(Path directory, Logger logger) {
- this.logger = logger;
- this.lockFilePath = directory.resolve(LOCK_FILE_NAME).toAbsolutePath();
- }
-
- public boolean tryLock() {
- try {
- lockRandomAccessFile = new RandomAccessFile(lockFilePath.toFile(), "rw");
- lockChannel = lockRandomAccessFile.getChannel();
- lockFile = lockChannel.tryLock(0, 1024, false);
-
- return lockFile != null;
- } catch (IOException e) {
- throw new IllegalStateException("Failed to create lock in " + lockFilePath.toString(), e);
- }
- }
-
- public void unlock() {
- if (lockFile != null) {
- try {
- lockFile.release();
- lockFile = null;
- } catch (IOException e) {
- logger.error("Error releasing lock", e);
- }
- }
- if (lockChannel != null) {
- try {
- lockChannel.close();
- lockChannel = null;
- } catch (IOException e) {
- logger.error("Error closing file channel", e);
- }
- }
- if (lockRandomAccessFile != null) {
- try {
- lockRandomAccessFile.close();
- lockRandomAccessFile = null;
- } catch (IOException e) {
- logger.error("Error closing file", e);
- }
- }
- }
-}
diff --git a/sonar-home/src/main/java/org/sonar/home/cache/FileCache.java b/sonar-home/src/main/java/org/sonar/home/cache/FileCache.java
deleted file mode 100644
index bc42ed0335c..00000000000
--- a/sonar-home/src/main/java/org/sonar/home/cache/FileCache.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2018 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.home.cache;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.jar.JarOutputStream;
-import java.util.jar.Pack200;
-import java.util.zip.GZIPInputStream;
-
-/**
- * This class is responsible for managing Sonar batch file cache. You can put file into cache and
- * later try to retrieve them. MD5 is used to differentiate files (name is not secure as files may come
- * from different Sonar servers and have same name but be actually different, and same for SNAPSHOTs).
- */
-public class FileCache {
-
- /** Maximum loop count when creating temp directories. */
- private static final int TEMP_DIR_ATTEMPTS = 10_000;
-
- private final File cacheDir;
- private final File tmpDir;
- private final FileHashes hashes;
- private final Logger logger;
-
- FileCache(File dir, FileHashes fileHashes, Logger logger) {
- this.hashes = fileHashes;
- this.logger = logger;
- this.cacheDir = createDir(dir, "user cache: ");
- logger.info(String.format("User cache: %s", dir.getAbsolutePath()));
- this.tmpDir = createDir(new File(dir, "_tmp"), "temp dir");
- }
-
- public static FileCache create(File dir, Logger logger) {
- return new FileCache(dir, new FileHashes(), logger);
- }
-
- public File getDir() {
- return cacheDir;
- }
-
- 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);
- File targetFile = new File(hashDir, filename);
- if (!targetFile.exists()) {
- cacheMiss(targetFile, hash, downloader);
- }
- return targetFile;
- }
-
- private void cacheMiss(File targetFile, String expectedHash, Downloader downloader) {
- File tempFile = newTempFile();
- download(downloader, targetFile.getName(), tempFile);
- String downloadedHash = hashes.of(tempFile);
- if (!expectedHash.equals(downloadedHash)) {
- throw new IllegalStateException("INVALID HASH: File " + tempFile.getAbsolutePath() + " was expected to have hash " + expectedHash
- + " but was downloaded with hash " + downloadedHash);
- }
- mkdirQuietly(targetFile.getParentFile());
- renameQuietly(tempFile, targetFile);
- }
-
- public File getCompressed(String filename, String hash, Downloader downloader) {
- File hashDir = hashDir(hash);
- File compressedFile = new File(hashDir, filename);
- File jarFile = new File(compressedFile.getParentFile(), getUnpackedFileName(compressedFile.getName()));
-
- if (!jarFile.exists()) {
- if (!compressedFile.exists()) {
- cacheMiss(compressedFile, hash, downloader);
- }
- File tempFile = newTempFile();
- unpack200(compressedFile.toPath(), tempFile.toPath());
- renameQuietly(tempFile, jarFile);
- }
- return jarFile;
- }
-
- private static String getUnpackedFileName(String packedName) {
- return packedName.substring(0, packedName.length() - 7) + "jar";
- }
-
- private void unpack200(Path compressedFile, Path jarFile) {
- logger.debug("Unpacking plugin " + compressedFile);
- Pack200.Unpacker unpacker = Pack200.newUnpacker();
- try {
- try (JarOutputStream jarStream = new JarOutputStream(new BufferedOutputStream(Files.newOutputStream(jarFile)));
- InputStream in = new GZIPInputStream(new BufferedInputStream(Files.newInputStream(compressedFile)))) {
- unpacker.unpack(in, jarStream);
- }
- } catch (IOException e) {
- throw new IllegalStateException(e);
- }
- }
-
- private static void download(Downloader downloader, String filename, File tempFile) {
- try {
- downloader.download(filename, tempFile);
- } catch (IOException e) {
- throw new IllegalStateException("Fail to download " + filename + " to " + tempFile, e);
- }
- }
-
- private void renameQuietly(File sourceFile, File targetFile) {
- boolean rename = sourceFile.renameTo(targetFile);
- // Check if the file was cached by another process during download
- if (!rename && !targetFile.exists()) {
- logger.warn(String.format("Unable to rename %s to %s", sourceFile.getAbsolutePath(), targetFile.getAbsolutePath()));
- logger.warn("A copy/delete will be tempted but with no guarantee of atomicity");
- try {
- Files.move(sourceFile.toPath(), targetFile.toPath());
- } catch (IOException e) {
- throw new IllegalStateException("Fail to move " + sourceFile.getAbsolutePath() + " to " + targetFile, e);
- }
- }
- }
-
- private File hashDir(String hash) {
- return new File(cacheDir, hash);
- }
-
- private static void mkdirQuietly(File hashDir) {
- try {
- Files.createDirectories(hashDir.toPath());
- } catch (IOException e) {
- throw new IllegalStateException("Fail to create cache directory: " + hashDir, e);
- }
- }
-
- private File newTempFile() {
- try {
- return File.createTempFile("fileCache", null, tmpDir);
- } catch (IOException e) {
- throw new IllegalStateException("Fail to create temp file in " + tmpDir, e);
- }
- }
-
- public File createTempDir() {
- String baseName = System.currentTimeMillis() + "-";
-
- for (int counter = 0; counter < TEMP_DIR_ATTEMPTS; counter++) {
- File tempDir = new File(tmpDir, baseName + counter);
- if (tempDir.mkdir()) {
- return tempDir;
- }
- }
- throw new IllegalStateException("Failed to create directory in " + tmpDir);
- }
-
- private File createDir(File dir, String debugTitle) {
- if (!dir.isDirectory() || !dir.exists()) {
- logger.debug("Create : " + dir.getAbsolutePath());
- try {
- Files.createDirectories(dir.toPath());
- } catch (IOException e) {
- throw new IllegalStateException("Unable to create " + debugTitle + dir.getAbsolutePath(), e);
- }
- }
- return dir;
- }
-}
diff --git a/sonar-home/src/main/java/org/sonar/home/cache/FileCacheBuilder.java b/sonar-home/src/main/java/org/sonar/home/cache/FileCacheBuilder.java
deleted file mode 100644
index 0bb78aada30..00000000000
--- a/sonar-home/src/main/java/org/sonar/home/cache/FileCacheBuilder.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2018 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.home.cache;
-
-import java.io.File;
-
-import javax.annotation.Nullable;
-
-public class FileCacheBuilder {
- private final Logger logger;
- private File userHome;
-
- public FileCacheBuilder(Logger logger) {
- this.logger = logger;
- }
-
- public FileCacheBuilder setUserHome(@Nullable File dir) {
- this.userHome = dir;
- return this;
- }
-
- public FileCache build() {
- if (userHome == null) {
- userHome = findHome();
- }
- File cacheDir = new File(userHome, "cache");
- return FileCache.create(cacheDir, logger);
- }
-
- private static File findHome() {
- String path = System.getenv("SONAR_USER_HOME");
- if (path == null) {
- // Default
- path = System.getProperty("user.home") + File.separator + ".sonar";
- }
- return new File(path);
- }
-}
diff --git a/sonar-home/src/main/java/org/sonar/home/cache/FileHashes.java b/sonar-home/src/main/java/org/sonar/home/cache/FileHashes.java
deleted file mode 100644
index a76f17c7340..00000000000
--- a/sonar-home/src/main/java/org/sonar/home/cache/FileHashes.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2018 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.home.cache;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.math.BigInteger;
-import java.security.MessageDigest;
-
-/**
- * Hashes used to store files in the cache directory.
- *
- * @since 3.5
- */
-public class FileHashes {
-
- private static final int STREAM_BUFFER_LENGTH = 1024;
-
- public String of(File file) {
- try {
- return of(new FileInputStream(file));
- } catch (IOException e) {
- throw new IllegalStateException("Fail to compute hash of: " + file.getAbsolutePath(), e);
- }
- }
-
- /**
- * Computes the hash of given stream. The stream is closed by this method.
- */
- public String of(InputStream input) {
- try(InputStream is = input) {
- MessageDigest digest = MessageDigest.getInstance("MD5");
- byte[] hash = digest(is, digest);
- return toHex(hash);
- } catch (Exception e) {
- throw new IllegalStateException("Fail to compute hash", e);
- }
- }
-
- private static byte[] digest(InputStream input, MessageDigest digest) throws IOException {
- final byte[] buffer = new byte[STREAM_BUFFER_LENGTH];
- int read = input.read(buffer, 0, STREAM_BUFFER_LENGTH);
- while (read > -1) {
- digest.update(buffer, 0, read);
- read = input.read(buffer, 0, STREAM_BUFFER_LENGTH);
- }
- return digest.digest();
- }
-
- static String toHex(byte[] bytes) {
- BigInteger bi = new BigInteger(1, bytes);
- return String.format("%0" + (bytes.length << 1) + "x", bi);
- }
-}
diff --git a/sonar-home/src/test/java/org/sonar/home/cache/DirectoryLockTest.java b/sonar-home/src/test/java/org/sonar/home/cache/DirectoryLockTest.java
deleted file mode 100644
index 36815b3c2b1..00000000000
--- a/sonar-home/src/test/java/org/sonar/home/cache/DirectoryLockTest.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2018 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.home.cache;
-
-import java.nio.file.Paths;
-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 expectedException = ExpectedException.none();
- private DirectoryLock lock;
-
- @Before
- public void setUp() {
- lock = new DirectoryLock(temp.getRoot().toPath(), mock(Logger.class));
- }
-
- @Test
- public void tryLock() {
- assertThat(temp.getRoot().list()).isEmpty();
- lock.tryLock();
- assertThat(temp.getRoot().toPath().resolve(".sonar_lock")).exists();
- lock.unlock();
- }
-
- @Test
- public void unlockWithoutLock() {
- lock.unlock();
- }
-
- @Test
- public void errorTryLock() {
- lock = new DirectoryLock(Paths.get("non", "existing", "path"), mock(Logger.class));
-
- expectedException.expect(IllegalStateException.class);
- expectedException.expectMessage("Failed to create lock");
-
- lock.tryLock();
- }
-}
diff --git a/sonar-home/src/test/java/org/sonar/home/cache/FileCacheBuilderTest.java b/sonar-home/src/test/java/org/sonar/home/cache/FileCacheBuilderTest.java
deleted file mode 100644
index 8e144c9ed14..00000000000
--- a/sonar-home/src/test/java/org/sonar/home/cache/FileCacheBuilderTest.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2018 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.home.cache;
-
-import java.io.File;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-
-public class FileCacheBuilderTest {
- @Rule
- public TemporaryFolder temp = new TemporaryFolder();
-
- @Test
- public void setUserHome() throws Exception {
- File userHome = temp.newFolder();
- FileCache cache = new FileCacheBuilder(mock(Logger.class)).setUserHome(userHome).build();
-
- assertThat(cache.getDir()).isDirectory().exists();
- assertThat(cache.getDir().getName()).isEqualTo("cache");
- assertThat(cache.getDir().getParentFile()).isEqualTo(userHome);
- }
-
- @Test
- public void user_home_property_can_be_null() {
- 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();
- assertThat(cache.getDir().getName()).isEqualTo("cache");
- }
-
- @Test
- public void use_default_path_or_env_variable() {
- FileCache cache = new FileCacheBuilder(mock(Logger.class)).build();
-
- assertThat(cache.getDir()).isDirectory().exists();
- assertThat(cache.getDir().getName()).isEqualTo("cache");
- }
-}
diff --git a/sonar-home/src/test/java/org/sonar/home/cache/FileCacheTest.java b/sonar-home/src/test/java/org/sonar/home/cache/FileCacheTest.java
deleted file mode 100644
index 63d4d85458f..00000000000
--- a/sonar-home/src/test/java/org/sonar/home/cache/FileCacheTest.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2018 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.home.cache;
-
-import java.io.File;
-import java.io.IOException;
-import org.apache.commons.io.FileUtils;
-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.ArgumentMatchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
-
-public class FileCacheTest {
-
- @Rule
- public TemporaryFolder tempFolder = new TemporaryFolder();
- @Rule
- public ExpectedException expectedException = ExpectedException.none();
-
- private FileHashes fileHashes = mock(FileHashes.class);
- private FileCache cache;
-
- @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 = (filename, toFile) -> {
- throw new IOException("fail");
- };
- 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();
- expectedException.expect(IllegalStateException.class);
- expectedException.expectMessage("Unable to create user cache");
- cache = new FileCache(file, fileHashes, mock(Logger.class));
- }
-
- @Test
- public void fail_to_create_hash_dir() throws IOException {
- when(fileHashes.of(any(File.class))).thenReturn("ABCDE");
-
- File hashDir = new File(cache.getDir(), "ABCDE");
- hashDir.createNewFile();
- expectedException.expect(IllegalStateException.class);
- expectedException.expectMessage("Fail to create cache directory");
- cache.get("sonar-foo-plugin-1.5.jar", "ABCDE", mock(FileCache.Downloader.class));
- }
-
- @Test
- public void download_and_add_to_cache() throws IOException {
- when(fileHashes.of(any(File.class))).thenReturn("ABCDE");
-
- 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");
- assertThat(cachedFile.getParentFile().getParentFile()).isEqualTo(cache.getDir());
- assertThat(FileUtils.readFileToString(cachedFile)).isEqualTo("body");
- }
-
- @Test
- public void download_and_add_to_cache_compressed_file() {
- when(fileHashes.of(any(File.class))).thenReturn("ABCDE");
-
- 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();
-
- assertThat(cachedFile.getName()).isEqualTo("sonar-foo-plugin-1.5.jar");
- assertThat(cachedFile.getParentFile().list()).containsOnly("sonar-foo-plugin-1.5.jar", "sonar-foo-plugin-1.5.pack.gz");
- assertThat(cachedFile.getParentFile().getParentFile()).isEqualTo(cache.getDir());
- }
-
- @Test
- public void dont_download_compressed_file_if_jar_exists() throws IOException {
- when(fileHashes.of(any(File.class))).thenReturn("ABCDE");
- FileCache.Downloader downloader = mock(FileCache.Downloader.class);
-
- File hashDir = new File(cache.getDir(), "ABCDE");
- hashDir.mkdirs();
- File jar = new File(new File(cache.getDir(), "ABCDE"), "sonar-foo-plugin-1.5.jar");
- jar.createNewFile();
- File cachedFile = cache.getCompressed("sonar-foo-plugin-1.5.pack.gz", "ABCDE", downloader);
- assertThat(cachedFile).isNotNull().exists().isFile();
-
- assertThat(cachedFile.getName()).isEqualTo("sonar-foo-plugin-1.5.jar");
- assertThat(cachedFile.getParentFile().list()).containsOnly("sonar-foo-plugin-1.5.jar");
- assertThat(cachedFile.getParentFile().getParentFile()).isEqualTo(cache.getDir());
-
- verifyZeroInteractions(downloader);
- }
-
- @Test
- public void dont_download_compressed_file_if_it_exists() throws IOException {
- when(fileHashes.of(any(File.class))).thenReturn("ABCDE");
- FileCache.Downloader downloader = mock(FileCache.Downloader.class);
-
- File hashDir = new File(cache.getDir(), "ABCDE");
- hashDir.mkdirs();
- FileUtils.copyFile(compressedFile(), new File(hashDir, "sonar-foo-plugin-1.5.pack.gz"));
- File cachedFile = cache.getCompressed("sonar-foo-plugin-1.5.pack.gz", "ABCDE", downloader);
- assertThat(cachedFile).isNotNull().exists().isFile();
-
- assertThat(cachedFile.getName()).isEqualTo("sonar-foo-plugin-1.5.jar");
- assertThat(cachedFile.getParentFile().list()).containsOnly("sonar-foo-plugin-1.5.jar", "sonar-foo-plugin-1.5.pack.gz");
- assertThat(cachedFile.getParentFile().getParentFile()).isEqualTo(cache.getDir());
-
- verifyZeroInteractions(downloader);
- }
-
- @Test
- public void download_corrupted_file() {
- expectedException.expect(IllegalStateException.class);
- expectedException.expectMessage("INVALID HASH");
-
- when(fileHashes.of(any(File.class))).thenReturn("VWXYZ");
-
- FileCache.Downloader downloader = (filename, toFile) -> FileUtils.write(toFile, "corrupted body");
- cache.get("sonar-foo-plugin-1.5.jar", "ABCDE", downloader);
- }
-
- @Test
- public void concurrent_download() throws IOException {
- when(fileHashes.of(any(File.class))).thenReturn("ABCDE");
-
- 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");
- };
-
- // do not fail
- 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");
- assertThat(cachedFile.getParentFile().getParentFile()).isEqualTo(cache.getDir());
- assertThat(FileUtils.readFileToString(cachedFile)).contains("downloaded by");
- }
-
- private File compressedFile() {
- return new File("src/test/resources/test.pack.gz");
- }
-}
diff --git a/sonar-home/src/test/java/org/sonar/home/cache/FileHashesTest.java b/sonar-home/src/test/java/org/sonar/home/cache/FileHashesTest.java
deleted file mode 100644
index 35bb977675d..00000000000
--- a/sonar-home/src/test/java/org/sonar/home/cache/FileHashesTest.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2018 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.home.cache;
-
-import org.apache.commons.codec.binary.Hex;
-import org.apache.commons.codec.digest.DigestUtils;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.IOUtils;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.junit.rules.TemporaryFolder;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.math.BigInteger;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.security.SecureRandom;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class FileHashesTest {
-
- private SecureRandom secureRandom = new SecureRandom();
-
- @Rule
- public ExpectedException expectedException = ExpectedException.none();
-
- @Rule
- public TemporaryFolder temp = new TemporaryFolder();
-
- @Test
- public void test_md5_hash() {
- assertThat(hash("sonar")).isEqualTo("d85e336d61f5344395c42126fac239bc");
-
- // compare results with commons-codec
- for (int index = 0; index < 100; index++) {
- String random = randomString();
- assertThat(hash(random)).as(random).isEqualTo(
- DigestUtils.md5Hex(random).toLowerCase()
- );
- }
- }
-
- @Test
- public void test_hash_file() throws IOException {
- File f = temp.newFile();
- Files.write(f.toPath(), "sonar".getBytes(StandardCharsets.UTF_8));
- assertThat(hashFile(f)).isEqualTo("d85e336d61f5344395c42126fac239bc");
- }
-
- @Test
- public void test_toHex() {
- // lower-case
- assertThat(FileHashes.toHex("aloa_bi_bop_a_loula".getBytes())).isEqualTo("616c6f615f62695f626f705f615f6c6f756c61");
-
- // compare results with commons-codec
- for (int index = 0; index < 100; index++) {
- String random = randomString();
- assertThat(FileHashes.toHex(random.getBytes())).as(random).isEqualTo(
- Hex.encodeHexString(random.getBytes()).toLowerCase()
- );
- }
- }
-
- @Test
- public void fail_if_file_does_not_exist() throws IOException {
- File file = temp.newFile("does_not_exist");
- FileUtils.forceDelete(file);
-
- 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 {
- 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());
- new FileHashes().of(input);
- }
-
- private String randomString() {
- return new BigInteger(130, secureRandom).toString(32);
- }
-
- private String hash(String s) {
- InputStream in = new ByteArrayInputStream(s.getBytes());
- try {
- return new FileHashes().of(in);
- } finally {
- IOUtils.closeQuietly(in);
- }
- }
-
- private String hashFile(File f) {
- return new FileHashes().of(f);
- }
-}