Package com.splunk.shuttl.archiver.bucketlock

Source Code of com.splunk.shuttl.archiver.bucketlock.SimpleFileLockSharedTest$LockExclusive_Release

// Copyright (C) 2011 Splunk Inc.
//
// Splunk Inc. licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.splunk.shuttl.archiver.bucketlock;

import static org.testng.AssertJUnit.*;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.apache.commons.io.FileUtils;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

import com.splunk.shuttl.testutil.ShellClassRunner;
import com.splunk.shuttl.testutil.TUtilsFile;

/**
* Fixture: One {@link SimpleFileLock} running in this JVM and another
* {@link SimpleFileLock} in another JVM, that uses
* {@link SimpleFileLock#tryLockShared()} to acquire lock.
*/
@Test(groups = { "slow-unit" })
public class SimpleFileLockSharedTest {

  private static final File FILE_TO_LOCK = new File(
      TUtilsFile.getShuttlTestDirectory(),
      SimpleFileLockSharedTest.class.getName() + "-fileToLock");

  private static final int GOT_SHARED_LOCK = 5;
  private static final int NO_SHARED_LOCK = 4;
  private static final int GOT_EXCLUSIVE_LOCK = 10;
  private static final int NO_EXCLUSIVE_LOCK = 11;
  private static final int DATA = 18;

  SimpleFileLock simpleLock;
  ShellClassRunner otherJvmLocker;

  @BeforeMethod
  public void setUp() throws IOException {
    assertTrue(FILE_TO_LOCK.createNewFile());

    otherJvmLocker = new ShellClassRunner();
    simpleLock = getSimpleFileLock();
  }

  @AfterMethod
  public void tearDown() throws IOException {
    otherJvmLocker.kill();
    FileUtils.forceDelete(FILE_TO_LOCK);
  }

  /**
   * Read this test case to understand the rest of the test cases. <br/>
   * <br/>
   * Uses the {@link LockShared_Release} class in combination with
   * {@link ShellClassRunner} for first creating a shared lock in another JVM,
   * and then trying to lock again on this JVM, which doesn't work. <br/>
   * See {@link LockShared_Release} for more information of how it works.
   */
  @Test(groups = { "slow-unit" }, timeOut = 3000)
  public void tryLockShared_noLockOnFile_acquiresLockAndCannotBeLockWithTryLock()
      throws IOException {
    otherJvmLocker.runClassAsync(LockShared_Release.class);
    waitForOtherJvmToTryLock();
    assertFalse(simpleLock.tryLockExclusive());
    signalOtherJvmToFinish();
    assertEquals(GOT_SHARED_LOCK, (int) otherJvmLocker.getExitCode());
  }

  private void waitForOtherJvmToTryLock() throws IOException {
    InputStream in = otherJvmLocker.getInputStreamFromClass();
    in.read();
  }

  private void signalOtherJvmToFinish() throws IOException {
    OutputStream out = otherJvmLocker.getOutputStreamToClass();
    out.write(DATA);
    out.flush();
  }

  @Test(timeOut = 3000)
  public void tryLockShared_lockIsConvertedBetweenExclusiveToShared_acquiresLockAndExclusiveLockAfterDoesntWork()
      throws IOException {
    assertTrue(simpleLock.tryLockExclusive());
    assertTrue(simpleLock.tryConvertExclusiveToSharedLock());
    otherJvmLocker.runClassAsync(LockShared_Release.class);
    waitForOtherJvmToTryLock();
    simpleLock.closeLock();

    // Should not acquire lock even though we just closed it, because of the
    // shared lock by LockShared_Release in the other JVM.
    SimpleFileLock newLock = getSimpleFileLock();
    assertFalse(newLock.tryLockExclusive());
    signalOtherJvmToFinish();
    assertEquals(GOT_SHARED_LOCK, (int) otherJvmLocker.getExitCode());
  }

  @Test(timeOut = 3000)
  public void tryLockShared_fileIsLockedExclusive_cannotGetSharedLock()
      throws IOException {
    assertTrue(simpleLock.tryLockExclusive());
    otherJvmLocker.runClassAsync(LockShared_Release.class);
    waitForOtherJvmToTryLock();
    signalOtherJvmToFinish();
    simpleLock.closeLock();
    assertEquals(NO_SHARED_LOCK, (int) otherJvmLocker.getExitCode());
  }

  @Test(timeOut = 3000)
  public void tryLockExclusive_fileIsLockedExclusive_otherJvmCannotGetExclusiveLock()
      throws IOException {
    assertTrue(simpleLock.tryLockExclusive());
    otherJvmLocker.runClassAsync(LockExclusive_Release.class);
    waitForOtherJvmToTryLock();
    signalOtherJvmToFinish();
    simpleLock.closeLock();
    assertEquals(NO_EXCLUSIVE_LOCK, (int) otherJvmLocker.getExitCode());
  }

  @Test(timeOut = 3000)
  public void tryLockExclusive_otherJvmGetsExclusiveLock_thisJvmCannotGetExclusiveLock()
      throws IOException {
    otherJvmLocker.runClassAsync(LockExclusive_Release.class);
    waitForOtherJvmToTryLock();
    assertFalse(simpleLock.tryLockExclusive());
    signalOtherJvmToFinish();
    simpleLock.closeLock();
    assertEquals(GOT_EXCLUSIVE_LOCK, (int) otherJvmLocker.getExitCode());
  }

  @Test(timeOut = 3000)
  public void tryLockExclusive_otherJvmGetsExclusiveLockThenGetsKilled_thisJvmGetsExclusiveLock()
      throws IOException {
    otherJvmLocker.runClassAsync(LockExclusive_Release.class);
    waitForOtherJvmToTryLock();
    assertFalse(simpleLock.tryLockExclusive());
    otherJvmLocker.kill();
    assertTrue(simpleLock.tryLockExclusive());
    simpleLock.closeLock();
  }

  private static SimpleFileLock getSimpleFileLock() {
    return SimpleFileLock.createFromFile(FILE_TO_LOCK);
  }

  /**
   * Communicates via stdin and stdout, to synchronize that calls are made in
   * the right order. This class first locks a {@link SimpleFileLock} with a
   * shared lock, writes to stdout and waits for a response. It releases the
   * lock once it has gotten a response.
   */
  private static class LockShared_Release {
    @SuppressWarnings("unused")
    public static void main(String[] args) throws IOException {
      SimpleFileLock sharedLock = getSimpleFileLock();
      boolean lockedShared = sharedLock.tryLockShared();
      writeData(); // Notifies that it's first action has been made
      readData(); // Waits until it can go again.
      sharedLock.closeLock();
      if (lockedShared)
        System.exit(GOT_SHARED_LOCK);
      else
        System.exit(NO_SHARED_LOCK);
    }
  }

  private static void writeData() {
    System.out.write(DATA);
    System.out.flush();
  }

  private static void readData() throws IOException {
    InputStream in = System.in;
    in.read();
  }

  /**
   * Communicates via stdin and stdout, to synchronize that calls are made in
   * the right order. This class first locks a {@link SimpleFileLock} with a
   * shared lock, writes to stdout and waits for a response. It releases the
   * lock once it has gotten a response.
   */
  private static class LockExclusive_Release {
    @SuppressWarnings("unused")
    public static void main(String[] args) throws IOException {
      SimpleFileLock exclusiveLock = getSimpleFileLock();
      boolean lockExclusive = exclusiveLock.tryLockExclusive();
      writeData(); // Notifies that it's first action has been made
      readData(); // Waits until it can go again.
      exclusiveLock.closeLock();
      if (lockExclusive)
        System.exit(GOT_EXCLUSIVE_LOCK);
      else
        System.exit(NO_EXCLUSIVE_LOCK);
    }
  }
}
TOP

Related Classes of com.splunk.shuttl.archiver.bucketlock.SimpleFileLockSharedTest$LockExclusive_Release

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.