public void testRemoveMixLockableFromLockedNode()
      throws RepositoryException, NotExecutableException {
    try {
      lockedNode.removeMixin(mixLockable);
      lockedNode.save();

      // the mixin got removed -> the lock should implicitely be released
      // as well in order not to have inconsistencies
      String msg = "Lock should have been released.";
      assertFalse(msg, lock.isLive());
      assertFalse(msg, lockedNode.isLocked());
      assertFalse(msg, lockMgr.isLocked(lockedNode.getPath()));

      assertFalse(msg, lockedNode.hasProperty(jcrLockOwner));
      assertFalse(msg, lockedNode.hasProperty(jcrlockIsDeep));

    } catch (ConstraintViolationException e) {
      // cannot remove the mixin -> ok
      // consequently the node must still be locked, the lock still live...
      String msg = "Lock must still be live.";
      assertTrue(msg, lock.isLive());
      assertTrue(msg, lockedNode.isLocked());
      assertTrue(msg, lockMgr.isLocked(lockedNode.getPath()));

      assertTrue(msg, lockedNode.hasProperty(jcrLockOwner));
      assertTrue(msg, lockedNode.hasProperty(jcrlockIsDeep));
    } finally {
      // ev. re-add the mixin in order to be able to unlock the node
      if (lockedNode.isLocked()) {
        ensureMixinType(lockedNode, mixLockable);
        lockedNode.save();
      }
    }
  }
  /** Test locks are released when session logs out */
  public void testImplicitUnlock() throws RepositoryException, NotExecutableException {
    Session other = getHelper().getReadWriteSession();
    try {
      Node testNode = (Node) other.getItem(testRootNode.getPath());
      Node lockedNode = testNode.addNode(nodeName1, testNodeType);
      other.save();

      assertLockable(lockedNode);

      Lock lock =
          getLockManager(other)
              .lock(
                  lockedNode.getPath(),
                  isDeep(),
                  isSessionScoped(),
                  getTimeoutHint(),
                  getLockOwner());
      other.logout();

      assertFalse(lock.isLive());
    } finally {
      if (other.isLive()) {
        other.logout();
      }
    }
  }
  /**
   * Test if Lock is properly released.
   *
   * @throws RepositoryException
   */
  public void testUnlock() throws RepositoryException {
    // release the lock
    lockMgr.unlock(lockedNode.getPath());

    // assert: lock must not be alive
    assertFalse("lock must not be alive", lock.isLive());
  }
  /** Test expiration of the lock */
  public synchronized void testLockExpiration() throws RepositoryException, NotExecutableException {
    lockedNode.unlock();

    long hint = 1;
    lock = lockMgr.lock(lockedNode.getPath(), isDeep(), isSessionScoped(), hint, null);

    // only test if timeout hint was respected.
    long remaining = lock.getSecondsRemaining();
    if (remaining <= hint) {
      try {
        wait(remaining * 2000); // wait twice as long to be safe
      } catch (InterruptedException ignore) {
      }
      assertTrue(
          "A released lock must return a negative number of seconds",
          lock.getSecondsRemaining() < 0);
      String message =
          "If the timeout hint is respected the lock" + " must be automatically released.";
      assertFalse(message, lock.isLive());
      assertFalse(message, lockedNode.isLocked());
      assertFalse(message, lockMgr.isLocked(lockedNode.getPath()));
      assertFalse(message, lockedNode.hasProperty(Property.JCR_LOCK_IS_DEEP));
      assertFalse(message, lockedNode.hasProperty(Property.JCR_LOCK_OWNER));
    } else {
      throw new NotExecutableException("timeout hint was ignored.");
    }
  }
 /** Test {@link javax.jcr.lock.Lock#getSecondsRemaining()} */
 public void testGetSecondsRemaining() throws RepositoryException {
   if (lock.isLive()) {
     assertTrue("Seconds remaining must be a positive long.", lock.getSecondsRemaining() > 0);
   } else {
     assertTrue("Seconds remaining must be a negative long.", lock.getSecondsRemaining() < 0);
   }
 }
 /** Test {@link javax.jcr.lock.Lock#isLive()}. */
 public void testIsLive() throws RepositoryException {
   assertTrue("Lock.isLive must be true.", lock.isLive());
 }