blob: 838a747919ce16088a34143b8e6665acc579390d [file] [log] [blame]
/*
* The MIT License (MIT)
*
* Copyright (c) 2015 Microsoft Corporation
*
* -=- Robust Distributed System Nucleus (rDSN) -=-
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <netinet/in.h>
#include <stdint.h>
#include <string>
#include <vector>
#include "gtest/gtest.h"
#include "runtime/rpc/group_address.h"
#include "runtime/rpc/rpc_address.h"
namespace dsn {
static inline uint32_t host_ipv4(uint8_t sec1, uint8_t sec2, uint8_t sec3, uint8_t sec4)
{
uint32_t ip = 0;
ip |= (uint32_t)sec1 << 24;
ip |= (uint32_t)sec2 << 16;
ip |= (uint32_t)sec3 << 8;
ip |= (uint32_t)sec4;
return ip;
}
TEST(rpc_address_test, rpc_address_ipv4_from_host)
{
// localhost --> 127.0.0.1
// on some systems "localhost" could be "127.0.1.1" (debian)
ASSERT_TRUE(host_ipv4(127, 0, 0, 1) == rpc_address::ipv4_from_host("localhost") ||
host_ipv4(127, 0, 1, 1) == rpc_address::ipv4_from_host("localhost"));
// 127.0.0.1 --> 127.0.0.1
ASSERT_EQ(host_ipv4(127, 0, 0, 1), rpc_address::ipv4_from_host("127.0.0.1"));
}
TEST(rpc_address_test, rpc_address_ipv4_from_network_interface)
{
ASSERT_EQ(host_ipv4(127, 0, 0, 1), rpc_address::ipv4_from_network_interface("lo"));
ASSERT_EQ(host_ipv4(0, 0, 0, 0),
rpc_address::ipv4_from_network_interface("not_exist_interface"));
}
TEST(rpc_address_test, is_site_local_address)
{
ASSERT_FALSE(rpc_address::is_site_local_address(htonl(host_ipv4(1, 2, 3, 4))));
ASSERT_TRUE(rpc_address::is_site_local_address(htonl(host_ipv4(10, 235, 111, 111))));
ASSERT_FALSE(rpc_address::is_site_local_address(htonl(host_ipv4(171, 11, 11, 11))));
ASSERT_TRUE(rpc_address::is_site_local_address(htonl(host_ipv4(172, 16, 2, 2))));
ASSERT_TRUE(rpc_address::is_site_local_address(htonl(host_ipv4(172, 31, 234, 255))));
ASSERT_FALSE(rpc_address::is_site_local_address(htonl(host_ipv4(191, 128, 1, 2))));
ASSERT_TRUE(rpc_address::is_site_local_address(htonl(host_ipv4(192, 168, 3, 45))));
ASSERT_FALSE(rpc_address::is_site_local_address(htonl(host_ipv4(201, 201, 201, 201))));
}
TEST(rpc_address_test, is_docker_netcard)
{
ASSERT_TRUE(rpc_address::is_docker_netcard("docker0", htonl(host_ipv4(1, 2, 3, 4))));
ASSERT_TRUE(rpc_address::is_docker_netcard("10docker5", htonl(host_ipv4(4, 5, 6, 8))));
ASSERT_FALSE(rpc_address::is_docker_netcard("eth0", htonl(host_ipv4(192, 168, 123, 123))));
ASSERT_TRUE(rpc_address::is_docker_netcard("eth0", htonl(host_ipv4(172, 17, 42, 1))));
}
TEST(rpc_address_test, rpc_address_to_string)
{
{
rpc_address addr;
addr.assign_ipv4(host_ipv4(127, 0, 0, 1), 8080);
ASSERT_EQ(std::string("127.0.0.1:8080"), addr.to_std_string());
}
{
const char *name = "test_group";
rpc_address addr;
addr.assign_group(name);
ASSERT_EQ(std::string(name), addr.to_std_string());
}
{
rpc_address addr;
ASSERT_EQ(std::string("invalid address"), addr.to_std_string());
}
}
TEST(rpc_address_test, dsn_address_build)
{
{
rpc_address addr;
addr.assign_ipv4(host_ipv4(127, 0, 0, 1), 8080);
ASSERT_EQ(HOST_TYPE_IPV4, addr.type());
ASSERT_EQ(host_ipv4(127, 0, 0, 1), addr.ip());
ASSERT_EQ(8080, addr.port());
ASSERT_TRUE(rpc_address("127.0.0.1", 8080) == rpc_address("localhost", 8080) ||
rpc_address("127.0.1.1", 8080) == rpc_address("localhost", 8080));
ASSERT_EQ(addr, rpc_address("127.0.0.1", 8080));
ASSERT_EQ(addr, rpc_address(host_ipv4(127, 0, 0, 1), 8080));
}
{
const char *name = "test_group";
rpc_address addr;
addr.assign_group(name);
ASSERT_EQ(HOST_TYPE_GROUP, addr.type());
ASSERT_STREQ(name, addr.group_address()->name());
ASSERT_EQ(1, addr.group_address()->get_count());
}
}
TEST(rpc_address_test, operators)
{
rpc_address addr(1234, 123);
ASSERT_EQ(addr, addr);
{
rpc_address new_addr(addr);
ASSERT_EQ(addr, new_addr);
}
{
rpc_address new_addr(1234, 321);
ASSERT_NE(addr, new_addr);
}
rpc_address addr_grp;
ASSERT_EQ(addr_grp, addr_grp);
ASSERT_NE(addr, addr_grp);
addr_grp.assign_group("test_group");
ASSERT_TRUE(addr_grp.group_address()->add(addr));
ASSERT_NE(addr, addr_grp);
{
rpc_address new_addr_grp(addr_grp);
ASSERT_EQ(addr_grp, new_addr_grp);
}
}
TEST(rpc_address_test, rpc_group_address)
{
rpc_address addr("127.0.0.1", 8080);
rpc_address invalid_addr;
rpc_address addr2("127.0.0.1", 8081);
rpc_address t;
t.assign_group("test_group");
ASSERT_EQ(HOST_TYPE_GROUP, t.type());
rpc_group_address *g = t.group_address();
ASSERT_EQ(std::string("test_group"), g->name());
ASSERT_EQ(1, g->get_count());
// { }
ASSERT_FALSE(g->remove(addr));
ASSERT_FALSE(g->contains(addr));
ASSERT_EQ(0u, g->members().size());
ASSERT_EQ(invalid_addr, g->random_member());
ASSERT_EQ(invalid_addr, g->next(addr));
ASSERT_EQ(invalid_addr, g->leader());
ASSERT_EQ(invalid_addr, g->possible_leader());
// { addr }
ASSERT_TRUE(g->add(addr));
ASSERT_FALSE(g->add(addr));
ASSERT_TRUE(g->contains(addr));
ASSERT_EQ(1u, g->members().size());
ASSERT_EQ(addr, g->members().at(0));
ASSERT_EQ(addr, g->random_member());
ASSERT_EQ(addr, g->next(addr));
ASSERT_EQ(addr, g->next(invalid_addr));
ASSERT_EQ(addr, g->next(addr2));
ASSERT_EQ(invalid_addr, g->leader());
ASSERT_EQ(addr, g->possible_leader());
// { addr* }
g->set_leader(addr);
ASSERT_TRUE(g->contains(addr));
ASSERT_EQ(1u, g->members().size());
ASSERT_EQ(addr, g->members().at(0));
ASSERT_EQ(addr, g->leader());
ASSERT_EQ(addr, g->possible_leader());
// { addr, addr2* }
g->set_leader(addr2);
ASSERT_TRUE(g->contains(addr));
ASSERT_TRUE(g->contains(addr2));
ASSERT_EQ(2u, g->members().size());
ASSERT_EQ(addr, g->members().at(0));
ASSERT_EQ(addr2, g->members().at(1));
ASSERT_EQ(addr2, g->leader());
ASSERT_EQ(addr2, g->possible_leader());
ASSERT_EQ(addr, g->next(addr2));
ASSERT_EQ(addr2, g->next(addr));
// { addr, addr2 }
g->set_leader(invalid_addr);
ASSERT_TRUE(g->contains(addr));
ASSERT_TRUE(g->contains(addr2));
ASSERT_EQ(2u, g->members().size());
ASSERT_EQ(addr, g->members().at(0));
ASSERT_EQ(addr2, g->members().at(1));
ASSERT_EQ(invalid_addr, g->leader());
// { addr*, addr2 }
g->set_leader(addr);
ASSERT_TRUE(g->contains(addr));
ASSERT_TRUE(g->contains(addr2));
ASSERT_EQ(2u, g->members().size());
ASSERT_EQ(addr, g->members().at(0));
ASSERT_EQ(addr2, g->members().at(1));
ASSERT_EQ(addr, g->leader());
// { uri_addr }
ASSERT_TRUE(g->remove(addr));
ASSERT_FALSE(g->contains(addr));
ASSERT_TRUE(g->contains(addr2));
ASSERT_EQ(1u, g->members().size());
ASSERT_EQ(addr2, g->members().at(0));
ASSERT_EQ(invalid_addr, g->leader());
// { }
ASSERT_TRUE(g->remove(addr2));
ASSERT_FALSE(g->contains(addr2));
ASSERT_EQ(0u, g->members().size());
ASSERT_EQ(invalid_addr, g->leader());
}
} // namespace dsn