aboutsummaryrefslogtreecommitdiffstats
path: root/zkfacade/src/test/java/com/yahoo/vespa/zookeeper/CuratorTest.java
blob: 396555d5e3a6b072d02a0cea22712191c6654f62 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.zookeeper;

import com.yahoo.cloud.config.ConfigserverConfig;
import com.yahoo.net.HostName;
import com.yahoo.vespa.curator.Curator;
import org.apache.curator.test.TestingServer;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;

import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;

/**
 * Sets up actual ZooKeeper servers and verifies we can talk to them.
 *
 * @author lulf
 */
public class CuratorTest {

    private String spec1;
    private String spec2;
    private TestingServer test1;
    private TestingServer test2;
    private int port1;
    private int port2;

    @Before
    public void setupServers() throws Exception {
        port1 = allocatePort();
        port2 = allocatePort();
        test1 = new TestingServer(port1);
        test2 = new TestingServer(port2);
        spec1 = "localhost:" + port1;
        spec2 = "localhost:" + port2;
    }

    private int allocatePort() {
        return PortAllocator.findAvailablePort();
    }

    @After
    public void teardownServers() throws IOException {
        test1.stop();
        test1.close();
        test2.close();
        test2.stop();
    }

    @Test
    public void require_curator_is_created_from_config() {
        try (Curator curator = createCurator(createTestConfig())) {
            assertThat(curator.connectionSpec(), is(spec1 + "," + spec2));
        }
    }

    @Test
    public void require_that_curator_can_produce_spec() {
        try (Curator curator = createCurator(createTestConfig())) {
            assertThat(curator.connectionSpec(), is(spec1 + "," + spec2));
            assertThat(curator.serverCount(), is(2));
        }
    }

    @Test
    public void require_that_server_count_is_correct() {
        ConfigserverConfig.Builder builder = new ConfigserverConfig.Builder();
        builder.zookeeperserver(createZKBuilder("localhost", port1));
        try (Curator curator = createCurator(new ConfigserverConfig(builder))) {
            assertThat(curator.serverCount(), is(1));
        }
    }

    @Test
    public void require_that_server_order_is_correct() {
        ConfigserverConfig.Builder builder = new ConfigserverConfig.Builder();
        builder.zookeeperserver(createZKBuilder("localhost", port1));
        builder.zookeeperserver(createZKBuilder(HostName.getLocalhost(), port2));
        builder.zookeeperserver(createZKBuilder("localhost", 1234));
        builder.zookeeperserver(createZKBuilder("localhost", 6789));
        try (Curator curator = createCurator(new ConfigserverConfig(builder))) {
            assertThat(curator.serverCount(), is(4));
            // host this is running on should come first
            assertTrue(curator.connectionSpec().startsWith(HostName.getLocalhost() + ":" + port2 + ",localhost:1234"));
        }
    }

    private ConfigserverConfig createTestConfig() {
        ConfigserverConfig.Builder builder = new ConfigserverConfig.Builder();
        builder.zookeeperserver(createZKBuilder("localhost", port1));
        builder.zookeeperserver(createZKBuilder("localhost", port2));
        return new ConfigserverConfig(builder);
    }

    private ConfigserverConfig.Zookeeperserver.Builder createZKBuilder(String hostname, int port) {
        ConfigserverConfig.Zookeeperserver.Builder zkBuilder = new ConfigserverConfig.Zookeeperserver.Builder();
        zkBuilder.hostname(hostname);
        zkBuilder.port(port);
        return zkBuilder;
    }

    private Curator createCurator(ConfigserverConfig configserverConfig) {
        return new Curator(configserverConfig, null);
    }

    private static class PortAllocator {

        private static class PortRange {
            private int first = 18621;
            private int last = 18630; // see: factory/doc/port-ranges
            private int value = first;

            synchronized int next() {
                if (value > last) {
                    throw new RuntimeException("no port ports in range");
                }
                return value++;
            }
        }

        private final static PortRange portRange = new PortRange();

        // Get the next port from a pre-allocated range
        public static int findAvailablePort() {
            return portRange.next();
        }

    }

}