2020import com .sonar .orchestrator .junit5 .OrchestratorExtension ;
2121import com .sonar .orchestrator .locator .FileLocation ;
2222import java .io .File ;
23+ import java .io .IOException ;
2324import java .nio .file .Files ;
2425import java .util .Collections ;
25- import java .util .List ;
26- import java .util .stream .Collectors ;
2726import org .junit .jupiter .api .BeforeAll ;
2827import org .junit .jupiter .api .Test ;
2928import 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 ;
3529import org .sonarsource .analyzer .commons .ProfileGenerator ;
3630
3731import static java .nio .charset .StandardCharsets .UTF_8 ;
38- import static java .util .Collections .singletonList ;
3932import static org .assertj .core .api .Assertions .assertThat ;
4033import 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
4236class 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