/************************************************************************ * EOS - the CERN Disk Storage System * * Copyright (C) 2023 CERN/Switzerland * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see .* ************************************************************************/ #include "mgm/placement/FsScheduler.hh" #include "gtest/gtest.h" using eos::mgm::placement::ClusterMgr; struct TestClusterMgrHandler : public eos::mgm::placement::ClusterMgrHandler { std::unique_ptr make_cluster_mgr(const std::string& spacename) override { auto mgr = std::make_unique(); int n_disks_per_group = 16; int n_groups = 32; { using namespace eos::mgm::placement; auto sh = mgr->getStorageHandler(2048); sh.addBucket(get_bucket_type(StdBucketType::ROOT), 0); for (int i=0; i< n_groups; ++i) { sh.addBucket(get_bucket_type(StdBucketType::GROUP), -100-i, 0); } for (int i=0; i < n_groups*n_disks_per_group; i++) { sh.addDisk(Disk(i+1, ConfigStatus::kRW, ActiveStatus::kOnline, 1), -100 - i/n_disks_per_group); } } return mgr; } eos::mgm::placement::ClusterMapT make_cluster_mgr() override { eos::mgm::placement::ClusterMapT cluster_map; cluster_map.insert_or_assign("default", make_cluster_mgr("default")); return cluster_map; } }; using eos::mgm::placement::FSScheduler; TEST(FSScheduler, construction) { FSScheduler fs_scheduler(2048, std::make_unique()); fs_scheduler.updateClusterData(); } TEST(FSScheduler, null_handler) { FSScheduler null_scheduler(2048, nullptr); null_scheduler.updateClusterData(); } TEST(FSScheduler, default_scheduler) { FSScheduler fs_scheduler(2048, std::make_unique()); auto strategy = fs_scheduler.getPlacementStrategy(); ASSERT_EQ(strategy, eos::mgm::placement::PlacementStrategyT::kGeoScheduler); } TEST(FSScheduler, geo_sched_err) { FSScheduler fs_scheduler(2048, std::make_unique()); fs_scheduler.updateClusterData(); auto result = fs_scheduler.schedule("default",2); ASSERT_FALSE(result); EXPECT_EQ(result.ret_code, EINVAL); EXPECT_EQ(result.error_string(), "Not a valid PlacementStrategy"); } TEST(FSScheduler, round_robin) { FSScheduler fs_scheduler(2048, std::make_unique()); fs_scheduler.updateClusterData(); fs_scheduler.setPlacementStrategy("roundrobin"); auto strategy = fs_scheduler.getPlacementStrategy(); ASSERT_EQ(strategy, eos::mgm::placement::PlacementStrategyT::kRoundRobin); auto result = fs_scheduler.schedule("default",2); ASSERT_TRUE(result); } TEST(FSScheduler, setPlacementStrategy) { FSScheduler fs_scheduler(2048, std::make_unique()); fs_scheduler.updateClusterData(); fs_scheduler.setPlacementStrategy("roundrobin"); EXPECT_EQ(fs_scheduler.getPlacementStrategy(), eos::mgm::placement::PlacementStrategyT::kRoundRobin); EXPECT_EQ(fs_scheduler.getPlacementStrategy("default"), eos::mgm::placement::PlacementStrategyT::kRoundRobin); EXPECT_EQ(fs_scheduler.getPlacementStrategy("foobar"), eos::mgm::placement::PlacementStrategyT::kRoundRobin); } TEST(FSScheduler, setPlacementStrategySpace) { FSScheduler fs_scheduler(2048, std::make_unique()); fs_scheduler.updateClusterData(); fs_scheduler.setPlacementStrategy("default", "weightedrandom"); EXPECT_EQ(fs_scheduler.getPlacementStrategy(), eos::mgm::placement::PlacementStrategyT::kGeoScheduler); EXPECT_EQ(fs_scheduler.getPlacementStrategy("default"), eos::mgm::placement::PlacementStrategyT::kWeightedRandom); EXPECT_EQ(fs_scheduler.getPlacementStrategy("tape"), eos::mgm::placement::PlacementStrategyT::kGeoScheduler); }