testImplementation project(':plugins:sonar-xoo-plugin')
testImplementation 'org.wiremock:wiremock-standalone'
testImplementation 'org.junit-pioneer:junit-pioneer'
+ testImplementation 'org.awaitility:awaitility'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
testRuntimeOnly 'org.junit.vintage:junit-vintage-engine'
int nbFiles = 100;
int ruleCount = 100000;
+ String fileContent = StringUtils.repeat(StringUtils.repeat("a", 100) + "\n", ruleCount / 1000);
for (int nb = 1; nb <= nbFiles; nb++) {
File xooFile = new File(srcDir, "sample" + nb + ".xoo");
- FileUtils.write(xooFile, StringUtils.repeat(StringUtils.repeat("a", 100) + "\n", ruleCount / 1000));
+ FileUtils.write(xooFile, fileContent);
}
AnalysisResult result = tester.newAnalysis()
@Parameters(name = "SVN server version {0}, WC version {1}")
public static Iterable<Object[]> data() {
- return Arrays.asList(new Object[][] {{"1.6", 10}, {"1.7", 29}, {"1.8", 31}, {"1.9", 31}});
+ //TODO add tests for 1.14
+ return Arrays.asList(new Object[][] {{"1.6", 10}, {"1.9", 31}});
}
public SvnBlameCommandIT(String serverVersion, int wcVersion) {
*/
package org.sonar.scanner.bootstrap;
+import com.google.common.annotations.VisibleForTesting;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class ScannerPluginJarExploder extends PluginJarExploder {
+ private static long lockRetrySleep = 200L;
private final PluginFiles pluginFiles;
public ScannerPluginJarExploder(PluginFiles pluginFiles) {
return destDir;
}
+ @VisibleForTesting
+ static void setLockRetrySleep(long sleep) {
+ lockRetrySleep = sleep;
+ }
+
private static FileLock createLockWithRetries(FileChannel channel) throws IOException {
int tryCount = 0;
while (tryCount++ < 10) {
// ignore overlapping file exception
}
try {
- Thread.sleep(200L * tryCount);
+ Thread.sleep(lockRetrySleep * tryCount);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
*/
package org.sonar.scanner.qualitygate;
+import com.google.common.annotations.VisibleForTesting;
import java.io.InputStream;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
private static final Logger LOG = LoggerFactory.getLogger(QualityGateCheck.class);
private static final EnumSet<TaskStatus> TASK_TERMINAL_STATUSES = EnumSet.of(TaskStatus.SUCCESS, TaskStatus.FAILED, TaskStatus.CANCELED);
- private static final int POLLING_INTERVAL_IN_MS = 5000;
private final DefaultScannerWsClient wsClient;
private final GlobalAnalysisMode analysisMode;
private final CeTaskReportDataHolder ceTaskReportDataHolder;
private final ScanProperties properties;
+ private int pollingIntervalInSeconds = 5000;
private long qualityGateTimeoutInMs;
private boolean enabled;
}
}
+ @VisibleForTesting
+ void setPollingIntervalInSeconds(int pollingIntervalInSeconds) {
+ this.pollingIntervalInSeconds = pollingIntervalInSeconds;
+ }
+
private Ce.Task waitForCeTaskToFinish(String taskId) {
GetRequest getTaskResultReq = new GetRequest("api/ce/task")
.setMediaType(MediaTypes.PROTOBUF)
return task;
}
- Thread.sleep(POLLING_INTERVAL_IN_MS);
- currentTime += POLLING_INTERVAL_IN_MS;
+ Thread.sleep(pollingIntervalInSeconds);
+ currentTime += pollingIntervalInSeconds;
} catch (HttpException e) {
throw MessageException.of(String.format("Failed to get CE Task status - %s", DefaultScannerWsClient.createErrorMessage(e)));
} catch (InterruptedException e) {
PluginFiles pluginFiles = mock(PluginFiles.class);
when(pluginFiles.createTempDir()).thenReturn(tempDir);
underTest = new ScannerPluginJarExploder(pluginFiles);
+ underTest.setLockRetrySleep(5L);
}
@Test
@BeforeEach
void before() {
underTest = new QualityGateCheck(wsClient, analysisMode, reportMetadataHolder, properties);
+ underTest.setPollingIntervalInSeconds(200);
logTester.setLevel(Level.DEBUG);
}
package org.sonar.scanner.util;
import java.util.Set;
+import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
+import org.awaitility.Awaitility;
+import org.awaitility.core.ConditionTimeoutException;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.DisableOnDebug;
}
@Test
- public void do_log() throws InterruptedException {
+ public void do_log() {
logTester.setLevel(Level.DEBUG);
underTest.start("start");
underTest.message("Some message");
boolean logged = false;
- Thread.sleep(2000);
while (!logged) {
- logged = logTester.logs().contains("Some message");
+ logged = containsWithRetry("Some message");
}
underTest.stop("stop");
- Thread.sleep(1000);
- assertThat(logTester.logs().stream().anyMatch(s -> Pattern.matches("stop", s))).isTrue();
+ assertThat(containsWithRetry("stop")).isTrue();
+ }
+
+ private boolean containsWithRetry(String message) {
+ try {
+ Awaitility.await().atMost(5, TimeUnit.SECONDS).until(() -> logTester.logs().contains(message));
+ } catch (ConditionTimeoutException e) {
+ return false;
+ }
+ return true;
}
@Test
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.io.CleanupMode;
import org.junit.jupiter.api.io.TempDir;
import org.junit.jupiter.params.ParameterizedTest;
class CompositeBlameCommandIT {
+ private static final ProcessWrapperFactory processWrapperFactory = new ProcessWrapperFactory();
+ private static final NativeGitBlameCommand nativeGitBlameCommand = new NativeGitBlameCommand(System2.INSTANCE, processWrapperFactory);
+
private final AnalysisWarnings analysisWarnings = mock(AnalysisWarnings.class);
private final BlameCommand.BlameInput input = mock(BlameCommand.BlameInput.class);
private final JGitBlameCommand jGitBlameCommand = new JGitBlameCommand();
- private final ProcessWrapperFactory processWrapperFactory = new ProcessWrapperFactory();
- private final NativeGitBlameCommand nativeGitBlameCommand = new NativeGitBlameCommand(System2.INSTANCE, processWrapperFactory);
-
// In JUnit4, if the cleanup cannot be performed, the test would not fail. This has changed with JUnit5
// As we cannot find the cause of failure during cleanup, we disable it for now
@TempDir (cleanup = NEVER)
private File temp;
+ @BeforeAll
+ public static void setUp() {
+ // locating the git executable is a costly operation that can be done just once for all tests in this class
+ nativeGitBlameCommand.checkIfEnabled();
+ }
+
@ParameterizedTest
@MethodSource("namesOfTheTestRepositoriesWithBlameAlgorithm")
void testThatBlameAlgorithmOutputsTheSameDataAsGitNativeBlame(String folder, BlameAlgorithmEnum blameAlgorithm) throws Exception {
@Before
public void before() throws IOException, SVNException {
svnTester = new SvnTester(temp.newFolder().toPath());
-
- Path worktree = temp.newFolder().toPath();
- svnTester.checkout(worktree, "trunk");
- createAndCommitFile(worktree, "file-in-first-commit.xoo");
}
@Test
}
@Test
- public void branchChangedFiles_and_lines_from_diverged() throws IOException, SVNException {
+ public void branchChangedFiles_and_lines_from_diverged() throws IOException, SVNException, InterruptedException {
Path trunk = temp.newFolder().toPath();
svnTester.checkout(trunk, "trunk");
- createAndCommitFile(trunk, "file-m1.xoo");
- createAndCommitFile(trunk, "file-m2.xoo");
- createAndCommitFile(trunk, "file-m3.xoo");
- createAndCommitFile(trunk, "lao.txt", CONTENT_LAO);
+ createFile(trunk, "file-m1.xoo");
+ createFile(trunk, "file-m2.xoo");
+ createFile(trunk, "file-m3.xoo");
+ createFile(trunk, "lao.txt", CONTENT_LAO);
+ svnTester.commit(trunk);
// create branch from trunk
svnTester.createBranch("b1");
// still on trunk
- appendToAndCommitFile(trunk, "file-m3.xoo");
- createAndCommitFile(trunk, "file-m4.xoo");
+ svnTester.appendToFile(trunk, "file-m3.xoo");
+ createFile(trunk, "file-m4.xoo");
+ svnTester.commit(trunk);
Path b1 = temp.newFolder().toPath();
svnTester.checkout(b1, "branches/b1");
Files.createDirectories(b1.resolve("sub"));
- createAndCommitFile(b1, "sub/file-b1.xoo");
- appendToAndCommitFile(b1, "file-m1.xoo");
- deleteAndCommitFile(b1, "file-m2.xoo");
+ createFile(b1, "sub/file-b1.xoo");
+ svnTester.appendToFile(b1, "file-m1.xoo");
+ deleteFile(b1, "file-m2.xoo");
createAndCommitFile(b1, "file-m5.xoo");
- deleteAndCommitFile(b1, "file-m5.xoo");
+ deleteFile(b1, "file-m5.xoo");
svnCopyAndCommitFile(b1, "file-m1.xoo", "file-m1-copy.xoo");
- appendToAndCommitFile(b1, "file-m1.xoo");
+ svnTester.appendToFile(b1, "file-m1.xoo");
+ svnTester.commit(b1);
// modify file without committing it -> should not be included (think generated files)
svnTester.appendToFile(b1, "file-m3.xoo");
}
private void createAndCommitFile(Path worktree, String filename, String content) throws IOException, SVNException {
- svnTester.createFile(worktree, filename, content);
- svnTester.add(worktree, filename);
+ createFile(worktree, filename, content);
svnTester.commit(worktree);
}
createAndCommitFile(worktree, filename, filename + "\n");
}
- private void appendToAndCommitFile(Path worktree, String filename) throws IOException, SVNException {
- svnTester.appendToFile(worktree, filename);
- svnTester.commit(worktree);
+ private void createFile(Path worktree, String filename) throws IOException, SVNException {
+ svnTester.createFile(worktree, filename, filename + "\n");
+ svnTester.add(worktree, filename);
+ }
+
+ private void createFile(Path worktree, String filename, String content) throws IOException, SVNException {
+ svnTester.createFile(worktree, filename, content);
+ svnTester.add(worktree, filename);
}
- private void deleteAndCommitFile(Path worktree, String filename) throws SVNException {
+ private void deleteFile(Path worktree, String filename) throws SVNException {
svnTester.deleteFile(worktree, filename);
- svnTester.commit(worktree);
}
private void svnCopyAndCommitFile(Path worktree, String src, String dst) throws SVNException {