From 3f816c5dbb9969a8642255496aa717897c48456d Mon Sep 17 00:00:00 2001 From: Andrey Serebryanskiy Date: Mon, 3 Feb 2025 16:05:36 +0300 Subject: [PATCH] fix flaky tests in ydb workload (#14035) --- ydb/apps/ydb/ut/workload-topic.cpp | 8 +- .../ut/workload-transfer-topic-to-table.cpp | 278 ++++++++++-------- 2 files changed, 168 insertions(+), 118 deletions(-) diff --git a/ydb/apps/ydb/ut/workload-topic.cpp b/ydb/apps/ydb/ut/workload-topic.cpp index a090b9990fc7..07b83b6cf9d3 100644 --- a/ydb/apps/ydb/ut/workload-topic.cpp +++ b/ydb/apps/ydb/ut/workload-topic.cpp @@ -11,6 +11,7 @@ #include #include +namespace { class TFixture : public NUnitTest::TBaseFixture { public: @@ -184,9 +185,9 @@ Y_UNIT_TEST(Full_Statistics_UseTx) const TVector expectedSubheaders = {"#", "msg/s", "MB/s", "percentile,ms", "percentile,msg", "msg/s", "MB/s", "percentile,ms", "percentile,ms", "percentile,ms", "percentile,ms"}; TVector values = ParseStatisticsLine(lines[2]); UnitAssertColumnsOrder(lines[1], expectedSubheaders); - // assert there are correct values in output - // messages per second - UNIT_ASSERT_EQUAL_C(values[1], "5", "Messages per second differs from expected: expected = " << 5 << ", got = " << values[1]); + // assert there are correct values in output messages per second + UNIT_ASSERT_GT(std::stoi(values[1]), 1); + UNIT_ASSERT_LE(std::stoi(values[1]), 5); } Y_UNIT_TEST(WriteInTx) @@ -242,3 +243,4 @@ Y_UNIT_TEST(WriteProducesToAllPartitionsEvenly) } } +} // anonymous namespace diff --git a/ydb/apps/ydb/ut/workload-transfer-topic-to-table.cpp b/ydb/apps/ydb/ut/workload-transfer-topic-to-table.cpp index 2525e113cd92..719bb1bc07c7 100644 --- a/ydb/apps/ydb/ut/workload-transfer-topic-to-table.cpp +++ b/ydb/apps/ydb/ut/workload-transfer-topic-to-table.cpp @@ -1,4 +1,5 @@ #include "run_ydb.h" +#include #include @@ -8,97 +9,160 @@ #include #include -Y_UNIT_TEST_SUITE(YdbWorkloadTransferTopicToTable) { - -struct TTopicConfigMatcher { - TString Name = "transfer-topic"; - ui32 Partitions = 128; - ui32 Consumers = 1; -}; - -struct TTableConfigMatcher { - TString Name = "transfer-table"; - ui32 Partitions = 128; +namespace { +class TFixture : public NUnitTest::TBaseFixture { + + + public: + TString TopicName; + TString TableName; + + public: + void SetUp(NUnitTest::TTestContext&) override { + // we need to generate random topic name and table name, cause in CI tests are executed parallely against one common database + TopicName = GenerateTopicName();; + TableName = GenerateTableName(); + + try { + ExecYdb({"init", "--topic", TopicName, "--table", TableName}); + } catch (const yexception) { + // ignore errors + } + } + + void TearDown(NUnitTest::TTestContext&) override { + try { + ExecYdb({"clean", "--topic", TopicName, "--table", TableName}); + } catch (const yexception) { + // ignore errors + } + } + + struct TTopicConfigMatcher { + TString Name; + ui32 Partitions; + ui32 Consumers; + }; + + struct TTableConfigMatcher { + TString Name; + ui32 Partitions; + }; + + NYdb::NTable::TSession GetSession(NYdb::NTable::TTableClient& client) + { + auto result = client.GetSession().GetValueSync(); + return result.GetSession(); + } + + void ExpectTopic(const TTopicConfigMatcher& matcher) + { + NYdb::TDriverConfig config; + config.SetEndpoint(GetYdbEndpoint()); + config.SetDatabase(GetYdbDatabase()); + + NYdb::TDriver driver(config); + NYdb::NTopic::TTopicClient client(driver); + + auto result = client.DescribeTopic(matcher.Name).GetValueSync(); + if (result.GetStatus() == NYdb::EStatus::SCHEME_ERROR) { + UNIT_ASSERT_VALUES_EQUAL(0, matcher.Partitions); + UNIT_ASSERT_VALUES_EQUAL(0, matcher.Consumers); + } else { + UNIT_ASSERT_VALUES_EQUAL(result.GetStatus(), NYdb::EStatus::SUCCESS); + + auto& description = result.GetTopicDescription(); + + UNIT_ASSERT_VALUES_EQUAL(description.GetPartitions().size(), matcher.Partitions); + UNIT_ASSERT_VALUES_EQUAL(description.GetConsumers().size(), matcher.Consumers); + } + } + + void ExpectTable(const TTableConfigMatcher& matcher) + { + NYdb::TDriverConfig config; + config.SetEndpoint(GetYdbEndpoint()); + config.SetDatabase(GetYdbDatabase()); + + NYdb::TDriver driver(config); + NYdb::NTable::TTableClient client(driver); + auto session = GetSession(client); + + NYdb::NTable::TDescribeTableSettings options; + options.WithTableStatistics(true); + + auto result = session.DescribeTable("/" + GetYdbDatabase() + "/" + matcher.Name, + options).GetValueSync(); + if (result.GetStatus() == NYdb::EStatus::SCHEME_ERROR) { + UNIT_ASSERT_VALUES_EQUAL(0, matcher.Partitions); + } else { + UNIT_ASSERT_VALUES_EQUAL(result.GetStatus(), NYdb::EStatus::SUCCESS); + + auto description = result.GetTableDescription(); + + UNIT_ASSERT_VALUES_EQUAL(description.GetPartitionsCount(), matcher.Partitions); + } + } + + TString ExecYdb(const TList& args, bool checkExitCode = true) + { + // + // ydb -e grpc://${YDB_ENDPOINT} -d /${YDB_DATABASE} workload transfer topic-to-table ${args} + // + return RunYdb({"workload", "transfer", "topic-to-table"}, args, checkExitCode); + } + + void RunYdbAndAssertTopicAndTableProps(const TList& args, + const TString& topic, ui32 topicPartitions, ui32 consumers, + const TString& table, ui32 tablePartitions) + { + ExecYdb(args); + ExpectTopic({.Name=topic, .Partitions=topicPartitions, .Consumers=consumers}); + ExpectTable({.Name=table, .Partitions=tablePartitions}); + } + + void EnsureStatisticsColumns(const TList& args, + const TVector& columns1, + const TVector& columns2) + { + ExecYdb({"init"}); + auto output = ExecYdb(args, false); + + TVector lines; + Split(output, "\n", lines); + + UnitAssertColumnsOrder(lines[0], columns1); + UnitAssertColumnsOrder(lines[1], columns2); + + ExecYdb({"clean"}); + } + + TString GenerateTopicName() + { + return "transfer-topic-" + GetRandomString(4); + } + + TString GenerateTableName() + { + return "transfer-table-" + GetRandomString(4); + } + private: + + TString GetRandomString(int len) + { + TString str; + for (int i = 0; i < len; ++i) { + str.push_back('a' + rand() % 26); + } + return str; + } }; -NYdb::NTable::TSession GetSession(NYdb::NTable::TTableClient& client) -{ - auto result = client.GetSession().GetValueSync(); - return result.GetSession(); -} - -void ExpectTopic(const TTopicConfigMatcher& matcher) -{ - NYdb::TDriverConfig config; - config.SetEndpoint(GetYdbEndpoint()); - config.SetDatabase(GetYdbDatabase()); - - NYdb::TDriver driver(config); - NYdb::NTopic::TTopicClient client(driver); - - auto result = client.DescribeTopic(matcher.Name).GetValueSync(); - if (result.GetStatus() == NYdb::EStatus::SCHEME_ERROR) { - UNIT_ASSERT_VALUES_EQUAL(0, matcher.Partitions); - UNIT_ASSERT_VALUES_EQUAL(0, matcher.Consumers); - } else { - UNIT_ASSERT_VALUES_EQUAL(result.GetStatus(), NYdb::EStatus::SUCCESS); - - auto& description = result.GetTopicDescription(); - - UNIT_ASSERT_VALUES_EQUAL(description.GetPartitions().size(), matcher.Partitions); - UNIT_ASSERT_VALUES_EQUAL(description.GetConsumers().size(), matcher.Consumers); - } -} - -void ExpectTable(const TTableConfigMatcher& matcher) -{ - NYdb::TDriverConfig config; - config.SetEndpoint(GetYdbEndpoint()); - config.SetDatabase(GetYdbDatabase()); - - NYdb::TDriver driver(config); - NYdb::NTable::TTableClient client(driver); - auto session = GetSession(client); - - NYdb::NTable::TDescribeTableSettings options; - options.WithTableStatistics(true); - - auto result = session.DescribeTable("/" + GetYdbDatabase() + "/" + matcher.Name, - options).GetValueSync(); - if (result.GetStatus() == NYdb::EStatus::SCHEME_ERROR) { - UNIT_ASSERT_VALUES_EQUAL(0, matcher.Partitions); - } else { - UNIT_ASSERT_VALUES_EQUAL(result.GetStatus(), NYdb::EStatus::SUCCESS); - - auto description = result.GetTableDescription(); - - UNIT_ASSERT_VALUES_EQUAL(description.GetPartitionsCount(), matcher.Partitions); - } -} - -TString ExecYdb(const TList& args, bool checkExitCode = true) -{ - // - // ydb -e grpc://${YDB_ENDPOINT} -d /${YDB_DATABASE} workload transfer topic-to-table ${args} - // - return RunYdb({"workload", "transfer", "topic-to-table"}, args, - checkExitCode); -} - -void RunYdb(const TList& args, - const TString& topic, ui32 topicPartitions, ui32 consumers, - const TString& table, ui32 tablePartitions) -{ - ExecYdb(args); - ExpectTopic({.Name=topic, .Partitions=topicPartitions, .Consumers=consumers}); - ExpectTable({.Name=table, .Partitions=tablePartitions}); -} +Y_UNIT_TEST_SUITE_F(YdbWorkloadTransferTopicToTable, TFixture) { Y_UNIT_TEST(Default_Run) { - ExecYdb({"init"}); - auto output = ExecYdb({"run", "-s", "10"}); - ExecYdb({"clean"}); + auto output = ExecYdb({"run", "-s", "10", "--topic", TopicName}); ui64 fullTime = GetFullTimeValue(output); @@ -108,24 +172,25 @@ Y_UNIT_TEST(Default_Run) Y_UNIT_TEST(Default_Init_Clean) { - const TString topic = "transfer-topic"; - const TString table = "transfer-table"; + // setip and tear down also executed but ignored + TopicName = GenerateTopicName();; + TableName = GenerateTableName(); - RunYdb({"init"}, topic, 128, 1, table, 128); - RunYdb({"clean"}, topic, 0, 0, table, 0); + ExecYdb({"init", "--topic", TopicName, "--table", TableName}); + ExecYdb({"clean", "--topic", TopicName, "--table", TableName}); } Y_UNIT_TEST(Specific_Init_Clean) { - const TString topic = "my-topic"; - const TString table = "my-table"; + const TString topic = GenerateTopicName(); + const TString table = GenerateTableName(); - RunYdb({"init", + RunYdbAndAssertTopicAndTableProps({"init", "--topic", topic, "--topic-partitions", "3", "--consumers", "5", "--table", table, "--table-partitions", "8"}, topic, 3, 5, table, 8); - RunYdb({"clean", + RunYdbAndAssertTopicAndTableProps({"clean", "--topic", topic, "--table", table}, topic, 0, 0, @@ -134,37 +199,20 @@ Y_UNIT_TEST(Specific_Init_Clean) Y_UNIT_TEST(Clean_Without_Init) { - UNIT_ASSERT_EXCEPTION(ExecYdb({"clean"}), yexception); + UNIT_ASSERT_EXCEPTION(ExecYdb({"clean", "--topic", GenerateTopicName(), "--table", GenerateTableName()}), yexception); } Y_UNIT_TEST(Double_Init) { - ExecYdb({"init"}); - UNIT_ASSERT_EXCEPTION(ExecYdb({"init"}), yexception); - ExecYdb({"clean"}); -} - -void EnsureStatisticsColumns(const TList& args, - const TVector& columns1, - const TVector& columns2) -{ - ExecYdb({"init"}); - auto output = ExecYdb(args, false); - - TVector lines; - Split(output, "\n", lines); - - UnitAssertColumnsOrder(lines[0], columns1); - UnitAssertColumnsOrder(lines[1], columns2); - - ExecYdb({"clean"}); + UNIT_ASSERT_EXCEPTION(ExecYdb({"init", "--topic", TopicName, "--table", TableName}), yexception); } Y_UNIT_TEST(Statistics) { - EnsureStatisticsColumns({"run", "-s", "1", "--warmup", "0"}, + EnsureStatisticsColumns({"run", "-s", "1", "--warmup", "0", "--topic", TopicName, "--table", TableName}, {"Window", "Write speed", "Write time", "Inflight", "Read speed", "Topic time", "Select time", "Upsert time", "Commit time"}, {"#", "msg/s", "MB/s", "percentile,ms", "percentile,msg", "msg/s", "MB/s", "percentile,ms", "percentile,ms", "percentile,ms", "percentile,ms"}); } } +} // anonymous namespace