Skip to content

Commit 25f3a5d

Browse files
Factorize analysis utilities for ITs, reduce flaky tests
Use a single Utils class to trigger analysis, wait for completion and for issues/hotpots raise calls, consume and return issues.
1 parent d7048c0 commit 25f3a5d

6 files changed

Lines changed: 197 additions & 251 deletions

File tree

its/tests/src/test/java/its/MockSonarLintRpcClientDelegate.java

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@
2121

2222
import java.net.URI;
2323
import java.net.URL;
24-
import java.util.HashMap;
2524
import java.util.List;
2625
import java.util.Map;
2726
import java.util.Set;
2827
import java.util.UUID;
2928
import java.util.concurrent.CancellationException;
29+
import java.util.concurrent.ConcurrentHashMap;
3030
import org.jetbrains.annotations.Nullable;
3131
import org.sonarsource.sonarlint.core.rpc.client.ConfigScopeNotFoundException;
3232
import org.sonarsource.sonarlint.core.rpc.client.ConnectionNotFoundException;
@@ -63,29 +63,25 @@
6363

6464
public class MockSonarLintRpcClientDelegate implements SonarLintRpcClientDelegate {
6565

66-
private final Map<String, Map<URI, List<RaisedIssueDto>>> raisedIssues = new HashMap<>();
67-
private final Map<String, Map<URI, List<RaisedHotspotDto>>> raisedHotspots = new HashMap<>();
66+
private final Map<String, Map<URI, List<RaisedIssueDto>>> raisedIssues = new ConcurrentHashMap<>();
67+
private final Map<String, Map<URI, List<RaisedHotspotDto>>> raisedHotspots = new ConcurrentHashMap<>();
6868

69-
public Map<URI, List<RaisedIssueDto>> getRaisedIssues(String configurationScopeId) {
70-
var issues = raisedIssues.get(configurationScopeId);
71-
return issues != null ? issues : Map.of();
69+
/**
70+
* @return null when raiseIssues was never called for the provided configurationScopeId.
71+
* Returns empty map if raiseIssues was called with no issues
72+
*/
73+
@Nullable
74+
public Map<URI, List<RaisedIssueDto>> takeRaisedIssues(String configurationScopeId) {
75+
return raisedIssues.remove(configurationScopeId);
7276
}
7377

74-
public Map<URI, List<RaisedHotspotDto>> getRaisedHotspots(String configurationScopeId) {
75-
var hotspots = raisedHotspots.get(configurationScopeId);
76-
return hotspots != null ? hotspots : Map.of();
77-
}
78-
79-
public Map<String, Map<URI, List<RaisedIssueDto>>> getRaisedIssues() {
80-
return raisedIssues;
81-
}
82-
83-
public List<RaisedIssueDto> getRaisedIssuesAsList(String configurationScopeId) {
84-
return raisedIssues.getOrDefault(configurationScopeId, new HashMap<>()).values().stream().flatMap(List::stream).toList();
85-
}
86-
87-
public List<RaisedHotspotDto> getRaisedHotspotsAsList(String configurationScopeId) {
88-
return raisedHotspots.getOrDefault(configurationScopeId, new HashMap<>()).values().stream().flatMap(List::stream).toList();
78+
/**
79+
* @return null when raiseHotspots was never called for the provided configurationScopeId.
80+
* Returns empty map if raiseHotspots was called with no hotspots
81+
*/
82+
@Nullable
83+
public Map<URI, List<RaisedHotspotDto>> takeRaisedHotspots(String configurationScopeId) {
84+
return raisedHotspots.remove(configurationScopeId);
8985
}
9086

9187
@Override
@@ -232,12 +228,16 @@ public void didChangeAnalysisReadiness(Set<String> configurationScopeIds, boolea
232228

233229
@Override
234230
public void raiseIssues(String configurationScopeId, Map<URI, List<RaisedIssueDto>> issuesByFileUri, boolean isIntermediatePublication, @Nullable UUID analysisId) {
235-
raisedIssues.computeIfAbsent(configurationScopeId, k -> new HashMap<>()).putAll(issuesByFileUri);
231+
if (!isIntermediatePublication) {
232+
raisedIssues.put(configurationScopeId, issuesByFileUri);
233+
}
236234
}
237235

238236
@Override
239237
public void raiseHotspots(String configurationScopeId, Map<URI, List<RaisedHotspotDto>> hotspotsByFileUri, boolean isIntermediatePublication, @Nullable UUID analysisId) {
240-
raisedHotspots.computeIfAbsent(configurationScopeId, k -> new HashMap<>()).putAll(hotspotsByFileUri);
238+
if (!isIntermediatePublication) {
239+
raisedHotspots.put(configurationScopeId, hotspotsByFileUri);
240+
}
241241
}
242242

243243
public void clear() {

its/tests/src/test/java/its/SonarCloudTests.java

Lines changed: 17 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
import java.util.Map;
3636
import java.util.Random;
3737
import java.util.Set;
38-
import java.util.UUID;
3938
import java.util.concurrent.ConcurrentHashMap;
4039
import java.util.concurrent.ExecutionException;
4140
import java.util.concurrent.TimeUnit;
@@ -71,10 +70,8 @@
7170
import org.sonarqube.ws.client.sources.RawRequest;
7271
import org.sonarsource.sonarlint.core.rpc.client.ClientJsonRpcLauncher;
7372
import org.sonarsource.sonarlint.core.rpc.client.ConnectionNotFoundException;
74-
import org.sonarsource.sonarlint.core.rpc.client.SonarLintRpcClientDelegate;
7573
import org.sonarsource.sonarlint.core.rpc.impl.BackendJsonRpcLauncher;
7674
import org.sonarsource.sonarlint.core.rpc.protocol.SonarLintRpcServer;
77-
import org.sonarsource.sonarlint.core.rpc.protocol.backend.analysis.AnalyzeFilesAndTrackParams;
7875
import org.sonarsource.sonarlint.core.rpc.protocol.backend.analysis.ShouldUseEnterpriseCSharpAnalyzerParams;
7976
import org.sonarsource.sonarlint.core.rpc.protocol.backend.branch.GetMatchedSonarProjectBranchParams;
8077
import org.sonarsource.sonarlint.core.rpc.protocol.backend.config.binding.BindingConfigurationDto;
@@ -89,7 +86,6 @@
8986
import org.sonarsource.sonarlint.core.rpc.protocol.backend.connection.projects.GetAllProjectsParams;
9087
import org.sonarsource.sonarlint.core.rpc.protocol.backend.connection.projects.SonarProjectDto;
9188
import org.sonarsource.sonarlint.core.rpc.protocol.backend.connection.validate.ValidateConnectionParams;
92-
import org.sonarsource.sonarlint.core.rpc.protocol.backend.file.DidUpdateFileSystemParams;
9389
import org.sonarsource.sonarlint.core.rpc.protocol.backend.hotspot.HotspotStatus;
9490
import org.sonarsource.sonarlint.core.rpc.protocol.backend.initialize.BackendCapability;
9591
import org.sonarsource.sonarlint.core.rpc.protocol.backend.initialize.HttpConfigurationDto;
@@ -99,10 +95,8 @@
9995
import org.sonarsource.sonarlint.core.rpc.protocol.backend.rules.GetEffectiveRuleDetailsParams;
10096
import org.sonarsource.sonarlint.core.rpc.protocol.backend.tracking.ListAllParams;
10197
import org.sonarsource.sonarlint.core.rpc.protocol.client.hotspot.RaisedHotspotDto;
102-
import org.sonarsource.sonarlint.core.rpc.protocol.client.issue.RaisedIssueDto;
10398
import org.sonarsource.sonarlint.core.rpc.protocol.client.log.LogParams;
10499
import org.sonarsource.sonarlint.core.rpc.protocol.common.CleanCodeAttribute;
105-
import org.sonarsource.sonarlint.core.rpc.protocol.common.ClientFileDto;
106100
import org.sonarsource.sonarlint.core.rpc.protocol.common.Either;
107101
import org.sonarsource.sonarlint.core.rpc.protocol.common.ImpactSeverity;
108102
import org.sonarsource.sonarlint.core.rpc.protocol.common.RuleType;
@@ -111,6 +105,8 @@
111105
import org.sonarsource.sonarlint.core.rpc.protocol.common.TokenDto;
112106
import org.sonarsource.sonarlint.core.rpc.protocol.common.UsernamePasswordDto;
113107

108+
import static its.utils.AnalysisUtils.analyzeAndAwaitHotspots;
109+
import static its.utils.AnalysisUtils.analyzeAndAwaitIssues;
114110
import static java.util.Collections.emptyList;
115111
import static java.util.Collections.emptyMap;
116112
import static java.util.Collections.emptySet;
@@ -156,7 +152,7 @@ class SonarCloudTests extends AbstractConnectedTests {
156152
private static int randomPositiveInt;
157153

158154
private static SonarLintRpcServer backend;
159-
private static SonarLintRpcClientDelegate client;
155+
private static MockSonarLintRpcClientDelegate client;
160156
private static final Set<String> openedConfigurationScopeIds = new HashSet<>();
161157
private static final Map<String, Boolean> analysisReadinessByConfigScopeId = new ConcurrentHashMap<>();
162158

@@ -205,7 +201,7 @@ static void cleanup() throws Exception {
205201
try (var response = adminWsClient.wsConnector().call(request)) {
206202
assertIsOk(response);
207203
}
208-
((MockSonarLintRpcClientDelegate) client).clear();
204+
client.clear();
209205
backend.shutdown().get();
210206
}
211207

@@ -332,7 +328,7 @@ void analysisJavascript() {
332328

333329
openBoundConfigurationScope(configScopeId, projectKeyJs);
334330
waitForAnalysisToBeReady(configScopeId);
335-
var issues = analyzeAndGetIssues(projectKeyJs, "src/Person.js", configScopeId);
331+
var issues = analyzeAndAwaitIssues(backend, client, configScopeId, Path.of("projects", projectKeyJs), "src/Person.js");
336332
assertThat(issues).hasSize(1);
337333
}
338334

@@ -347,7 +343,7 @@ void analysisPHP() {
347343
openBoundConfigurationScope(configScopeId, projectKeyPhp);
348344
waitForAnalysisToBeReady(configScopeId);
349345

350-
var issues = analyzeAndGetIssues(projectKeyPhp, "src/Math.php", configScopeId);
346+
var issues = analyzeAndAwaitIssues(backend, client, configScopeId, Path.of("projects", projectKeyPhp), "src/Math.php");
351347
assertThat(issues).hasSize(1);
352348
}
353349

@@ -362,7 +358,7 @@ void analysisPython() {
362358
openBoundConfigurationScope(configScopeId, projectKeyPython);
363359
waitForAnalysisToBeReady(configScopeId);
364360

365-
var issues = analyzeAndGetIssues(projectKeyPython, "src/hello.py", configScopeId);
361+
var issues = analyzeAndAwaitIssues(backend, client, configScopeId, Path.of("projects", projectKeyPython), "src/hello.py");
366362
assertThat(issues).hasSize(1);
367363
}
368364

@@ -377,7 +373,7 @@ void analysisWeb() {
377373
openBoundConfigurationScope(configScopeId, projectKey);
378374
waitForAnalysisToBeReady(configScopeId);
379375

380-
var issues = analyzeAndGetIssues(projectKey, "src/file.html", configScopeId);
376+
var issues = analyzeAndAwaitIssues(backend, client, configScopeId, Path.of("projects", projectKey), "src/file.html");
381377

382378
assertThat(issues).hasSize(1);
383379
}
@@ -387,7 +383,7 @@ void analysisWeb() {
387383
void analysisUseConfiguration() {
388384
var configScopeId = "analysisUseConfiguration";
389385
openUnboundConfigurationScope(configScopeId);
390-
var issues = analyzeAndGetIssues(PROJECT_KEY_JAVA, "src/main/java/foo/Foo.java", configScopeId,
386+
var issues = analyzeAndAwaitIssues(backend, client, configScopeId, Path.of("projects", PROJECT_KEY_JAVA), "src/main/java/foo/Foo.java",
391387
"sonar.java.binaries", new File("projects/sample-java/target/classes").getAbsolutePath());
392388
assertThat(issues).hasSize(2);
393389

@@ -398,7 +394,7 @@ void analysisUseConfiguration() {
398394
backend.getConfigurationService().didUpdateBinding(new DidUpdateBindingParams(configScopeId, new BindingConfigurationDto(CONNECTION_ID, projectKey(PROJECT_KEY_JAVA), true)));
399395
waitForAnalysisToBeReady(configScopeId);
400396

401-
issues = analyzeAndGetIssues(PROJECT_KEY_JAVA, "src/main/java/foo/Foo.java", configScopeId,
397+
issues = analyzeAndAwaitIssues(backend, client, configScopeId, Path.of("projects", PROJECT_KEY_JAVA), "src/main/java/foo/Foo.java",
402398
"sonar.java.binaries", new File("projects/sample-java/target/classes").getAbsolutePath());
403399
assertThat(issues).isEmpty();
404400
} finally {
@@ -436,7 +432,7 @@ void analysisRuby() {
436432
openBoundConfigurationScope(configScopeId, projectKeyRuby);
437433
waitForAnalysisToBeReady(configScopeId);
438434

439-
var issues = analyzeAndGetIssues(projectKeyRuby, "src/hello.rb", configScopeId);
435+
var issues = analyzeAndAwaitIssues(backend, client, configScopeId, Path.of("projects", projectKeyRuby), "src/hello.rb");
440436
assertThat(issues).hasSize(1);
441437
}
442438

@@ -451,7 +447,7 @@ void analysisKotlin() {
451447
openBoundConfigurationScope(configScopeId, projectKeyKotlin);
452448
waitForAnalysisToBeReady(configScopeId);
453449

454-
var issues = analyzeAndGetIssues(projectKeyKotlin, "src/hello.kt", configScopeId);
450+
var issues = analyzeAndAwaitIssues(backend, client, configScopeId, Path.of("projects", projectKeyKotlin), "src/hello.kt");
455451
assertThat(issues).hasSize(1);
456452
}
457453

@@ -466,7 +462,7 @@ void analysisScala() {
466462
openBoundConfigurationScope(configScopeId, projectKeyScala);
467463
waitForAnalysisToBeReady(configScopeId);
468464

469-
var issues = analyzeAndGetIssues(projectKeyScala, "src/Hello.scala", configScopeId);
465+
var issues = analyzeAndAwaitIssues(backend, client, configScopeId, Path.of("projects", projectKeyScala), "src/Hello.scala");
470466
assertThat(issues).hasSize(1);
471467
}
472468

@@ -481,7 +477,7 @@ void analysisXml() {
481477
openBoundConfigurationScope(configScopeId, projectKeyXml);
482478
waitForAnalysisToBeReady(configScopeId);
483479

484-
var issues = analyzeAndGetIssues(projectKeyXml, "src/foo.xml", configScopeId);
480+
var issues = analyzeAndAwaitIssues(backend, client, configScopeId, Path.of("projects", projectKeyXml), "src/foo.xml");
485481
assertThat(issues).hasSize(1);
486482
}
487483

@@ -525,7 +521,7 @@ void reportHotspots() {
525521
openBoundConfigurationScope(configScopeId, PROJECT_KEY_JAVA_HOTSPOT);
526522
waitForAnalysisToBeReady(configScopeId);
527523

528-
var issues = analyzeAndGetHotspots(PROJECT_KEY_JAVA_HOTSPOT, "src/main/java/foo/Foo.java", configScopeId);
524+
var issues = analyzeAndAwaitHotspots(backend, client, configScopeId, Path.of("projects", PROJECT_KEY_JAVA_HOTSPOT), "src/main/java/foo/Foo.java");
529525
assertThat(issues)
530526
.extracting(RaisedHotspotDto::getRuleKey, h -> h.getSeverityMode().getLeft().getType())
531527
.containsExactly(tuple("java:S4792", RuleType.SECURITY_HOTSPOT));
@@ -547,7 +543,7 @@ void shouldMatchServerSecurityHotspots() {
547543
openBoundConfigurationScope(configScopeId, PROJECT_KEY_JAVA_HOTSPOT);
548544
waitForAnalysisToBeReady(configScopeId);
549545

550-
var raisedHotspots = analyzeAndGetHotspots(PROJECT_KEY_JAVA_HOTSPOT, "src/main/java/foo/Foo.java", configScopeId);
546+
var raisedHotspots = analyzeAndAwaitHotspots(backend, client, configScopeId, Path.of("projects", PROJECT_KEY_JAVA_HOTSPOT), "src/main/java/foo/Foo.java");
551547

552548
assertThat(raisedHotspots).hasSize(1);
553549
assertThat(raisedHotspots.get(0).getStatus()).isEqualTo(HotspotStatus.TO_REVIEW);
@@ -692,7 +688,7 @@ private static void assertIsOk(WsResponse response) {
692688
.isBetween(200, 399);
693689
}
694690

695-
private static SonarLintRpcClientDelegate newDummySonarLintClient() {
691+
private static MockSonarLintRpcClientDelegate newDummySonarLintClient() {
696692
return new MockSonarLintRpcClientDelegate() {
697693

698694
@Override
@@ -716,36 +712,4 @@ public void log(LogParams params) {
716712
};
717713
}
718714

719-
private static List<RaisedIssueDto> analyzeAndGetIssues(String projectKey, String fileName, String configScopeId, String... properties) {
720-
final var baseDir = Paths.get("projects/" + projectKey).toAbsolutePath();
721-
final var filePath = baseDir.resolve(fileName);
722-
backend.getFileService().didUpdateFileSystem(new DidUpdateFileSystemParams(
723-
List.of(new ClientFileDto(filePath.toUri(), Path.of(fileName), configScopeId, false, null, filePath, null, null, true)),
724-
List.of(),
725-
List.of()));
726-
727-
var analyzeResponse = backend.getAnalysisService().analyzeFilesAndTrack(
728-
new AnalyzeFilesAndTrackParams(configScopeId, UUID.randomUUID(), List.of(filePath.toUri()), toMap(properties), true, System.currentTimeMillis())).join();
729-
730-
assertThat(analyzeResponse.getFailedAnalysisFiles()).isEmpty();
731-
var raisedIssues = ((MockSonarLintRpcClientDelegate) client).getRaisedIssues(configScopeId);
732-
((MockSonarLintRpcClientDelegate) client).getRaisedIssues().clear();
733-
return raisedIssues != null ? raisedIssues.values().stream().flatMap(List::stream).toList() : List.of();
734-
}
735-
736-
private static List<RaisedHotspotDto> analyzeAndGetHotspots(String projectKey, String fileName, String configScopeId, String... properties) {
737-
final var baseDir = Paths.get("projects/" + projectKey).toAbsolutePath();
738-
final var filePath = baseDir.resolve(fileName);
739-
backend.getFileService().didUpdateFileSystem(new DidUpdateFileSystemParams(List.of(),
740-
List.of(new ClientFileDto(filePath.toUri(), Path.of(fileName), configScopeId, false, null, filePath, null, null, true)), List.of()));
741-
742-
var analyzeResponse = backend.getAnalysisService().analyzeFilesAndTrack(
743-
new AnalyzeFilesAndTrackParams(configScopeId, UUID.randomUUID(), List.of(filePath.toUri()), toMap(properties), true, System.currentTimeMillis())).join();
744-
745-
assertThat(analyzeResponse.getFailedAnalysisFiles()).isEmpty();
746-
var raisedHotspots = ((MockSonarLintRpcClientDelegate) client).getRaisedHotspots(configScopeId);
747-
((MockSonarLintRpcClientDelegate) client).getRaisedIssues().clear();
748-
return raisedHotspots != null ? raisedHotspots.values().stream().flatMap(List::stream).toList() : List.of();
749-
}
750-
751715
}

0 commit comments

Comments
 (0)