If MaxScale cannot ping the health-check port of a node, the state of the node should become 'Down'.
		
			
				
	
	
		
			161 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			161 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/**
 | 
						|
 * @file clustrix_mon.cpp - simple Clustrix monitor test
 | 
						|
 * Just creates Clustrix cluster and connect Maxscale to it
 | 
						|
 * It can be used as a template for clustrix tests
 | 
						|
 *
 | 
						|
 * See Clustrix_nodes.h for details about configiration
 | 
						|
 */
 | 
						|
 | 
						|
#include <iostream>
 | 
						|
#include <maxbase/string.hh>
 | 
						|
#include <maxscale/jansson.hh>
 | 
						|
#include "testconnections.h"
 | 
						|
#include "maxrest.hh"
 | 
						|
 | 
						|
using namespace std;
 | 
						|
 | 
						|
namespace
 | 
						|
{
 | 
						|
 | 
						|
const set<string> bootstrap_servers =
 | 
						|
{
 | 
						|
    "clustrix_server1",
 | 
						|
    "clustrix_server2",
 | 
						|
    "clustrix_server3",
 | 
						|
    "clustrix_server4",
 | 
						|
};
 | 
						|
 | 
						|
const std::string monitor_name = "Clustrix-Monitor";
 | 
						|
 | 
						|
 | 
						|
void check_for_servers(const MaxRest& maxrest)
 | 
						|
{
 | 
						|
    TestConnections& test = maxrest.test();
 | 
						|
 | 
						|
    auto servers = maxrest.list_servers();
 | 
						|
 | 
						|
    test.expect(servers.size() >= bootstrap_servers.size(),
 | 
						|
                "Expected at least %d servers.", (int)bootstrap_servers.size());
 | 
						|
 | 
						|
    set<string> static_servers;
 | 
						|
    set<string> dynamic_servers;
 | 
						|
 | 
						|
    string prefix = "@@" + monitor_name;
 | 
						|
 | 
						|
    for (const auto& server : servers)
 | 
						|
    {
 | 
						|
        string name = server.name;
 | 
						|
 | 
						|
        cout << "Looking at: " << name << endl;
 | 
						|
 | 
						|
        if (bootstrap_servers.find(name) != bootstrap_servers.end())
 | 
						|
        {
 | 
						|
            static_servers.insert(name);
 | 
						|
            continue;
 | 
						|
        }
 | 
						|
 | 
						|
        if (name.find(prefix) != 0)
 | 
						|
        {
 | 
						|
            test.expect(false, "The name of a dynamic Clustrix node does not start with \"%s\": %s",
 | 
						|
                        prefix.c_str(), name.c_str());
 | 
						|
        }
 | 
						|
 | 
						|
        dynamic_servers.insert(name);
 | 
						|
    }
 | 
						|
 | 
						|
    test.expect(static_servers == bootstrap_servers,
 | 
						|
                "Did not find expected servers.\n"
 | 
						|
                "Found   : %s\n"
 | 
						|
                "Expected: %s",
 | 
						|
                mxb::join(static_servers).c_str(),
 | 
						|
                mxb::join(bootstrap_servers).c_str());
 | 
						|
 | 
						|
    test.expect(dynamic_servers.size() == 4,
 | 
						|
                "Did not find expected numbers of servers %d != 4: %s",
 | 
						|
                (int)dynamic_servers.size(),
 | 
						|
                mxb::join(dynamic_servers).c_str());
 | 
						|
}
 | 
						|
 | 
						|
void expect_all_servers_to_be(const MaxRest& maxrest, const std::string& state)
 | 
						|
{
 | 
						|
    cout << "Expecting the state of all servers to be: " << state << endl;
 | 
						|
 | 
						|
    TestConnections& test = maxrest.test();
 | 
						|
    auto servers = maxrest.list_servers();
 | 
						|
 | 
						|
    for (const auto& server : servers)
 | 
						|
    {
 | 
						|
        cout << server.name << "(" << server.address << "): " << server.state << endl;
 | 
						|
        test.expect(server.state == state,
 | 
						|
                    "State of %s(%s) is '%s', expected '%s.",
 | 
						|
                    server.name.c_str(),
 | 
						|
                    server.address.c_str(),
 | 
						|
                    server.state.c_str(),
 | 
						|
                    state.c_str());
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void check_state_change(const MaxRest& maxrest)
 | 
						|
{
 | 
						|
    TestConnections& test = maxrest.test();
 | 
						|
 | 
						|
    expect_all_servers_to_be(maxrest, "Master, Running");
 | 
						|
    cout << endl;
 | 
						|
 | 
						|
    int node = 0;
 | 
						|
    string address = test.clustrix->IP_private[node];
 | 
						|
 | 
						|
    cout << "Blocking node: " << node << endl;
 | 
						|
    test.clustrix->block_node(node);
 | 
						|
 | 
						|
    int cycles = 3;
 | 
						|
    cout << "Waiting for " << cycles << " monitor cycles." << endl;
 | 
						|
    test.maxscales->wait_for_monitor(cycles);
 | 
						|
 | 
						|
    auto servers = maxrest.list_servers();
 | 
						|
 | 
						|
    for (const auto& server : servers)
 | 
						|
    {
 | 
						|
        cout << server.name << "(" << server.address << "): " << server.state << endl;
 | 
						|
        if (server.address == address)
 | 
						|
        {
 | 
						|
            test.expect(server.state == "Down", "Blocked server was not 'Down' but '%s'.", server.state.c_str());
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    cout << endl;
 | 
						|
 | 
						|
    test.clustrix->unblock_node(node);
 | 
						|
    cout << "Waiting for " << cycles << " monitor cycles." << endl;
 | 
						|
    test.maxscales->wait_for_monitor(cycles);
 | 
						|
 | 
						|
    expect_all_servers_to_be(maxrest, "Master, Running");
 | 
						|
    cout << endl;
 | 
						|
}
 | 
						|
 | 
						|
void run_test(TestConnections& test)
 | 
						|
{
 | 
						|
    MaxRest maxrest(&test);
 | 
						|
 | 
						|
    check_for_servers(maxrest);
 | 
						|
    check_state_change(maxrest);
 | 
						|
}
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
int main(int argc, char* argv[])
 | 
						|
{
 | 
						|
    TestConnections test(argc, argv);
 | 
						|
 | 
						|
    try
 | 
						|
    {
 | 
						|
        run_test(test);
 | 
						|
    }
 | 
						|
    catch (const std::exception& x)
 | 
						|
    {
 | 
						|
        cout << "Exception: " << x.what() << endl;
 | 
						|
    }
 | 
						|
 | 
						|
    return test.global_result;
 | 
						|
}
 |