/* Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved. Contact: SYSTAP, LLC DBA Blazegraph 2501 Calvert ST NW #106 Washington, DC 20008 licenses@blazegraph.com This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * Created on Sep 19, 2008 */ package com.bigdata.io; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.channels.FileChannel; import java.nio.channels.FileLock; import java.nio.channels.OverlappingFileLockException; import junit.framework.TestCase2; /** * Test suite for {@link FileLockUtility}. * * @todo this test suite could be developed further. * * @author <a href="mailto:thompsonbry@users.sourceforge.net">Bryan Thompson</a> * @version $Id$ */ public class TestFileLockUtility extends TestCase2 { /** * */ public TestFileLockUtility() { } /** * @param arg0 */ public TestFileLockUtility(String arg0) { super(arg0); } /** * Test verifies creation of an exclusive lock, that an advisory lock was * NOT created, and that the {@link FileChannel} is correctly closed. * * @throws IOException */ public void test_exclusiveLock() throws IOException { final File file = File.createTempFile(getClass().getSimpleName(), getName()); RandomAccessFile raf = null; try { raf = FileLockUtility.openFile(file, "rw", true/* useFileLock */); final File lockFile = new File(file + ".lock"); assertFalse("Created an advisory lock: file=" + file, lockFile .exists()); try { // verify FileLock is in place. raf.getChannel().tryLock(); fail("Expecting: " + OverlappingFileLockException.class); } catch (OverlappingFileLockException ex) { log.info("Ignoring expected exception: " + ex); } // close the file. FileLockUtility.closeFile(file, raf); // verify that the channel was closed. raf.getChannel().isOpen(); } finally { if (raf != null && raf.getChannel().isOpen()) { raf.close(); } file.delete(); } } /** * Test creation of an advisory lock, that * {@link FileLockUtility#openFile(File, String, boolean)} will not grant an * exclusive {@link FileLock} if an advisory lock exists for a file, and * that the advisory lock is removed when the file is closed using * {@link FileLockUtility#closeFile(File, RandomAccessFile)}. * * @throws IOException */ public void test_advisoryLock() throws IOException { final File file = File.createTempFile(getClass().getSimpleName(), getName()); final File lockFile = new File(file + ".lock"); RandomAccessFile raf = null; try { raf = FileLockUtility.openFile(file, "rw", false/* useFileLock */); assertTrue("Did not create an advisory lock: file=" + file, lockFile .exists()); try { // verify FileLock is NOT in place. FileLock fileLock = raf.getChannel().tryLock(); assertNotNull("FileLock was created.", fileLock); } catch (Throwable t) { log.warn("FileLock not available: " + t + " for " + file); } /* * In fact, we allow "re-entrant" advisory locks in order to handle * asynchronous close of the file channel by an interrupt. * Asynchronous close correctly releases a FileLock, but there is no * way to have it delete our advisory lock so we allow re-entrant * advisory locks instead as long as it is the same process seeking * the lock. */ // try { // // /* // * verify that we notice an existing advisory lock when // * requsting another advisory lock for the same file. // */ // FileLockUtility.openFile(file, "rw", false/*useFileLock*/); // // fail("Expecting: "+IOException.class); // // } catch(IOException ex) { // // log.warn("Ignoring expected exception: "+ex); // // } try { /* * verify that we notice an existing advisory lock when * requsting an exclusive lock for the same file. */ FileLockUtility.openFile(file, "rw", true/* useFileLock */); fail("Expecting: "+IOException.class); } catch(IOException ex) { log.warn("Ignoring expected exception: "+ex); } // close the file. FileLockUtility.closeFile(file, raf); // verify that the channel was closed. raf.getChannel().isOpen(); // verify that the advisory lock was removed. assertFalse("Did not remove advisory lock: file=" + file, lockFile .exists()); } finally { if (raf != null && raf.getChannel().isOpen()) { raf.close(); } file.delete(); lockFile.delete(); } } }