<dependency>
<groupId>org.codehaus.sonar</groupId>
<artifactId>sonar-persistit</artifactId>
- <version>3.3.1</version>
+ <version>3.3.2-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
}
return tempFolder;
}
-
}
*/
package org.sonar.batch.bootstrap;
+import org.sonar.batch.index.CachesManager;
+
import java.util.List;
import java.util.Map;
+
import org.sonar.api.CoreProperties;
import org.sonar.api.Plugin;
import org.sonar.api.utils.Durations;
BatchPluginPredicate.class,
ExtensionInstaller.class,
+ CachesManager.class,
GlobalSettings.class,
ServerClient.class,
Logback.class,
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.batch.bootstrap;
+
+import org.sonar.api.utils.ProjectTempFolder;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.StringUtils;
+import org.picocontainer.injectors.ProviderAdapter;
+import org.sonar.api.CoreProperties;
+import org.sonar.api.utils.internal.DefaultTempFolder;
+
+import java.io.File;
+import java.io.IOException;
+
+public class ProjectTempFolderProvider extends ProviderAdapter {
+ static final String TMP_NAME = ".sonartmp";
+ private ProjectTempFolder projectTempFolder;
+
+ public ProjectTempFolder provide(BootstrapProperties bootstrapProps) {
+ if (projectTempFolder == null) {
+ String workingDirPath = StringUtils.defaultIfBlank(bootstrapProps.property(CoreProperties.WORKING_DIRECTORY), CoreProperties.WORKING_DIRECTORY_DEFAULT_VALUE);
+ File workingDir = new File(workingDirPath).getAbsoluteFile();
+ File tempDir = new File(workingDir, TMP_NAME);
+ try {
+ FileUtils.forceMkdir(tempDir);
+ } catch (IOException e) {
+ throw new IllegalStateException("Unable to create root temp directory " + tempDir, e);
+ }
+ projectTempFolder = new DefaultTempFolder(tempDir, true);
+ }
+ return projectTempFolder;
+ }
+
+}
*/
package org.sonar.batch.bootstrap;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.lang.StringUtils;
+import org.sonar.api.utils.TempFolder;
import org.picocontainer.injectors.ProviderAdapter;
+import org.apache.commons.lang.StringUtils;
import org.sonar.api.CoreProperties;
-import org.sonar.api.utils.TempFolder;
import org.sonar.api.utils.internal.DefaultTempFolder;
-import java.io.File;
import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
public class TempFolderProvider extends ProviderAdapter {
-
+ static final String TMP_NAME = ".sonartmp";
private TempFolder tempFolder;
public TempFolder provide(BootstrapProperties bootstrapProps) {
if (tempFolder == null) {
- String workingDirPath = StringUtils.defaultIfBlank(bootstrapProps.property(CoreProperties.WORKING_DIRECTORY), CoreProperties.WORKING_DIRECTORY_DEFAULT_VALUE);
- File workingDir = new File(workingDirPath).getAbsoluteFile();
- File tempDir = new File(workingDir, ".sonartmp");
+
+ String workingPathName = StringUtils.defaultIfBlank(bootstrapProps.property(CoreProperties.GLOBAL_WORKING_DIRECTORY), CoreProperties.GLOBAL_WORKING_DIRECTORY_DEFAULT_VALUE);
+ Path workingPath = Paths.get(workingPathName).normalize();
+
+ if (!workingPath.isAbsolute()) {
+ Path home = findHome(bootstrapProps);
+ workingPath = home.resolve(workingPath).normalize();
+ }
+
+ Path tempDir = workingPath.resolve(TMP_NAME);
try {
- FileUtils.forceMkdir(tempDir);
+ Files.createDirectories(tempDir);
} catch (IOException e) {
throw new IllegalStateException("Unable to create root temp directory " + tempDir, e);
}
- tempFolder = new DefaultTempFolder(tempDir);
+ tempFolder = new DefaultTempFolder(tempDir.toFile(), true);
}
return tempFolder;
}
+ private static Path findHome(BootstrapProperties props) {
+ String home = props.property("sonar.userHome");
+ if (home != null) {
+ return Paths.get(home);
+ }
+
+ home = System.getenv("SONAR_USER_HOME");
+
+ if (home != null) {
+ return Paths.get(home);
+ }
+
+ home = System.getProperty("user.home");
+ return Paths.get(home, ".sonar");
+ }
+
}
import javax.annotation.Nullable;
import java.io.File;
+import java.io.PrintStream;
import java.util.Map;
/**
setVerbose(verbose);
return this;
}
+
+ public LoggingConfiguration setStreams(PrintStream out, PrintStream err) {
+
+ return this;
+ }
public LoggingConfiguration setVerbose(boolean verbose) {
return setRootLevel(verbose ? LEVEL_ROOT_VERBOSE : LEVEL_ROOT_DEFAULT);
*/
package org.sonar.batch.index;
+import com.google.common.collect.Maps;
+
+import java.util.Map;
+import java.util.Map.Entry;
+
import com.google.common.base.Preconditions;
-import com.google.common.collect.Sets;
import com.persistit.Exchange;
-import com.persistit.Persistit;
import com.persistit.Value;
-import com.persistit.Volume;
import com.persistit.encoding.CoderManager;
+import com.persistit.Persistit;
import com.persistit.encoding.ValueCoder;
import com.persistit.exception.PersistitException;
-import com.persistit.logging.Slf4jAdapter;
-import org.apache.commons.io.FileUtils;
+import com.persistit.Volume;
import org.picocontainer.Startable;
-import org.slf4j.LoggerFactory;
import org.sonar.api.batch.BatchSide;
-import org.sonar.api.utils.TempFolder;
-import java.io.File;
-import java.util.Properties;
-import java.util.Set;
-
-/**
- * Factory of caches
- *
- * @since 3.6
- */
@BatchSide
public class Caches implements Startable {
-
- private final Set<String> cacheNames = Sets.newHashSet();
- private File tempDir;
+ private final Map<String, Exchange> caches = Maps.newHashMap();
private Persistit persistit;
private Volume volume;
- private final TempFolder tempFolder;
- public Caches(TempFolder tempFolder) {
- this.tempFolder = tempFolder;
- initPersistit();
+ public Caches(CachesManager caches) {
+ persistit = caches.persistit();
+ start();
}
- private void initPersistit() {
+ @Override
+ public void start() {
try {
- tempDir = tempFolder.newDir("caches");
- persistit = new Persistit();
- persistit.setPersistitLogger(new Slf4jAdapter(LoggerFactory.getLogger("PERSISTIT")));
- Properties props = new Properties();
- props.setProperty("datapath", tempDir.getAbsolutePath());
- props.setProperty("logpath", "${datapath}/log");
- props.setProperty("logfile", "${logpath}/persistit_${timestamp}.log");
- props.setProperty("buffer.count.8192", "10");
- props.setProperty("journalpath", "${datapath}/journal");
- props.setProperty("tmpvoldir", "${datapath}");
- props.setProperty("volume.1", "${datapath}/persistit,create,pageSize:8192,initialPages:10,extensionPages:100,maximumPages:25000");
- persistit.setProperties(props);
- persistit.initialize();
+ persistit.flush();
volume = persistit.createTemporaryVolume();
-
} catch (Exception e) {
- throw new IllegalStateException("Fail to start caches", e);
+ throw new IllegalStateException("Fail to create a cache volume", e);
}
}
public <V> Cache<V> createCache(String cacheName) {
Preconditions.checkState(volume != null && volume.isOpened(), "Caches are not initialized");
- Preconditions.checkState(!cacheNames.contains(cacheName), "Cache is already created: " + cacheName);
+ Preconditions.checkState(!caches.containsKey(cacheName), "Cache is already created: " + cacheName);
try {
Exchange exchange = persistit.getExchange(volume, cacheName, true);
exchange.setMaximumValueSize(Value.MAXIMUM_SIZE);
Cache<V> cache = new Cache<>(cacheName, exchange);
- cacheNames.add(cacheName);
+ caches.put(cacheName, exchange);
return cache;
} catch (Exception e) {
throw new IllegalStateException("Fail to create cache: " + cacheName, e);
}
}
- @Override
- public void start() {
- // already started in constructor
- }
-
@Override
public void stop() {
- if (persistit != null) {
+ for (Entry<String, Exchange> e : caches.entrySet()) {
+ persistit.releaseExchange(e.getValue());
+ }
+
+ caches.clear();
+
+ if (volume != null) {
try {
- persistit.close(false);
- persistit = null;
- volume = null;
+ volume.close();
+ volume.delete();
} catch (PersistitException e) {
throw new IllegalStateException("Fail to close caches", e);
}
+ volume = null;
}
- FileUtils.deleteQuietly(tempDir);
- tempDir = null;
- cacheNames.clear();
- }
-
- File tempDir() {
- return tempDir;
- }
-
- Persistit persistit() {
- return persistit;
}
}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.batch.index;
+
+import org.sonar.api.utils.TempFolder;
+
+import com.persistit.Persistit;
+import com.persistit.exception.PersistitException;
+import com.persistit.logging.Slf4jAdapter;
+import org.apache.commons.io.FileUtils;
+import org.picocontainer.Startable;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.batch.BatchSide;
+
+import java.io.File;
+import java.util.Properties;
+
+/**
+ * Factory of caches
+ *
+ * @since 3.6
+ */
+@BatchSide
+public class CachesManager implements Startable {
+ private File tempDir;
+ private Persistit persistit;
+ private final TempFolder tempFolder;
+
+ public CachesManager(TempFolder tempFolder) {
+ this.tempFolder = tempFolder;
+ initPersistit();
+ }
+
+ private void initPersistit() {
+ try {
+ tempDir = tempFolder.newDir("caches");
+ persistit = new Persistit();
+ persistit.setPersistitLogger(new Slf4jAdapter(LoggerFactory.getLogger("PERSISTIT")));
+ Properties props = new Properties();
+ props.setProperty("datapath", tempDir.getAbsolutePath());
+ props.setProperty("logpath", "${datapath}/log");
+ props.setProperty("logfile", "${logpath}/persistit_${timestamp}.log");
+ props.setProperty("buffer.count.8192", "10");
+ props.setProperty("journalpath", "${datapath}/journal");
+ props.setProperty("tmpvoldir", "${datapath}");
+ props.setProperty("volume.1", "${datapath}/persistit,create,pageSize:8192,initialPages:10,extensionPages:100,maximumPages:25000");
+ persistit.setProperties(props);
+ persistit.initialize();
+
+ } catch (Exception e) {
+ throw new IllegalStateException("Fail to start caches", e);
+ }
+ }
+
+ @Override
+ public void start() {
+ // already started in constructor
+ }
+
+ @Override
+ public void stop() {
+ if (persistit != null) {
+ try {
+ persistit.close(false);
+ persistit = null;
+ } catch (PersistitException e) {
+ throw new IllegalStateException("Fail to close caches", e);
+ }
+ }
+ FileUtils.deleteQuietly(tempDir);
+ tempDir = null;
+ }
+
+ File tempDir() {
+ return tempDir;
+ }
+
+ Persistit persistit() {
+ return persistit;
+ }
+}
*/
package org.sonar.batch.scan;
+import org.sonar.batch.bootstrap.ProjectTempFolderProvider;
+
+import org.sonar.api.utils.internal.TempFolderCleaner;
+import org.sonar.batch.bootstrap.TempFolderProvider;
import com.google.common.annotations.VisibleForTesting;
import org.sonar.api.CoreProperties;
import org.sonar.api.batch.InstantiationStrategy;
Caches.class,
BatchComponentCache.class,
- // file system
+ //temp
+ new ProjectTempFolderProvider(),
+
+ // file system
InputPathCache.class,
PathResolver.class,
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.batch.bootstrap;
+
+import org.apache.commons.io.FileUtils;
+
+import org.sonar.api.utils.ProjectTempFolder;
+import com.google.common.collect.ImmutableMap;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.sonar.api.CoreProperties;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collections;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class ProjectTempFolderProviderTest {
+
+ @Rule
+ public TemporaryFolder temp = new TemporaryFolder();
+
+ private ProjectTempFolderProvider tempFolderProvider = new ProjectTempFolderProvider();
+
+ @Test
+ public void createTempFolderWithProps() throws Exception {
+ File workingDir = temp.newFolder();
+ File tmpDir = new File(workingDir, ProjectTempFolderProvider.TMP_NAME);
+
+ ProjectTempFolder tempFolder = tempFolderProvider.provide(new BootstrapProperties(ImmutableMap.of(CoreProperties.WORKING_DIRECTORY, workingDir.getAbsolutePath())));
+ tempFolder.newDir();
+ tempFolder.newFile();
+ assertThat(tmpDir).exists();
+ assertThat(tmpDir.list()).hasSize(2);
+ }
+
+ @Test
+ public void createTempFolder() throws IOException {
+ File defaultDir = new File(CoreProperties.WORKING_DIRECTORY_DEFAULT_VALUE, ProjectTempFolderProvider.TMP_NAME);
+
+ try {
+ ProjectTempFolder tempFolder = tempFolderProvider.provide(new BootstrapProperties(Collections.<String, String>emptyMap()));
+ tempFolder.newDir();
+ tempFolder.newFile();
+ assertThat(defaultDir).exists();
+ assertThat(defaultDir.list()).hasSize(2);
+ } finally {
+ FileUtils.deleteDirectory(defaultDir);
+ }
+ }
+}
*/
package org.sonar.batch.bootstrap;
+import org.apache.commons.io.FileUtils;
+import org.sonar.api.utils.TempFolder;
import com.google.common.collect.ImmutableMap;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.junit.rules.TemporaryFolder;
import org.sonar.api.CoreProperties;
-import org.sonar.api.utils.TempFolder;
import java.io.File;
+import java.util.Collections;
import static org.assertj.core.api.Assertions.assertThat;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
public class TempFolderProviderTest {
-
- @Rule
- public ExpectedException throwable = ExpectedException.none();
-
@Rule
public TemporaryFolder temp = new TemporaryFolder();
+ private TempFolderProvider tempFolderProvider = new TempFolderProvider();
+
@Test
- public void createTempFolder() throws Exception {
+ public void createTempFolderProps() throws Exception {
File workingDir = temp.newFolder();
- TempFolderProvider tempFolderProvider = new TempFolderProvider();
- TempFolder tempFolder = tempFolderProvider.provide(new BootstrapProperties(ImmutableMap.of(CoreProperties.WORKING_DIRECTORY, workingDir.getAbsolutePath())));
+
+ TempFolder tempFolder = tempFolderProvider.provide(new BootstrapProperties(ImmutableMap.of(CoreProperties.GLOBAL_WORKING_DIRECTORY, workingDir.getAbsolutePath())));
tempFolder.newDir();
tempFolder.newFile();
- assertThat(new File(workingDir, ".sonartmp")).exists();
+ assertThat(new File(workingDir, TempFolderProvider.TMP_NAME)).exists();
assertThat(new File(workingDir, ".sonartmp").list()).hasSize(2);
}
+
+ @Test
+ public void createTempFolderSonarHome() throws Exception {
+ // with sonar home, it will be in {sonar.home}/.sonartmp
+ File sonarHome = temp.newFolder();
+ File tmpDir = new File(new File(sonarHome, CoreProperties.GLOBAL_WORKING_DIRECTORY_DEFAULT_VALUE), TempFolderProvider.TMP_NAME);
+
+ TempFolder tempFolder = tempFolderProvider.provide(new BootstrapProperties(ImmutableMap.of("sonar.userHome", sonarHome.getAbsolutePath())));
+ tempFolder.newDir();
+ tempFolder.newFile();
+ assertThat(tmpDir).exists();
+ assertThat(tmpDir.list()).hasSize(2);
+ }
+
+ @Test
+ public void createTempFolderDefault() throws Exception {
+ // if nothing is defined, it will be in {user.home}/.sonar/.sonartmp
+ File defaultSonarHome = new File(System.getProperty("user.home"), ".sonar");
+ File tmpDir = new File(new File(defaultSonarHome, CoreProperties.GLOBAL_WORKING_DIRECTORY_DEFAULT_VALUE), TempFolderProvider.TMP_NAME);
+
+ try {
+ TempFolder tempFolder = tempFolderProvider.provide(new BootstrapProperties(Collections.<String, String>emptyMap()));
+ tempFolder.newDir();
+ tempFolder.newFile();
+ assertThat(tmpDir).exists();
+ assertThat(tmpDir.list()).hasSize(2);
+ } finally {
+ FileUtils.deleteDirectory(tmpDir);
+ }
+ }
}
*/
package org.sonar.batch.duplication;
-import org.junit.After;
-import org.junit.Before;
+import org.sonar.batch.index.AbstractCachesTest;
+
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
-import org.junit.rules.TemporaryFolder;
import org.sonar.api.batch.sensor.duplication.Duplication;
import org.sonar.api.batch.sensor.duplication.internal.DefaultDuplication;
-import org.sonar.batch.index.Caches;
-import org.sonar.batch.index.CachesTest;
-
import static org.assertj.core.api.Assertions.assertThat;
-public class DuplicationCacheTest {
-
- @Rule
- public TemporaryFolder temp = new TemporaryFolder();
+public class DuplicationCacheTest extends AbstractCachesTest {
@Rule
public ExpectedException thrown = ExpectedException.none();
- Caches caches;
-
- @Before
- public void start() {
- caches = CachesTest.createCacheOnTemp(temp);
- caches.start();
- }
-
- @After
- public void stop() {
- caches.stop();
- }
-
@Test
public void should_add_clone_groups() {
DuplicationCache cache = new DuplicationCache(caches);
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.batch.index;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.rules.TemporaryFolder;
+
+public abstract class AbstractCachesTest {
+ @ClassRule
+ public static TemporaryFolder temp = new TemporaryFolder();
+
+ protected Caches caches;
+ protected static CachesManager cachesManager;
+
+ @BeforeClass
+ public static void startClass() {
+ cachesManager = CachesManagerTest.createCacheOnTemp(temp);
+ cachesManager.start();
+ }
+
+ @Before
+ public void start() {
+ caches = new Caches(cachesManager);
+ caches.start();
+ }
+
+ @After
+ public void stop() {
+ caches.stop();
+ caches = null;
+ }
+
+ @AfterClass
+ public static void stopClass() {
+ cachesManager.stop();
+ cachesManager = null;
+ }
+}
package org.sonar.batch.index;
import com.google.common.collect.Iterables;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
import org.sonar.batch.index.Cache.Entry;
import static org.assertj.core.api.Assertions.assertThat;
-public class CacheTest {
-
- @Rule
- public TemporaryFolder temp = new TemporaryFolder();
-
- Caches caches;
-
- @Before
- public void start() {
- caches = CachesTest.createCacheOnTemp(temp);
- caches.start();
- }
-
- @After
- public void stop() {
- caches.stop();
- }
+public class CacheTest extends AbstractCachesTest {
@Test
public void one_part_key() {
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.batch.index;
+
+import org.sonar.batch.bootstrap.TempFolderProvider;
+
+import com.google.common.collect.ImmutableMap;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.sonar.api.CoreProperties;
+import org.sonar.batch.bootstrap.BootstrapProperties;
+
+import java.io.File;
+import java.io.IOException;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class CachesManagerTest {
+
+ @ClassRule
+ public static TemporaryFolder temp = new TemporaryFolder();
+
+ public static CachesManager createCacheOnTemp(TemporaryFolder temp) {
+ try {
+ BootstrapProperties bootstrapProps = new BootstrapProperties(ImmutableMap.of(CoreProperties.WORKING_DIRECTORY, temp.newFolder().getAbsolutePath()));
+ return new CachesManager(new TempFolderProvider().provide(bootstrapProps));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ CachesManager cachesMgr;
+
+ @Before
+ public void prepare() {
+ cachesMgr = createCacheOnTemp(temp);
+ cachesMgr.start();
+ }
+
+ @Test
+ public void should_stop_and_clean_temp_dir() {
+ File tempDir = cachesMgr.tempDir();
+ assertThat(tempDir).isDirectory().exists();
+ assertThat(cachesMgr.persistit()).isNotNull();
+ assertThat(cachesMgr.persistit().isInitialized()).isTrue();
+
+ cachesMgr.stop();
+
+ assertThat(tempDir).doesNotExist();
+ assertThat(cachesMgr.tempDir()).isNull();
+ assertThat(cachesMgr.persistit()).isNull();
+ }
+}
*/
package org.sonar.batch.index;
-import com.google.common.collect.ImmutableMap;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.sonar.api.CoreProperties;
-import org.sonar.batch.bootstrap.BootstrapProperties;
-import org.sonar.batch.bootstrap.TempFolderProvider;
-
-import java.io.File;
-import java.io.IOException;
import java.io.Serializable;
+import com.persistit.exception.PersistitException;
+import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;
-public class CachesTest {
-
- @ClassRule
- public static TemporaryFolder temp = new TemporaryFolder();
-
- public static Caches createCacheOnTemp(TemporaryFolder temp) {
- try {
- BootstrapProperties bootstrapProps = new BootstrapProperties(ImmutableMap.of(CoreProperties.WORKING_DIRECTORY, temp.newFolder().getAbsolutePath()));
- return new Caches(new TempFolderProvider().provide(bootstrapProps));
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- Caches caches;
-
- @Before
- public void prepare() {
- caches = createCacheOnTemp(temp);
- }
-
- @After
- public void stop() {
- caches.stop();
- }
-
- @Test
- public void should_stop_and_clean_temp_dir() {
- File tempDir = caches.tempDir();
- assertThat(tempDir).isDirectory().exists();
- assertThat(caches.persistit()).isNotNull();
- assertThat(caches.persistit().isInitialized()).isTrue();
-
- caches.stop();
-
- assertThat(tempDir).doesNotExist();
- assertThat(caches.tempDir()).isNull();
- assertThat(caches.persistit()).isNull();
- }
-
+public class CachesTest extends AbstractCachesTest {
@Test
public void should_create_cache() {
- caches.start();
Cache<Element> cache = caches.createCache("foo");
assertThat(cache).isNotNull();
}
@Test
public void should_not_create_cache_twice() {
- caches.start();
caches.<Element>createCache("foo");
try {
caches.<Element>createCache("foo");
}
}
- static class Element implements Serializable {
+ @Test
+ public void should_clean_resources() throws PersistitException {
+ Cache<String> c = caches.<String>createCache("test1");
+ for (int i = 0; i < 1_000_000; i++) {
+ c.put("a" + i, "a" + i);
+ }
+
+ caches.stop();
+
+ // manager continues up
+ assertThat(cachesManager.persistit().isInitialized()).isTrue();
+
+ caches = new Caches(cachesManager);
+ caches.start();
+ caches.createCache("test1");
+ }
+
+ @Test
+ public void leak_test() throws PersistitException {
+ caches.stop();
+
+ System.out.println(cachesManager.tempDir());
+
+ int len = 1 * 1024 * 1024;
+ StringBuilder sb = new StringBuilder(len);
+ for (int i = 0; i < len; i++) {
+ sb.append("a");
+ }
+
+ for (int i = 0; i < 3; i++) {
+ caches = new Caches(cachesManager);
+ caches.start();
+ Cache<String> c = caches.<String>createCache("test" + i);
+ c.put("key" + i, sb.toString());
+ cachesManager.persistit().flush();
+
+ caches.stop();
+ }
+ }
+
+ private static class Element implements Serializable {
+ private static final long serialVersionUID = 1L;
}
}
*/
package org.sonar.batch.issue;
+import org.sonar.batch.index.AbstractCachesTest;
+
import com.google.common.base.Function;
import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableList;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.ClassRule;
import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
import org.sonar.api.issue.Issue;
import org.sonar.api.issue.internal.DefaultIssue;
import org.sonar.api.rule.Severity;
-import org.sonar.batch.index.Caches;
-import org.sonar.batch.index.CachesTest;
import javax.annotation.Nullable;
import static org.assertj.core.api.Assertions.assertThat;
-public class IssueCacheTest {
-
- @ClassRule
- public static TemporaryFolder temp = new TemporaryFolder();
-
- Caches caches;
-
- @Before
- public void start() {
- caches = CachesTest.createCacheOnTemp(temp);
- caches.start();
- }
-
- @After
- public void stop() {
- caches.stop();
- }
+public class IssueCacheTest extends AbstractCachesTest {
@Test
public void should_add_new_issue() {
package org.sonar.batch.issue.tracking;
+import org.sonar.batch.index.AbstractCachesTest;
+
import org.junit.After;
import org.junit.Before;
-import org.junit.ClassRule;
import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.sonar.api.CoreProperties;
-import org.sonar.batch.bootstrap.BootstrapProperties;
-import org.sonar.batch.bootstrap.TempFolderProvider;
-import org.sonar.batch.index.Caches;
import org.sonar.core.issue.db.IssueChangeDto;
import org.sonar.core.issue.db.IssueDto;
-import java.io.IOException;
-import java.util.Collections;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
-public class InitialOpenIssuesStackTest {
-
- @ClassRule
- public static TemporaryFolder temp = new TemporaryFolder();
-
- public static Caches createCacheOnTemp(TemporaryFolder temp) {
- BootstrapProperties bootstrapSettings = new BootstrapProperties(Collections.<String, String>emptyMap());
- try {
- bootstrapSettings.properties().put(CoreProperties.WORKING_DIRECTORY, temp.newFolder().getAbsolutePath());
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- return new Caches(new TempFolderProvider().provide(bootstrapSettings));
- }
+public class InitialOpenIssuesStackTest extends AbstractCachesTest {
InitialOpenIssuesStack stack;
- Caches caches;
@Before
public void before() {
- caches = createCacheOnTemp(temp);
- caches.start();
stack = new InitialOpenIssuesStack(caches);
}
*/
package org.sonar.batch.scan.measure;
+import org.sonar.batch.index.AbstractCachesTest;
import org.apache.commons.lang.builder.EqualsBuilder;
-import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
-import org.junit.rules.TemporaryFolder;
import org.sonar.api.batch.measure.MetricFinder;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.Measure;
import org.sonar.api.technicaldebt.batch.TechnicalDebtModel;
import org.sonar.api.technicaldebt.batch.internal.DefaultCharacteristic;
import org.sonar.batch.index.Cache.Entry;
-import org.sonar.batch.index.Caches;
-import org.sonar.batch.index.CachesTest;
import java.util.Date;
import java.util.Iterator;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
-public class MeasureCacheTest {
-
- @Rule
- public TemporaryFolder temp = new TemporaryFolder();
-
+public class MeasureCacheTest extends AbstractCachesTest {
@Rule
public ExpectedException thrown = ExpectedException.none();
- Caches caches;
-
private MetricFinder metricFinder;
private TechnicalDebtModel techDebtModel;
- private MeasureCache cache;
+ private MeasureCache measureCache;
@Before
public void start() {
- caches = CachesTest.createCacheOnTemp(temp);
- caches.start();
+ super.start();
metricFinder = mock(MetricFinder.class);
when(metricFinder.findByKey(CoreMetrics.NCLOC_KEY)).thenReturn(CoreMetrics.NCLOC);
techDebtModel = mock(TechnicalDebtModel.class);
- cache = new MeasureCache(caches, metricFinder, techDebtModel);
- }
-
- @After
- public void stop() {
- caches.stop();
+ measureCache = new MeasureCache(caches, metricFinder, techDebtModel);
}
@Test
public void should_add_measure() {
Project p = new Project("struts");
- assertThat(cache.entries()).hasSize(0);
+ assertThat(measureCache.entries()).hasSize(0);
- assertThat(cache.byResource(p)).hasSize(0);
+ assertThat(measureCache.byResource(p)).hasSize(0);
Measure m = new Measure(CoreMetrics.NCLOC, 1.0);
- cache.put(p, m);
+ measureCache.put(p, m);
- assertThat(cache.contains(p, m)).isTrue();
- assertThat(cache.entries()).hasSize(1);
- Iterator<Entry<Measure>> iterator = cache.entries().iterator();
+ assertThat(measureCache.contains(p, m)).isTrue();
+ assertThat(measureCache.entries()).hasSize(1);
+ Iterator<Entry<Measure>> iterator = measureCache.entries().iterator();
iterator.hasNext();
Entry<Measure> next = iterator.next();
assertThat(next.value()).isEqualTo(m);
assertThat(next.key()[0]).isEqualTo("struts");
- assertThat(cache.byResource(p)).hasSize(1);
- assertThat(cache.byResource(p).iterator().next()).isEqualTo(m);
+ assertThat(measureCache.byResource(p)).hasSize(1);
+ assertThat(measureCache.byResource(p).iterator().next()).isEqualTo(m);
Measure mRule = RuleMeasure.createForPriority(CoreMetrics.CRITICAL_VIOLATIONS, RulePriority.BLOCKER, 1.0);
- cache.put(p, mRule);
+ measureCache.put(p, mRule);
- assertThat(cache.entries()).hasSize(2);
+ assertThat(measureCache.entries()).hasSize(2);
- assertThat(cache.byResource(p)).hasSize(2);
+ assertThat(measureCache.byResource(p)).hasSize(2);
}
@Test
- public void should_add_measure_with_big_data() {
+ public void should_add_measure_with_big_data() throws InterruptedException {
Project p = new Project("struts");
- assertThat(cache.entries()).hasSize(0);
+ assertThat(measureCache.entries()).hasSize(0);
- assertThat(cache.byResource(p)).hasSize(0);
+ assertThat(measureCache.byResource(p)).hasSize(0);
Measure m = new Measure(CoreMetrics.NCLOC, 1.0).setDate(new Date());
m.setAlertText("foooooooooooooooooooooooooooooooooooo");
StringBuilder data = new StringBuilder();
- for (int i = 0; i < 1048575; i++) {
+ for (int i = 0; i < 1_048_575; i++) {
data.append("a");
}
+
m.setData(data.toString());
- cache.put(p, m);
+ measureCache.put(p, m);
- assertThat(cache.contains(p, m)).isTrue();
- assertThat(cache.entries()).hasSize(1);
- Iterator<Entry<Measure>> iterator = cache.entries().iterator();
+ assertThat(measureCache.contains(p, m)).isTrue();
+ assertThat(measureCache.entries()).hasSize(1);
+ Iterator<Entry<Measure>> iterator = measureCache.entries().iterator();
iterator.hasNext();
Entry<Measure> next = iterator.next();
assertThat(next.value()).isEqualTo(m);
assertThat(next.key()[0]).isEqualTo("struts");
- assertThat(cache.byResource(p)).hasSize(1);
- assertThat(cache.byResource(p).iterator().next()).isEqualTo(m);
+ assertThat(measureCache.byResource(p)).hasSize(1);
+ assertThat(measureCache.byResource(p).iterator().next()).isEqualTo(m);
RuleMeasure mRule = RuleMeasure.createForPriority(CoreMetrics.CRITICAL_VIOLATIONS, RulePriority.BLOCKER, 1.0);
mRule.setRuleKey(RuleKey.of("repo", "rule"));
- cache.put(p, mRule);
+ measureCache.put(p, mRule);
- assertThat(cache.entries()).hasSize(2);
+ assertThat(measureCache.entries()).hasSize(2);
}
/**
public void should_add_measure_with_too_big_data_for_persistit_pre_patch() {
Project p = new Project("struts");
- assertThat(cache.entries()).hasSize(0);
+ assertThat(measureCache.entries()).hasSize(0);
- assertThat(cache.byResource(p)).hasSize(0);
+ assertThat(measureCache.byResource(p)).hasSize(0);
Measure m = new Measure(CoreMetrics.NCLOC, 1.0).setDate(new Date());
StringBuilder data = new StringBuilder();
}
m.setData(data.toString());
- cache.put(p, m);
+ measureCache.put(p, m);
- assertThat(cache.contains(p, m)).isTrue();
- assertThat(cache.entries()).hasSize(1);
- Iterator<Entry<Measure>> iterator = cache.entries().iterator();
+ assertThat(measureCache.contains(p, m)).isTrue();
+ assertThat(measureCache.entries()).hasSize(1);
+ Iterator<Entry<Measure>> iterator = measureCache.entries().iterator();
iterator.hasNext();
Entry<Measure> next = iterator.next();
assertThat(next.value()).isEqualTo(m);
assertThat(next.key()[0]).isEqualTo("struts");
- assertThat(cache.byResource(p)).hasSize(1);
- assertThat(cache.byResource(p).iterator().next()).isEqualTo(m);
+ assertThat(measureCache.byResource(p)).hasSize(1);
+ assertThat(measureCache.byResource(p).iterator().next()).isEqualTo(m);
RuleMeasure mRule = RuleMeasure.createForPriority(CoreMetrics.CRITICAL_VIOLATIONS, RulePriority.BLOCKER, 1.0);
mRule.setRuleKey(RuleKey.of("repo", "rule"));
- cache.put(p, mRule);
+ measureCache.put(p, mRule);
- assertThat(cache.entries()).hasSize(2);
+ assertThat(measureCache.entries()).hasSize(2);
}
@Test
public void should_add_measure_with_too_big_data_for_persistit() {
Project p = new Project("struts");
- assertThat(cache.entries()).hasSize(0);
+ assertThat(measureCache.entries()).hasSize(0);
- assertThat(cache.byResource(p)).hasSize(0);
+ assertThat(measureCache.byResource(p)).hasSize(0);
Measure m = new Measure(CoreMetrics.NCLOC, 1.0).setDate(new Date());
StringBuilder data = new StringBuilder(64 * 1024 * 1024 + 1);
thrown.expect(IllegalStateException.class);
thrown.expectMessage("Fail to put element in the cache measures");
- cache.put(p, m);
+ measureCache.put(p, m);
}
@Test
public void should_add_measure_with_same_metric() {
Project p = new Project("struts");
- assertThat(cache.entries()).hasSize(0);
- assertThat(cache.byResource(p)).hasSize(0);
+ assertThat(measureCache.entries()).hasSize(0);
+ assertThat(measureCache.byResource(p)).hasSize(0);
Measure m1 = new Measure(CoreMetrics.NCLOC, 1.0);
Measure m2 = new Measure(CoreMetrics.NCLOC, 1.0).setCharacteristic(new DefaultCharacteristic().setKey("charac"));
Measure m3 = new Measure(CoreMetrics.NCLOC, 1.0).setPersonId(2);
Measure m4 = new RuleMeasure(CoreMetrics.NCLOC, RuleKey.of("repo", "rule"), RulePriority.BLOCKER, null);
- cache.put(p, m1);
- cache.put(p, m2);
- cache.put(p, m3);
- cache.put(p, m4);
+ measureCache.put(p, m1);
+ measureCache.put(p, m2);
+ measureCache.put(p, m3);
+ measureCache.put(p, m4);
- assertThat(cache.entries()).hasSize(4);
+ assertThat(measureCache.entries()).hasSize(4);
- assertThat(cache.byResource(p)).hasSize(4);
+ assertThat(measureCache.byResource(p)).hasSize(4);
}
@Test
Resource file1 = Directory.create("foo/bar/File1.txt").setEffectiveKey("struts:foo/bar/File1.txt");
Resource file2 = Directory.create("foo/bar/File2.txt").setEffectiveKey("struts:foo/bar/File2.txt");
- assertThat(cache.entries()).hasSize(0);
+ assertThat(measureCache.entries()).hasSize(0);
- assertThat(cache.byResource(p)).hasSize(0);
- assertThat(cache.byResource(dir)).hasSize(0);
+ assertThat(measureCache.byResource(p)).hasSize(0);
+ assertThat(measureCache.byResource(dir)).hasSize(0);
Measure mFile1 = new Measure(CoreMetrics.NCLOC, 1.0);
- cache.put(file1, mFile1);
+ measureCache.put(file1, mFile1);
Measure mFile2 = new Measure(CoreMetrics.NCLOC, 3.0);
- cache.put(file2, mFile2);
+ measureCache.put(file2, mFile2);
- assertThat(cache.entries()).hasSize(2);
- assertThat(cache.byResource(p)).hasSize(0);
- assertThat(cache.byResource(dir)).hasSize(0);
+ assertThat(measureCache.entries()).hasSize(2);
+ assertThat(measureCache.byResource(p)).hasSize(0);
+ assertThat(measureCache.byResource(dir)).hasSize(0);
Measure mDir = new Measure(CoreMetrics.NCLOC, 4.0);
- cache.put(dir, mDir);
+ measureCache.put(dir, mDir);
- assertThat(cache.entries()).hasSize(3);
- assertThat(cache.byResource(p)).hasSize(0);
- assertThat(cache.byResource(dir)).hasSize(1);
- assertThat(cache.byResource(dir).iterator().next()).isEqualTo(mDir);
+ assertThat(measureCache.entries()).hasSize(3);
+ assertThat(measureCache.byResource(p)).hasSize(0);
+ assertThat(measureCache.byResource(dir)).hasSize(1);
+ assertThat(measureCache.byResource(dir).iterator().next()).isEqualTo(mDir);
Measure mProj = new Measure(CoreMetrics.NCLOC, 4.0);
- cache.put(p, mProj);
+ measureCache.put(p, mProj);
- assertThat(cache.entries()).hasSize(4);
- assertThat(cache.byResource(p)).hasSize(1);
- assertThat(cache.byResource(p).iterator().next()).isEqualTo(mProj);
- assertThat(cache.byResource(dir)).hasSize(1);
- assertThat(cache.byResource(dir).iterator().next()).isEqualTo(mDir);
+ assertThat(measureCache.entries()).hasSize(4);
+ assertThat(measureCache.byResource(p)).hasSize(1);
+ assertThat(measureCache.byResource(p).iterator().next()).isEqualTo(mProj);
+ assertThat(measureCache.byResource(dir)).hasSize(1);
+ assertThat(measureCache.byResource(dir).iterator().next()).isEqualTo(mDir);
}
@Test
Resource file1 = File.create("foo/bar/File1.txt").setEffectiveKey("struts:foo/bar/File1.txt");
Measure measure = new Measure(CoreMetrics.NCLOC, 1.786, 5);
- cache.put(file1, measure);
+ measureCache.put(file1, measure);
- Measure savedMeasure = cache.byResource(file1).iterator().next();
+ Measure savedMeasure = measureCache.byResource(file1).iterator().next();
assertThat(EqualsBuilder.reflectionEquals(measure, savedMeasure)).isTrue();
measure.setVariation3(13.0);
measure.setVariation4(14.0);
measure.setVariation5(15.0);
- cache.put(file1, measure);
+ measureCache.put(file1, measure);
- savedMeasure = cache.byResource(file1).iterator().next();
+ savedMeasure = measureCache.byResource(file1).iterator().next();
assertThat(EqualsBuilder.reflectionEquals(measure, savedMeasure)).isTrue();
}
* @since 4.0
*/
String WORKING_DIRECTORY = "sonar.working.directory";
+
String WORKING_DIRECTORY_DEFAULT_VALUE = ".sonar";
+
+ /**
+ * @since 5.2
+ */
+ String GLOBAL_WORKING_DIRECTORY = "sonar.globalWorking.directory";
+ String GLOBAL_WORKING_DIRECTORY_DEFAULT_VALUE = ".";
+
/**
* @since 3.4
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.api.utils;
+
+import javax.annotation.Nullable;
+
+import java.io.File;
+
+import org.sonar.api.batch.BatchSide;
+
+
+/**
+ * Use this component to deal with temp files/folders that have a scope linked to each
+ * project analysis.
+ * Root location will typically be the working directory (see sonar.working.directory)
+
+ * @since 5.2
+ *
+ */
+@BatchSide
+public interface ProjectTempFolder {
+
+ /**
+ * Create a directory in temp folder with a random unique name.
+ */
+ File newDir();
+
+ /**
+ * Create a directory in temp folder using provided name.
+ */
+ File newDir(String name);
+
+ File newFile();
+
+ File newFile(@Nullable String prefix, @Nullable String suffix);
+
+}
\ No newline at end of file
* depends on situation:
* <ul>
* <li>${SONAR_HOME}/temp on server side</li>
- * <li>Working directory on batch side (see sonar.working.directory)</li>
+ * <li>${SONAR_HOME}/.sonartmp<rnd> on the batch side</li>
* </ul>
* @since 4.0
*
*/
package org.sonar.api.utils.internal;
+import org.sonar.api.utils.ProjectTempFolder;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.utils.TempFolder;
import java.io.IOException;
import java.text.MessageFormat;
-public class DefaultTempFolder implements TempFolder {
+public class DefaultTempFolder implements TempFolder, ProjectTempFolder {
/** Maximum loop count when creating temp directories. */
private static final int TEMP_DIR_ATTEMPTS = 10000;
private final File tempDir;
+ private final boolean cleanUp;
public DefaultTempFolder(File tempDir) {
+ this(tempDir, false);
+ }
+
+ public DefaultTempFolder(File tempDir, boolean cleanUp) {
this.tempDir = tempDir;
+ this.cleanUp = cleanUp;
}
@Override
FileUtils.deleteQuietly(tempDir);
}
+ public void stop() {
+ if(cleanUp) {
+ clean();
+ }
+ }
+
}
*/
package org.sonar.api.utils.internal;
+import org.sonar.api.utils.ProjectTempFolder;
+
import org.apache.commons.lang.StringUtils;
import org.junit.rules.ExternalResource;
import org.junit.rules.TemporaryFolder;
*
* @since 5.1
*/
-public class JUnitTempFolder extends ExternalResource implements TempFolder {
+public class JUnitTempFolder extends ExternalResource implements TempFolder, ProjectTempFolder {
private final TemporaryFolder junit = new TemporaryFolder();