// ---------------------------------------------------------------------- // File: RRSeedTests // Author: Abhishek Lekshmanan - CERN // ---------------------------------------------------------------------- /************************************************************************ * 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/RRSeed.hh" #include "gtest/gtest.h" #include using RRSeed = eos::mgm::placement::RRSeed; TEST(RRSeed, Construction) { RRSeed seed(10); EXPECT_EQ(seed.getNumSeeds(), 10); } TEST(RRSeed, out_of_bounds) { RRSeed seed(10); // 0-indexing, 10 should be offby1 EXPECT_THROW(seed.get(10,0), std::out_of_range); } TEST(RRSeed, single_thread) { RRSeed seed(10); EXPECT_EQ(seed.getNumSeeds(), 10); // Trivial No op case - base condition, we don't change anything here EXPECT_EQ(seed.get(0,0),0); // We ask for the next seed, we'd get the starting seed ie. 0 and internally // the counter is 1 EXPECT_EQ(seed.get(0,1),0); // No op - check internal counter EXPECT_EQ(seed.get(0,0),1); // Repeat No op! EXPECT_EQ(seed.get(0,0),1); // Now we ask for the next seed, we'd still get 1, internal counter = 2 EXPECT_EQ(seed.get(0,1),1); // No op - check internal counter EXPECT_EQ(seed.get(0,0),2); // ask for 10 seeds EXPECT_EQ(seed.get(0,10),2); // No op - check internal counter EXPECT_EQ(seed.get(0,0),12); } TEST(RRSeed, multithread) { RRSeed seed(10); auto f = [&seed]() { for (int i = 0; i < 1000; i++) { seed.get(0, 1); } }; std::vector threads; for (int i=0;i<16;++i){ threads.emplace_back(f); } for (int i=0;i<16;++i){ threads[i].join(); } EXPECT_EQ(seed.get(0,0),16000); // Get at a different index, we only modified index 0 seed, // rest should all be 0 EXPECT_EQ(seed.get(1,0),0); } TEST(RRSeed, wrap_around) { eos::mgm::placement::RRSeed seed(10); // no op - check initial state EXPECT_EQ(seed.get(0,0),0); for (int i = 0; i < 255; i++) { EXPECT_EQ(seed.get(0,1),i); } // no op - final value at 255 EXPECT_EQ(seed.get(0,0),255); // now increment! EXPECT_EQ(seed.get(0,1),255); // wrap aroound! check reusability EXPECT_EQ(seed.get(0,1),0); EXPECT_EQ(seed.get(0,1),1); EXPECT_EQ(seed.get(0,1),2); }