24 /* @test 25 * @bug 4313887 6838333 26 * @summary Unit test for java.nio.file.WatchService 27 * @library .. 28 * @run main/timeout=120 Basic 29 */ 30 31 import java.nio.file.*; 32 import static java.nio.file.StandardWatchEventKind.*; 33 import java.nio.file.attribute.*; 34 import java.io.*; 35 import java.util.*; 36 import java.util.concurrent.TimeUnit; 37 38 /** 39 * Unit test for WatchService that exercises all methods in various scenarios. 40 */ 41 42 public class Basic { 43 44 static void createFile(Path file) throws IOException { 45 file.newOutputStream().close(); 46 } 47 48 static void takeExpectedKey(WatchService watcher, WatchKey expected) { 49 System.out.println("take events..."); 50 WatchKey key; 51 try { 52 key = watcher.take(); 53 } catch (InterruptedException x) { 54 // not expected 55 throw new RuntimeException(x); 56 } 57 if (key != expected) 58 throw new RuntimeException("removed unexpected key"); 59 } 60 61 static void checkExpectedEvent(Iterable<WatchEvent<?>> events, 62 WatchEvent.Kind<?> expectedKind, 63 Object expectedContext) 64 { 65 WatchEvent<?> event = events.iterator().next(); 66 System.out.format("got event: type=%s, count=%d, context=%s\n", 67 event.kind(), event.count(), event.context()); 68 if (event.kind() != expectedKind) 69 throw new RuntimeException("unexpected event"); 70 if (!expectedContext.equals(event.context())) 71 throw new RuntimeException("unexpected context"); 72 } 73 74 /** 75 * Simple test of each of the standard events 76 */ 77 static void testEvents(Path dir) throws IOException { 78 System.out.println("-- Standard Events --"); 79 80 FileSystem fs = FileSystems.getDefault(); 81 Path name = fs.getPath("foo"); 82 83 WatchService watcher = fs.newWatchService(); 84 try { 85 // --- ENTRY_CREATE --- 86 87 // register for event 88 System.out.format("register %s for ENTRY_CREATE\n", dir); 89 WatchKey myKey = dir.register(watcher, 90 new WatchEvent.Kind<?>[]{ ENTRY_CREATE }); 91 92 // create file 93 Path file = dir.resolve("foo"); 94 System.out.format("create %s\n", file); 95 createFile(file); 96 97 // remove key and check that we got the ENTRY_CREATE event 98 takeExpectedKey(watcher, myKey); 99 checkExpectedEvent(myKey.pollEvents(), 100 StandardWatchEventKind.ENTRY_CREATE, name); 101 102 System.out.println("reset key"); 103 if (!myKey.reset()) 104 throw new RuntimeException("key has been cancalled"); 105 106 System.out.println("OKAY"); 107 108 // --- ENTRY_DELETE --- 109 110 System.out.format("register %s for ENTRY_DELETE\n", dir); 111 WatchKey deleteKey = dir.register(watcher, 112 new WatchEvent.Kind<?>[]{ ENTRY_DELETE }); 113 if (deleteKey != myKey) 114 throw new RuntimeException("register did not return existing key"); 115 116 System.out.format("delete %s\n", file); 117 file.delete(); 118 takeExpectedKey(watcher, myKey); 119 checkExpectedEvent(myKey.pollEvents(), 120 StandardWatchEventKind.ENTRY_DELETE, name); 121 122 System.out.println("reset key"); 123 if (!myKey.reset()) 124 throw new RuntimeException("key has been cancalled"); 125 126 System.out.println("OKAY"); 127 128 // create the file for the next test 129 createFile(file); 130 131 // --- ENTRY_MODIFY --- 132 133 System.out.format("register %s for ENTRY_MODIFY\n", dir); 134 WatchKey newKey = dir.register(watcher, 135 new WatchEvent.Kind<?>[]{ ENTRY_MODIFY }); 136 if (newKey != myKey) 137 throw new RuntimeException("register did not return existing key"); 138 139 System.out.format("update: %s\n", file); 140 OutputStream out = file.newOutputStream(StandardOpenOption.APPEND); 141 try { 142 out.write("I am a small file".getBytes("UTF-8")); 143 } finally { 144 out.close(); 145 } 146 147 // remove key and check that we got the ENTRY_MODIFY event 148 takeExpectedKey(watcher, myKey); 149 checkExpectedEvent(myKey.pollEvents(), 150 StandardWatchEventKind.ENTRY_MODIFY, name); 151 System.out.println("OKAY"); 152 153 // done 154 file.delete(); 155 156 } finally { 157 watcher.close(); 158 } 159 } 160 161 /** 162 * Check that a cancelled key will never be queued 163 */ 164 static void testCancel(Path dir) throws IOException { 165 System.out.println("-- Cancel --"); 166 167 WatchService watcher = FileSystems.getDefault().newWatchService(); 168 try { 169 170 System.out.format("register %s for events\n", dir); 171 WatchKey myKey = dir.register(watcher, 172 new WatchEvent.Kind<?>[]{ ENTRY_CREATE }); 173 174 System.out.println("cancel key"); 175 myKey.cancel(); 176 177 // create a file in the directory 178 Path file = dir.resolve("mars"); 179 System.out.format("create: %s\n", file); 180 createFile(file); 181 182 // poll for keys - there will be none 183 System.out.println("poll..."); 184 try { 185 WatchKey key = watcher.poll(3000, TimeUnit.MILLISECONDS); 186 if (key != null) 187 throw new RuntimeException("key should not be queued"); 188 } catch (InterruptedException x) { 189 throw new RuntimeException(x); 190 } 191 192 // done 193 file.delete(); 194 195 System.out.println("OKAY"); 196 197 } finally { 198 watcher.close(); 199 } 200 } 201 202 /** 203 * Check that deleting a registered directory causes the key to be 204 * cancelled and queued. 205 */ 206 static void testAutomaticCancel(Path dir) throws IOException { 207 System.out.println("-- Automatic Cancel --"); 208 209 Path subdir = dir.resolve("bar").createDirectory(); 210 211 WatchService watcher = FileSystems.getDefault().newWatchService(); 212 try { 213 214 System.out.format("register %s for events\n", subdir); 215 WatchKey myKey = subdir.register(watcher, 216 new WatchEvent.Kind<?>[]{ ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY }); 217 218 System.out.format("delete: %s\n", subdir); 219 subdir.delete(); 220 takeExpectedKey(watcher, myKey); 221 222 System.out.println("reset key"); 223 if (myKey.reset()) 224 throw new RuntimeException("Key was not cancelled"); 225 if (myKey.isValid()) 226 throw new RuntimeException("Key is still valid"); 227 228 System.out.println("OKAY"); 229 230 } finally { 231 watcher.close(); 232 } 233 } 234 235 /** 236 * Asynchronous close of watcher causes blocked threads to wakeup 237 */ 238 static void testWakeup(Path dir) throws IOException { 239 System.out.println("-- Wakeup Tests --"); 240 final WatchService watcher = FileSystems.getDefault().newWatchService(); 241 Runnable r = new Runnable() { 242 public void run() { 243 try { 244 Thread.sleep(5000); 245 System.out.println("close WatchService..."); 246 watcher.close(); 247 } catch (InterruptedException x) { 248 x.printStackTrace(); 249 } catch (IOException x) { 250 x.printStackTrace(); 251 } 394 System.out.println("OKAY"); 395 } 396 397 /** 398 * Test that directory can be registered with more than one watch service 399 * and that events don't interfere with each other 400 */ 401 static void testTwoWatchers(Path dir) throws IOException { 402 System.out.println("-- Two watchers test --"); 403 404 FileSystem fs = FileSystems.getDefault(); 405 WatchService watcher1 = fs.newWatchService(); 406 WatchService watcher2 = fs.newWatchService(); 407 try { 408 Path name1 = fs.getPath("gus1"); 409 Path name2 = fs.getPath("gus2"); 410 411 // create gus1 412 Path file1 = dir.resolve(name1); 413 System.out.format("create %s\n", file1); 414 createFile(file1); 415 416 // register with both watch services (different events) 417 System.out.println("register for different events"); 418 WatchKey key1 = dir.register(watcher1, 419 new WatchEvent.Kind<?>[]{ ENTRY_CREATE }); 420 WatchKey key2 = dir.register(watcher2, 421 new WatchEvent.Kind<?>[]{ ENTRY_DELETE }); 422 423 if (key1 == key2) 424 throw new RuntimeException("keys should be different"); 425 426 // create gus2 427 Path file2 = dir.resolve(name2); 428 System.out.format("create %s\n", file2); 429 createFile(file2); 430 431 // check that key1 got ENTRY_CREATE 432 takeExpectedKey(watcher1, key1); 433 checkExpectedEvent(key1.pollEvents(), 434 StandardWatchEventKind.ENTRY_CREATE, name2); 435 436 // check that key2 got zero events 437 WatchKey key = watcher2.poll(); 438 if (key != null) 439 throw new RuntimeException("key not expected"); 440 441 // delete gus1 442 file1.delete(); 443 444 // check that key2 got ENTRY_DELETE 445 takeExpectedKey(watcher2, key2); 446 checkExpectedEvent(key2.pollEvents(), 447 StandardWatchEventKind.ENTRY_DELETE, name1); 448 449 // check that key1 got zero events 450 key = watcher1.poll(); 451 if (key != null) 452 throw new RuntimeException("key not expected"); 453 454 // reset for next test 455 key1.reset(); 456 key2.reset(); 457 458 // change registration with watcher2 so that they are both 459 // registered for the same event 460 System.out.println("register for same event"); 461 key2 = dir.register(watcher2, new WatchEvent.Kind<?>[]{ ENTRY_CREATE }); 462 463 // create file and key2 should be queued 464 System.out.format("create %s\n", file1); 465 createFile(file1); 466 takeExpectedKey(watcher2, key2); 467 checkExpectedEvent(key2.pollEvents(), 468 StandardWatchEventKind.ENTRY_CREATE, name1); 469 470 System.out.println("OKAY"); 471 472 } finally { 473 watcher2.close(); 474 watcher1.close(); 475 } 476 } 477 478 public static void main(String[] args) throws IOException { 479 Path dir = TestUtil.createTemporaryDirectory(); 480 try { 481 482 testEvents(dir); 483 testCancel(dir); 484 testAutomaticCancel(dir); 485 testWakeup(dir); | 24 /* @test 25 * @bug 4313887 6838333 26 * @summary Unit test for java.nio.file.WatchService 27 * @library .. 28 * @run main/timeout=120 Basic 29 */ 30 31 import java.nio.file.*; 32 import static java.nio.file.StandardWatchEventKind.*; 33 import java.nio.file.attribute.*; 34 import java.io.*; 35 import java.util.*; 36 import java.util.concurrent.TimeUnit; 37 38 /** 39 * Unit test for WatchService that exercises all methods in various scenarios. 40 */ 41 42 public class Basic { 43 44 static void checkKey(WatchKey key, Path dir) { 45 if (!key.isValid()) 46 throw new RuntimeException("Key is not valid"); 47 } 48 49 static void takeExpectedKey(WatchService watcher, WatchKey expected) { 50 System.out.println("take events..."); 51 WatchKey key; 52 try { 53 key = watcher.take(); 54 } catch (InterruptedException x) { 55 // not expected 56 throw new RuntimeException(x); 57 } 58 if (key != expected) 59 throw new RuntimeException("removed unexpected key"); 60 } 61 62 static void checkExpectedEvent(Iterable<WatchEvent<?>> events, 63 WatchEvent.Kind<?> expectedKind, 64 Object expectedContext) 65 { 66 WatchEvent<?> event = events.iterator().next(); 67 System.out.format("got event: type=%s, count=%d, context=%s\n", 68 event.kind(), event.count(), event.context()); 69 if (event.kind() != expectedKind) 70 throw new RuntimeException("unexpected event"); 71 if (!expectedContext.equals(event.context())) 72 throw new RuntimeException("unexpected context"); 73 } 74 75 /** 76 * Simple test of each of the standard events 77 */ 78 static void testEvents(Path dir) throws IOException { 79 System.out.println("-- Standard Events --"); 80 81 FileSystem fs = FileSystems.getDefault(); 82 Path name = fs.getPath("foo"); 83 84 try (WatchService watcher = fs.newWatchService()) { 85 // --- ENTRY_CREATE --- 86 87 // register for event 88 System.out.format("register %s for ENTRY_CREATE\n", dir); 89 WatchKey myKey = dir.register(watcher, 90 new WatchEvent.Kind<?>[]{ ENTRY_CREATE }); 91 checkKey(myKey, dir); 92 93 // create file 94 Path file = dir.resolve("foo"); 95 System.out.format("create %s\n", file); 96 Files.createFile(file); 97 98 // remove key and check that we got the ENTRY_CREATE event 99 takeExpectedKey(watcher, myKey); 100 checkExpectedEvent(myKey.pollEvents(), 101 StandardWatchEventKind.ENTRY_CREATE, name); 102 103 System.out.println("reset key"); 104 if (!myKey.reset()) 105 throw new RuntimeException("key has been cancalled"); 106 107 System.out.println("OKAY"); 108 109 // --- ENTRY_DELETE --- 110 111 System.out.format("register %s for ENTRY_DELETE\n", dir); 112 WatchKey deleteKey = dir.register(watcher, 113 new WatchEvent.Kind<?>[]{ ENTRY_DELETE }); 114 if (deleteKey != myKey) 115 throw new RuntimeException("register did not return existing key"); 116 checkKey(deleteKey, dir); 117 118 System.out.format("delete %s\n", file); 119 Files.delete(file); 120 takeExpectedKey(watcher, myKey); 121 checkExpectedEvent(myKey.pollEvents(), 122 StandardWatchEventKind.ENTRY_DELETE, name); 123 124 System.out.println("reset key"); 125 if (!myKey.reset()) 126 throw new RuntimeException("key has been cancalled"); 127 128 System.out.println("OKAY"); 129 130 // create the file for the next test 131 Files.createFile(file); 132 133 // --- ENTRY_MODIFY --- 134 135 System.out.format("register %s for ENTRY_MODIFY\n", dir); 136 WatchKey newKey = dir.register(watcher, 137 new WatchEvent.Kind<?>[]{ ENTRY_MODIFY }); 138 if (newKey != myKey) 139 throw new RuntimeException("register did not return existing key"); 140 checkKey(newKey, dir); 141 142 System.out.format("update: %s\n", file); 143 try (OutputStream out = Files.newOutputStream(file, StandardOpenOption.APPEND)) { 144 out.write("I am a small file".getBytes("UTF-8")); 145 } 146 147 // remove key and check that we got the ENTRY_MODIFY event 148 takeExpectedKey(watcher, myKey); 149 checkExpectedEvent(myKey.pollEvents(), 150 StandardWatchEventKind.ENTRY_MODIFY, name); 151 System.out.println("OKAY"); 152 153 // done 154 Files.delete(file); 155 } 156 } 157 158 /** 159 * Check that a cancelled key will never be queued 160 */ 161 static void testCancel(Path dir) throws IOException { 162 System.out.println("-- Cancel --"); 163 164 try (WatchService watcher = FileSystems.getDefault().newWatchService()) { 165 166 System.out.format("register %s for events\n", dir); 167 WatchKey myKey = dir.register(watcher, 168 new WatchEvent.Kind<?>[]{ ENTRY_CREATE }); 169 checkKey(myKey, dir); 170 171 System.out.println("cancel key"); 172 myKey.cancel(); 173 174 // create a file in the directory 175 Path file = dir.resolve("mars"); 176 System.out.format("create: %s\n", file); 177 Files.createFile(file); 178 179 // poll for keys - there will be none 180 System.out.println("poll..."); 181 try { 182 WatchKey key = watcher.poll(3000, TimeUnit.MILLISECONDS); 183 if (key != null) 184 throw new RuntimeException("key should not be queued"); 185 } catch (InterruptedException x) { 186 throw new RuntimeException(x); 187 } 188 189 // done 190 Files.delete(file); 191 192 System.out.println("OKAY"); 193 } 194 } 195 196 /** 197 * Check that deleting a registered directory causes the key to be 198 * cancelled and queued. 199 */ 200 static void testAutomaticCancel(Path dir) throws IOException { 201 System.out.println("-- Automatic Cancel --"); 202 203 Path subdir = Files.createDirectory(dir.resolve("bar")); 204 205 try (WatchService watcher = FileSystems.getDefault().newWatchService()) { 206 207 System.out.format("register %s for events\n", subdir); 208 WatchKey myKey = subdir.register(watcher, 209 new WatchEvent.Kind<?>[]{ ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY }); 210 211 System.out.format("delete: %s\n", subdir); 212 Files.delete(subdir); 213 takeExpectedKey(watcher, myKey); 214 215 System.out.println("reset key"); 216 if (myKey.reset()) 217 throw new RuntimeException("Key was not cancelled"); 218 if (myKey.isValid()) 219 throw new RuntimeException("Key is still valid"); 220 221 System.out.println("OKAY"); 222 223 } 224 } 225 226 /** 227 * Asynchronous close of watcher causes blocked threads to wakeup 228 */ 229 static void testWakeup(Path dir) throws IOException { 230 System.out.println("-- Wakeup Tests --"); 231 final WatchService watcher = FileSystems.getDefault().newWatchService(); 232 Runnable r = new Runnable() { 233 public void run() { 234 try { 235 Thread.sleep(5000); 236 System.out.println("close WatchService..."); 237 watcher.close(); 238 } catch (InterruptedException x) { 239 x.printStackTrace(); 240 } catch (IOException x) { 241 x.printStackTrace(); 242 } 385 System.out.println("OKAY"); 386 } 387 388 /** 389 * Test that directory can be registered with more than one watch service 390 * and that events don't interfere with each other 391 */ 392 static void testTwoWatchers(Path dir) throws IOException { 393 System.out.println("-- Two watchers test --"); 394 395 FileSystem fs = FileSystems.getDefault(); 396 WatchService watcher1 = fs.newWatchService(); 397 WatchService watcher2 = fs.newWatchService(); 398 try { 399 Path name1 = fs.getPath("gus1"); 400 Path name2 = fs.getPath("gus2"); 401 402 // create gus1 403 Path file1 = dir.resolve(name1); 404 System.out.format("create %s\n", file1); 405 Files.createFile(file1); 406 407 // register with both watch services (different events) 408 System.out.println("register for different events"); 409 WatchKey key1 = dir.register(watcher1, 410 new WatchEvent.Kind<?>[]{ ENTRY_CREATE }); 411 WatchKey key2 = dir.register(watcher2, 412 new WatchEvent.Kind<?>[]{ ENTRY_DELETE }); 413 414 if (key1 == key2) 415 throw new RuntimeException("keys should be different"); 416 417 // create gus2 418 Path file2 = dir.resolve(name2); 419 System.out.format("create %s\n", file2); 420 Files.createFile(file2); 421 422 // check that key1 got ENTRY_CREATE 423 takeExpectedKey(watcher1, key1); 424 checkExpectedEvent(key1.pollEvents(), 425 StandardWatchEventKind.ENTRY_CREATE, name2); 426 427 // check that key2 got zero events 428 WatchKey key = watcher2.poll(); 429 if (key != null) 430 throw new RuntimeException("key not expected"); 431 432 // delete gus1 433 Files.delete(file1); 434 435 // check that key2 got ENTRY_DELETE 436 takeExpectedKey(watcher2, key2); 437 checkExpectedEvent(key2.pollEvents(), 438 StandardWatchEventKind.ENTRY_DELETE, name1); 439 440 // check that key1 got zero events 441 key = watcher1.poll(); 442 if (key != null) 443 throw new RuntimeException("key not expected"); 444 445 // reset for next test 446 key1.reset(); 447 key2.reset(); 448 449 // change registration with watcher2 so that they are both 450 // registered for the same event 451 System.out.println("register for same event"); 452 key2 = dir.register(watcher2, new WatchEvent.Kind<?>[]{ ENTRY_CREATE }); 453 454 // create file and key2 should be queued 455 System.out.format("create %s\n", file1); 456 Files.createFile(file1); 457 takeExpectedKey(watcher2, key2); 458 checkExpectedEvent(key2.pollEvents(), 459 StandardWatchEventKind.ENTRY_CREATE, name1); 460 461 System.out.println("OKAY"); 462 463 } finally { 464 watcher2.close(); 465 watcher1.close(); 466 } 467 } 468 469 public static void main(String[] args) throws IOException { 470 Path dir = TestUtil.createTemporaryDirectory(); 471 try { 472 473 testEvents(dir); 474 testCancel(dir); 475 testAutomaticCancel(dir); 476 testWakeup(dir); |