Package org.lilyproject.repository.model.impl

Source Code of org.lilyproject.repository.model.impl.RepositoryModelTest$TestListener

/*
* Copyright 2013 NGDATA nv
*
* 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.repository.model.impl;

import org.apache.commons.io.FileUtils;
import org.apache.hadoop.hbase.zookeeper.MiniZooKeeperCluster;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.lilyproject.repository.model.api.RepositoryDefinition;
import org.lilyproject.repository.model.api.RepositoryModel;
import org.lilyproject.repository.model.api.RepositoryModelEvent;
import org.lilyproject.repository.model.api.RepositoryModelEventType;
import org.lilyproject.repository.model.api.RepositoryModelListener;
import org.lilyproject.util.net.NetUtils;
import org.lilyproject.util.zookeeper.ZkUtil;
import org.lilyproject.util.zookeeper.ZooKeeperItf;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

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

public class RepositoryModelTest {
    private MiniZooKeeperCluster zkCluster;
    private File zkDir;
    private int zkClientPort;
    private ZooKeeperItf zk;
    private RepositoryModel repositoryModel;

    @Before
    public void setUpBeforeClass() throws Exception {
        zkDir = new File(System.getProperty("java.io.tmpdir") + File.separator + "lily.repositorymodeltest");
        zkClientPort = NetUtils.getFreePort();

        zkCluster = new MiniZooKeeperCluster();
        zkCluster.setDefaultClientPort(zkClientPort);
        zkCluster.startup(zkDir);

        zk = ZkUtil.connect("localhost:" + zkClientPort, 15000);
        repositoryModel = new RepositoryModelImpl(zk);
    }

    @After
    public void tearDownAfterClass() throws Exception {
        if (zk != null) {
            zk.close();
        }

        if (repositoryModel != null) {
            ((RepositoryModelImpl)repositoryModel).close();
        }

        if (zkCluster != null) {
            zkCluster.shutdown();
            FileUtils.deleteDirectory(zkDir);
        }
    }

    @Test
    public void testRepositories() throws Exception {
        TestListener listener = new TestListener();
        repositoryModel.registerListener(listener);

        repositoryModel.create("repo1");
        listener.waitForEvents(1);
        listener.verifyEvents(new RepositoryModelEvent(RepositoryModelEventType.REPOSITORY_ADDED, "repo1"));

        assertFalse(repositoryModel.repositoryExistsAndActive("repo1"));

        assertEquals(2, repositoryModel.getRepositories().size()); // 2 because the default repository is also there

        repositoryModel.updateRepository(new RepositoryDefinition("repo1", RepositoryDefinition.RepositoryLifecycleState.ACTIVE));
        listener.waitForEvents(1);
        listener.verifyEvents(new RepositoryModelEvent(RepositoryModelEventType.REPOSITORY_UPDATED, "repo1"));

        assertTrue(repositoryModel.repositoryExistsAndActive("repo1"));

        repositoryModel.delete("repo1");
        listener.waitForEvents(1);
        listener.verifyEvents(new RepositoryModelEvent(RepositoryModelEventType.REPOSITORY_UPDATED, "repo1"));

        assertEquals(2, repositoryModel.getRepositories().size());
        assertEquals(RepositoryDefinition.RepositoryLifecycleState.DELETE_REQUESTED, repositoryModel.getRepository("repo1").getLifecycleState());

        repositoryModel.deleteDirect("repo1");
        assertEquals(1, repositoryModel.getRepositories().size());
        listener.waitForEvents(1);
        listener.verifyEvents(new RepositoryModelEvent(RepositoryModelEventType.REPOSITORY_REMOVED, "repo1"));

        repositoryModel.unregisterListener(listener);
        repositoryModel.create("repo1");
        Thread.sleep(20); // this is not very robust, but if the code would be wrong this will fail most of the time
        listener.waitForEvents(0);
    }

    @Test
    public void testTwoModelInstances() throws Exception {
        ZooKeeperItf zk1 = ZkUtil.connect("localhost:" + zkClientPort, 15000);
        ZooKeeperItf zk2 = ZkUtil.connect("localhost:" + zkClientPort, 15000);
        RepositoryModel repositoryModel1 = new RepositoryModelImpl(zk1);
        RepositoryModel repositoryModel2 = new RepositoryModelImpl(zk2);

        TestListener model1Listener = new TestListener();
        assertEquals(1, repositoryModel1.getRepositories(model1Listener).size());

        TestListener model2Listener = new TestListener();
        assertEquals(1, repositoryModel2.getRepositories(model2Listener).size());

        repositoryModel1.create("repo1");
        repositoryModel1.create("repo2");
        repositoryModel2.create("repo3");
        repositoryModel2.create("repo4");

        model2Listener.waitForEvents(4);
        model1Listener.waitForEvents(4);

        assertEquals(5, repositoryModel1.getRepositories().size());
        assertEquals(5, repositoryModel2.getRepositories().size());

        ((RepositoryModelImpl)repositoryModel1).close();
        ((RepositoryModelImpl)repositoryModel2).close();

        zk1.close();
        zk2.close();
    }

    @Test(expected = Exception.class)
    public void testDefaultRepositoryCannotBeDeleted() throws Exception {
        repositoryModel.delete("default");
    }

    @Test(expected = Exception.class)
    public void testDefaultRepositoryCannotBeDirectDeleted() throws Exception {
        repositoryModel.deleteDirect("default");
    }

    @Test(expected = Exception.class)
    public void testDefaultRepositoryCannotBeUpdated() throws Exception {
        repositoryModel.updateRepository(new RepositoryDefinition("default", RepositoryDefinition.RepositoryLifecycleState.ACTIVE));
    }

    @Test(expected = Exception.class)
    public void testInvalidRepositoryName() throws Exception {
        repositoryModel.create("repository#");
    }

    @Test(expected = Exception.class)
    public void testInvalidRepositoryName2() throws Exception {
        repositoryModel.create("repository__");
    }

    public static class TestListener implements RepositoryModelListener {
        private List<RepositoryModelEvent> events = new ArrayList<RepositoryModelEvent>();

        @Override
        public void process(RepositoryModelEvent event) {
            events.add(event);
        }

        public void waitForEvents(int count) throws InterruptedException {
            long now = System.currentTimeMillis();
            synchronized (this) {
                while (events.size() < count && System.currentTimeMillis() - now < 60000) {
                    Thread.sleep(50);
                }
            }
        }

        public void verifyEvents(RepositoryModelEvent... expectedEvents) {
            if (events.size() != expectedEvents.length) {
                if (events.size() > 0) {
                    System.out.println("The events are:");
                    for (RepositoryModelEvent event : events) {
                        System.out.println(event.getEventType() + " - " + event.getRepositoryName());
                    }
                } else {
                    System.out.println("There are no events.");
                }

                assertEquals("Expected number of events", expectedEvents.length, events.size());
            }

            Set<RepositoryModelEvent> expectedEventsSet = new HashSet<RepositoryModelEvent>(Arrays.asList(expectedEvents));

            for (RepositoryModelEvent event : expectedEvents) {
                if (!events.contains(event)) {
                    fail("Expected event not present among events: " + event);
                }
            }

            for (RepositoryModelEvent event : events) {
                if (!expectedEventsSet.contains(event)) {
                    fail("Got an event which is not among the expected events: " + event);
                }
            }

            events.clear();
        }
    }

    public static class DummyWatcher implements Watcher {
        @Override
        public void process(WatchedEvent watchedEvent) {
        }
    }
}
TOP

Related Classes of org.lilyproject.repository.model.impl.RepositoryModelTest$TestListener

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.