Package org.apache.accumulo.fate.zookeeper

Source Code of org.apache.accumulo.fate.zookeeper.ZooLockTest

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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 org.apache.accumulo.fate.zookeeper;

import java.io.File;
import java.lang.reflect.Field;
import java.util.Collections;
import java.util.List;

import org.apache.accumulo.fate.zookeeper.ZooLock.AsyncLockWatcher;
import org.apache.accumulo.fate.zookeeper.ZooLock.LockLossReason;
import org.apache.accumulo.minicluster.MiniAccumuloCluster;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

/**
*
*/
public class ZooLockTest {

  public static TemporaryFolder folder = new TemporaryFolder(new File(System.getProperty("user.dir") + "/target"));

  private static MiniAccumuloCluster accumulo;

  static class TestALW implements AsyncLockWatcher {

    LockLossReason reason = null;
    boolean locked = false;
    Exception exception = null;
    int changes = 0;

    @Override
    public synchronized void lostLock(LockLossReason reason) {
      this.reason = reason;
      changes++;
      this.notifyAll();
    }

    @Override
    public synchronized void acquiredLock() {
      this.locked = true;
      changes++;
      this.notifyAll();
    }

    @Override
    public synchronized void failedToAcquireLock(Exception e) {
      this.exception = e;
      changes++;
      this.notifyAll();
    }

    public synchronized void waitForChanges(int numExpected) throws InterruptedException {
      while (changes < numExpected) {
        this.wait();
      }
    }

    @Override
    public synchronized void unableToMonitorLockNode(Throwable e) {
      changes++;
      this.notifyAll();
    }
  }

  @BeforeClass
  public static void setupMiniCluster() throws Exception {

    folder.create();

    Logger.getLogger("org.apache.zookeeper").setLevel(Level.ERROR);

    accumulo = new MiniAccumuloCluster(folder.getRoot(), "superSecret");

    accumulo.start();

  }

  private static int pdCount = 0;

  @Test(timeout = 10000)
  public void testDeleteParent() throws Exception {
    accumulo.getZooKeepers();

    String parent = "/zltest-" + this.hashCode() + "-l" + pdCount++;

    ZooLock zl = new ZooLock(accumulo.getZooKeepers(), 30000, "digest", "secret".getBytes(), parent);

    Assert.assertFalse(zl.isLocked());

    ZooReaderWriter zk = ZooReaderWriter.getInstance(accumulo.getZooKeepers(), 30000, "digest", "secret".getBytes());

    // intentionally created parent after lock
    zk.mkdirs(parent);

    zk.delete(parent, -1);

    zk.mkdirs(parent);

    TestALW lw = new TestALW();

    zl.lockAsync(lw, "test1".getBytes());

    lw.waitForChanges(1);

    Assert.assertTrue(lw.locked);
    Assert.assertTrue(zl.isLocked());
    Assert.assertNull(lw.exception);
    Assert.assertNull(lw.reason);

    zl.unlock();
  }

  @Test(timeout = 10000)
  public void testNoParent() throws Exception {
    accumulo.getZooKeepers();

    String parent = "/zltest-" + this.hashCode() + "-l" + pdCount++;

    ZooLock zl = new ZooLock(accumulo.getZooKeepers(), 30000, "digest", "secret".getBytes(), parent);

    Assert.assertFalse(zl.isLocked());

    TestALW lw = new TestALW();

    zl.lockAsync(lw, "test1".getBytes());

    lw.waitForChanges(1);

    Assert.assertFalse(lw.locked);
    Assert.assertFalse(zl.isLocked());
    Assert.assertNotNull(lw.exception);
    Assert.assertNull(lw.reason);
  }

  @Test(timeout = 10000)
  public void testDeleteLock() throws Exception {
    accumulo.getZooKeepers();

    String parent = "/zltest-" + this.hashCode() + "-l" + pdCount++;

    ZooReaderWriter zk = ZooReaderWriter.getInstance(accumulo.getZooKeepers(), 30000, "digest", "secret".getBytes());
    zk.mkdirs(parent);

    ZooLock zl = new ZooLock(accumulo.getZooKeepers(), 30000, "digest", "secret".getBytes(), parent);

    Assert.assertFalse(zl.isLocked());

    TestALW lw = new TestALW();

    zl.lockAsync(lw, "test1".getBytes());

    lw.waitForChanges(1);

    Assert.assertTrue(lw.locked);
    Assert.assertTrue(zl.isLocked());
    Assert.assertNull(lw.exception);
    Assert.assertNull(lw.reason);

    zk.delete(zl.getLockPath(), -1);

    lw.waitForChanges(2);

    Assert.assertEquals(LockLossReason.LOCK_DELETED, lw.reason);
    Assert.assertNull(lw.exception);

  }

  @Test(timeout = 10000)
  public void testDeleteWaiting() throws Exception {
    accumulo.getZooKeepers();

    String parent = "/zltest-" + this.hashCode() + "-l" + pdCount++;

    ZooReaderWriter zk = ZooReaderWriter.getInstance(accumulo.getZooKeepers(), 30000, "digest", "secret".getBytes());
    zk.mkdirs(parent);

    ZooLock zl = new ZooLock(accumulo.getZooKeepers(), 30000, "digest", "secret".getBytes(), parent);

    Assert.assertFalse(zl.isLocked());

    TestALW lw = new TestALW();

    zl.lockAsync(lw, "test1".getBytes());

    lw.waitForChanges(1);

    Assert.assertTrue(lw.locked);
    Assert.assertTrue(zl.isLocked());
    Assert.assertNull(lw.exception);
    Assert.assertNull(lw.reason);

    ZooLock zl2 = new ZooLock(accumulo.getZooKeepers(), 30000, "digest", "secret".getBytes(), parent);

    TestALW lw2 = new TestALW();

    zl2.lockAsync(lw2, "test2".getBytes());

    Assert.assertFalse(lw2.locked);
    Assert.assertFalse(zl2.isLocked());

    ZooLock zl3 = new ZooLock(accumulo.getZooKeepers(), 30000, "digest", "secret".getBytes(), parent);

    TestALW lw3 = new TestALW();

    zl3.lockAsync(lw3, "test3".getBytes());

    List<String> children = zk.getChildren(parent);
    Collections.sort(children);

    zk.delete(parent + "/" + children.get(1), -1);

    lw2.waitForChanges(1);

    Assert.assertFalse(lw2.locked);
    Assert.assertNotNull(lw2.exception);
    Assert.assertNull(lw2.reason);

    zk.delete(parent + "/" + children.get(0), -1);

    lw.waitForChanges(2);

    Assert.assertEquals(LockLossReason.LOCK_DELETED, lw.reason);
    Assert.assertNull(lw.exception);

    lw3.waitForChanges(1);

    Assert.assertTrue(lw3.locked);
    Assert.assertTrue(zl3.isLocked());
    Assert.assertNull(lw3.exception);
    Assert.assertNull(lw3.reason);

    zl3.unlock();

  }

  @Test(timeout = 10000)
  public void testUnexpectedEvent() throws Exception {
    accumulo.getZooKeepers();

    String parent = "/zltest-" + this.hashCode() + "-l" + pdCount++;

    ZooKeeper zk = new ZooKeeper(accumulo.getZooKeepers(), 30000, null);
    zk.addAuthInfo("digest", "secret".getBytes());

    zk.create(parent, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);

    ZooLock zl = new ZooLock(accumulo.getZooKeepers(), 30000, "digest", "secret".getBytes(), parent);

    Assert.assertFalse(zl.isLocked());

    // would not expect data to be set on this node, but it should not cause problems.....
    zk.setData(parent, "foo".getBytes(), -1);

    TestALW lw = new TestALW();

    zl.lockAsync(lw, "test1".getBytes());

    lw.waitForChanges(1);

    Assert.assertTrue(lw.locked);
    Assert.assertTrue(zl.isLocked());
    Assert.assertNull(lw.exception);
    Assert.assertNull(lw.reason);

    // would not expect data to be set on this node either
    zk.setData(zl.getLockPath(), "bar".getBytes(), -1);

    zk.delete(zl.getLockPath(), -1);

    lw.waitForChanges(2);

    Assert.assertEquals(LockLossReason.LOCK_DELETED, lw.reason);
    Assert.assertNull(lw.exception);

  }

  @Test(timeout = 10000)
  public void testTryLock() throws Exception {
    String parent = "/zltest-" + this.hashCode() + "-l" + pdCount++;

    ZooLock zl = new ZooLock(accumulo.getZooKeepers(), 1000, "digest", "secret".getBytes(), parent);

    ZooKeeper zk = new ZooKeeper(accumulo.getZooKeepers(), 1000, null);
    zk.addAuthInfo("digest", "secret".getBytes());

    for (int i = 0; i < 10; i++) {
      zk.create(parent, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
      zk.delete(parent, -1);
    }

    zk.create(parent, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);

    TestALW lw = new TestALW();

    boolean ret = zl.tryLock(lw, "test1".getBytes());

    Assert.assertTrue(ret);

    // make sure still watching parent even though a lot of events occurred for the parent
    synchronized (zl) {
      Field field = zl.getClass().getDeclaredField("watchingParent");
      field.setAccessible(true);
      Assert.assertTrue((Boolean) field.get(zl));
    }

    zl.unlock();
  }

  @Test(timeout = 10000)
  public void testChangeData() throws Exception {
    String parent = "/zltest-" + this.hashCode() + "-l" + pdCount++;
    ZooKeeper zk = new ZooKeeper(accumulo.getZooKeepers(), 1000, null);
    zk.addAuthInfo("digest", "secret".getBytes());
    zk.create(parent, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);

    ZooLock zl = new ZooLock(accumulo.getZooKeepers(), 1000, "digest", "secret".getBytes(), parent);

    TestALW lw = new TestALW();

    zl.lockAsync(lw, "test1".getBytes());
    Assert.assertEquals("test1", new String(zk.getData(zl.getLockPath(), null, null)));

    zl.replaceLockData("test2".getBytes());
    Assert.assertEquals("test2", new String(zk.getData(zl.getLockPath(), null, null)));
  }

  @AfterClass
  public static void tearDownMiniCluster() throws Exception {
    accumulo.stop();
    folder.delete();
  }

}
TOP

Related Classes of org.apache.accumulo.fate.zookeeper.ZooLockTest

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.