#include #include #include #include #include #include "v1/primitives/bool.grpc.pb.h" #include "v1/primitives/int.grpc.pb.h" #include "v1/primitives/string.grpc.pb.h" #include "v1/collections/list.grpc.pb.h" class RediskaBasicTest : public ::testing::Test { protected: void SetUp() override { channel_ = grpc::CreateChannel(grpc::InsecureChannel("localhost:50051")); bool_stub_ = std::make_unique(channel_); int_stub_ = std::make_unique(channel_); string_stub_ = std::make_unique(channel_); list_stub_ = std::make_unique(channel_); } void TearDown() override { channel_->Shutdown(); } std::shared_ptr channel_; std::unique_ptr bool_stub_; std::unique_ptr int_stub_; std::unique_ptr string_stub_; std::unique_ptr list_stub_; }; TEST_F(RediskaBasicTest, BooleanOperations) { // Test SET operation bool_stub_->Set(v1::primitives::boolean::BoolSetRequest(id="test_bool", value=true)); // Test GET operation auto response = bool_stub_->Get(v1::primitives::BoolGetRequest(id="test_bool")); EXPECT_TRUE(response.value()); // Test DELETE operation auto delete_response = bool_stub_->Delete(v1::primitives::BoolDeleteRequest(id="test_bool")); EXPECT_TRUE(delete_response.removed_value()); } TEST_F(RediskaBasicTest, IntegerOperations) { // Test SET operation int_stub_->Set(v1::primitives::integer::IntSetRequest(id="test_int", value=42)); // Test GET operation auto response = int_stub_->Get(v1::primitives::integer::IntGetRequest(id="test_int")); EXPECT_EQ(response.value(), 42); // Test DELETE operation auto delete_response = int_stub_->Delete(v1::primitives::integer::IntDeleteRequest(id="test_int")); EXPECT_EQ(delete_response.removed_value(), 42); } TEST_F(RediskaBasicTest, StringOperations) { // Test SET operation string_stub_->Set(v1::primitives::str::StringSetRequest(id="test_string", value="hello")); // Test GET operation auto response = string_stub_->Get(v1::primitives::str::StringGetRequest(id="test_string")); EXPECT_EQ(response.value(), "hello"); // Test DELETE operation auto delete_response = string_stub_->Delete(v1::primitives::str::StringDeleteRequest(id="test_string")); EXPECT_EQ(delete_response.removed_value(), "hello"); } TEST_FediskaBasicTest, ListOperations) { // Test CREATE operation auto create_response = list_stub_->Create(v1::collections::list::ListCreateRequest( element_kind=v1::collections::common::ElementKind::INT, ttl_seconds=3600 )); std::string list_id = create_response.id; // Test SET operation std::vector elements; elements.push_back(v1::collections::common::CollectionElement(integer=1)); elements.push_back(v1::collections::common::CollectionElement(integer=2)); elements.push_back(v1::collections::common::CollectionElement(integer=3)); list_stub_->Set(v1::collections::list::ListSetRequest(id=list_id, elements=elements)); // Test GET operation (streaming) auto get_response = list_stub_->Get(v1::collections::list::ListGetRequest(id=list_id)); int count = 0; for (auto element : get_response) { EXPECT_EQ(element.integer(), count + 1); count++; } EXPECT_EQ(count, 3); // Test LENGTH operation auto length_response = list_stub_->Length(v1::collections::list::ListLengthRequest(id=list_id)); EXPECT_EQ(length_response.length(), 3); // Test DELETE operation list_stub_->Delete(v1::collections::DeleteRequest(id=list_id)); } TEST_FediskaBasicTest, ConcurrentOperations) { const int num_threads = 10; const int operations_per_thread = 100; std::vector threads; std::vector> exceptions; // Запускаем несколько потоков одновременно for (int i = 0; i < num_threads; ++i) { threads.emplace_back([&, i, operations_per_thread]() { try { for (int j = 0; j < operations_per_thread; ++j) { std::string key = "test_" + std::to_string(i * operations_per_thread + j); if (j % 3 == 0) { bool_stub_->Set(v1::primitives::boolean::BoolSetRequest(key, true)); } else if (j % 3 == 1) { int_stub_->Set(v1::primitives::integer::IntSetRequest(key, j)); } else { string_stub_->Set(v1::primitives::str::StringSetRequest(key, "value_" + std::to_string(j))); } } } catch (const std::exception& e) { exceptions.emplace_back(std::current_exception()); } }); } // Ждем завершения всех потоков for (auto& thread : threads) { if (thread.joinable()) { thread.join(); } } // Проверяем, что не было исключений EXPECT_TRUE(exceptions.empty()); } TEST_FediskaBasicTest, ServerStability) { // Тест на стабильность сервера при множественных запросов const int num_requests = 1000; for (int i = 0; i < num_requests; ++i) { std::string key = "stability_test_" + std::to_string(i); if (i % 4 == 0) { bool_stub_->Set(v1::primitives::boolean::BoolSetRequest(key, true)); } else if (i % 4 == 1) { int_stub_->Set(v1::primitives::integer::IntSetRequest(key, i)); } else if (i % 4 == 2) { string_stub_->Set(v1::primitives::str::StringSetRequest(key, "value_" + std::to_string(i))); } else { list_stub_->Set(v1::collections::ListSetRequest( id="list_" + std::to_string(i), elements={ v1::collections::common::CollectionElement(integer=i) } )); } if (i % 10 == 0) { auto response = bool_stub_->Get(v1::primitives::boolean::BoolGetRequest(key)); EXPECT_TRUE(response.value()); } } }