com.couchbase.client.core.node.locate.KeyValueLocatorTest.java Source code

Java tutorial

Introduction

Here is the source code for com.couchbase.client.core.node.locate.KeyValueLocatorTest.java

Source

/*
 * Copyright (c) 2016 Couchbase, Inc.
 *
 * 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 com.couchbase.client.core.node.locate;

import com.couchbase.client.core.config.ClusterConfig;
import com.couchbase.client.core.config.CouchbaseBucketConfig;
import com.couchbase.client.core.config.DefaultNodeInfo;
import com.couchbase.client.core.config.NodeInfo;
import com.couchbase.client.core.message.kv.GetBucketConfigRequest;
import com.couchbase.client.core.message.kv.GetRequest;
import com.couchbase.client.core.node.Node;
import com.couchbase.client.core.state.LifecycleState;
import io.netty.util.CharsetUtil;
import org.junit.Test;

import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

/**
 * Verifies the functionality of the {@link KeyValueLocator}.
 *
 * @author Michael Nitschinger
 * @since 1.0.0
 */
public class KeyValueLocatorTest {

    @Test
    public void shouldLocateGetRequestForCouchbaseBucket() throws Exception {
        Locator locator = new KeyValueLocator();

        NodeInfo nodeInfo1 = new DefaultNodeInfo("foo", "192.168.56.101:11210", Collections.EMPTY_MAP);
        NodeInfo nodeInfo2 = new DefaultNodeInfo("foo", "192.168.56.102:11210", Collections.EMPTY_MAP);

        GetRequest getRequestMock = mock(GetRequest.class);
        ClusterConfig configMock = mock(ClusterConfig.class);
        List<Node> nodes = new ArrayList<Node>();
        Node node1Mock = mock(Node.class);
        when(node1Mock.hostname()).thenReturn(InetAddress.getByName("192.168.56.101"));
        Node node2Mock = mock(Node.class);
        when(node2Mock.hostname()).thenReturn(InetAddress.getByName("192.168.56.102"));
        nodes.addAll(Arrays.asList(node1Mock, node2Mock));
        CouchbaseBucketConfig bucketMock = mock(CouchbaseBucketConfig.class);
        when(getRequestMock.bucket()).thenReturn("bucket");
        when(getRequestMock.key()).thenReturn("key");
        when(getRequestMock.keyBytes()).thenReturn("key".getBytes(CharsetUtil.UTF_8));
        when(configMock.bucketConfig("bucket")).thenReturn(bucketMock);
        when(bucketMock.nodes()).thenReturn(Arrays.asList(nodeInfo1, nodeInfo2));
        when(bucketMock.numberOfPartitions()).thenReturn(1024);
        when(bucketMock.nodeIndexForMaster(656, false)).thenReturn((short) 0);
        when(bucketMock.nodeAtIndex(0)).thenReturn(nodeInfo1);

        locator.locateAndDispatch(getRequestMock, nodes, configMock, null, null);
        verify(node1Mock, times(1)).send(getRequestMock);
        verify(node2Mock, never()).send(getRequestMock);
    }

    @Test
    public void shouldPickTheRightNodeForGetBucketConfigRequest() throws Exception {
        Locator locator = new KeyValueLocator();

        List<Node> nodes = new ArrayList<Node>();
        Node node1Mock = mock(Node.class);
        when(node1Mock.hostname()).thenReturn(InetAddress.getByName("192.168.56.101"));
        when(node1Mock.isState(LifecycleState.CONNECTED)).thenReturn(true);
        Node node2Mock = mock(Node.class);
        when(node2Mock.hostname()).thenReturn(InetAddress.getByName("192.168.56.102"));
        when(node2Mock.isState(LifecycleState.CONNECTED)).thenReturn(true);
        nodes.addAll(Arrays.asList(node1Mock, node2Mock));

        GetBucketConfigRequest requestMock = mock(GetBucketConfigRequest.class);
        when(requestMock.hostname()).thenReturn(InetAddress.getByName("192.168.56.102"));

        locator.locateAndDispatch(requestMock, nodes, mock(ClusterConfig.class), null, null);
        verify(node1Mock, never()).send(requestMock);
        verify(node2Mock, times(1)).send(requestMock);
    }

    @Test
    public void shouldPickFastForwardIfAvailableAndRetry() throws Exception {
        Locator locator = new KeyValueLocator();

        // Setup 2 nodes
        NodeInfo nodeInfo1 = new DefaultNodeInfo("foo", "192.168.56.101:11210", Collections.EMPTY_MAP);
        NodeInfo nodeInfo2 = new DefaultNodeInfo("foo", "192.168.56.102:11210", Collections.EMPTY_MAP);
        List<Node> nodes = new ArrayList<Node>();
        Node node1Mock = mock(Node.class);
        when(node1Mock.hostname()).thenReturn(InetAddress.getByName("192.168.56.101"));
        Node node2Mock = mock(Node.class);
        when(node2Mock.hostname()).thenReturn(InetAddress.getByName("192.168.56.102"));
        nodes.addAll(Arrays.asList(node1Mock, node2Mock));

        // Configure Cluster and Bucket config
        ClusterConfig configMock = mock(ClusterConfig.class);
        CouchbaseBucketConfig bucketMock = mock(CouchbaseBucketConfig.class);
        when(configMock.bucketConfig("bucket")).thenReturn(bucketMock);
        when(bucketMock.nodes()).thenReturn(Arrays.asList(nodeInfo1, nodeInfo2));
        when(bucketMock.numberOfPartitions()).thenReturn(1024);
        when(bucketMock.nodeAtIndex(0)).thenReturn(nodeInfo1);
        when(bucketMock.nodeAtIndex(1)).thenReturn(nodeInfo2);
        when(bucketMock.hasFastForwardMap()).thenReturn(true);

        // Fake a vbucket move in ffwd map from node 0 to node 1
        when(bucketMock.nodeIndexForMaster(656, false)).thenReturn((short) 0);
        when(bucketMock.nodeIndexForMaster(656, true)).thenReturn((short) 1);

        // Create Request
        GetRequest getRequestMock = mock(GetRequest.class);
        when(getRequestMock.bucket()).thenReturn("bucket");
        when(getRequestMock.key()).thenReturn("key");
        when(getRequestMock.keyBytes()).thenReturn("key".getBytes(CharsetUtil.UTF_8));

        // Dispatch with retry 0
        when(getRequestMock.retryCount()).thenReturn(0);
        locator.locateAndDispatch(getRequestMock, nodes, configMock, null, null);
        verify(node1Mock, times(1)).send(getRequestMock);
        verify(node2Mock, never()).send(getRequestMock);

        // Dispatch with retry 1
        when(getRequestMock.retryCount()).thenReturn(1);
        locator.locateAndDispatch(getRequestMock, nodes, configMock, null, null);
        verify(node1Mock, times(1)).send(getRequestMock);
        verify(node2Mock, times(1)).send(getRequestMock);

        // Dispatch with retry 5
        when(getRequestMock.retryCount()).thenReturn(5);
        locator.locateAndDispatch(getRequestMock, nodes, configMock, null, null);
        verify(node1Mock, times(1)).send(getRequestMock);
        verify(node2Mock, times(2)).send(getRequestMock);
    }

    @Test
    public void shouldPickCurrentIfNoFFMapAndRetry() throws Exception {
        Locator locator = new KeyValueLocator();

        // Setup 2 nodes
        NodeInfo nodeInfo1 = new DefaultNodeInfo("foo", "192.168.56.101:11210", Collections.EMPTY_MAP);
        NodeInfo nodeInfo2 = new DefaultNodeInfo("foo", "192.168.56.102:11210", Collections.EMPTY_MAP);
        List<Node> nodes = new ArrayList<Node>();
        Node node1Mock = mock(Node.class);
        when(node1Mock.hostname()).thenReturn(InetAddress.getByName("192.168.56.101"));
        Node node2Mock = mock(Node.class);
        when(node2Mock.hostname()).thenReturn(InetAddress.getByName("192.168.56.102"));
        nodes.addAll(Arrays.asList(node1Mock, node2Mock));

        // Configure Cluster and Bucket config
        ClusterConfig configMock = mock(ClusterConfig.class);
        CouchbaseBucketConfig bucketMock = mock(CouchbaseBucketConfig.class);
        when(configMock.bucketConfig("bucket")).thenReturn(bucketMock);
        when(bucketMock.nodes()).thenReturn(Arrays.asList(nodeInfo1, nodeInfo2));
        when(bucketMock.numberOfPartitions()).thenReturn(1024);
        when(bucketMock.nodeAtIndex(0)).thenReturn(nodeInfo1);
        when(bucketMock.nodeAtIndex(1)).thenReturn(nodeInfo2);
        when(bucketMock.hasFastForwardMap()).thenReturn(false);

        // Fake a vbucket move in ffwd map from node 0 to node 1
        when(bucketMock.nodeIndexForMaster(656, false)).thenReturn((short) 0);
        when(bucketMock.nodeIndexForMaster(656, true)).thenReturn((short) 1);

        // Create Request
        GetRequest getRequestMock = mock(GetRequest.class);
        when(getRequestMock.bucket()).thenReturn("bucket");
        when(getRequestMock.key()).thenReturn("key");
        when(getRequestMock.keyBytes()).thenReturn("key".getBytes(CharsetUtil.UTF_8));

        // Dispatch with retry 0
        when(getRequestMock.retryCount()).thenReturn(0);
        locator.locateAndDispatch(getRequestMock, nodes, configMock, null, null);
        verify(node1Mock, times(1)).send(getRequestMock);
        verify(node2Mock, never()).send(getRequestMock);

        // Dispatch with retry 1
        when(getRequestMock.retryCount()).thenReturn(1);
        locator.locateAndDispatch(getRequestMock, nodes, configMock, null, null);
        verify(node1Mock, times(2)).send(getRequestMock);
        verify(node2Mock, never()).send(getRequestMock);

        // Dispatch with retry 5
        when(getRequestMock.retryCount()).thenReturn(5);
        locator.locateAndDispatch(getRequestMock, nodes, configMock, null, null);
        verify(node1Mock, times(3)).send(getRequestMock);
        verify(node2Mock, never()).send(getRequestMock);
    }

}