3131import java .util .Iterator ;
3232import java .util .List ;
3333import java .util .Set ;
34+ import java .util .concurrent .atomic .AtomicInteger ;
3435import java .util .function .Function ;
3536import javax .annotation .Nullable ;
3637import org .junit .jupiter .api .BeforeEach ;
@@ -141,6 +142,7 @@ class PythonSensorTest {
141142 private static final String CUSTOM_REPOSITORY_KEY = "customKey" ;
142143 private static final String CUSTOM_RULE_KEY = "key" ;
143144 private static final String RULE_CRASHING_ON_SCAN_KEY = "key2" ;
145+ private static final String END_OF_ANALYSIS_KEY = "key3" ;
144146
145147 private static final Version SONARLINT_DETECTABLE_VERSION = Version .create (6 , 0 );
146148
@@ -154,7 +156,7 @@ public String repositoryKey() {
154156
155157 @ Override
156158 public List <Class <?>> checkClasses () {
157- return List .of (MyCustomRule .class , RuleCrashingOnRegularScan .class );
159+ return List .of (MyCustomRule .class , RuleCrashingOnRegularScan .class , AccumulatingForEndOfAnalysis . class );
158160 }
159161 }};
160162 private static Path workDir ;
@@ -164,9 +166,7 @@ public List<Class<?>> checkClasses() {
164166 name = "name" ,
165167 description = "desc" ,
166168 tags = {"bug" })
167- public static class MyCustomRule implements PythonCheck , EndOfAnalysis {
168-
169- private static final Logger LOG = LoggerFactory .getLogger (MyCustomRule .class );
169+ public static class MyCustomRule implements PythonCheck {
170170
171171 @ RuleProperty (
172172 key = "customParam" ,
@@ -184,10 +184,6 @@ public boolean scanWithoutParsing(PythonInputFileContext inputFile) {
184184 return false ;
185185 }
186186
187- @ Override
188- public void endOfAnalysis (CacheContext cacheContext ) {
189- LOG .trace ("End of analysis called!" );
190- }
191187 }
192188
193189 @ Rule (
@@ -208,6 +204,27 @@ public boolean scanWithoutParsing(PythonInputFileContext inputFile) {
208204 }
209205 }
210206
207+ @ Rule (key = END_OF_ANALYSIS_KEY )
208+ public static class AccumulatingForEndOfAnalysis implements PythonCheck , EndOfAnalysis {
209+ private static final Logger LOG = LoggerFactory .getLogger (AccumulatingForEndOfAnalysis .class );
210+ private final AtomicInteger scanFileCount = new AtomicInteger (0 );
211+
212+ @ Override
213+ public void scanFile (PythonVisitorContext visitorContext ) {
214+ scanFileCount .incrementAndGet ();
215+ }
216+
217+ @ Override
218+ public boolean scanWithoutParsing (PythonInputFileContext inputFile ) {
219+ return false ;
220+ }
221+
222+ @ Override
223+ public void endOfAnalysis (CacheContext cacheContext ) {
224+ LOG .trace ("End of analysis called with {} files" , scanFileCount .get ());
225+ }
226+ }
227+
211228 private final File baseDir = new File ("src/test/resources/org/sonar/plugins/python/sensor" ).getAbsoluteFile ();
212229
213230 private SensorContextTester context ;
@@ -506,15 +523,16 @@ void not_relying_on_stubs_for_project_under_analysis_2() {
506523
507524 @ Test
508525 void end_of_analysis_called () {
526+ inputFile (FILE_1 );
509527 inputFile (FILE_2 );
510528 activeRules = new ActiveRulesBuilder ()
511529 .addRule (new NewActiveRule .Builder ()
512- .setRuleKey (RuleKey .of (CUSTOM_REPOSITORY_KEY , CUSTOM_RULE_KEY ))
530+ .setRuleKey (RuleKey .of (CUSTOM_REPOSITORY_KEY , END_OF_ANALYSIS_KEY ))
513531 .build ())
514532 .build ();
515533 sensor ().execute (context );
516534
517- assertThat (traceLogTester .logs (Level .TRACE )).containsExactly ("End of analysis called! " );
535+ assertThat (traceLogTester .logs (Level .TRACE )).containsExactly ("End of analysis called with 2 files " );
518536 }
519537
520538 @ Test
0 commit comments