8164649: Cleanup of test java/nio/channels/FileChannel/Lock.java
authorclanger
Mon, 29 Aug 2016 11:23:34 +0200
changeset 40566 cf1f1b3822e7
parent 40565 3ac0ba151e70
child 40567 ae58ca4561cd
8164649: Cleanup of test java/nio/channels/FileChannel/Lock.java Reviewed-by: alanb
jdk/test/java/nio/channels/FileChannel/Lock.java
--- a/jdk/test/java/nio/channels/FileChannel/Lock.java	Fri Aug 26 13:44:20 2016 -0700
+++ b/jdk/test/java/nio/channels/FileChannel/Lock.java	Mon Aug 29 11:23:34 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,8 +22,8 @@
  */
 
 /* @test
- * @bug 4429043 4493595 6332756 6709457
- * @summary The FileChannel file locking
+ * @bug 4429043 4493595 6332756 6709457 7146506
+ * @summary Test FileChannel file locking
  */
 
 import java.io.*;
@@ -33,17 +33,14 @@
 /**
  * Testing FileChannel's lock method.
  */
-
 public class Lock {
 
     public static void main(String[] args) throws Exception {
-        if (args.length > 0) {
-            if(args[0].equals("1")) {
-                MadWriter mw = new MadWriter(args[1], false);
-            } else {
-                MadWriter mw = new MadWriter(args[1], true);
-            }
+        if (args.length == 2) {
+            attemptLock(args[1], args[0].equals("2"));
             return;
+        } else if (args.length != 0) {
+            throw new RuntimeException("Wrong number of parameters.");
         }
         File blah = File.createTempFile("blah", null);
         blah.deleteOnExit();
@@ -56,120 +53,128 @@
         test2(blah, false);
         test3(blah);
         test4(blah);
-        blah.delete();
-    }
-
-    private static void test2(File blah, boolean b) throws Exception {
-        RandomAccessFile raf = new RandomAccessFile(blah, "rw");
-        FileChannel channel = raf.getChannel();
-        FileLock lock;
-        if (b)
-            lock = channel.lock();
-        else
-            lock = channel.tryLock();
-        lock.release();
-        channel.close();
     }
 
+    /**
+     * Test mutual locking with other process
+     */
     static void test1(File blah, String str) throws Exception {
+        try (RandomAccessFile fis = new RandomAccessFile(blah, "rw")) {
+            FileChannel fc = fis.getChannel();
+            FileLock lock = null;
 
-        // Grab the lock
-        RandomAccessFile fis = new RandomAccessFile(blah, "rw");
-        FileChannel fc = fis.getChannel();
-        FileLock lock = null;
+            // grab the lock
+            if (str.equals("1")) {
+                lock = fc.lock(0, 10, false);
+                if (lock == null)
+                    throw new RuntimeException("Lock should not return null");
+                try {
+                    fc.lock(5, 10, false);
+                    throw new RuntimeException("Overlapping locks allowed");
+                } catch (OverlappingFileLockException e) {} // correct result
+            }
+
+            // execute the tamperer
+            String command = System.getProperty("java.home") +
+                File.separator + "bin" + File.separator + "java";
+            String testClasses = System.getProperty("test.classes");
+            if (testClasses != null)
+                command += " -cp " + testClasses;
+            command += " Lock " + str + " " + blah;
+            Process p = Runtime.getRuntime().exec(command);
 
-        if (str.equals("1")) {
-            lock = fc.lock(0, 10, false);
-            if (lock == null)
-                throw new RuntimeException("Lock should not return null");
-            try {
-                FileLock lock2 = fc.lock(5, 10, false);
-                throw new RuntimeException("Overlapping locks allowed");
-            } catch (OverlappingFileLockException e) {
-                // Correct result
+            // evaluate System.out of child process
+            String s;
+            boolean hasOutput = false;
+            InputStreamReader isr;
+            isr = new InputStreamReader(p.getInputStream());
+            BufferedReader br = new BufferedReader(isr);
+            while ((s = br.readLine()) != null) {
+                // only throw on Unix as windows over NFS fails...
+                if ((File.separatorChar == '/') && !s.equals("good")) {
+                    throw new RuntimeException("Failed: " + s);
+                }
+                hasOutput = true;
+            }
+
+            // evaluate System.err in case of System.out of child process
+            // was empty
+            if (!hasOutput) {
+                isr = new InputStreamReader(p.getErrorStream());
+                br = new BufferedReader(isr);
+                if ((s = br.readLine()) != null) {
+                    System.err.println("Error output:");
+                    System.err.println(s);
+                    while ((s = br.readLine()) != null) {
+                        System.err.println(s);
+                    }
+                }
+                throw new RuntimeException("Failed, no output");
+            }
+
+            // clean up, check multiple releases
+            if (lock != null) {
+                lock.release();
+                lock.release();
             }
         }
-
-        // Exec the tamperer
-        String command = System.getProperty("java.home") +
-            File.separator + "bin" + File.separator + "java";
-        String testClasses = System.getProperty("test.classes");
-        if (testClasses != null)
-            command += " -cp " + testClasses;
-        command += " Lock " + str + " " + blah;
-        Process p = Runtime.getRuntime().exec(command);
-
-        BufferedReader in = new BufferedReader
-            (new InputStreamReader(p.getInputStream()));
+    }
 
-        String s;
-        int count = 0;
-        while ((s = in.readLine()) != null) {
-            if (!s.equals("good")) {
-                if (File.separatorChar == '/') {
-                    // Fails on windows over NFS...
-                    throw new RuntimeException("Failed: "+s);
-                }
-            }
-            count++;
-        }
-
-        if (count == 0) {
-            in = new BufferedReader(new InputStreamReader(p.getErrorStream()));
-            while ((s = in.readLine()) != null) {
-                System.err.println("Error output: " + s);
-            }
-            throw new RuntimeException("Failed, no output");
-        }
-
-        // Clean up
-        if (lock != null) {
-            /* Check multiple releases */
-            lock.release();
+    /**
+     * Basic test for FileChannel.lock() and FileChannel.tryLock()
+     */
+    static void test2(File blah, boolean b) throws Exception {
+        try (RandomAccessFile raf = new RandomAccessFile(blah, "rw")) {
+            FileChannel channel = raf.getChannel();
+            FileLock lock;
+            if (b)
+                lock = channel.lock();
+            else
+                lock = channel.tryLock();
             lock.release();
         }
-        fc.close();
-        fis.close();
     }
 
-    // The overlap check for file locks should be JVM-wide
-    private static void test3(File blah) throws Exception {
-        FileChannel fc1 = new RandomAccessFile(blah, "rw").getChannel();
-        FileChannel fc2 = new RandomAccessFile(blah, "rw").getChannel();
+    /**
+     * Test that overlapping file locking is not possible when using different
+     * FileChannel objects to the same file path
+     */
+    static void test3(File blah) throws Exception {
+        try (RandomAccessFile raf1 = new RandomAccessFile(blah, "rw");
+             RandomAccessFile raf2 = new RandomAccessFile(blah, "rw"))
+        {
+            FileChannel fc1 = raf1.getChannel();
+            FileChannel fc2 = raf2.getChannel();
 
-        // lock via one channel, and then attempt to lock the same file
-        // using a second channel
-        FileLock fl1 = fc1.lock();
-        try {
-            fc2.tryLock();
-            throw new RuntimeException("Overlapping locks allowed");
-        } catch (OverlappingFileLockException x) {
-        }
-        try {
+            // lock via one channel, and then attempt to lock the same file
+            // using a second channel
+            FileLock fl1 = fc1.lock();
+            try {
+                fc2.tryLock();
+                throw new RuntimeException("Overlapping locks allowed");
+            } catch (OverlappingFileLockException x) {}
+            try {
+                fc2.lock();
+                throw new RuntimeException("Overlapping locks allowed");
+            } catch (OverlappingFileLockException x) {}
+
+            // release lock and the attempt to lock with the second channel
+            // should succeed.
+            fl1.release();
             fc2.lock();
-            throw new RuntimeException("Overlapping locks allowed");
-        } catch (OverlappingFileLockException x) {
+            try {
+                fc1.lock();
+                throw new RuntimeException("Overlapping locks allowed");
+            } catch (OverlappingFileLockException x) {}
         }
-
-        // release lock and the attempt to lock with the second channel
-        // should succeed.
-        fl1.release();
-        FileLock fl2 = fc2.lock();
-        try {
-            fc1.lock();
-            throw new RuntimeException("Overlapping locks allowed");
-        } catch (OverlappingFileLockException x) {
-        }
-
-        fc1.close();
-        fc2.close();
     }
 
     /**
      * Test file locking when file is opened for append
      */
     static void test4(File blah) throws Exception {
-        try (FileChannel fc = new FileOutputStream(blah, true).getChannel()) {
+        try (FileOutputStream fos = new FileOutputStream(blah, true)) {
+            FileChannel fc = fos.getChannel();
             fc.tryLock().release();
             fc.tryLock(0L, 1L, false).release();
             fc.lock().release();
@@ -182,30 +187,31 @@
             fc.lock(0L, 1L, false).release();
         }
     }
-}
 
-class MadWriter {
-    public MadWriter(String s, boolean b) throws Exception {
-        File f = new File(s);
-        RandomAccessFile fos = new RandomAccessFile(f, "rw");
-        FileChannel fc = fos.getChannel();
-        if (fc.tryLock(10, 10, false) == null) {
-            System.out.println("bad: Failed to grab adjacent lock");
+    /**
+     * Utility method to be run in secondary process which tries to acquire a
+     * lock on a FileChannel
+     */
+    static void attemptLock(String fileName,
+                            boolean expectsLock) throws Exception
+    {
+        File f = new File(fileName);
+        try (RandomAccessFile raf = new RandomAccessFile(f, "rw")) {
+            FileChannel fc = raf.getChannel();
+            if (fc.tryLock(10, 10, false) == null) {
+                System.out.println("bad: Failed to grab adjacent lock");
+            }
+            if (fc.tryLock(0, 10, false) == null) {
+                if (expectsLock)
+                    System.out.println("bad");
+                else
+                    System.out.println("good");
+            } else {
+                if (expectsLock)
+                    System.out.println("good");
+                else
+                    System.out.println("bad");
+            }
         }
-        FileLock lock = fc.tryLock(0, 10, false);
-        if (lock == null) {
-            if (b)
-                System.out.println("bad");
-            else
-                System.out.println("good");
-        } else {
-            if (b)
-                System.out.println("good");
-            else
-                System.out.println("bad");
-        }
-        fc.close();
-        fos.close();
     }
-
 }