package com.hazelcast.jmx;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.util.concurrent.TimeUnit;

import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;

import com.hazelcast.core.ILock;
import com.hazelcast.test.HazelcastParallelClassRunner;
import com.hazelcast.test.HazelcastTestSupport;
import com.hazelcast.test.annotation.QuickTest;

@RunWith(HazelcastParallelClassRunner.class)
@Category(QuickTest.class)
public class LockMBeanTest extends HazelcastTestSupport {

    private JmxTestDataHolder holder = new JmxTestDataHolder();
    private ILock lock = holder.getHz().getLock("lock");

    @Before
    public void ensureMBeanCreated() throws Exception {
        // --- Check that mbean gets created at all
        holder.assertMBeanExistEventually("ILock", lock.getName());
    }

    @Test
    public void testLockCountIsTwo_whenLockedTwice() throws Exception {
        lock.lock(1000, TimeUnit.MILLISECONDS);
        lock.lock(1000, TimeUnit.MILLISECONDS);

        // --- Check number of times locked (locked twice now)
        int lockCount = (Integer) holder.getMBeanAttribute("ILock", lock.getName(), "lockCount");

        assertEquals(2, lockCount);
    }

    @Test
    public void testMBeanHasLeaseTime_whenLockedWithLeaseTime() throws Exception {
        lock.lock(1000, TimeUnit.MILLISECONDS);

        // --- Check remaining lease time
        Thread.sleep(20);
        long remainingLeaseTime = (Long) holder.getMBeanAttribute("ILock", lock.getName(), "remainingLeaseTime");

        // The remaining lease time has to be in the given range from the originally set value
        assertTrue("Lease time: " + remainingLeaseTime, remainingLeaseTime > 0 && remainingLeaseTime < 1000);
    }

    @Test
    public void testIsNotLocked_whenMBeanForceUnlocked() throws Exception {
        lock.lock(1000, TimeUnit.MILLISECONDS);

        holder.invokeMBeanOperation("ILock", lock.getName(), "forceUnlock", null, null);

        assertFalse("Lock is locked", lock.isLocked() );
    }
}

@@ -1415,16 +1415,62 @@
 easeTime
+_remainingLeaseTimeCannotBeGreaterThanOriginal
 () throw
@@ -1544,65 +1544,401 @@
     
-// --- Check remaining lease time%0A        Thread.sleep(20
+long remainingLeaseTime = (Long) holder.getMBeanAttribute(%22ILock%22, lock.getName(), %22remainingLeaseTime%22);%0A        assertFalse(remainingLeaseTime %3E 1000);%0A    %7D%0A%0A    @Test%0A    public void testMBeanHasLeaseTime_whenLockedWithLeaseTime_mustBeLockedWhenHasRemainingLease() throws Exception %7B%0A        lock.lock(1000, TimeUnit.MILLISECONDS);%0A%0A        boolean isLocked = lock.isLockedByCurrentThread(
 );%0A 
@@ -2050,25 +2050,24 @@
 Time%22);%0A
-%0A
         
 // The r
@@ -2062,14 +2062,35 @@
     
-// The
+boolean hasRemainingLease =
  rem
@@ -2099,186 +2099,557 @@
 ning
- l
+L
 ease
- time has to be in the given range from the originally set value%0A        assertTrue(%22Lease time: %22 + remainingLeaseTime, remainingLeaseTime %3E 0 && remainingLeaseTime %3C 1000
+Time %3E 0;%0A        assertTrue(isLocked %7C%7C !hasRemainingLease);%0A    %7D%0A%0A%0A    @Test%0A    public void testMBeanHasLeaseTime_whenLockedWithLeaseTime_eitherHasRemainingLeaseOrIsUnlocked() throws Exception %7B%0A        lock.lock(1000, TimeUnit.MILLISECONDS);%0A%0A        long remainingLeaseTime = (Long) holder.getMBeanAttribute(%22ILock%22, lock.getName(), %22remainingLeaseTime%22);%0A        boolean hasLeaseRemaining = remainingLeaseTime %3E 0;%0A        boolean isLocked = lock.isLockedByCurrentThread();%0A        assertTrue((isLocked && hasLeaseRemaining) %7C%7C !isLocked
 );%0A 
@@ -2932,17 +2932,16 @@
 Locked()
- 
 );%0A    %7D

update for fix