test/jdk/java/nio/channels/FileChannel/Lock.java
changeset 47216 71c04702a3d5
parent 40566 cf1f1b3822e7
equal deleted inserted replaced
47215:4ebc2e2fb97c 47216:71c04702a3d5
       
     1 /*
       
     2  * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  */
       
    23 
       
    24 /* @test
       
    25  * @bug 4429043 4493595 6332756 6709457 7146506
       
    26  * @summary Test FileChannel file locking
       
    27  */
       
    28 
       
    29 import java.io.*;
       
    30 import java.nio.channels.*;
       
    31 import static java.nio.file.StandardOpenOption.*;
       
    32 
       
    33 /**
       
    34  * Testing FileChannel's lock method.
       
    35  */
       
    36 public class Lock {
       
    37 
       
    38     public static void main(String[] args) throws Exception {
       
    39         if (args.length == 2) {
       
    40             attemptLock(args[1], args[0].equals("2"));
       
    41             return;
       
    42         } else if (args.length != 0) {
       
    43             throw new RuntimeException("Wrong number of parameters.");
       
    44         }
       
    45         File blah = File.createTempFile("blah", null);
       
    46         blah.deleteOnExit();
       
    47         RandomAccessFile raf = new RandomAccessFile(blah, "rw");
       
    48         raf.write(1);
       
    49         raf.close();
       
    50         test1(blah, "1");
       
    51         test1(blah, "2");
       
    52         test2(blah, true);
       
    53         test2(blah, false);
       
    54         test3(blah);
       
    55         test4(blah);
       
    56     }
       
    57 
       
    58     /**
       
    59      * Test mutual locking with other process
       
    60      */
       
    61     static void test1(File blah, String str) throws Exception {
       
    62         try (RandomAccessFile fis = new RandomAccessFile(blah, "rw")) {
       
    63             FileChannel fc = fis.getChannel();
       
    64             FileLock lock = null;
       
    65 
       
    66             // grab the lock
       
    67             if (str.equals("1")) {
       
    68                 lock = fc.lock(0, 10, false);
       
    69                 if (lock == null)
       
    70                     throw new RuntimeException("Lock should not return null");
       
    71                 try {
       
    72                     fc.lock(5, 10, false);
       
    73                     throw new RuntimeException("Overlapping locks allowed");
       
    74                 } catch (OverlappingFileLockException e) {} // correct result
       
    75             }
       
    76 
       
    77             // execute the tamperer
       
    78             String command = System.getProperty("java.home") +
       
    79                 File.separator + "bin" + File.separator + "java";
       
    80             String testClasses = System.getProperty("test.classes");
       
    81             if (testClasses != null)
       
    82                 command += " -cp " + testClasses;
       
    83             command += " Lock " + str + " " + blah;
       
    84             Process p = Runtime.getRuntime().exec(command);
       
    85 
       
    86             // evaluate System.out of child process
       
    87             String s;
       
    88             boolean hasOutput = false;
       
    89             InputStreamReader isr;
       
    90             isr = new InputStreamReader(p.getInputStream());
       
    91             BufferedReader br = new BufferedReader(isr);
       
    92             while ((s = br.readLine()) != null) {
       
    93                 // only throw on Unix as windows over NFS fails...
       
    94                 if ((File.separatorChar == '/') && !s.equals("good")) {
       
    95                     throw new RuntimeException("Failed: " + s);
       
    96                 }
       
    97                 hasOutput = true;
       
    98             }
       
    99 
       
   100             // evaluate System.err in case of System.out of child process
       
   101             // was empty
       
   102             if (!hasOutput) {
       
   103                 isr = new InputStreamReader(p.getErrorStream());
       
   104                 br = new BufferedReader(isr);
       
   105                 if ((s = br.readLine()) != null) {
       
   106                     System.err.println("Error output:");
       
   107                     System.err.println(s);
       
   108                     while ((s = br.readLine()) != null) {
       
   109                         System.err.println(s);
       
   110                     }
       
   111                 }
       
   112                 throw new RuntimeException("Failed, no output");
       
   113             }
       
   114 
       
   115             // clean up, check multiple releases
       
   116             if (lock != null) {
       
   117                 lock.release();
       
   118                 lock.release();
       
   119             }
       
   120         }
       
   121     }
       
   122 
       
   123     /**
       
   124      * Basic test for FileChannel.lock() and FileChannel.tryLock()
       
   125      */
       
   126     static void test2(File blah, boolean b) throws Exception {
       
   127         try (RandomAccessFile raf = new RandomAccessFile(blah, "rw")) {
       
   128             FileChannel channel = raf.getChannel();
       
   129             FileLock lock;
       
   130             if (b)
       
   131                 lock = channel.lock();
       
   132             else
       
   133                 lock = channel.tryLock();
       
   134             lock.release();
       
   135         }
       
   136     }
       
   137 
       
   138     /**
       
   139      * Test that overlapping file locking is not possible when using different
       
   140      * FileChannel objects to the same file path
       
   141      */
       
   142     static void test3(File blah) throws Exception {
       
   143         try (RandomAccessFile raf1 = new RandomAccessFile(blah, "rw");
       
   144              RandomAccessFile raf2 = new RandomAccessFile(blah, "rw"))
       
   145         {
       
   146             FileChannel fc1 = raf1.getChannel();
       
   147             FileChannel fc2 = raf2.getChannel();
       
   148 
       
   149             // lock via one channel, and then attempt to lock the same file
       
   150             // using a second channel
       
   151             FileLock fl1 = fc1.lock();
       
   152             try {
       
   153                 fc2.tryLock();
       
   154                 throw new RuntimeException("Overlapping locks allowed");
       
   155             } catch (OverlappingFileLockException x) {}
       
   156             try {
       
   157                 fc2.lock();
       
   158                 throw new RuntimeException("Overlapping locks allowed");
       
   159             } catch (OverlappingFileLockException x) {}
       
   160 
       
   161             // release lock and the attempt to lock with the second channel
       
   162             // should succeed.
       
   163             fl1.release();
       
   164             fc2.lock();
       
   165             try {
       
   166                 fc1.lock();
       
   167                 throw new RuntimeException("Overlapping locks allowed");
       
   168             } catch (OverlappingFileLockException x) {}
       
   169         }
       
   170     }
       
   171 
       
   172     /**
       
   173      * Test file locking when file is opened for append
       
   174      */
       
   175     static void test4(File blah) throws Exception {
       
   176         try (FileOutputStream fos = new FileOutputStream(blah, true)) {
       
   177             FileChannel fc = fos.getChannel();
       
   178             fc.tryLock().release();
       
   179             fc.tryLock(0L, 1L, false).release();
       
   180             fc.lock().release();
       
   181             fc.lock(0L, 1L, false).release();
       
   182         }
       
   183         try (FileChannel fc = FileChannel.open(blah.toPath(), APPEND)) {
       
   184             fc.tryLock().release();
       
   185             fc.tryLock(0L, 1L, false).release();
       
   186             fc.lock().release();
       
   187             fc.lock(0L, 1L, false).release();
       
   188         }
       
   189     }
       
   190 
       
   191     /**
       
   192      * Utility method to be run in secondary process which tries to acquire a
       
   193      * lock on a FileChannel
       
   194      */
       
   195     static void attemptLock(String fileName,
       
   196                             boolean expectsLock) throws Exception
       
   197     {
       
   198         File f = new File(fileName);
       
   199         try (RandomAccessFile raf = new RandomAccessFile(f, "rw")) {
       
   200             FileChannel fc = raf.getChannel();
       
   201             if (fc.tryLock(10, 10, false) == null) {
       
   202                 System.out.println("bad: Failed to grab adjacent lock");
       
   203             }
       
   204             if (fc.tryLock(0, 10, false) == null) {
       
   205                 if (expectsLock)
       
   206                     System.out.println("bad");
       
   207                 else
       
   208                     System.out.println("good");
       
   209             } else {
       
   210                 if (expectsLock)
       
   211                     System.out.println("good");
       
   212                 else
       
   213                     System.out.println("bad");
       
   214             }
       
   215         }
       
   216     }
       
   217 }