/*
 * The MIT License (MIT)
 * 
 * Copyright (c) 2014 Jeff Nelson, Cinchapi Software Collective
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package org.cinchapi.concourse.server.concurrent;

import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;

import org.cinchapi.concourse.ConcourseBaseTest;
import org.cinchapi.concourse.util.TestData;
import org.junit.Assert;
import org.junit.Test;

/**
 * Unit tests for {@link LockService}.
 * 
 * @author jnelson
 */
public class LockServiceTest extends ConcourseBaseTest {
    
    private LockService lockService;
    
    @Override
    protected void beforeEachTest() {
        lockService = LockService.create();
    }

    @Test
    public void testLockServiceDoesNotEvictLocksThatAreBeingUsed()
            throws InterruptedException {

        final AtomicBoolean done = new AtomicBoolean(false);
        final AtomicBoolean passed = new AtomicBoolean(true);
        Thread a = new Thread(new Runnable() {

            @Override
            public void run() {
                while (!done.get()) {
                    try {
                        lockService.getReadLock("foo", 1).lock();
                        lockService.getReadLock("foo", 1).unlock();
                    }
                    catch (IllegalMonitorStateException e) {
                        e.printStackTrace();
                        passed.set(false);
                        done.set(true);
                        break;
                    }
                }
            }

        });

        Thread b = new Thread(new Runnable() {

            @Override
            public void run() {
                while (!done.get()) {
                    try {
                        lockService.getWriteLock("foo", 1).lock();
                        lockService.getWriteLock("foo", 1).unlock();
                    }
                    catch (IllegalMonitorStateException e) {
                        e.printStackTrace();
                        passed.set(false);
                        done.set(true);
                        break;

                    }
                }
            }

        });
        Thread c = new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    Thread.sleep(TestData.getScaleCount() * 10);
                    done.set(true);
                }
                catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        });
        a.start();
        b.start();
        TestData.getScaleCount(); // make sure that a and b start first
        c.start();
        a.join();
        b.join();
        c.join();
        Assert.assertTrue(passed.get());
    }

    @Test(expected = IllegalMonitorStateException.class)
    public void testLockServiceDoesEvictLocksThatAreNotBeingUsed() {
        ReadLock a = lockService.getReadLock("foo");
        a.lock();
        lockService.getReadLock("foo").unlock();
        lockService.getReadLock("foo").lock();
        a.unlock();
    

    }

}

@@ -1459,16 +1459,41 @@
 Assert;%0A
+import org.junit.Ignore;%0A
 import o
@@ -1635,20 +1635,16 @@
 eTest %7B%0A
-    
 %0A    pri
@@ -1673,20 +1673,16 @@
 ervice;%0A
-    
 %0A    @Ov
@@ -3908,16 +3908,28 @@
 .class)%0A
+    @Ignore%0A
     publ
@@ -3985,24 +3985,164 @@
 ingUsed() %7B%0A
+        // (9/28/2014) - This test should be ignored since lock eviction is%0A        // handled by the Guava cache based on memory pressure.%0A
         Read
@@ -4288,32 +4288,32 @@
 (%22foo%22).lock();%0A
+
         a.unlock
@@ -4315,21 +4315,16 @@
 nlock();
-%0A    
 %0A%0A    %7D%0A

fix flaky test