diff options
author | gvit <gvit@ydb.tech> | 2022-10-24 09:58:13 +0300 |
---|---|---|
committer | gvit <gvit@ydb.tech> | 2022-10-24 09:58:13 +0300 |
commit | dd79472cbdb87cf2e28d1d2b9d83886286898b8d (patch) | |
tree | 5e50cb64c1acfdf6ed7854397646c4d9ad6a5ed6 | |
parent | b34683ebe91bfb714a1405f0b67dcc88a7060614 (diff) | |
download | ydb-dd79472cbdb87cf2e28d1d2b9d83886286898b8d.tar.gz |
fix some tests
-rw-r--r-- | ydb/core/cms/console/configs_dispatcher_ut.cpp | 51 | ||||
-rw-r--r-- | ydb/core/cms/console/console_ut_tenants.cpp | 28 | ||||
-rw-r--r-- | ydb/core/cms/console/ut_helpers.h | 149 | ||||
-rw-r--r-- | ydb/core/mind/tenant_ut_pool.cpp | 172 | ||||
-rw-r--r-- | ydb/core/testlib/tenant_helpers.h | 151 |
5 files changed, 168 insertions, 383 deletions
diff --git a/ydb/core/cms/console/configs_dispatcher_ut.cpp b/ydb/core/cms/console/configs_dispatcher_ut.cpp index 6fe29a3b2f..8c9a26890d 100644 --- a/ydb/core/cms/console/configs_dispatcher_ut.cpp +++ b/ydb/core/cms/console/configs_dispatcher_ut.cpp @@ -19,7 +19,9 @@ TTenantTestConfig::TTenantPoolConfig TenantTenantPoolConfig() { TTenantTestConfig::TTenantPoolConfig res = { // Static slots {tenant, {cpu, memory, network}} - {}, + { + {TENANT1_1_NAME, {1, 1, 1}} + }, // NodeType "type1" }; @@ -30,13 +32,13 @@ TTenantTestConfig DefaultConsoleTestConfig() { TTenantTestConfig res = { // Domains {name, schemeshard {{ subdomain_names }}} - {{ {DOMAIN1_NAME, SCHEME_SHARD1_ID, TVector<TString>()} }}, + {{ {DOMAIN1_NAME, SCHEME_SHARD1_ID, { TENANT1_1_NAME }} }}, // HiveId HIVE_ID, // FakeTenantSlotBroker true, // FakeSchemeShard - false, + true, // CreateConsole true, // Nodes {tenant_pool_config, data_center} @@ -65,21 +67,6 @@ TActorId InitConfigsDispatcher(TTenantTestRuntime &runtime) NKikimrConfig::TAppConfig(), {}, {}, "", "", 2, NKikimrConsole::TConfigItem::MERGE, ""); - CheckCreateTenant(runtime, Ydb::StatusIds::SUCCESS, - TCreateTenantRequest(TENANT1_1_NAME) - .WithPools({{"hdd", 1}})); - CheckTenantStatus(runtime, TENANT1_1_NAME, Ydb::StatusIds::SUCCESS, - Ydb::Cms::GetDatabaseStatusResult::PENDING_RESOURCES, - {{"hdd", 1, 1}}, {}); - CheckCreateTenant(runtime, Ydb::StatusIds::SUCCESS, - TCreateTenantRequest(TENANT1_2_NAME) - .WithPools({{"hdd", 1}})); - CheckTenantStatus(runtime, TENANT1_2_NAME, Ydb::StatusIds::SUCCESS, - Ydb::Cms::GetDatabaseStatusResult::PENDING_RESOURCES, - {{"hdd", 1, 1}}, {}); - - ChangeTenant(runtime, TENANT1_1_NAME); - return MakeConfigsDispatcherID(runtime.GetNodeId(0)); } @@ -422,34 +409,6 @@ Y_UNIT_TEST_SUITE(TConfigsDispatcherTests) { runtime.DispatchEvents(options2); } - Y_UNIT_TEST(TestChangeTenant) { - TTenantTestRuntime runtime(DefaultConsoleTestConfig()); - TAutoPtr<IEventHandle> handle; - InitConfigsDispatcher(runtime); - - AddSubscriber(runtime, {(ui32)NKikimrConsole::TConfigItem::LogConfigItem}); - AddSubscriber(runtime, {(ui32)NKikimrConsole::TConfigItem::LogConfigItem}); - - // Subscribers get notification. - TDispatchOptions options1; - options1.FinalEvents.emplace_back(TEvConfigsDispatcher::EvSetConfigSubscriptionResponse, 2); - runtime.DispatchEvents(options1); - - SendConfigure(runtime, MakeAddAction(ITEM_DOMAIN_LOG_1)); - - // Expect two responses from subscribers and one from dispatcher. - TDispatchOptions options2; - options2.FinalEvents.emplace_back(TEvConsole::EvConfigNotificationResponse, 3); - runtime.DispatchEvents(options2); - - // Change tenant and expect new notifications. - ChangeTenant(runtime, TENANT1_2_NAME, 0, false); - - TDispatchOptions options3; - options3.FinalEvents.emplace_back(TEvConsole::EvConfigNotificationResponse, 3); - runtime.DispatchEvents(options3); - } - Y_UNIT_TEST(TestGetCachedConfig) { TTenantTestRuntime runtime(DefaultConsoleTestConfig()); TAutoPtr<IEventHandle> handle; diff --git a/ydb/core/cms/console/console_ut_tenants.cpp b/ydb/core/cms/console/console_ut_tenants.cpp index cdacb4b454..5d9a0971b2 100644 --- a/ydb/core/cms/console/console_ut_tenants.cpp +++ b/ydb/core/cms/console/console_ut_tenants.cpp @@ -927,34 +927,6 @@ Y_UNIT_TEST_SUITE(TConsoleTests) { RunTestRestartConsoleAndPools(runtime); } - void RunTestAlterTenantModifyComputationalResourcesForPending(TTenantTestRuntime& runtime) { - CheckCreateTenant(runtime, Ydb::StatusIds::SUCCESS, - TCreateTenantRequest(TENANT1_1_NAME).WithPools({{"hdd", 1}})); - - CheckTenantStatus(runtime, TENANT1_1_NAME, Ydb::StatusIds::SUCCESS, - Ydb::Cms::GetDatabaseStatusResult::PENDING_RESOURCES, {{"hdd", 1, 1}}, {}); - - CheckAlterTenantSlots(runtime, TENANT1_1_NAME, Ydb::StatusIds::SUCCESS, - {{ {SLOT1_TYPE, ZONE1, 5} }}, {}); - - runtime.WaitForHiveState({{{DOMAIN1_NAME, 8, 8, 8}, - {TENANT1_1_NAME, 5, 5, 5}}}); - - CheckTenantStatus(runtime, TENANT1_1_NAME, Ydb::StatusIds::SUCCESS, - Ydb::Cms::GetDatabaseStatusResult::RUNNING, {{"hdd", 1, 1}}, {}, - SLOT1_TYPE, ZONE1, 5, 5); - } - - Y_UNIT_TEST(TestAlterTenantModifyComputationalResourcesForPending) { - TTenantTestRuntime runtime(DefaultConsoleTestConfig()); - RunTestAlterTenantModifyComputationalResourcesForPending(runtime); - } - - Y_UNIT_TEST(TestAlterTenantModifyComputationalResourcesForPendingExtSubdomain) { - TTenantTestRuntime runtime(DefaultConsoleTestConfig(), {}, true); - RunTestAlterTenantModifyComputationalResourcesForPending(runtime); - } - void RunTestAlterTenantModifyComputationalResourcesForRunning(TTenantTestRuntime& runtime) { CheckCreateTenant(runtime, TENANT1_1_NAME, Ydb::StatusIds::SUCCESS, {{"hdd", 1}}, diff --git a/ydb/core/cms/console/ut_helpers.h b/ydb/core/cms/console/ut_helpers.h index 9faf6468fa..ac9711963b 100644 --- a/ydb/core/cms/console/ut_helpers.h +++ b/ydb/core/cms/console/ut_helpers.h @@ -15,19 +15,6 @@ namespace NKikimr { namespace NConsole { namespace NUT { -struct TUnitRegistration { - TUnitRegistration(const TString &host = "", ui32 port = 0, const TString &kind = "") - : Host(host) - , Port(port) - , Kind(kind) - { - } - - TString Host; - ui32 Port; - TString Kind; -}; - inline NKikimrConsole::TUsageScope MakeUsageScope(const TVector<ui32> &nodes) { NKikimrConsole::TUsageScope res; @@ -228,142 +215,6 @@ void CheckListConfigSubscriptions(TTenantTestRuntime &runtime, Ydb::StatusIds::S UNIT_ASSERT(subscriptions.empty()); } -inline bool CompareState(THashMap<std::pair<TString, TString>, TSlotState> slots, - THashMap<TString, TPoolAllocation> pools, - THashMap<std::pair<TString, ui32>, TUnitRegistration> registrations, - const Ydb::Cms::GetDatabaseStatusResult &status, bool shared = false) -{ - const auto& resources = shared ? status.required_shared_resources() : status.required_resources(); - - for (auto &unit : resources.computational_units()) { - auto key = std::make_pair(unit.unit_kind(), unit.availability_zone()); - auto count = unit.count(); - if (!slots.contains(key)) - return false; - if (slots[key].Required != count) - return false; - slots[key].Required = 0; - } - - for (auto &unit : resources.storage_units()) { - auto key = unit.unit_kind(); - auto size = unit.count(); - if (!pools.contains(key)) - return false; - if (pools[key].PoolSize != size) - return false; - pools[key].PoolSize = 0; - } - - for (auto &unit : status.allocated_resources().computational_units()) { - auto key = std::make_pair(unit.unit_kind(), unit.availability_zone()); - auto count = unit.count(); - if (!slots.contains(key)) - return false; - if (slots[key].Allocated != count) - return false; - slots[key].Allocated = 0; - } - - for (auto &unit : status.allocated_resources().storage_units()) { - auto key = unit.unit_kind(); - auto size = unit.count(); - if (!pools.contains(key)) - return false; - if (pools[key].Allocated != size) - return false; - pools[key].Allocated = 0; - } - - for (auto &unit : status.registered_resources()) { - auto key = std::make_pair(unit.host(), unit.port()); - if (!registrations.contains(key)) - return false; - if (registrations.at(key).Kind != unit.unit_kind()) - return false; - registrations.erase(key); - } - - for (auto &pr : slots) { - if (pr.second.Required || pr.second.Allocated) - return false; - } - - for (auto &pr : pools) { - if (pr.second.PoolSize || pr.second.Allocated) - return false; - } - - if (registrations.size()) - return false; - - return true; -} - -template <typename ...Ts> -void CheckTenantStatus(TTenantTestRuntime &runtime, const TString &path, bool shared, - Ydb::StatusIds::StatusCode code, - Ydb::Cms::GetDatabaseStatusResult::State state, - TVector<TPoolAllocation> poolTypes, - TVector<TUnitRegistration> unitRegistrations, - Ts... args) -{ - THashMap<std::pair<TString, TString>, TSlotState> slots; - CollectSlots(slots, args...); - - THashMap<TString, TPoolAllocation> pools; - for (auto &pool : poolTypes) - pools[pool.PoolType] = pool; - - THashMap<std::pair<TString, ui32>, TUnitRegistration> registrations; - for (auto ® : unitRegistrations) - registrations[std::make_pair(reg.Host, reg.Port)] = reg; - - bool ok = false; - while (!ok) { - auto *event = new TEvConsole::TEvGetTenantStatusRequest; - event->Record.MutableRequest()->set_path(path); - - TAutoPtr<IEventHandle> handle; - runtime.SendToConsole(event); - auto reply = runtime.GrabEdgeEventRethrow<TEvConsole::TEvGetTenantStatusResponse>(handle); - auto &operation = reply->Record.GetResponse().operation(); - UNIT_ASSERT_VALUES_EQUAL(operation.status(), code); - if (code != Ydb::StatusIds::SUCCESS) - return; - - Ydb::Cms::GetDatabaseStatusResult status; - UNIT_ASSERT(operation.result().UnpackTo(&status)); - - UNIT_ASSERT_VALUES_EQUAL(status.path(), CanonizePath(path)); - - ok = status.state() == state && CompareState(slots, pools, registrations, status, shared); - if (!ok) { - TDispatchOptions options; - options.FinalEvents.emplace_back(NConsole::TTenantsManager::TEvPrivate::EvRetryAllocateResources); - options.FinalEvents.emplace_back(NConsole::TTenantsManager::TEvPrivate::EvSubdomainFailed); - options.FinalEvents.emplace_back(NConsole::TTenantsManager::TEvPrivate::EvSubdomainCreated); - options.FinalEvents.emplace_back(NConsole::TTenantsManager::TEvPrivate::EvSubdomainReady); - options.FinalEvents.emplace_back(NConsole::TTenantsManager::TEvPrivate::EvSubdomainRemoved); - options.FinalEvents.emplace_back(NConsole::TTenantsManager::TEvPrivate::EvPoolAllocated); - options.FinalEvents.emplace_back(NConsole::TTenantsManager::TEvPrivate::EvPoolFailed); - options.FinalEvents.emplace_back(NConsole::TTenantsManager::TEvPrivate::EvPoolDeleted); - runtime.DispatchEvents(options, TDuration::Seconds(10)); - } - } -} - -template <typename ...Ts> -void CheckTenantStatus(TTenantTestRuntime &runtime, const TString &path, - Ydb::StatusIds::StatusCode code, - Ydb::Cms::GetDatabaseStatusResult::State state, - TVector<TPoolAllocation> poolTypes, - TVector<TUnitRegistration> unitRegistrations, - Ts... args) -{ - CheckTenantStatus(runtime, path, false, code, state, poolTypes, unitRegistrations, args...); -} - inline void WaitForTenantStatus(TTenantTestRuntime &runtime, const TString &path, Ydb::StatusIds::StatusCode code) diff --git a/ydb/core/mind/tenant_ut_pool.cpp b/ydb/core/mind/tenant_ut_pool.cpp index 2efa337625..bd3dbc7fc0 100644 --- a/ydb/core/mind/tenant_ut_pool.cpp +++ b/ydb/core/mind/tenant_ut_pool.cpp @@ -16,112 +16,6 @@ struct TAction { TString Label; }; -class TActionChecker : public TActorBootstrapped<TActionChecker> { - TActorId EdgeActor; - ui32 NodeId; - ui32 Domain; - TVector<TAction> Actions; - THashMap<TString, TVector<TAction>> Answers; - bool Finished; - -public: - TActionChecker(TActorId edge, ui32 nodeId, ui32 domain, TVector<TAction> actions) - : EdgeActor(edge) - , NodeId(nodeId) - , Domain(domain) - , Actions(std::move(actions)) - , Finished(false) - { - } - - void Bootstrap(const TActorContext &ctx) - { - ctx.Send(MakeTenantPoolID(NodeId, Domain), new TEvTenantPool::TEvTakeOwnership); - for (auto &action : Actions) { - auto *event = new TEvTenantPool::TEvConfigureSlot; - event->Record.SetSlotId(action.SlotId); - event->Record.SetAssignedTenant(action.TenantName); - event->Record.SetLabel(action.Label); - ctx.Send(MakeTenantPoolID(NodeId, Domain), event, 0, action.Cookie); - - Answers[action.SlotId].push_back(action); - } - Become(&TThis::StateWork); - } - - void Handle(TEvTenantPool::TEvConfigureSlotResult::TPtr &ev, const TActorContext &ctx) - { - auto &rec = ev->Get()->Record; - auto &id = rec.GetSlotStatus().GetId(); - UNIT_ASSERT(Answers.contains(id)); - auto &answer = Answers[id].front(); - UNIT_ASSERT_VALUES_EQUAL((int)rec.GetStatus(), (int)answer.Status); - UNIT_ASSERT_VALUES_EQUAL(ev->Cookie, answer.Cookie); - if (answer.Status == NKikimrTenantPool::SUCCESS) { - UNIT_ASSERT_VALUES_EQUAL(rec.GetSlotStatus().GetAssignedTenant(), answer.TenantName); - UNIT_ASSERT_VALUES_EQUAL(rec.GetSlotStatus().GetLabel(), answer.Label); - } - Answers[id].erase(Answers[id].begin()); - if (Answers[id].empty()) - Answers.erase(id); - - if (Answers.empty()) { - ctx.Send(EdgeActor, new TEvTest::TEvActionSuccess); - Finished = true; - } - } - - void LostOwnership() - { - UNIT_ASSERT(Finished); - } - - STFUNC(StateWork) { - switch (ev->GetTypeRewrite()) { - HFunc(TEvTenantPool::TEvConfigureSlotResult, Handle); - IgnoreFunc(TEvTenantPool::TEvTenantPoolStatus); - cFunc(TEvTenantPool::EvLostOwnership, LostOwnership); - - default: - Y_FAIL("unexpected event type: %" PRIx32 " event: %s", - ev->GetTypeRewrite(), ev->HasEvent() ? ev->GetBase()->ToString().data() : "serialized?"); - break; - } - } -}; - -template<typename ...Ts> -void CollectActions(TVector<TAction> &actions, ui64 cookie, const TString &slotId, - const TString &tenantName, NKikimrTenantPool::EStatus status, - Ts ...args) -{ - CollectActions(actions, cookie, slotId, tenantName, status); - CollectActions(actions, cookie + 1, args...); -} - -template<typename ...Ts> -void CollectActions(TVector<TAction> &actions, ui64 cookie, const TString &slotId, - const TString &tenantName, const TString &label, - NKikimrTenantPool::EStatus status, Ts ...args) -{ - CollectActions(actions, cookie, slotId, tenantName, status, label); - CollectActions(actions, cookie + 1, args...); -} - -template<typename ...Ts> -void CheckConfigureSlot(TTenantTestRuntime &runtime, ui32 domain, - Ts ...args) -{ - TVector<TAction> actions; - CollectActions(actions, 1, args...); - - auto *actor = new TActionChecker(runtime.Sender, runtime.GetNodeId(0), domain, actions); - runtime.Register(actor); - - TAutoPtr<IEventHandle> handle; - runtime.GrabEdgeEventRethrow<TEvTest::TEvActionSuccess>(handle); -} - void CheckLabels(TIntrusivePtr<::NMonitoring::TDynamicCounters> counters, const TString &database, const TString &slot, @@ -281,6 +175,15 @@ Y_UNIT_TEST_SUITE(TTenantPoolTests) { "", } }, + // Node2 + { + // TenantPoolConfig + { + // Static slots {tenant, {cpu, memory, network}} + {{ {TENANT1_2_NAME, {1, 1, 1}} }}, + "", + } + } }}, // DataCenterCount @@ -291,8 +194,9 @@ Y_UNIT_TEST_SUITE(TTenantPoolTests) { ext.MutableMonitoringConfig()->SetForceDatabaseLabels(true); TTenantTestRuntime runtime(config, ext); - runtime.WaitForHiveState({{{DOMAIN1_NAME, 6, 6, 6}, - {TENANT1_1_NAME, 5, 5, 5}}}); + runtime.WaitForHiveState({{{DOMAIN1_NAME, 1, 1, 1}, + {TENANT1_1_NAME, 1, 1, 1}, + {TENANT1_2_NAME, 1, 1, 1}}}); TVector<std::pair<TString, TString>> labels = { { CanonizePath(DOMAIN1_NAME), "static" }, { TENANT1_1_NAME, "static" }, }; @@ -302,58 +206,6 @@ Y_UNIT_TEST_SUITE(TTenantPoolTests) { } } - Y_UNIT_TEST(TestDatabaseAttributeSensorLabels) { - const TTenantTestConfig config = { - // Domains {name, schemeshard {{ subdomain_names }}} - {{ {DOMAIN1_NAME, SCHEME_SHARD1_ID, TVector<TString>()} }}, - // HiveId - HIVE_ID, - // FakeTenantSlotBroker - false, - // FakeSchemeShard - false, - // CreateConsole - true, - // Nodes {tenant_pool_config, data_center} - {{ - { - { - // Static slots {tenant, {cpu, memory, network}} - {{ {DOMAIN1_NAME, {1, 1, 1}} }}, - "node-type" - } - }, - }}, - // DataCenterCount - 1 - }; - TTenantTestRuntime runtime(config); - auto counters = runtime.GetDynamicCounters(); - - THashMap<TString, TString> attrs; - for (auto &l : GetDatabaseAttributeLabels()) - attrs[l] = l + "_value"; - TVector<std::pair<TString, TString>> attrsv; - for (auto &pr : attrs) - attrsv.push_back(pr); - - CheckCreateTenant(runtime, TENANT1_1_NAME, Ydb::StatusIds::SUCCESS, - {{"hdd", 1}}, - attrsv, - SLOT2_TYPE, ZONE_ANY, 1); - - runtime.WaitForHiveState({{{TENANT1_1_NAME, 1, 1, 1}}}); - - CheckLabels(counters, TENANT1_1_NAME, "slot-1", attrs); - - WaitTenantRunning(runtime, TENANT1_1_NAME); // workaround for scheme cache race - CheckRemoveTenant(runtime, TENANT1_1_NAME, Ydb::StatusIds::SUCCESS); - - runtime.WaitForHiveState({}); - - CheckLabels(counters, "", ""); - } - Y_UNIT_TEST(TestSensorsConfigForStaticSlot) { const TTenantTestConfig config = { // Domains {name, schemeshard {{ subdomain_names }}} diff --git a/ydb/core/testlib/tenant_helpers.h b/ydb/core/testlib/tenant_helpers.h index 209b73baa0..13758d5b99 100644 --- a/ydb/core/testlib/tenant_helpers.h +++ b/ydb/core/testlib/tenant_helpers.h @@ -3,6 +3,7 @@ #include "tenant_runtime.h" #include <ydb/core/cms/console/console.h> +#include <ydb/core/cms/console/console_tenants_manager.h> #include <library/cpp/testing/unittest/registar.h> @@ -32,6 +33,19 @@ struct TPoolAllocation { ui32 Allocated; }; +struct TUnitRegistration { + TUnitRegistration(const TString &host = "", ui32 port = 0, const TString &kind = "") + : Host(host) + , Port(port) + , Kind(kind) + { + } + + TString Host; + ui32 Port; + TString Kind; +}; + inline void CollectSlots(TVector<TSlotRequest> &) { } @@ -148,6 +162,143 @@ struct TCreateTenantRequest { } }; +inline bool CompareState(THashMap<std::pair<TString, TString>, TSlotState> slots, + THashMap<TString, TPoolAllocation> pools, + THashMap<std::pair<TString, ui32>, TUnitRegistration> registrations, + const Ydb::Cms::GetDatabaseStatusResult &status, bool shared = false) +{ + const auto& resources = shared ? status.required_shared_resources() : status.required_resources(); + + for (auto &unit : resources.computational_units()) { + auto key = std::make_pair(unit.unit_kind(), unit.availability_zone()); + auto count = unit.count(); + if (!slots.contains(key)) + return false; + if (slots[key].Required != count) + return false; + slots[key].Required = 0; + } + + for (auto &unit : resources.storage_units()) { + auto key = unit.unit_kind(); + auto size = unit.count(); + if (!pools.contains(key)) + return false; + if (pools[key].PoolSize != size) + return false; + pools[key].PoolSize = 0; + } + + for (auto &unit : status.allocated_resources().computational_units()) { + auto key = std::make_pair(unit.unit_kind(), unit.availability_zone()); + auto count = unit.count(); + if (!slots.contains(key)) + return false; + if (slots[key].Allocated != count) + return false; + slots[key].Allocated = 0; + } + + for (auto &unit : status.allocated_resources().storage_units()) { + auto key = unit.unit_kind(); + auto size = unit.count(); + if (!pools.contains(key)) + return false; + if (pools[key].Allocated != size) + return false; + pools[key].Allocated = 0; + } + + for (auto &unit : status.registered_resources()) { + auto key = std::make_pair(unit.host(), unit.port()); + if (!registrations.contains(key)) + return false; + if (registrations.at(key).Kind != unit.unit_kind()) + return false; + registrations.erase(key); + } + + for (auto &pr : slots) { + if (pr.second.Required || pr.second.Allocated) + return false; + } + + for (auto &pr : pools) { + if (pr.second.PoolSize || pr.second.Allocated) + return false; + } + + if (registrations.size()) + return false; + + return true; +} + +template <typename ...Ts> +inline void CheckTenantStatus(TTenantTestRuntime &runtime, const TString &path, bool shared, + Ydb::StatusIds::StatusCode code, + Ydb::Cms::GetDatabaseStatusResult::State state, + TVector<TPoolAllocation> poolTypes, + TVector<TUnitRegistration> unitRegistrations, + Ts... args) +{ + THashMap<std::pair<TString, TString>, TSlotState> slots; + CollectSlots(slots, args...); + + THashMap<TString, TPoolAllocation> pools; + for (auto &pool : poolTypes) + pools[pool.PoolType] = pool; + + THashMap<std::pair<TString, ui32>, TUnitRegistration> registrations; + for (auto ® : unitRegistrations) + registrations[std::make_pair(reg.Host, reg.Port)] = reg; + + bool ok = false; + while (!ok) { + auto *event = new NConsole::TEvConsole::TEvGetTenantStatusRequest; + event->Record.MutableRequest()->set_path(path); + + TAutoPtr<IEventHandle> handle; + runtime.SendToConsole(event); + auto reply = runtime.GrabEdgeEventRethrow<NConsole::TEvConsole::TEvGetTenantStatusResponse>(handle); + auto &operation = reply->Record.GetResponse().operation(); + UNIT_ASSERT_VALUES_EQUAL(operation.status(), code); + if (code != Ydb::StatusIds::SUCCESS) + return; + + Ydb::Cms::GetDatabaseStatusResult status; + UNIT_ASSERT(operation.result().UnpackTo(&status)); + + UNIT_ASSERT_VALUES_EQUAL(status.path(), CanonizePath(path)); + + ok = status.state() == state && CompareState(slots, pools, registrations, status, shared); + if (!ok) { + TDispatchOptions options; + options.FinalEvents.emplace_back(NConsole::TTenantsManager::TEvPrivate::EvRetryAllocateResources); + options.FinalEvents.emplace_back(NConsole::TTenantsManager::TEvPrivate::EvSubdomainFailed); + options.FinalEvents.emplace_back(NConsole::TTenantsManager::TEvPrivate::EvSubdomainCreated); + options.FinalEvents.emplace_back(NConsole::TTenantsManager::TEvPrivate::EvSubdomainReady); + options.FinalEvents.emplace_back(NConsole::TTenantsManager::TEvPrivate::EvSubdomainRemoved); + options.FinalEvents.emplace_back(NConsole::TTenantsManager::TEvPrivate::EvPoolAllocated); + options.FinalEvents.emplace_back(NConsole::TTenantsManager::TEvPrivate::EvPoolFailed); + options.FinalEvents.emplace_back(NConsole::TTenantsManager::TEvPrivate::EvPoolDeleted); + runtime.DispatchEvents(options, TDuration::Seconds(10)); + } + } +} + +template <typename ...Ts> +inline void CheckTenantStatus(TTenantTestRuntime &runtime, const TString &path, + Ydb::StatusIds::StatusCode code, + Ydb::Cms::GetDatabaseStatusResult::State state, + TVector<TPoolAllocation> poolTypes, + TVector<TUnitRegistration> unitRegistrations, + Ts... args) +{ + CheckTenantStatus(runtime, path, false, code, state, poolTypes, unitRegistrations, args...); +} + + inline void CheckCreateTenant(TTenantTestRuntime &runtime, const TString &token, Ydb::StatusIds::StatusCode code, |