Skip to content

Commit 3839043

Browse files
committed
SONARPY-2429: Merge the ruling and the extended ruling (#2232)
1 parent a090b60 commit 3839043

File tree

2,429 files changed

+331681
-74
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

2,429 files changed

+331681
-74
lines changed

.cirrus.yml

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -184,29 +184,6 @@ ruling_task:
184184
- mvn verify -Dsonar.runtimeVersion=LATEST_RELEASE -Dmaven.test.redirectTestOutputToFile=false -B -e -V -Dtest=PythonRulingTest
185185
cleanup_before_cache_script: cleanup_maven_repository
186186

187-
extended_ruling_task:
188-
depends_on:
189-
- build
190-
<<: *ONLY_SONARSOURCE_QA
191-
eks_container:
192-
<<: *QA_CONTAINER_DEFINITION
193-
cpu: 4
194-
memory: 8G
195-
env:
196-
CIRRUS_CLONE_DEPTH: 10
197-
SONARSOURCE_QA: true
198-
maven_cache:
199-
folder: ${CIRRUS_WORKING_DIR}/.m2/repository
200-
<<: *ORCHESTRATOR_CACHE_DEFINITION
201-
submodules_script:
202-
- git submodule update --init
203-
ruling_script:
204-
- source cirrus-env QA
205-
- source set_maven_build_version $BUILD_NUMBER
206-
- cd its/ruling
207-
- mvn verify -Dsonar.runtimeVersion=LATEST_RELEASE -Dmaven.test.redirectTestOutputToFile=false -B -e -V -Dtest=PythonExtendedRulingTest
208-
cleanup_before_cache_script: cleanup_maven_repository
209-
210187
pr_analysis_qa_task:
211188
depends_on:
212189
- build

.gitmodules

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
[submodule "its/sources"]
2-
path = its/sources
1+
[submodule "its/sources_ruling"]
2+
path = its/sources_ruling
33
url = https://github.com/SonarCommunity/python-test-sources.git
4-
[submodule "its/sources_extended"]
5-
path = its/sources_extended
6-
url = https://github.com/SonarCommunity/python-test-sources.git
7-
branch = extended
4+
branch = master-temp
5+
shallow = true
86
[submodule "tools/typeshed_serializer/resources/typeshed"]
97
path = python-frontend/typeshed_serializer/resources/typeshed
108
url = https://github.com/python/typeshed.git
9+
shallow = true
1110
[submodule "tools/typeshed_serializer/resources/python-type-stubs"]
1211
path = python-frontend/typeshed_serializer/resources/python-type-stubs
1312
url = https://github.com/microsoft/python-type-stubs
13+
shallow = true

its/ruling/src/test/java/org/sonar/python/it/PythonRulingTest.java

Lines changed: 242 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -20,32 +20,26 @@
2020
import com.sonar.orchestrator.junit5.OrchestratorExtension;
2121
import com.sonar.orchestrator.locator.FileLocation;
2222
import java.io.File;
23+
import java.io.IOException;
2324
import java.nio.file.Files;
2425
import java.util.Collections;
25-
import java.util.List;
26-
import java.util.stream.Collectors;
2726
import org.junit.jupiter.api.BeforeAll;
2827
import org.junit.jupiter.api.Test;
2928
import org.junit.jupiter.api.extension.RegisterExtension;
30-
import org.sonarqube.ws.Issues;
31-
import org.sonarqube.ws.client.HttpConnector;
32-
import org.sonarqube.ws.client.WsClient;
33-
import org.sonarqube.ws.client.WsClientFactories;
34-
import org.sonarqube.ws.client.issues.SearchRequest;
3529
import org.sonarsource.analyzer.commons.ProfileGenerator;
3630

3731
import static java.nio.charset.StandardCharsets.UTF_8;
38-
import static java.util.Collections.singletonList;
3932
import static org.assertj.core.api.Assertions.assertThat;
4033
import static org.sonar.python.it.RulingHelper.getOrchestrator;
4134

35+
// Ruling test for bug rules, to ensure they are properly tested without slowing down the CI
4236
class PythonRulingTest {
4337

44-
public static final String PROJECT_KEY = "project";
45-
4638
@RegisterExtension
4739
public static final OrchestratorExtension ORCHESTRATOR = getOrchestrator();
4840

41+
private static final String PROFILE_NAME = "rules";
42+
4943
@BeforeAll
5044
static void prepare_quality_profile() {
5145
ProfileGenerator.RulesConfiguration parameters = new ProfileGenerator.RulesConfiguration()
@@ -59,47 +53,252 @@ static void prepare_quality_profile() {
5953
}
6054

6155
@Test
62-
void test() throws Exception {
63-
ORCHESTRATOR.getServer().provisionProject(PROJECT_KEY, PROJECT_KEY);
64-
ORCHESTRATOR.getServer().associateProjectToQualityProfile(PROJECT_KEY, "py", "rules");
65-
ORCHESTRATOR.getServer().associateProjectToQualityProfile(PROJECT_KEY, "ipynb", "rules");
66-
File litsDifferencesFile = FileLocation.of("target/differences").getFile();
67-
SonarScanner build = SonarScanner.create(FileLocation.of("../sources").getFile())
68-
.setProjectKey(PROJECT_KEY)
69-
.setProjectName(PROJECT_KEY)
70-
.setProjectVersion("1")
71-
.setSourceEncoding("UTF-8")
72-
.setSourceDirs(".")
73-
.setProperty("sonar.lits.dump.old", FileLocation.of("src/test/resources/expected").getFile().getAbsolutePath())
74-
.setProperty("sonar.lits.dump.new", FileLocation.of("target/actual").getFile().getAbsolutePath())
75-
.setProperty("sonar.cpd.exclusions", "**/*")
76-
.setProperty("sonar.lits.differences", litsDifferencesFile.getAbsolutePath())
77-
.setProperty("sonar.internal.analysis.failFast", "true")
78-
.setEnvironmentVariable("SONAR_RUNNER_OPTS", "-Xmx2000m");
79-
ORCHESTRATOR.executeBuild(build);
56+
void test_airflow() throws IOException {
57+
SonarScanner build = buildWithCommonProperties("airflow");
58+
build.setProperty("sonar.sources", "airflow");
59+
build.setProperty("sonar.tests", "tests");
60+
executeBuild(build);
61+
}
62+
63+
@Test
64+
void test_archery() throws IOException {
65+
executeBuild(buildWithCommonProperties("Archery"));
66+
}
8067

81-
String issueDifferences = issues(PROJECT_KEY).stream()
82-
.map(i -> String.join("\t", i.getRule(), "" + i.getSeverity(), i.getComponent(), "" + i.getLine()))
83-
.collect(Collectors.joining("\n"));
84-
assertThat(issueDifferences).isEmpty();
68+
@Test
69+
void test_autokeras() throws IOException {
70+
executeBuild(buildWithCommonProperties("autokeras"));
71+
}
8572

86-
String litsDifferences = new String(Files.readAllBytes(litsDifferencesFile.toPath()), UTF_8);
87-
assertThat(litsDifferences).isEmpty();
73+
@Test
74+
void test_biopython() throws IOException {
75+
executeBuild(buildWithCommonProperties("biopython"));
76+
}
77+
78+
@Test
79+
void test_black() throws IOException {
80+
SonarScanner build = buildWithCommonProperties("black");
81+
build.setProperty("sonar.sources", "src");
82+
build.setProperty("sonar.tests", "tests");
83+
build.setProperty("sonar.test.exclusions", "tests/data/async_as_identifier.py");
84+
executeBuild(build);
85+
}
86+
87+
@Test
88+
void test_buildbot() throws IOException {
89+
SonarScanner build = buildWithCommonProperties("buildbot","buildbot-0.8.6p1");
90+
build.setProperty("sonar.sources", "buildbot");
91+
build.setProperty("sonar.tests", "contrib");
92+
executeBuild(build);
93+
}
94+
95+
@Test
96+
void test_buildbot_slave() throws IOException {
97+
SonarScanner build = buildWithCommonProperties("buildbot-slave", "buildbot-slave-0.8.6p1");
98+
build.setProperty("sonar.sources", "buildslave");
99+
build.setProperty("sonar.tests", "contrib");
100+
executeBuild(build);
101+
}
102+
103+
@Test
104+
void test_calibre() throws IOException {
105+
SonarScanner build = buildWithCommonProperties("calibre");
106+
build.setProperty("sonar.sources", "src");
107+
executeBuild(build);
108+
}
109+
110+
@Test
111+
void test_celery() throws IOException {
112+
SonarScanner build = buildWithCommonProperties("celery");
113+
build.setProperty("sonar.sources", "celery");
114+
build.setProperty("sonar.tests", "t");
115+
executeBuild(build);
116+
}
117+
118+
@Test
119+
void test_chalice() throws IOException {
120+
SonarScanner build = buildWithCommonProperties("chalice");
121+
build.setProperty("sonar.sources", "chalice");
122+
build.setProperty("sonar.tests", "tests");
123+
executeBuild(build);
124+
}
125+
126+
@Test
127+
void test_django() throws IOException {
128+
SonarScanner build = buildWithCommonProperties("django", "django-2.2.3");
129+
build.setProperty("sonar.sources", "django");
130+
executeBuild(build);
131+
}
132+
133+
@Test
134+
void test_django_cms() throws IOException {
135+
SonarScanner build = buildWithCommonProperties("django-cms", "django-cms-3.7.1");
136+
build.setProperty("sonar.sources", "cms");
137+
build.setProperty("sonar.test", "cms/tests");
138+
executeBuild(build);
139+
}
140+
141+
@Test
142+
void test_django_shop() throws IOException {
143+
SonarScanner build = buildWithCommonProperties("django-shop");
144+
build.setProperty("sonar.sources", "shop");
145+
build.setProperty("sonar.tests", "tests");
146+
executeBuild(build);
147+
}
148+
149+
@Test
150+
void test_docker_compose() throws IOException {
151+
SonarScanner build = buildWithCommonProperties("docker-compose", "docker-compose-1.24.1");
152+
build.setProperty("sonar.sources", "compose");
153+
build.setProperty("sonar.tests", "tests");
154+
executeBuild(build);
155+
}
156+
157+
@Test
158+
void test_indico() throws IOException {
159+
SonarScanner build = buildWithCommonProperties("indico");
160+
build.setProperty("sonar.sources", "indico");
161+
executeBuild(build);
88162
}
89163

90-
static WsClient newWsClient() {
91-
return newWsClient(null, null);
164+
@Test
165+
void test_keras_tutorials() throws IOException {
166+
executeBuild(buildWithCommonProperties("keras-tutorials"));
167+
}
168+
169+
@Test
170+
void test_LibCST() throws IOException {
171+
SonarScanner build = buildWithCommonProperties("LibCST");
172+
build.setProperty("sonar.sources", "libcst");
173+
build.setProperty("sonar.tests", "libcst/tests");
174+
build.setProperty("sonar.test.inclusions", "**/");
175+
executeBuild(build);
176+
}
177+
178+
@Test
179+
void test_mypy() throws IOException {
180+
SonarScanner build = buildWithCommonProperties("mypy", "mypy-0.782");
181+
build.setProperty("sonar.sources", "mypy,mypyc");
182+
build.setProperty("sonar.exclusions", "**/test/**/*");
183+
build.setProperty("sonar.tests", "mypy/test,mypyc/test");
184+
executeBuild(build);
185+
}
186+
187+
@Test
188+
void test_nltk() throws IOException {
189+
SonarScanner build = buildWithCommonProperties("nltk");
190+
build.setProperty("sonar.sources", ".");
191+
build.setProperty("sonar.exclusions", "**/test/**/*");
192+
executeBuild(build);
193+
}
194+
195+
@Test
196+
void test_numpy() throws IOException {
197+
SonarScanner build = buildWithCommonProperties("numpy", "numpy-1.16.4");
198+
build.setProperty("sonar.sources", "numpy");
199+
build.setProperty("sonar.exclusions", "**/tests/**/*");
200+
build.setProperty("sonar.tests", "numpy/tests");
201+
executeBuild(build);
202+
}
203+
204+
@Test
205+
void test_pecos() throws IOException {
206+
SonarScanner build = buildWithCommonProperties("pecos");
207+
build.setProperty("sonar.sources", "pecos");
208+
build.setProperty("sonar.tests", "test");
209+
executeBuild(build);
210+
}
211+
212+
@Test
213+
void test_saleor() throws IOException {
214+
SonarScanner build = buildWithCommonProperties("saleor");
215+
build.setProperty("sonar.sources", "saleor");
216+
executeBuild(build);
217+
}
218+
219+
@Test
220+
void test_salt() throws IOException {
221+
SonarScanner build = buildWithCommonProperties("salt");
222+
// salt is not actually a Python 3.12 project. This is to ensure analysis is performed correctly when the parameter is set.
223+
build.setProperty("sonar.python.version", "3.12");
224+
build.setProperty("sonar.sources", "salt");
225+
build.setProperty("sonar.tests", "tests");
226+
executeBuild(build);
227+
}
228+
229+
@Test
230+
void test_scikit_learn() throws IOException {
231+
SonarScanner build = buildWithCommonProperties("scikit-learn");
232+
build.setProperty("sonar.sources", "sklearn");
233+
executeBuild(build);
234+
}
235+
236+
@Test
237+
void test_specific_rules() throws IOException {
238+
// this tests is a hodgepodge of tests which are designed for specific rules
239+
executeBuild(buildWithCommonProperties("specific-rules"));
240+
}
241+
242+
@Test
243+
void test_tensorflow() throws IOException {
244+
SonarScanner build = buildWithCommonProperties("tensorflow");
245+
build.setProperty("sonar.sources", "python");
246+
executeBuild(build);
247+
}
248+
249+
@Test
250+
void test_timesketch() throws IOException {
251+
SonarScanner build = buildWithCommonProperties("timesketch");
252+
build.setProperty("sonar.sources", "timesketch");
253+
build.setProperty("sonar.test.inclusions", "**/*_test.py");
254+
executeBuild(build);
255+
}
256+
257+
@Test
258+
void test_tornado() throws IOException {
259+
SonarScanner build = buildWithCommonProperties("tornado", "tornado-2.3");
260+
build.setProperty("sonar.sources", "tornado");
261+
build.setProperty("sonar.exclusions", "**/test/**/*");
262+
build.setProperty("sonar.tests", "tornado/test");
263+
executeBuild(build);
264+
}
265+
266+
@Test
267+
void test_twisted() throws IOException {
268+
SonarScanner build = buildWithCommonProperties("twisted", "twisted-12.1.0");
269+
build.setProperty("sonar.sources", "twisted");
270+
build.setProperty("sonar.exclusions", "**/test/**/*");
271+
build.setProperty("sonar.tests", "twisted/test");
272+
executeBuild(build);
92273
}
93274

94-
static WsClient newWsClient(String login, String password) {
95-
return WsClientFactories.getDefault().newClient(HttpConnector.newBuilder()
96-
.url(ORCHESTRATOR.getServer().getUrl())
97-
.credentials(login, password)
98-
.build());
275+
276+
public SonarScanner buildWithCommonProperties(String projectKey) {
277+
return buildWithCommonProperties(projectKey, projectKey);
99278
}
100279

101-
static List<Issues.Issue> issues(String projectKey) {
102-
return newWsClient().issues().search(new SearchRequest().setProjects(singletonList(projectKey))).getIssuesList();
280+
public SonarScanner buildWithCommonProperties(String projectKey, String projectName) {
281+
ORCHESTRATOR.getServer().provisionProject(projectKey, projectKey);
282+
ORCHESTRATOR.getServer().associateProjectToQualityProfile(projectKey, "py", PROFILE_NAME);
283+
ORCHESTRATOR.getServer().associateProjectToQualityProfile(projectKey, "ipynb", PROFILE_NAME);
284+
return SonarScanner.create(FileLocation.of(String.format("../sources_ruling/%s", projectName)).getFile())
285+
.setProjectKey(projectKey)
286+
.setProjectName(projectKey)
287+
.setProjectVersion("1")
288+
.setSourceEncoding("UTF-8")
289+
.setSourceDirs(".")
290+
.setProperty("sonar.lits.dump.old", FileLocation.of(String.format("src/test/resources/expected_ruling/%s", projectKey)).getFile().getAbsolutePath())
291+
.setProperty("sonar.lits.dump.new", FileLocation.of(String.format("target/actual_ruling/%s", projectKey)).getFile().getAbsolutePath())
292+
.setProperty("sonar.cpd.exclusions", "**/*")
293+
.setProperty("sonar.internal.analysis.failFast", "true")
294+
.setEnvironmentVariable("SONAR_RUNNER_OPTS", "-Xmx2000m");
103295
}
104296

297+
void executeBuild(SonarScanner build) throws IOException {
298+
File litsDifferencesFile = FileLocation.of("target/differences").getFile();
299+
build.setProperty("sonar.lits.differences", litsDifferencesFile.getAbsolutePath());
300+
ORCHESTRATOR.executeBuild(build);
301+
String litsDifferences = new String(Files.readAllBytes(litsDifferencesFile.toPath()), UTF_8);
302+
assertThat(litsDifferences).isEmpty();
303+
}
105304
}

0 commit comments

Comments
 (0)