summaryrefslogtreecommitdiffstats
path: root/container-search/src/test/java/com/yahoo/prelude/fastsearch/test/FastSearcherTester.java
blob: 4f6d2d88917b23645a10d6222152c1b354a62929 (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
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.prelude.fastsearch.test;

import com.google.common.util.concurrent.MoreExecutors;
import com.yahoo.container.handler.ClustersStatus;
import com.yahoo.container.handler.VipStatus;
import com.yahoo.net.HostName;
import com.yahoo.prelude.fastsearch.CacheParams;
import com.yahoo.prelude.fastsearch.ClusterParams;
import com.yahoo.prelude.fastsearch.DocumentdbInfoConfig;
import com.yahoo.prelude.fastsearch.FastSearcher;
import com.yahoo.prelude.fastsearch.SummaryParameters;
import com.yahoo.prelude.fastsearch.test.fs4mock.MockBackend;
import com.yahoo.prelude.fastsearch.test.fs4mock.MockFS4ResourcePool;
import com.yahoo.prelude.fastsearch.test.fs4mock.MockFSChannel;
import com.yahoo.search.Query;
import com.yahoo.search.Result;
import com.yahoo.search.dispatch.SearchCluster;
import com.yahoo.search.searchchain.Execution;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

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

/**
 * @author bratseth
 */
class FastSearcherTester {

    public static final String selfHostname = HostName.getLocalhost();

    private final MockFS4ResourcePool mockFS4ResourcePool;
    private final FastSearcher fastSearcher;
    private final MockDispatcher mockDispatcher;
    private final VipStatus vipStatus;

    public FastSearcherTester(int containerClusterSize, SearchCluster.Node searchNode) {
        this(containerClusterSize, Collections.singletonList(searchNode));
    }

    public FastSearcherTester(int containerClusterSize, String... hostAndPortAndGroupStrings) {
        this(containerClusterSize, toNodes(hostAndPortAndGroupStrings));
    }

    public FastSearcherTester(int containerClusterSize, List<SearchCluster.Node> searchNodes) {
        ClustersStatus clustersStatus = new ClustersStatus();
        clustersStatus.setContainerHasClusters(true);
        vipStatus = new VipStatus(clustersStatus);
        mockFS4ResourcePool = new MockFS4ResourcePool();
        mockDispatcher = new MockDispatcher(searchNodes, mockFS4ResourcePool, containerClusterSize, vipStatus);
        fastSearcher = new FastSearcher(new MockBackend(selfHostname, 0L, true),
                                        mockFS4ResourcePool,
                                        mockDispatcher,
                                        new SummaryParameters(null),
                                        new ClusterParams("testhittype"),
                                        new CacheParams(100, 1e64),
                                        new DocumentdbInfoConfig(new DocumentdbInfoConfig.Builder()));
    }

    private static List<SearchCluster.Node> toNodes(String... hostAndPortAndGroupStrings) {
        List<SearchCluster.Node> nodes = new ArrayList<>();
        int key = 0;
        for (String s : hostAndPortAndGroupStrings) {
            String[] parts = s.split(":");
            nodes.add(new SearchCluster.Node(key++, parts[0], Integer.parseInt(parts[1]), Integer.parseInt(parts[2])));
        }
        return nodes;
    }

    public Result search(String query) {
        Result result = fastSearcher.search(new Query(query), new Execution(Execution.Context.createContextStub()));
        assertEquals(null, result.hits().getError());
        return result;
    }

    /** Returns the number of times a backend for this hostname and port has been requested */
    public int requestCount(String hostname, int port) {
        return mockFS4ResourcePool.requestCount(hostname, port);
    }

    public MockDispatcher dispatcher() { return mockDispatcher; }

    /** Sets the response status of a node and ping it to update the monitor status */
    public void setResponding(String hostname, boolean responding) {
        // Start/stop returning a failing backend
        mockFS4ResourcePool.setResponding(hostname, responding);

        // Make the search cluster monitor notice right now in this thread
        SearchCluster.Node node = mockDispatcher.searchCluster().nodesByHost().get(hostname).iterator().next();
        mockDispatcher.searchCluster().ping(node, MoreExecutors.directExecutor());
    }

    /** Sets the response status of a node and ping it to update the monitor status */
    public void setActiveDocuments(String hostname, long activeDocuments) {
        mockFS4ResourcePool.setActiveDocuments(hostname, activeDocuments);

        // Make the search cluster monitor notice right now in this thread
        SearchCluster.Node node = mockDispatcher.searchCluster().nodesByHost().get(hostname).iterator().next();
        mockDispatcher.searchCluster().ping(node, MoreExecutors.directExecutor());
        mockDispatcher.searchCluster().pingIterationCompleted();
    }

    public VipStatus vipStatus() { return vipStatus; }

    /** Retrying is needed because earlier pings from the monitoring thread may interfere with the testing thread */
    public void waitForInRotationIs(boolean expectedRotationStatus) {
        int triesLeft = 9000;
        while (vipStatus.isInRotation() != expectedRotationStatus && triesLeft > 0) {
            triesLeft--;
            try { Thread.sleep(10); } catch (InterruptedException e) {}
        }
        if (triesLeft == 0)
            fail("Did not reach VIP in rotation status = " + expectedRotationStatus + " after trying for 90 seconds");
    }

}