11package engineering .swat .watch ;
22
3- import static org .awaitility .Awaitility .doNotCatchUncaughtExceptionsByDefault ;
43import static org .awaitility .Awaitility .await ;
54import static org .junit .jupiter .api .Assertions .assertTrue ;
65import static org .junit .jupiter .api .Assertions .fail ;
1110import java .time .Duration ;
1211import java .time .LocalTime ;
1312import java .util .Random ;
13+ import java .util .Collections ;
1414import java .util .Set ;
15- import java .util .concurrent .CompletableFuture ;
1615import java .util .concurrent .ConcurrentHashMap ;
1716import java .util .concurrent .ConcurrentLinkedDeque ;
1817import java .util .concurrent .Executor ;
2726import org .apache .logging .log4j .Logger ;
2827import org .junit .jupiter .api .AfterEach ;
2928import org .junit .jupiter .api .BeforeEach ;
30- import org .junit .jupiter .api .Disabled ;
29+ import org .junit .jupiter .api .RepeatedTest ;
3130import org .junit .jupiter .api .Test ;
32- import org .junit .jupiter .api .condition .DisabledIfEnvironmentVariable ;
33- import org .junit .jupiter .api .condition .EnabledIf ;
3431import org .junit .jupiter .api .condition .EnabledIfEnvironmentVariable ;
3532
3633import engineering .swat .watch .WatchEvent .Kind ;
@@ -173,24 +170,30 @@ void pressureOnFSShouldNotMissNewFilesAnything() throws InterruptedException, IO
173170 }
174171 }
175172
176- @ Test
173+ private final int TORTURE_REGISTRATION_THREADS = THREADS * 500 ;
174+
175+ @ RepeatedTest (failureThreshold =1 , value = 20 )
177176 void manyRegistrationsForSamePath () throws InterruptedException , IOException {
178177 var startRegistering = new Semaphore (0 );
178+ var startedWatching = new Semaphore (0 );
179179 var startDeregistring = new Semaphore (0 );
180180 var done = new Semaphore (0 );
181181 var seen = ConcurrentHashMap .<Path >newKeySet ();
182182 var exceptions = new LinkedBlockingDeque <Exception >();
183- for (int t = 0 ; t < THREADS * 100 ; t ++) {
183+
184+ for (int t = 0 ; t < TORTURE_REGISTRATION_THREADS ; t ++) {
184185 var r = new Thread (() -> {
185186 try {
186187 var watcher = Watcher
187188 .watch (testDir .getTestDirectory (), WatchScope .PATH_AND_CHILDREN )
188- .onEvent (e -> { if ( e . getKind () == Kind . CREATED ) seen .add (e .calculateFullPath ()); } );
189+ .onEvent (e -> seen .add (e .calculateFullPath ()));
189190 startRegistering .acquire ();
190191 try (var c = watcher .start ()) {
192+ startedWatching .release ();
191193 startDeregistring .acquire ();
192194 }
193195 catch (Exception e ) {
196+ startedWatching .release ();
194197 exceptions .push (e );
195198 }
196199 } catch (InterruptedException e1 ) {
@@ -203,29 +206,39 @@ void manyRegistrationsForSamePath() throws InterruptedException, IOException {
203206 r .start ();
204207 }
205208
206- startRegistering .release (THREADS * 100 );
207- startDeregistring .release ((THREADS * 100 ) - 1 );
208- done .acquire ((THREADS * 100 ) - 1 );
209- assertTrue (seen .isEmpty (), "No events should have been sent" );
210- Files .writeString (testDir .getTestDirectory ().resolve ("test124.txt" ), "Hello World" );
211- await ("We should see only one event" )
212- .failFast (() -> !exceptions .isEmpty ())
213- .timeout (TestHelper .LONG_WAIT )
214- .pollInterval (Duration .ofMillis (10 ))
215- .until (seen ::size , s -> s == 1 );
216- if (!exceptions .isEmpty ()) {
217- fail (exceptions .pop ());
209+ try {
210+ startRegistering .release (TORTURE_REGISTRATION_THREADS );
211+ startDeregistring .release (TORTURE_REGISTRATION_THREADS - 1 );
212+ startedWatching .acquire (TORTURE_REGISTRATION_THREADS ); // make sure they area ll started
213+ done .acquire (TORTURE_REGISTRATION_THREADS - 1 );
214+ assertTrue (seen .isEmpty (), "No events should have been sent" );
215+ var target = testDir .getTestDirectory ().resolve ("test124.txt" );
216+ //logger.info("Writing: {}", target);
217+ Files .writeString (target , "Hello World" );
218+ var expected = Collections .singleton (target );
219+ await ("We should see only one event" )
220+ .failFast (() -> !exceptions .isEmpty ())
221+ .timeout (TestHelper .LONG_WAIT )
222+ .pollInterval (Duration .ofMillis (10 ))
223+ .until (() -> seen , expected ::equals );
224+ if (!exceptions .isEmpty ()) {
225+ fail (exceptions .pop ());
226+ }
227+ }
228+ finally {
229+ startDeregistring .release (TORTURE_REGISTRATION_THREADS );
218230 }
219- startDeregistring .release ();
220231 }
221232
222- @ Test
233+ @ RepeatedTest ( failureThreshold = 1 , value = 20 )
223234 void manyRegisterAndUnregisterSameTime () throws InterruptedException , IOException {
224235 var startRegistering = new Semaphore (0 );
236+ var startedWatching = new Semaphore (0 );
225237 var stopAll = new Semaphore (0 );
226238 var done = new Semaphore (0 );
227- var seen = new ConcurrentLinkedDeque < Path > ();
239+ var seen = ConcurrentHashMap .< Long > newKeySet ();
228240 var exceptions = new LinkedBlockingDeque <Exception >();
241+ var target = testDir .getTestDirectory ().resolve ("test124.txt" );
229242 int amountOfWatchersActive = 0 ;
230243 try {
231244 for (int t = 0 ; t < THREADS ; t ++) {
@@ -239,10 +252,14 @@ void manyRegisterAndUnregisterSameTime() throws InterruptedException, IOExceptio
239252 for (int k = 0 ; k < 1000 ; k ++) {
240253 var watcher = Watcher
241254 .watch (testDir .getTestDirectory (), WatchScope .PATH_AND_CHILDREN )
242- .onEvent (e -> { if (e .getKind () == Kind .CREATED ) seen .add (e .calculateFullPath ()); });
255+ .onEvent (e -> {
256+ if (e .calculateFullPath ().equals (target )) {
257+ seen .add (Thread .currentThread ().getId ());
258+ }
259+ });
243260 try (var c = watcher .start ()) {
244261 if (finishWatching && k + 1 == 1000 ) {
245- logger . info ( "Waiting on stop signal" );
262+ startedWatching . release ( );
246263 stopAll .acquire ();
247264 }
248265 }
@@ -253,6 +270,7 @@ void manyRegisterAndUnregisterSameTime() throws InterruptedException, IOExceptio
253270 } catch (InterruptedException e1 ) {
254271 }
255272 finally {
273+ startedWatching .release ();
256274 done .release ();
257275 }
258276 });
@@ -262,9 +280,10 @@ void manyRegisterAndUnregisterSameTime() throws InterruptedException, IOExceptio
262280
263281 startRegistering .release (THREADS );
264282 done .acquire (THREADS - amountOfWatchersActive );
283+ startedWatching .acquire (THREADS );
265284 assertTrue (seen .isEmpty (), "No events should have been sent" );
266- Files .writeString (testDir . getTestDirectory (). resolve ( "test124.txt" ) , "Hello World" );
267- await ("We should see only exactly the events we expect" )
285+ Files .writeString (target , "Hello World" );
286+ await ("We should see only exactly the " + amountOfWatchersActive + " events we expect" )
268287 .failFast (() -> !exceptions .isEmpty ())
269288 .pollDelay (TestHelper .NORMAL_WAIT .minusMillis (100 ))
270289 .until (seen ::size , Predicate .isEqual (amountOfWatchersActive ))
0 commit comments