com.pinterest.terrapin.zookeeper.ZooKeeperManagerTest.java Source code

Java tutorial

Introduction

Here is the source code for com.pinterest.terrapin.zookeeper.ZooKeeperManagerTest.java

Source

/**
* 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 com.pinterest.terrapin.zookeeper;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyListOf;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.powermock.api.mockito.PowerMockito.verifyStatic;

import com.pinterest.terrapin.thrift.generated.Options;

import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Sets;
import com.twitter.common.zookeeper.ZooKeeperClient;
import com.twitter.common.zookeeper.ZooKeeperMap;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.ACL;
import org.apache.zookeeper.data.Stat;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.api.support.membermodification.MemberModifier;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import java.net.InetSocketAddress;
import java.util.Map;
import java.util.Set;

@RunWith(PowerMockRunner.class)
public class ZooKeeperManagerTest {
    private static final String CLUSTER_NAME = "test_cluster";
    private static final String FILE_SET = "test_fileset";
    private static final FileSetInfo FILE_SET_INFO = new FileSetInfo();
    private static final String FILE_SET_DIR = "/" + CLUSTER_NAME + "/filesets";
    private static final String VIEWS_DIR = "/" + CLUSTER_NAME + "/views";
    private static final String LOCKS_DIR = "/" + CLUSTER_NAME + "/locks";
    private static final String FILE_SET_PATH = FILE_SET_DIR + "/" + FILE_SET;
    private static final String FILE_SET_LOCK_PATH = LOCKS_DIR + "/" + FILE_SET;

    private ZooKeeperManager zkManager;
    private ZooKeeperClient zkClient;
    private ZooKeeper zk;

    @Before
    public void setUp() throws Exception {
        zkClient = mock(ZooKeeperClient.class);
        zk = mock(ZooKeeper.class);
        zkManager = new ZooKeeperManager(zkClient, CLUSTER_NAME);
        when(zkClient.get()).thenReturn(zk);
    }

    @Test
    public void testCreateClusterPaths() throws Exception {
        when(zk.create(anyString(), any(byte[].class), anyListOf(ACL.class), any(CreateMode.class))).thenReturn("");
        ArgumentCaptor<String> pathCaptor = ArgumentCaptor.forClass(String.class);
        zkManager.createClusterPaths();

        verify(zk, times(3)).create(pathCaptor.capture(), any(byte[].class), anyListOf(ACL.class),
                any(CreateMode.class));
        Set<String> allPaths = Sets.newHashSet(pathCaptor.getAllValues());
        assertTrue(allPaths.contains(FILE_SET_DIR));
        assertTrue(allPaths.contains(VIEWS_DIR));
        assertTrue(allPaths.contains(LOCKS_DIR));
    }

    @Test
    @PrepareForTest(ZooKeeperMap.class)
    public void testRegisterWatchAllFileSets() throws Exception {
        PowerMockito.mockStatic(ZooKeeperMap.class);
        when(ZooKeeperMap.create(any(ZooKeeperClient.class), anyString(), any(Function.class))).thenReturn(null);
        ArgumentCaptor<String> pathCaptor = ArgumentCaptor.forClass(String.class);
        zkManager.registerWatchAllFileSets();
        verifyStatic(times(2));
        ZooKeeperMap.create(any(ZooKeeperClient.class), pathCaptor.capture(), any(Function.class));
        Set<String> allPaths = Sets.newHashSet(pathCaptor.getAllValues());
        assertTrue(allPaths.contains(FILE_SET_DIR));
        assertTrue(allPaths.contains(VIEWS_DIR));
    }

    @Test
    public void testLockFileSet() throws Exception {
        when(zk.create(anyString(), any(byte[].class), anyListOf(ACL.class), any(CreateMode.class))).thenReturn("");
        CreateMode mode = CreateMode.EPHEMERAL;
        zkManager.lockFileSet(FILE_SET, FILE_SET_INFO, mode);
        verify(zk).create(eq(FILE_SET_LOCK_PATH), any(byte[].class), anyListOf(ACL.class), eq(mode));
    }

    @Test
    public void testUnlockFileSet() throws Exception {
        doNothing().when(zk).delete(anyString(), anyInt());
        ArgumentCaptor<String> pathCaptor = ArgumentCaptor.forClass(String.class);
        ArgumentCaptor<Integer> versionCaptor = ArgumentCaptor.forClass(Integer.class);
        zkManager.unlockFileSet(FILE_SET);
        verify(zk).delete(pathCaptor.capture(), versionCaptor.capture());
        assertEquals(FILE_SET_LOCK_PATH, pathCaptor.getValue());
        assertEquals(new Integer(-1), versionCaptor.getValue());
    }

    @Test
    public void testSetNonExistingFileSetInfo() throws Exception {
        when(zk.exists(anyString(), anyBoolean())).thenReturn(null);
        when(zk.create(anyString(), any(byte[].class), anyListOf(ACL.class), any(CreateMode.class))).thenReturn("");
        zkManager.setFileSetInfo(FILE_SET, FILE_SET_INFO);

        verify(zk).exists(eq(FILE_SET_PATH), eq(false));
        verify(zk).create(eq(FILE_SET_PATH), eq(FILE_SET_INFO.toJson()), anyListOf(ACL.class),
                any(CreateMode.class));
    }

    @Test
    public void testSetExistingFileSetInfo() throws Exception {
        when(zk.exists(anyString(), anyBoolean())).thenReturn(mock(Stat.class));
        when(zk.setData(anyString(), any(byte[].class), anyInt())).thenReturn(mock(Stat.class));
        zkManager.setFileSetInfo(FILE_SET, FILE_SET_INFO);
        verify(zk).exists(eq(FILE_SET_PATH), eq(false));
        verify(zk).setData(eq(FILE_SET_PATH), eq(FILE_SET_INFO.toJson()), eq(-1));
    }

    @Test
    public void testDeleteFileSetInfo() throws Exception {
        doNothing().when(zk).delete(anyString(), anyInt());
        zkManager.deleteFileSetInfo(FILE_SET);
        verify(zk).delete(eq(FILE_SET_PATH), eq(-1));
    }

    @Test
    public void testGetViewInfo() throws Exception {
        PowerMockito.mockStatic(ZooKeeperMap.class);
        ViewInfo viewInfo = new ViewInfo();
        String resource1 = "test_view";
        MemberModifier.field(ZooKeeperManager.class, "viewInfoMap").set(zkManager,
                ImmutableMap.of(resource1, viewInfo));
        assertNotNull(zkManager.getViewInfo(resource1));
        assertNull(zkManager.getViewInfo("non_existing"));
    }

    @Test
    public void testSetExistingViewInfo() throws Exception {
        ViewInfo viewInfo = mock(ViewInfo.class);
        String resource = "test_resource";
        String resourcePath = VIEWS_DIR + "/" + resource;
        byte[] resourceData = "hello".getBytes();
        when(viewInfo.toCompressedJson()).thenReturn(resourceData);
        when(viewInfo.hasOnlinePartitions()).thenReturn(true);
        when(viewInfo.getResource()).thenReturn(resource);
        when(zk.exists(eq(resourcePath), anyBoolean())).thenReturn(new Stat());
        when(zk.setData(eq(resourcePath), eq(resourceData), eq(-1))).thenReturn(new Stat());
        zkManager.setViewInfo(viewInfo);
        verify(zk).setData(eq(resourcePath), eq(resourceData), eq(-1));
    }

    @Test
    public void testSetNonExistingViewInfo() throws Exception {
        ViewInfo viewInfo = mock(ViewInfo.class);
        String resource = "test_resource";
        String resourcePath = VIEWS_DIR + "/" + resource;
        byte[] resourceData = "hello".getBytes();
        when(viewInfo.toCompressedJson()).thenReturn(resourceData);
        when(viewInfo.hasOnlinePartitions()).thenReturn(true);
        when(viewInfo.getResource()).thenReturn(resource);
        when(zk.exists(eq(resourcePath), anyBoolean())).thenReturn(null);
        when(zk.create(eq(resourcePath), eq(resourceData), anyListOf(ACL.class), any(CreateMode.class)))
                .thenReturn(null);
        zkManager.setViewInfo(viewInfo);
        verify(zk).create(eq(resourcePath), eq(resourceData), anyListOf(ACL.class), any(CreateMode.class));
    }

    @Test
    public void testSetViewInfoNoOnlinePart() throws Exception {
        ViewInfo viewInfo = mock(ViewInfo.class);
        byte[] resourceData = "hello".getBytes();
        when(viewInfo.toCompressedJson()).thenReturn(resourceData);
        when(viewInfo.hasOnlinePartitions()).thenReturn(false);
        zkManager.setViewInfo(viewInfo);
        verify(zk, times(0)).create(anyString(), any(byte[].class), anyListOf(ACL.class), any(CreateMode.class));
        verify(zk, times(0)).setData(anyString(), any(byte[].class), anyInt());
    }

    @Test
    public void testGetCandidateHdfsDirMap() throws Exception {
        FileSetInfo fileSetInfo1 = new FileSetInfo("abc", "123", 0,
                ImmutableList.copyOf(new FileSetInfo.ServingInfo[] {}), new Options());
        FileSetInfo fileSetInfo2 = new FileSetInfo("def", "456", 0,
                ImmutableList.copyOf(new FileSetInfo.ServingInfo[] {}), new Options());
        FileSetInfo fileSetInfo3 = new FileSetInfo("ghi", "789", 0,
                ImmutableList.copyOf(new FileSetInfo.ServingInfo[] {}), new Options());
        MemberModifier.field(ZooKeeperManager.class, "fileSetInfoMap").set(zkManager,
                ImmutableMap.builder().put(fileSetInfo1.fileSetName, fileSetInfo1)
                        .put(fileSetInfo2.fileSetName, fileSetInfo2).put(fileSetInfo3.fileSetName, fileSetInfo3)
                        .build());

        when(zk.getData(eq(FILE_SET_DIR + "/" + fileSetInfo1.fileSetName), anyBoolean(), any(Stat.class)))
                .thenReturn(fileSetInfo1.toJson());
        when(zk.getData(eq(LOCKS_DIR + "/" + fileSetInfo1.fileSetName), anyBoolean(), any(Stat.class)))
                .thenReturn(fileSetInfo1.toJson());

        when(zk.getData(eq(FILE_SET_DIR + "/" + fileSetInfo2.fileSetName), anyBoolean(), any(Stat.class)))
                .thenReturn(fileSetInfo2.toJson());
        when(zk.getData(eq(LOCKS_DIR + "/" + fileSetInfo2.fileSetName), anyBoolean(), any(Stat.class)))
                .thenThrow(new KeeperException.NoNodeException());

        when(zk.getData(eq(FILE_SET_DIR + "/" + fileSetInfo3.fileSetName), anyBoolean(), any(Stat.class)))
                .thenThrow(new KeeperException.NoNodeException());
        when(zk.getData(eq(LOCKS_DIR + "/" + fileSetInfo3.fileSetName), anyBoolean(), any(Stat.class)))
                .thenReturn(fileSetInfo3.toJson());

        Map<String, Pair<FileSetInfo, FileSetInfo>> results = zkManager.getCandidateHdfsDirMap();
        assertEquals(3, results.size());
        assertEquals(fileSetInfo1, results.get(fileSetInfo1.fileSetName).getLeft());
        assertEquals(fileSetInfo1, results.get(fileSetInfo1.fileSetName).getRight());
        assertEquals(fileSetInfo2, results.get(fileSetInfo2.fileSetName).getLeft());
        assertNull(results.get(fileSetInfo2.fileSetName).getRight());
        assertNull(results.get(fileSetInfo3.fileSetName).getLeft());
        assertEquals(fileSetInfo3, results.get(fileSetInfo3.fileSetName).getRight());
    }

    @Test
    public void testGetControllerLeader() throws Exception {
        String host = "somehost";
        int port = 9090;
        String json = String.format("{\"id\": \"%s_%d\"}", host, port);
        when(zk.getData(eq("/" + CLUSTER_NAME + "/CONTROLLER/LEADER"), anyBoolean(), any(Stat.class)))
                .thenReturn(json.getBytes());
        InetSocketAddress address = zkManager.getControllerLeader();
        assertEquals(host, address.getHostName());
        assertEquals(port, address.getPort());
    }

    @Test
    public void testGetClusterInfo() throws Exception {
        String hdfsNameNode = "namenode001";
        int replicaFactor = 3;
        ClusterInfo clusterInfo = new ClusterInfo(hdfsNameNode, replicaFactor);
        when(zk.getData(eq("/" + CLUSTER_NAME), anyBoolean(), any(Stat.class))).thenReturn(clusterInfo.toJson());
        ClusterInfo returnedInfo = zkManager.getClusterInfo();
        assertEquals(hdfsNameNode, returnedInfo.hdfsNameNode);
        assertEquals(replicaFactor, returnedInfo.hdfsReplicationFactor);
    }

    @Test
    public void testSetClusterInfo() throws Exception {
        String hdfsNameNode = "namenode001";
        int replicaFactor = 3;
        ClusterInfo clusterInfo = new ClusterInfo(hdfsNameNode, replicaFactor);
        when(zk.setData(eq("/" + CLUSTER_NAME), eq(clusterInfo.toJson()), anyInt())).thenReturn(new Stat());
        zkManager.setClusterInfo(clusterInfo);
        verify(zk).setData(eq("/" + CLUSTER_NAME), eq(clusterInfo.toJson()), anyInt());
    }
}