blob: 4340e7a0607f4208da9f3d5edde2d693d8d21db1 [file]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to You 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.
#include <gtest/gtest.h>
#include <cstring>
#include <string>
#include "butil/macros.h"
#include "butil/sys_byteorder.h"
#include "brpc/socket.h"
#if BRPC_WITH_UBRING
#include "brpc/ubshm/ub_endpoint.h"
#include "brpc/ubshm/shm/shm_def.h"
#include "brpc/ubshm/shm/shm_mgr.h"
#include "brpc/ubshm/ub_ring_manager.h"
namespace brpc {
namespace ubring {
extern bool g_skip_ub_init;
} // namespace ubring
} // namespace brpc
namespace {
struct __attribute__((packed)) HelloMessageLayout {
uint16_t msg_len;
uint16_t hello_ver;
uint16_t impl_ver;
uint64_t len;
char shm_name[SHM_MAX_NAME_BUFF_LEN];
};
}
class HelloMessageTest : public ::testing::Test {
protected:
void SetUp() override {
memset(&msg, 0, sizeof(msg));
buffer.resize(256, 0);
}
brpc::ubring::HelloMessage msg;
std::string buffer;
};
TEST_F(HelloMessageTest, serialize_deserialize_roundtrip) {
msg.msg_len = 64;
msg.hello_ver = 2;
msg.impl_ver = 1;
msg.len = 4 * 1024 * 1024;
memcpy(msg.shm_name, "UBRING_test_C", 14);
msg.Serialize(&buffer[0]);
brpc::ubring::HelloMessage decoded;
memset(&decoded, 0, sizeof(decoded));
decoded.Deserialize(&buffer[0]);
EXPECT_EQ(msg.msg_len, decoded.msg_len);
EXPECT_EQ(msg.hello_ver, decoded.hello_ver);
EXPECT_EQ(msg.impl_ver, decoded.impl_ver);
EXPECT_EQ(msg.len, decoded.len);
EXPECT_EQ(0, memcmp(msg.shm_name, decoded.shm_name, SHM_MAX_NAME_BUFF_LEN));
}
TEST_F(HelloMessageTest, serialize_uses_network_byte_order) {
msg.msg_len = 0x0102;
msg.hello_ver = 0x0304;
msg.impl_ver = 0x0506;
msg.len = 0x0102030405060708ULL;
memset(msg.shm_name, 0, SHM_MAX_NAME_BUFF_LEN);
msg.Serialize(&buffer[0]);
HelloMessageLayout* raw = reinterpret_cast<HelloMessageLayout*>(&buffer[0]);
EXPECT_EQ(butil::HostToNet16(0x0102), raw->msg_len);
EXPECT_EQ(butil::HostToNet16(0x0304), raw->hello_ver);
EXPECT_EQ(butil::HostToNet16(0x0506), raw->impl_ver);
EXPECT_EQ(butil::HostToNet64(0x0102030405060708ULL), raw->len);
}
TEST_F(HelloMessageTest, large_len_value) {
msg.msg_len = 64;
msg.hello_ver = 2;
msg.impl_ver = 1;
msg.len = 0xFFFFFFFFFFFFFFFFULL;
memset(msg.shm_name, 0, SHM_MAX_NAME_BUFF_LEN);
msg.Serialize(&buffer[0]);
brpc::ubring::HelloMessage decoded;
memset(&decoded, 0, sizeof(decoded));
decoded.Deserialize(&buffer[0]);
EXPECT_EQ(0xFFFFFFFFFFFFFFFFULL, decoded.len);
}
TEST_F(HelloMessageTest, full_shm_name) {
memset(msg.shm_name, 'A', SHM_MAX_NAME_BUFF_LEN);
msg.msg_len = 64;
msg.hello_ver = 2;
msg.impl_ver = 1;
msg.len = 0;
msg.Serialize(&buffer[0]);
brpc::ubring::HelloMessage decoded;
memset(&decoded, 0, sizeof(decoded));
decoded.Deserialize(&buffer[0]);
EXPECT_EQ(0, memcmp(msg.shm_name, decoded.shm_name, SHM_MAX_NAME_BUFF_LEN));
}
TEST_F(HelloMessageTest, toString_contains_fields) {
msg.msg_len = 64;
msg.hello_ver = 2;
msg.impl_ver = 1;
msg.len = 4194304;
memcpy(msg.shm_name, "UBRING_test", 12);
std::string s = msg.toString();
EXPECT_NE(std::string::npos, s.find("msg_len=64"));
EXPECT_NE(std::string::npos, s.find("hello_ver=2"));
EXPECT_NE(std::string::npos, s.find("impl_ver=1"));
EXPECT_NE(std::string::npos, s.find("UBRING_test"));
}
namespace brpc {
namespace ubring {
class UBShmEndpointTest : public ::testing::Test {
protected:
void SetUp() override {
_saved_skip = g_skip_ub_init;
g_skip_ub_init = false;
ShmMgrInit();
UBRingManager::UbrMgrInit();
UBShmEndpoint::GlobalInitialize();
brpc::SocketOptions options;
ASSERT_EQ(0, brpc::Socket::Create(options, &_socket_id));
brpc::SocketUniquePtr s;
ASSERT_EQ(0, brpc::Socket::Address(_socket_id, &s));
_socket = s.get();
_ep = new UBShmEndpoint(_socket);
}
void TearDown() override {
delete _ep;
brpc::SocketUniquePtr s;
if (brpc::Socket::Address(_socket_id, &s) == 0) {
s->SetFailed();
}
UBShmEndpoint::GlobalRelease();
UBRingManager::UbrMgrFini();
ShmMgrFini();
g_skip_ub_init = _saved_skip;
}
brpc::SocketId _socket_id = brpc::INVALID_SOCKET_ID;
brpc::Socket* _socket = nullptr;
UBShmEndpoint* _ep = nullptr;
bool _saved_skip = false;
};
} // namespace ubring
} // namespace brpc
using brpc::ubring::UBShmEndpointTest;
TEST_F(UBShmEndpointTest, construct_initial_state) {
ASSERT_NE(nullptr, _ep);
}
TEST_F(UBShmEndpointTest, allocate_client_resources_real_shm) {
brpc::ubring::SHM local_trx_shm =
{NULL, 4 * 1024 * 1024, 0, {0}, (uint32_t)_socket->fd()};
int ret = _ep->AllocateClientResources(&local_trx_shm, "UBRING_ut_client");
EXPECT_EQ(0, ret);
}
TEST_F(UBShmEndpointTest, reset_cleans_up_resources) {
brpc::ubring::SHM local_trx_shm =
{NULL, 4 * 1024 * 1024, 0, {0}, (uint32_t)_socket->fd()};
_ep->AllocateClientResources(&local_trx_shm, "UBRING_ut_reset");
_ep->Reset();
}
TEST_F(UBShmEndpointTest, reset_is_idempotent) {
_ep->Reset();
_ep->Reset();
}
#else
TEST(UbringDisabledTest, skip) {
SUCCEED() << "BRPC_WITH_UBRING is not enabled, skip.";
}
#endif // BRPC_WITH_UBRING