Package org.lilyproject.util.zookeeper.test

Source Code of org.lilyproject.util.zookeeper.test.ZkLockTest$Variable

/*
* Copyright 2010 Outerthought bvba
*
* Licensed 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.lilyproject.util.zookeeper.test;

import java.io.File;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.hbase.zookeeper.MiniZooKeeperCluster;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.lilyproject.hadooptestfw.TestHelper;
import org.lilyproject.util.io.Closer;
import org.lilyproject.util.net.NetUtils;
import org.lilyproject.util.zookeeper.ZkLock;
import org.lilyproject.util.zookeeper.ZkUtil;
import org.lilyproject.util.zookeeper.ZooKeeperItf;

import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

public class ZkLockTest {
    private static MiniZooKeeperCluster ZK_CLUSTER;
    private static File ZK_DIR;
    private static int ZK_CLIENT_PORT;
    private static ZooKeeperItf ZK;

    private static Log log = LogFactory.getLog(ZkLockTest.class);

    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
        TestHelper.setupLogging("org.lilyproject.util.zookeeper");

        ZK_DIR = new File(System.getProperty("java.io.tmpdir") + File.separator + "lily.zklocktest");
        ZK_CLIENT_PORT = NetUtils.getFreePort();

        ZK_CLUSTER = new MiniZooKeeperCluster();
        ZK_CLUSTER.setDefaultClientPort(ZK_CLIENT_PORT);
        ZK_CLUSTER.startup(ZK_DIR);

        ZK = ZkUtil.connect("localhost:" + ZK_CLIENT_PORT, 30000);
    }

    @AfterClass
    public static void tearDownAfterClass() throws Exception {
        Closer.close(ZK);
        if (ZK_CLUSTER != null) {
            ZK_CLUSTER.shutdown();
        }
    }

    @Test
    public void testObtainReleaseLock() throws Exception {
        ZkUtil.createPath(ZK, "/lily/test/zklockA");
        String obtainedLock = ZkLock.lock(ZK, "/lily/test/zklockA");
        ZkLock.unlock(ZK, obtainedLock);
    }

    /**
     * Tests the following: first user takes lock, then second user tries to take lock before first has released
     * it. Then first releases it, after this second user gets the lock.
     * @throws Exception
     */
    @Test
    public void testTwoUsersForSameLock() throws Exception {
        final String lockPath = "/lily/test/zklockB";
        ZkUtil.createPath(ZK, lockPath);

        log.debug("Request first lock.");
        String obtainedLock1 = ZkLock.lock(ZK, lockPath);
        log.debug("First lock obtained.");

        final Variable<String> obtainedLock2 = new Variable<String>();
        final Variable<Long> obtainTime = new Variable<Long>();
        final Variable<Throwable> throwable = new Variable<Throwable>();

        // The following will block
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    log.debug("Request second lock.");
                    obtainedLock2.value = ZkLock.lock(ZK, lockPath);
                    obtainTime.value = System.currentTimeMillis();
                    log.debug("Second lock obtained.");
                } catch (Throwable t) {
                    throwable.value = t;
                }
            }
        });
        t.start();

        // Wait more then enough time for the second lock to be obtained (thread needs to start)
        Thread.sleep(2000);

        long releaseTime = System.currentTimeMillis();
        log.debug("Will now release first lock.");
        ZkLock.unlock(ZK, obtainedLock1);
        log.debug("First lock released.");

        // wait for thread to end
        t.join();

        if (throwable.value != null) {
            throwable.value.printStackTrace();
            fail("Failure in second lock thread.");
        }

        // It should only be after release of the first lock that the second lock can be obtained.
        log.debug("First lock released at " + releaseTime + ", second lock obtained at " + obtainTime.value);
        assertTrue(releaseTime <= obtainTime.value);

        // remove second lock
        log.debug("Will now release second lock.");
        ZkLock.unlock(ZK, obtainedLock2.value);
        log.debug("Second lock released.");
    }

    public static class Variable<T> {
        public T value;
    }

}
TOP

Related Classes of org.lilyproject.util.zookeeper.test.ZkLockTest$Variable

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.