aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgvit <gvit@ydb.tech>2022-10-24 09:58:13 +0300
committergvit <gvit@ydb.tech>2022-10-24 09:58:13 +0300
commitdd79472cbdb87cf2e28d1d2b9d83886286898b8d (patch)
tree5e50cb64c1acfdf6ed7854397646c4d9ad6a5ed6
parentb34683ebe91bfb714a1405f0b67dcc88a7060614 (diff)
downloadydb-dd79472cbdb87cf2e28d1d2b9d83886286898b8d.tar.gz
fix some tests
-rw-r--r--ydb/core/cms/console/configs_dispatcher_ut.cpp51
-rw-r--r--ydb/core/cms/console/console_ut_tenants.cpp28
-rw-r--r--ydb/core/cms/console/ut_helpers.h149
-rw-r--r--ydb/core/mind/tenant_ut_pool.cpp172
-rw-r--r--ydb/core/testlib/tenant_helpers.h151
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 &reg : 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 &reg : 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,