20
20
import com .sonar .orchestrator .junit5 .OrchestratorExtension ;
21
21
import com .sonar .orchestrator .locator .FileLocation ;
22
22
import java .io .File ;
23
+ import java .io .IOException ;
23
24
import java .nio .file .Files ;
24
25
import java .util .Collections ;
25
- import java .util .List ;
26
- import java .util .stream .Collectors ;
27
26
import org .junit .jupiter .api .BeforeAll ;
28
27
import org .junit .jupiter .api .Test ;
29
28
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 ;
35
29
import org .sonarsource .analyzer .commons .ProfileGenerator ;
36
30
37
31
import static java .nio .charset .StandardCharsets .UTF_8 ;
38
- import static java .util .Collections .singletonList ;
39
32
import static org .assertj .core .api .Assertions .assertThat ;
40
33
import static org .sonar .python .it .RulingHelper .getOrchestrator ;
41
34
35
+ // Ruling test for bug rules, to ensure they are properly tested without slowing down the CI
42
36
class PythonRulingTest {
43
37
44
- public static final String PROJECT_KEY = "project" ;
45
-
46
38
@ RegisterExtension
47
39
public static final OrchestratorExtension ORCHESTRATOR = getOrchestrator ();
48
40
41
+ private static final String PROFILE_NAME = "rules" ;
42
+
49
43
@ BeforeAll
50
44
static void prepare_quality_profile () {
51
45
ProfileGenerator .RulesConfiguration parameters = new ProfileGenerator .RulesConfiguration ()
@@ -59,47 +53,252 @@ static void prepare_quality_profile() {
59
53
}
60
54
61
55
@ 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
+ }
80
67
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
+ }
85
72
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 );
88
162
}
89
163
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 );
92
273
}
93
274
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 );
99
278
}
100
279
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" );
103
295
}
104
296
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
+ }
105
304
}
0 commit comments