Protocol Buffers - Google's data interchange format (grpc依赖)
https://developers.google.com/protocol-buffers/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
125 lines
3.7 KiB
125 lines
3.7 KiB
1 year ago
|
// Protocol Buffers - Google's data interchange format
|
||
|
// Copyright 2023 Google LLC. All rights reserved.
|
||
|
//
|
||
1 year ago
|
// Use of this source code is governed by a BSD-style
|
||
|
// license that can be found in the LICENSE file or at
|
||
|
// https://developers.google.com/open-source/licenses/bsd
|
||
1 year ago
|
|
||
4 months ago
|
#include "google/protobuf/hpb/internal/message_lock.h"
|
||
1 year ago
|
|
||
|
#include <atomic>
|
||
|
#include <mutex>
|
||
|
#include <string>
|
||
|
#include <thread>
|
||
|
|
||
1 year ago
|
#include <gmock/gmock.h>
|
||
|
#include <gtest/gtest.h>
|
||
1 year ago
|
#include "absl/hash/hash.h"
|
||
|
#include "absl/log/absl_check.h"
|
||
5 months ago
|
#include "google/protobuf/compiler/hpb/tests/test_model.upb.proto.h"
|
||
5 months ago
|
#include "google/protobuf/hpb/hpb.h"
|
||
1 year ago
|
#include "upb/mem/arena.hpp"
|
||
1 year ago
|
|
||
|
#ifndef ASSERT_OK
|
||
|
#define ASSERT_OK(x) ASSERT_TRUE(x.ok())
|
||
|
#endif // ASSERT_OK
|
||
|
#ifndef EXPECT_OK
|
||
|
#define EXPECT_OK(x) EXPECT_TRUE(x.ok())
|
||
|
#endif // EXPECT_OK
|
||
|
|
||
5 months ago
|
namespace hpb_unittest::protos {
|
||
1 year ago
|
|
||
|
namespace {
|
||
|
|
||
|
std::string GenerateTestData() {
|
||
|
TestModel model;
|
||
|
model.set_str1("str");
|
||
|
ThemeExtension extension1;
|
||
|
extension1.set_ext_name("theme");
|
||
4 months ago
|
ABSL_CHECK_OK(::hpb::SetExtension(&model, theme, extension1));
|
||
1 year ago
|
ThemeExtension extension2;
|
||
|
extension2.set_ext_name("theme_extension");
|
||
4 months ago
|
ABSL_CHECK_OK(
|
||
|
::hpb::SetExtension(&model, ThemeExtension::theme_extension, extension2));
|
||
1 year ago
|
::upb::Arena arena;
|
||
4 months ago
|
auto bytes = ::hpb::Serialize(&model, arena);
|
||
1 year ago
|
ABSL_CHECK_OK(bytes);
|
||
|
return std::string(bytes->data(), bytes->size());
|
||
|
}
|
||
|
|
||
|
std::mutex m[8];
|
||
|
void unlock_func(const void* msg) { m[absl::HashOf(msg) & 0x7].unlock(); }
|
||
5 months ago
|
::hpb::internal::UpbExtensionUnlocker lock_func(const void* msg) {
|
||
1 year ago
|
m[absl::HashOf(msg) & 0x7].lock();
|
||
|
return &unlock_func;
|
||
|
}
|
||
|
|
||
4 months ago
|
void TestConcurrentExtensionAccess(::hpb::ExtensionRegistry registry) {
|
||
5 months ago
|
::hpb::internal::upb_extension_locker_global.store(&lock_func,
|
||
|
std::memory_order_release);
|
||
1 year ago
|
const std::string payload = GenerateTestData();
|
||
|
TestModel parsed_model =
|
||
|
::protos::Parse<TestModel>(payload, registry).value();
|
||
|
const auto test_main = [&] { EXPECT_EQ("str", parsed_model.str1()); };
|
||
|
const auto test_theme = [&] {
|
||
4 months ago
|
ASSERT_TRUE(::hpb::HasExtension(&parsed_model, theme));
|
||
1 year ago
|
auto ext = ::protos::GetExtension(&parsed_model, theme);
|
||
|
ASSERT_OK(ext);
|
||
|
EXPECT_EQ((*ext)->ext_name(), "theme");
|
||
|
};
|
||
|
const auto test_theme_extension = [&] {
|
||
|
auto ext =
|
||
|
::protos::GetExtension(&parsed_model, ThemeExtension::theme_extension);
|
||
|
ASSERT_OK(ext);
|
||
|
EXPECT_EQ((*ext)->ext_name(), "theme_extension");
|
||
|
};
|
||
|
const auto test_serialize = [&] {
|
||
|
::upb::Arena arena;
|
||
4 months ago
|
EXPECT_OK(::hpb::Serialize(&parsed_model, arena));
|
||
1 year ago
|
};
|
||
1 year ago
|
const auto test_copy_constructor = [&] {
|
||
|
TestModel copy_a = parsed_model;
|
||
|
TestModel copy_b = parsed_model;
|
||
|
EXPECT_EQ(copy_a.has_str1(), copy_b.has_str1());
|
||
|
};
|
||
1 year ago
|
std::thread t1(test_main);
|
||
|
std::thread t2(test_main);
|
||
|
std::thread t3(test_theme);
|
||
|
std::thread t4(test_theme);
|
||
|
std::thread t5(test_theme_extension);
|
||
|
std::thread t6(test_theme_extension);
|
||
|
std::thread t7(test_serialize);
|
||
1 year ago
|
std::thread t8(test_copy_constructor);
|
||
1 year ago
|
t1.join();
|
||
|
t2.join();
|
||
|
t3.join();
|
||
|
t4.join();
|
||
|
t5.join();
|
||
|
t6.join();
|
||
|
t7.join();
|
||
1 year ago
|
t8.join();
|
||
1 year ago
|
test_main();
|
||
|
test_theme();
|
||
|
test_theme_extension();
|
||
|
}
|
||
|
|
||
|
TEST(CppGeneratedCode, ConcurrentAccessDoesNotRaceBothLazy) {
|
||
|
::upb::Arena arena;
|
||
|
TestConcurrentExtensionAccess({{}, arena});
|
||
|
}
|
||
|
|
||
|
TEST(CppGeneratedCode, ConcurrentAccessDoesNotRaceOneLazyOneEager) {
|
||
|
::upb::Arena arena;
|
||
|
TestConcurrentExtensionAccess({{&theme}, arena});
|
||
|
TestConcurrentExtensionAccess({{&ThemeExtension::theme_extension}, arena});
|
||
|
}
|
||
|
|
||
|
TEST(CppGeneratedCode, ConcurrentAccessDoesNotRaceBothEager) {
|
||
|
::upb::Arena arena;
|
||
|
TestConcurrentExtensionAccess(
|
||
|
{{&theme, &ThemeExtension::theme_extension}, arena});
|
||
|
}
|
||
|
|
||
|
} // namespace
|
||
5 months ago
|
} // namespace hpb_unittest::protos
|