Skip to content

Commit 402ad1b

Browse files
SCAN4NET-342 Prepare AnalysisContext (#2404)
1 parent 3ba8849 commit 402ad1b

File tree

5 files changed

+143
-29
lines changed

5 files changed

+143
-29
lines changed

its/src/test/java/com/sonar/it/scanner/msbuild/sonarqube/ScannerTest.java

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
*/
2020
package com.sonar.it.scanner.msbuild.sonarqube;
2121

22+
import com.sonar.it.scanner.msbuild.utils.AnalysisContext;
2223
import com.sonar.it.scanner.msbuild.utils.ScannerClassifier;
2324
import com.sonar.it.scanner.msbuild.utils.ScannerCommand;
2425
import com.sonar.it.scanner.msbuild.utils.TestUtils;
@@ -51,28 +52,23 @@ class ScannerTest {
5152
public Path basePath;
5253

5354
@Test
54-
void testSample() throws Exception {
55-
String projectKey = "testSample";
55+
void testSample() {
56+
var context = AnalysisContext.forServer("testSample", basePath, "ProjectUnderTest");
5657
ORCHESTRATOR.getServer().restoreProfile(FileLocation.of("projects/ProjectUnderTest/TestQualityProfile.xml"));
57-
ORCHESTRATOR.getServer().provisionProject(projectKey, projectKey);
58-
ORCHESTRATOR.getServer().associateProjectToQualityProfile(projectKey, "cs", "ProfileForTest");
59-
60-
String token = TestUtils.getNewToken(ORCHESTRATOR);
61-
62-
Path projectDir = TestUtils.projectDir(basePath, "ProjectUnderTest");
63-
TestUtils.newScannerBegin(ORCHESTRATOR, projectKey, projectDir, token).execute(ORCHESTRATOR);
64-
TestUtils.buildMSBuild(ORCHESTRATOR, projectDir);
65-
BuildResult result = TestUtils.executeEndStepAndDumpResults(ORCHESTRATOR, projectDir, projectKey, token);
58+
ORCHESTRATOR.getServer().provisionProject(context.projectKey, context.projectKey);
59+
ORCHESTRATOR.getServer().associateProjectToQualityProfile(context.projectKey, "cs", "ProfileForTest");
60+
var result = context.runAnalysis();
6661

6762
assertTrue(result.isSuccess());
68-
List<Issue> issues = TestUtils.projectIssues(ORCHESTRATOR, projectKey);
63+
List<Issue> issues = TestUtils.projectIssues(ORCHESTRATOR, context.projectKey);
6964
// 1 * csharpsquid:S1134 (line 34)
7065
assertThat(issues).hasSize(1);
71-
assertThat(TestUtils.getMeasureAsInteger(projectKey, "ncloc", ORCHESTRATOR)).isEqualTo(25);
72-
assertThat(TestUtils.getMeasureAsInteger(projectKey + ":ProjectUnderTest/Foo.cs", "ncloc", ORCHESTRATOR)).isEqualTo(25);
73-
assertThat(TestUtils.getMeasureAsInteger(projectKey + ":ProjectUnderTest/Foo.cs", "lines", ORCHESTRATOR)).isEqualTo(52);
66+
assertThat(TestUtils.getMeasureAsInteger(context.projectKey, "ncloc", ORCHESTRATOR)).isEqualTo(25);
67+
assertThat(TestUtils.getMeasureAsInteger(context.projectKey + ":ProjectUnderTest/Foo.cs", "ncloc", ORCHESTRATOR)).isEqualTo(25);
68+
assertThat(TestUtils.getMeasureAsInteger(context.projectKey + ":ProjectUnderTest/Foo.cs", "lines", ORCHESTRATOR)).isEqualTo(52);
7469
}
7570

71+
7672
@Test
7773
void testNoActiveRule() throws IOException {
7874
String projectKey = "testNoActiveRule";

its/src/test/java/com/sonar/it/scanner/msbuild/sonarqube/SolutionKindTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
*/
2020
package com.sonar.it.scanner.msbuild.sonarqube;
2121

22+
import com.sonar.it.scanner.msbuild.utils.AnalysisContext;
2223
import com.sonar.it.scanner.msbuild.utils.ScannerClassifier;
2324
import com.sonar.it.scanner.msbuild.utils.TestUtils;
2425
import com.sonar.orchestrator.build.BuildResult;
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* SonarScanner for .NET
3+
* Copyright (C) 2016-2025 SonarSource SA
4+
* mailto:info AT sonarsource DOT com
5+
*
6+
* This program is free software; you can redistribute it and/or
7+
* modify it under the terms of the GNU Lesser General Public
8+
* License as published by the Free Software Foundation; either
9+
* version 3 of the License, or (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
* Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public License
17+
* along with this program; if not, write to the Free Software Foundation,
18+
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19+
*/
20+
package com.sonar.it.scanner.msbuild.utils;
21+
22+
import com.sonar.it.scanner.msbuild.sonarcloud.CloudConstants;
23+
import com.sonar.it.scanner.msbuild.sonarqube.ServerTests;
24+
import com.sonar.orchestrator.Orchestrator;
25+
import java.nio.file.Path;
26+
import org.slf4j.Logger;
27+
import org.slf4j.LoggerFactory;
28+
29+
public class AnalysisContext {
30+
final static Logger LOG = LoggerFactory.getLogger(AnalysisContext.class);
31+
32+
public final Orchestrator orchestrator;
33+
public final String projectKey;
34+
public final Path projectDir;
35+
public final String token;
36+
public final ScannerCommand begin;
37+
public final ScannerCommand end;
38+
39+
public AnalysisContext(Orchestrator orchestrator, ScannerClassifier classifier, String projectKey, Path projectDir, String token) {
40+
this.orchestrator = orchestrator;
41+
this.projectKey = projectKey;
42+
this.projectDir = projectDir;
43+
this.token = token;
44+
begin = ScannerCommand.createBeginStep(classifier, token, projectDir, projectKey);
45+
end = ScannerCommand.createEndStep(classifier, token, projectDir);
46+
}
47+
48+
public static AnalysisContext forServer(String projectKey, Path temp, String directoryName) {
49+
return forServer(projectKey, temp, directoryName, ScannerClassifier.NET_FRAMEWORK);
50+
}
51+
52+
public static AnalysisContext forServer(String projectKey, Path temp, String directoryName, ScannerClassifier classifier) {
53+
return new AnalysisContext(ServerTests.ORCHESTRATOR, classifier, projectKey, TestUtils.projectDir(temp, directoryName), ServerTests.token());
54+
}
55+
56+
57+
public AnalysisResult runAnalysis() {
58+
var beginResult = begin.execute(orchestrator);
59+
// ToDo: NuGet vs Restore
60+
// ToDo: SCAN4NET-10 Use BuildCommand
61+
var buildResult = TestUtils.buildMSBuild(orchestrator, this.projectDir);
62+
var endResult = end.execute(orchestrator);
63+
if (endResult.isSuccess()) {
64+
TestUtils.dumpComponentList(orchestrator, projectKey);
65+
TestUtils.dumpProjectIssues(orchestrator, projectKey);
66+
} else {
67+
LOG.warn("End step was not successful - skipping dumping issues data");
68+
}
69+
return new AnalysisResult(beginResult, buildResult, endResult);
70+
}
71+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* SonarScanner for .NET
3+
* Copyright (C) 2016-2025 SonarSource SA
4+
* mailto:info AT sonarsource DOT com
5+
*
6+
* This program is free software; you can redistribute it and/or
7+
* modify it under the terms of the GNU Lesser General Public
8+
* License as published by the Free Software Foundation; either
9+
* version 3 of the License, or (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
* Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public License
17+
* along with this program; if not, write to the Free Software Foundation,
18+
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19+
*/
20+
package com.sonar.it.scanner.msbuild.utils;
21+
22+
import com.sonar.orchestrator.build.BuildResult;
23+
24+
public record AnalysisResult(BuildResult begin, BuildResult build, BuildResult end) {
25+
public boolean isSuccess() {
26+
return begin.isSuccess() && build.isSuccess() && end.isSuccess();
27+
}
28+
}

its/src/test/java/com/sonar/it/scanner/msbuild/utils/TestUtils.java

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -97,23 +97,23 @@ public static String developmentScannerVersion() {
9797
return "99";
9898
}
9999

100-
// ToDo: SCAN4NET-201: Remove Orchestrator
100+
// ToDo: SCAN4NET-201: Remove this, after SCAN4NET-320 or SCAN4NET199 will stop using it
101101
public static ScannerCommand newScannerBegin(Orchestrator orchestrator, String projectKey, Path projectDir, String token) {
102102
// ToDo: Cleanup inconsistent "end" logic. For now, this defaults to "end" step and caller must override it
103103
return ScannerCommand.createBeginStep(ScannerClassifier.NET_FRAMEWORK, token, projectDir, projectKey);
104104
}
105105

106-
// ToDo: SCAN4NET-201: Remove Orchestrator
106+
// ToDo: SCAN4NET-201: Remove this, after SCAN4NET-320 or SCAN4NET199 will stop using it
107107
public static ScannerCommand newScannerBegin(Orchestrator orchestrator, String projectKey, Path projectDir, String token, ScannerClassifier classifier) {
108108
return ScannerCommand.createBeginStep(classifier, token, projectDir, projectKey);
109109
}
110110

111-
// ToDo: SCAN4NET-201: Remove Orchestrator
111+
// ToDo: SCAN4NET-201: Remove this, after SCAN4NET-320 or SCAN4NET199 will stop using it
112112
public static ScannerCommand newScannerEnd(Orchestrator orchestrator, Path projectDir, String token) {
113113
return ScannerCommand.createEndStep(ScannerClassifier.NET_FRAMEWORK, token, projectDir);
114114
}
115115

116-
// ToDo: SCAN4NET-201: Remove Orchestrator
116+
// ToDo: SCAN4NET-201: Remove this, after SCAN4NET-320 or SCAN4NET199 will stop using it
117117
public static ScannerCommand newScannerEnd(Orchestrator orchestrator, Path projectDir, ScannerClassifier classifier, String token) {
118118
return ScannerCommand.createEndStep(classifier, token, projectDir);
119119
}
@@ -165,14 +165,18 @@ public static void deleteVirtualDrive(String drive) {
165165
assertThat(cleanupStatus).isZero();
166166
}
167167

168-
public static Path projectDir(Path temp, String projectName) throws IOException {
169-
File projectToCopy = Paths.get("projects").resolve(projectName).toFile();
170-
File destination = new File(temp.toFile(), projectName).getCanonicalFile();
171-
FileUtils.deleteDirectory(destination);
172-
Path newFolder = Files.createDirectories(destination.toPath());
173-
FileUtils.copyDirectory(projectToCopy, newFolder.toFile());
174-
Files.copy(Paths.get("..", "NuGet.Config"), newFolder.resolve("NuGet.Config"));
175-
return newFolder;
168+
public static Path projectDir(Path temp, String projectName) {
169+
try {
170+
File projectToCopy = Paths.get("projects").resolve(projectName).toFile();
171+
File destination = new File(temp.toFile(), projectName).getCanonicalFile();
172+
FileUtils.deleteDirectory(destination);
173+
Path newFolder = Files.createDirectories(destination.toPath());
174+
FileUtils.copyDirectory(projectToCopy, newFolder.toFile());
175+
Files.copy(Paths.get("..", "NuGet.Config"), newFolder.resolve("NuGet.Config"));
176+
return newFolder;
177+
} catch (IOException ex) {
178+
throw new RuntimeException(ex.getMessage(), ex);
179+
}
176180
}
177181

178182
public static void runMSBuildWithBuildWrapper(Orchestrator orch, Path projectDir, File buildWrapperPath, File outDir,
@@ -193,20 +197,24 @@ public static void updateSetting(Orchestrator orchestrator, String projectKey, S
193197
newWsClient(orchestrator).settings().set(new SetRequest().setComponent(projectKey).setKey(propertyKey).setValues(values));
194198
}
195199

200+
// ToDo: SCAN4NET-10 will move/deprecate/remove this in favor of BuildCommand
196201
public static void runMSBuild(Orchestrator orch, Path projectDir, String... arguments) {
197202
runMSBuild(orch, projectDir, Collections.emptyList(), TIMEOUT_LIMIT, arguments);
198203
}
199204

200-
public static void buildMSBuild(Orchestrator orchestrator, Path projectDir) {
201-
runMSBuild(orchestrator, projectDir, Collections.emptyList(), TIMEOUT_LIMIT, "/t:Restore,Rebuild");
205+
// ToDo: SCAN4NET-10 will move/deprecate/remove this in favor of BuildCommand
206+
public static BuildResult buildMSBuild(Orchestrator orchestrator, Path projectDir) {
207+
return runMSBuild(orchestrator, projectDir, Collections.emptyList(), TIMEOUT_LIMIT, "/t:Restore,Rebuild");
202208
}
203209

210+
// ToDo: SCAN4NET-10 will move/deprecate/remove this in favor of BuildCommand
204211
public static BuildResult runMSBuild(Orchestrator orch, Path projectDir, List<EnvironmentVariable> environmentVariables, long timeoutLimit, String... arguments) {
205212
BuildResult r = runMSBuildQuietly(orch, projectDir, environmentVariables, timeoutLimit, arguments);
206213
assertThat(r.isSuccess()).isTrue();
207214
return r;
208215
}
209216

217+
// ToDo: Move to AnalysisContext
210218
public static void runNuGet(Orchestrator orch, Path projectDir, Boolean useDefaultVSCodeMSBuild, String... arguments) {
211219
Path nugetPath = getNuGetPath(orch);
212220
var nugetRestore = Command.create(nugetPath.toString())
@@ -221,10 +229,12 @@ public static void runNuGet(Orchestrator orch, Path projectDir, Boolean useDefau
221229
assertThat(r).isZero();
222230
}
223231

232+
// ToDo: SCAN4NET-10 will move/deprecate/remove this in favor of BuildCommand
224233
public static BuildResult runDotnetCommand(Path workingDir, String dotnetCommand, String... arguments) {
225234
return runDotnetCommand(workingDir, Collections.emptyList(), dotnetCommand, arguments);
226235
}
227236

237+
// ToDo: SCAN4NET-10 will move/deprecate/remove this in favor of BuildCommand
228238
public static BuildResult runDotnetCommand(Path workingDir, List<EnvironmentVariable> environmentVariables, String dotnetCommand, String... arguments) {
229239
var argumentList = new ArrayList<>(Arrays.asList(arguments));
230240
argumentList.add(0, dotnetCommand);
@@ -255,6 +265,7 @@ private static Path getNuGetPath(Orchestrator orch) {
255265
return nugetPath;
256266
}
257267

268+
// ToDo: SCAN4NET-10 will move/deprecate/remove this in favor of BuildCommand
258269
private static BuildResult runMSBuildQuietly(Orchestrator orch, Path projectDir, List<EnvironmentVariable> environmentVariables, long timeoutLimit, String... arguments) {
259270
Path msBuildPath = getMsBuildPath(orch);
260271

@@ -316,6 +327,7 @@ public static void dumpProjectIssues(Orchestrator orchestrator, String projectKe
316327
}
317328
}
318329

330+
@Deprecated // Use AnalysisContext instead
319331
public static BuildResult runAnalysis(Path projectDir, String projectKey, Boolean useNuGet) {
320332
String token = TestUtils.getNewToken(ORCHESTRATOR);
321333
String folderName = projectDir.getFileName().toString();
@@ -327,15 +339,18 @@ public static BuildResult runAnalysis(Path projectDir, String projectKey, Boolea
327339
return TestUtils.executeEndStepAndDumpResults(ORCHESTRATOR, projectDir, projectKey, token);
328340
}
329341

342+
@Deprecated // Use AnalysisContext instead
330343
public static BuildResult executeEndStepAndDumpResults(Orchestrator orchestrator, Path projectDir, String projectKey, String token) {
331344
return executeEndStepAndDumpResults(orchestrator, projectDir, projectKey, token, ScannerClassifier.NET_FRAMEWORK, Collections.emptyList(), Collections.emptyList());
332345
}
333346

347+
@Deprecated // Use AnalysisContext instead
334348
public static BuildResult executeEndStepAndDumpResults(Orchestrator orchestrator, Path projectDir, String projectKey, String token,
335349
List<EnvironmentVariable> environmentVariables) {
336350
return executeEndStepAndDumpResults(orchestrator, projectDir, projectKey, token, ScannerClassifier.NET_FRAMEWORK, environmentVariables, Collections.emptyList());
337351
}
338352

353+
@Deprecated // Use AnalysisContext instead
339354
public static BuildResult executeEndStepAndDumpResults(
340355
Orchestrator orchestrator,
341356
Path projectDir,
@@ -346,6 +361,7 @@ public static BuildResult executeEndStepAndDumpResults(
346361
return executeEndStepAndDumpResults(orchestrator, projectDir, projectKey, token, ScannerClassifier.NET_FRAMEWORK, environmentVariables, additionalProperties);
347362
}
348363

364+
@Deprecated // Use AnalysisContext instead
349365
public static BuildResult executeEndStepAndDumpResults(Orchestrator orchestrator,
350366
Path projectDir,
351367
String projectKey,
@@ -408,6 +424,7 @@ public static String getNewToken(Orchestrator orchestrator) {
408424
return ServerTests.token();
409425
}
410426

427+
// ToDo: Remove this in SCAN4NET-290
411428
public static boolean hasModules(Orchestrator orch) {
412429
return !orch.getServer().version().isGreaterThanOrEquals(7, 6);
413430
}
@@ -468,6 +485,7 @@ private static List<String> extractCeTaskIds(BuildResult buildResult) {
468485
.collect(Collectors.toList());
469486
}
470487

488+
// ToDo: SCAN4NET-10 will deprecate/remove this. By using AnalysisContext and its environment variable handling, this will not be needed anymore
471489
private static Command initCommandEnvironment(Command command, List<EnvironmentVariable> environmentVariables) {
472490
var buildDirectory = environmentVariables.stream().filter(x -> x.name() == AzureDevOps.AGENT_BUILDDIRECTORY).findFirst();
473491
if (buildDirectory.isPresent()) {

0 commit comments

Comments
 (0)