2727package  engineering .swat .watch ;
2828
2929import  static  engineering .swat .watch .WatchEvent .Kind .CREATED ;
30- import  static  org .awaitility .Awaitility .await ;
30+ import  static  engineering .swat .watch .util .WaitFor .await ;
31+ import  static  org .junit .jupiter .api .Assertions .assertEquals ;
3132
3233import  java .io .IOException ;
3334import  java .nio .file .Files ;
3435import  java .nio .file .Path ;
36+ import  java .util .ArrayList ;
37+ import  java .util .Arrays ;
38+ import  java .util .Collection ;
39+ import  java .util .Collections ;
40+ import  java .util .List ;
3541import  java .util .concurrent .ForkJoinPool ;
3642import  java .util .concurrent .atomic .AtomicBoolean ;
3743import  java .util .concurrent .atomic .AtomicReference ;
3844import  java .util .function .Consumer ;
45+ import  java .util .stream .Collectors ;
3946
4047import  org .apache .logging .log4j .LogManager ;
4148import  org .apache .logging .log4j .Logger ;
4956
5057import  engineering .swat .watch .WatchEvent .Kind ;
5158import  engineering .swat .watch .impl .EventHandlingWatch ;
59+ import  engineering .swat .watch .util .WaitFor ;
5260
5361class  RecursiveWatchTests  {
5462    private  final  Logger  logger  = LogManager .getLogger ();
@@ -69,7 +77,7 @@ void cleanup() {
6977
7078    @ BeforeAll 
7179    static  void  setupEverything () {
72-         Awaitility .setDefaultTimeout (TestHelper .NORMAL_WAIT );
80+         WaitFor .setDefaultTimeout (TestHelper .NORMAL_WAIT );
7381    }
7482
7583    @ Test 
@@ -99,9 +107,9 @@ void newDirectoryWithFilesChangesDetected() throws IOException {
99107            target .set (freshFile );
100108            logger .debug ("Interested in: {}" , freshFile );
101109            Files .writeString (freshFile , "Hello world" );
102-             await ("New files should have been seen" ).untilTrue (created );
110+             await ("New files should have been seen" ).until (created );
103111            Files .writeString (freshFile , "Hello world 2" );
104-             await ("Fresh file change have been detected" ).untilTrue (changed );
112+             await ("Fresh file change have been detected" ).until (changed );
105113        }
106114    }
107115
@@ -121,7 +129,7 @@ void correctRelativePathIsReported() throws IOException {
121129            var  targetFile  = testDir .getTestDirectory ().resolve (relative );
122130            Files .createDirectories (targetFile .getParent ());
123131            Files .writeString (targetFile , "Hello World" );
124-             await ("Nested path is seen" ).untilTrue (seen );
132+             await ("Nested path is seen" ).until (seen );
125133        }
126134
127135    }
@@ -143,19 +151,19 @@ void deleteOfFileInDirectoryShouldBeVisible() throws IOException {
143151        try  (var  watch  = watchConfig .start ()) {
144152            Files .delete (target );
145153            await ("File deletion should generate delete event" )
146-                 .untilTrue (seen );
154+                 .until (seen );
147155        }
148156    }
149157
150158    @ ParameterizedTest 
151159    @ EnumSource  // Repeat test for each `Approximation` value 
152160    void  overflowsAreRecoveredFrom (Approximation  whichFiles ) throws  IOException , InterruptedException  {
153161        var  parent  = testDir .getTestDirectory ();
154-         var  descendants  = new   Path [] { 
162+         var  descendants  = List . of ( 
155163            Path .of ("foo" ),
156164            Path .of ("bar" ),
157165            Path .of ("bar" , "x" , "y" , "z" )
158-         } ;
166+         ) ;
159167
160168        // Configure and start watch 
161169        var  dropEvents  = new  AtomicBoolean (false ); // Toggles overflow simulation 
@@ -169,28 +177,38 @@ void overflowsAreRecoveredFrom(Approximation whichFiles) throws IOException, Int
169177        try  (var  watch  = (EventHandlingWatch ) watchConfig .start ()) {
170178
171179            // Define helper functions to test which events have happened 
172-             Consumer <Path > awaitCreation  = p  ->
173-                 await ("Creation of `"  + p  + "` should be observed" )
174-                     .until (() -> bookkeeper .events ().kind (CREATED ).rootPath (parent ).relativePath (p ).any ());
175- 
176-             Consumer <Path > awaitNotCreation  = p  ->
177-                 await ("Creation of `"  + p  + "` shouldn't be observed: "  + bookkeeper )
178-                     .pollDelay (TestHelper .TINY_WAIT )
179-                     .until (() -> bookkeeper .events ().kind (CREATED ).rootPath (parent ).relativePath (p ).none ());
180+             Consumer <Collection <Path >> awaitCreation  = paths  ->
181+                 WaitFor .await ("Creation should be observed" )
182+                     .untilContainsAll (() ->
183+                         bookkeeper .events ()
184+                             .kind (CREATED )
185+                             .rootPath (parent )
186+                             .relativePath (paths )
187+                             .events ()
188+                             .map (WatchEvent ::getRelativePath )
189+                             , paths );
180190
181191            // Begin overflow simulation 
182192            dropEvents .set (true );
183193
184194            // Create descendants and files. They *shouldn't* be observed yet. 
195+             var  missedCreates  = new  ArrayList <Path >();
185196            var  file1  = Path .of ("file1.txt" );
186197            for  (var  descendant  : descendants ) {
187-                 Files . createDirectories ( parent .resolve (descendant ) );
188-                 Files . createFile ( parent . resolve (descendant ). resolve ( file1 ) );
189-             } 
190-             for  ( var   descendant  :  descendants ) { 
191-                 awaitNotCreation . accept (descendant );
192-                 awaitNotCreation . accept (descendant .resolve (file1 ));
198+                 var   d  =  parent .resolve (descendant );
199+                 var   f  =  d . resolve (file1 );
200+                  Files . createDirectories ( d ); 
201+                  Files . createFile ( f ); 
202+                 missedCreates . add (descendant );
203+                 missedCreates . add (descendant .resolve (file1 ));
193204            }
205+             WaitFor .await (() -> "We should not have seen any events" )
206+                 .time (TestHelper .TINY_WAIT )
207+                 .holdsEmpty (() -> bookkeeper .events ()
208+                     .kind (CREATED )
209+                     .rootPath (parent )
210+                     .relativePath (missedCreates )
211+                     .events ());
194212
195213            // End overflow simulation, and generate the `OVERFLOW` event. The 
196214            // previous creation of descendants and files *should* now be 
@@ -201,10 +219,7 @@ void overflowsAreRecoveredFrom(Approximation whichFiles) throws IOException, Int
201219            watch .handleEvent (overflow );
202220
203221            if  (whichFiles  != Approximation .NONE ) { // Auto-handler is configured 
204-                 for  (var  descendant  : descendants ) {
205-                     awaitCreation .accept (descendant );
206-                     awaitCreation .accept (descendant .resolve (file1 ));
207-                 }
222+                 awaitCreation .accept (missedCreates );
208223            } else  {
209224                // Give the watch some time to process the `OVERFLOW` event and 
210225                // do internal bookkeeping 
@@ -213,13 +228,14 @@ void overflowsAreRecoveredFrom(Approximation whichFiles) throws IOException, Int
213228
214229            // Create more files. They *should* be observed (regardless of 
215230            // whether an auto-handler for `OVERFLOW` events is configured). 
216-             var  file2  = Path . of ( "file2.txt" ); 
217-             for  ( var   descendant  :  descendants ) { 
218-                 Files . createFile ( parent . resolve ( descendant ). resolve ( file2 ));
219-             } 
220-             for  (var  descendant  : descendants ) {
221-                 awaitCreation . accept ( descendant .resolve (file2 ));
231+             var  moreFiles  = descendants . stream () 
232+                 . map ( d  ->  d . resolve ( Path . of ( "file2.txt" ))) 
233+                 . collect ( Collectors . toList ( ));
234+ 
235+             for  (var  f  : moreFiles ) {
236+                 Files . createFile ( parent .resolve (f ));
222237            }
238+             awaitCreation .accept (moreFiles );
223239        }
224240    }
225241}
0 commit comments