diff --git a/src/meta/processors/parts/CreateSpaceProcessor.cpp b/src/meta/processors/parts/CreateSpaceProcessor.cpp index 638a69646fe..80846ccf5ed 100644 --- a/src/meta/processors/parts/CreateSpaceProcessor.cpp +++ b/src/meta/processors/parts/CreateSpaceProcessor.cpp @@ -196,6 +196,12 @@ void CreateSpaceProcessor::process(const cpp2::CreateSpaceReq& req) { } auto partHosts = std::move(partHostsRet).value(); + if (partHosts.empty()) { + LOG(ERROR) << "Pick hosts is empty."; + handleErrorCode(nebula::cpp2::ErrorCode::E_INVALID_PARM); + onFinished(); + return; + } std::stringstream ss; for (const auto& host : partHosts) { @@ -281,6 +287,7 @@ StatusOr CreateSpaceProcessor::pickHostsWithZone( const std::vector& zones, const std::unordered_map& zoneHosts) { Hosts pickedHosts; + nebula::cpp2::ErrorCode code = nebula::cpp2::ErrorCode::SUCCEEDED; for (auto iter = zoneHosts.begin(); iter != zoneHosts.end(); iter++) { auto zoneIter = std::find(std::begin(zones), std::end(zones), iter->first); if (zoneIter == std::end(zones)) { @@ -293,9 +300,8 @@ StatusOr CreateSpaceProcessor::pickHostsWithZone( auto hostIter = hostLoading_.find(host); if (hostIter == hostLoading_.end()) { LOG(ERROR) << "Host " << host << " not found"; - handleErrorCode(nebula::cpp2::ErrorCode::E_NO_HOSTS); - onFinished(); - return Status::Error("Host not found"); + code = nebula::cpp2::ErrorCode::E_NO_HOSTS; + break; } if (size > hostIter->second) { @@ -307,6 +313,12 @@ StatusOr CreateSpaceProcessor::pickHostsWithZone( hostLoading_[picked] += 1; pickedHosts.emplace_back(toThriftHost(std::move(picked))); } + + if (code != nebula::cpp2::ErrorCode::SUCCEEDED) { + handleErrorCode(code); + onFinished(); + return Status::Error("Host not found"); + } return pickedHosts; } diff --git a/src/meta/test/ProcessorTest.cpp b/src/meta/test/ProcessorTest.cpp index 903a7b98f81..6e7bd60dd03 100644 --- a/src/meta/test/ProcessorTest.cpp +++ b/src/meta/test/ProcessorTest.cpp @@ -37,6 +37,7 @@ #include "meta/processors/zone/ListGroupsProcessor.h" #include "meta/processors/zone/ListZonesProcessor.h" #include "meta/processors/zone/UpdateGroupProcessor.h" +#include "meta/processors/zone/UpdateZoneProcessor.h" #include "meta/test/TestUtils.h" DECLARE_int32(expired_threshold_sec); @@ -471,7 +472,7 @@ TEST(ProcessorTest, SpaceWithGroupTest) { fs::TempDir rootPath("/tmp/SpaceWithGroupTest.XXXXXX"); std::unique_ptr kv(MockCluster::initMetaKV(rootPath.path())); std::vector addresses; - for (int32_t i = 0; i < 10; i++) { + for (int32_t i = 0; i <= 10; i++) { addresses.emplace_back(std::to_string(i), i); } TestUtils::createSomeHosts(kv.get(), std::move(addresses)); @@ -707,6 +708,56 @@ TEST(ProcessorTest, SpaceWithGroupTest) { auto resp = std::move(f).get(); ASSERT_EQ(nebula::cpp2::ErrorCode::E_GROUP_NOT_FOUND, resp.get_code()); } +// Create space on empty zone +{ + { + std::vector nodes = {HostAddr("10", 10)}; + cpp2::AddZoneReq req; + req.set_zone_name("zone_5"); + req.set_nodes(std::move(nodes)); + auto* processor = AddZoneProcessor::instance(kv.get()); + auto f = processor->getFuture(); + processor->process(req); + auto resp = std::move(f).get(); + ASSERT_EQ(nebula::cpp2::ErrorCode::SUCCEEDED, resp.get_code()); + } + { + cpp2::AddGroupReq req; + req.set_group_name("group_2"); + std::vector zones = {"zone_5"}; + req.set_zone_names(std::move(zones)); + auto* processor = AddGroupProcessor::instance(kv.get()); + auto f = processor->getFuture(); + processor->process(req); + auto resp = std::move(f).get(); + ASSERT_EQ(nebula::cpp2::ErrorCode::SUCCEEDED, resp.get_code()); + } + { + cpp2::DropHostFromZoneReq req; + req.set_zone_name("zone_5"); + HostAddr node{"10", 10}; + req.set_node(std::move(node)); + auto* processor = DropHostFromZoneProcessor::instance(kv.get()); + auto f = processor->getFuture(); + processor->process(req); + auto resp = std::move(f).get(); + ASSERT_EQ(nebula::cpp2::ErrorCode::SUCCEEDED, resp.get_code()); + } + { + cpp2::SpaceDesc properties; + properties.set_space_name("space_on_empty_hosts"); + properties.set_partition_num(1); + properties.set_replica_factor(1); + properties.set_group_name("group_2"); + cpp2::CreateSpaceReq req; + req.set_properties(std::move(properties)); + auto* processor = CreateSpaceProcessor::instance(kv.get()); + auto f = processor->getFuture(); + processor->process(req); + auto resp = std::move(f).get(); + ASSERT_EQ(nebula::cpp2::ErrorCode::E_INVALID_PARM, resp.get_code()); + } +} } // namespace nebula TEST(ProcessorTest, CreateTagTest) {