/** @throws Exception If test failed. */
  public void testBasicLock() throws Exception {
    IgniteCache<Integer, String> cache = ignite1.cache(null);

    Lock lock = cache.lock(1);

    lock.lock();

    assert cache.isLocalLocked(1, false);
    assert cache.isLocalLocked(1, true);

    lock.unlock();

    checkUnlocked(cache, 1);
  }
  /** @throws Exception If failed. */
  public void testTwoCaches() throws Exception {
    IgniteCache<Integer, String> cache1 = ignite1.cache(CACHE1);
    IgniteCache<Integer, String> cache2 = ignite1.cache(CACHE2);

    final Integer key = primaryKey(cache1);

    Lock lock = cache1.lock(key);

    lock.lock();

    try {
      assertTrue(cache1.isLocalLocked(key, true));
      assertTrue(cache1.isLocalLocked(key, false));

      assertFalse(cache2.isLocalLocked(key, true));
      assertFalse(cache2.isLocalLocked(key, false));
    } finally {
      lock.unlock();
    }
  }
  /**
   * @param cache Cache.
   * @param key Key.
   * @throws IgniteCheckedException If failed.
   */
  @SuppressWarnings({"BusyWait"})
  private void checkUnlocked(IgniteCache<Integer, String> cache, Integer key)
      throws IgniteCheckedException {
    assert !cache.isLocalLocked(key, true);

    if (partitioned()) {
      for (int i = 0; i < 200; i++)
        if (cache.isLocalLocked(key, false)) {
          try {
            Thread.sleep(10);
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
        } else return;
    }

    assertFalse(
        "Key locked [key=" + key + ", entries=" + entries(key) + "]",
        cache.isLocalLocked(key, false));
  }
  /** @throws Exception If test fails. */
  public void testMultiNodeLockWithKeyLists() throws Exception {
    IgniteCache<Integer, String> cache1 = ignite1.cache(null);
    IgniteCache<Integer, String> cache2 = ignite2.cache(null);

    Collection<Integer> keys1 = Arrays.asList(1, 2, 3);
    Collection<Integer> keys2 = Arrays.asList(2, 3, 4);

    Lock lock1_1 = cache1.lockAll(keys1);
    Lock lock2_2 = cache2.lockAll(keys2);

    lock1_1.lock();

    checkLocked(cache1, keys1);

    try {
      assert !lock2_2.tryLock();

      assert cache2.isLocalLocked(2, false);
      assert cache2.isLocalLocked(3, false);

      checkUnlocked(cache1, 4);
      checkUnlocked(cache2, 4);

      assert !cache2.isLocalLocked(2, true);
      assert !cache2.isLocalLocked(3, true);
      assert !cache2.isLocalLocked(4, true);
    } finally {
      lock1_1.unlock();
    }

    checkUnlocked(cache1, keys1);

    checkUnlocked(cache1, keys2);
    checkUnlocked(cache2, 4);

    lock2_2.lock();

    CountDownLatch latch1 = new CountDownLatch(keys2.size());
    CountDownLatch latch2 = new CountDownLatch(1);

    addListener(ignite2, new UnlockListener(latch2, 1));
    addListener(ignite1, (new UnlockListener(latch1, keys2)));

    Lock lock1_ = cache1.lock(1);

    try {
      checkLocked(cache2, keys2);

      checkUnlocked(cache2, 1);

      assert lock1_.tryLock();

      checkLocked(cache1, 1);

      checkRemoteLocked(cache1, keys2);

      checkRemoteLocked(cache2, 1);
    } finally {
      lock2_2.unlock();

      lock1_.unlock();
    }

    latch1.await();
    latch2.await();

    checkUnlocked(cache1, keys1);
    checkUnlocked(cache2, keys1);
    checkUnlocked(cache1, keys2);
    checkUnlocked(cache2, keys2);
  }
  /** @throws Exception If test fails. */
  public void testMultiNodeLock() throws Exception {
    IgniteCache<Integer, String> cache1 = ignite1.cache(null);
    IgniteCache<Integer, String> cache2 = ignite2.cache(null);

    Lock lock1_1 = cache1.lock(1);
    Lock lock2_1 = cache2.lock(1);

    lock1_1.lock();

    try {
      assert cache1.isLocalLocked(1, false) : entries(1);
      assert cache1.isLocalLocked(1, true);

      assert cache2.isLocalLocked(1, false) : entries(1);
      assert !cache2.isLocalLocked(1, true);

      assert !lock2_1.tryLock();

      assert cache2.isLocalLocked(1, false) : entries(1);
      assert !cache2.isLocalLocked(1, true);
    } finally {
      lock1_1.unlock();

      checkUnlocked(cache1, 1);
    }

    CountDownLatch latch = new CountDownLatch(1);

    lock2_1.lock();

    try {
      assert cache2.isLocalLocked(1, false) : entries(1);
      assert cache2.isLocalLocked(1, true);

      assert cache1.isLocalLocked(1, false) : entries(1);
      assert !cache1.isLocalLocked(1, true);

      addListener(ignite1, new UnlockListener(latch, 1));

      assert !lock1_1.tryLock();

      assert cache1.isLocalLocked(1, false) : entries(1);
      assert !cache1.isLocalLocked(1, true);
    } finally {
      lock2_1.unlock();
    }

    latch.await();

    checkUnlocked(cache1, 1);
    checkUnlocked(cache2, 1);
  }
 /**
  * @param cache Cache.
  * @param key Key.
  */
 private void checkRemoteLocked(IgniteCache<Integer, String> cache, Integer key) {
   assert cache.isLocalLocked(key, false);
   assert !cache.isLocalLocked(key, true);
 }