Skip to content

Commit b9be84e

Browse files
Ravi Nagarjun AkellaRavi Nagarjun Akella
authored andcommitted
Add random read test
1 parent 5334807 commit b9be84e

File tree

4 files changed

+47
-65
lines changed

4 files changed

+47
-65
lines changed

conanfile.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
class HomeBlocksConan(ConanFile):
1111
name = "homeblocks"
12-
version = "1.0.17"
12+
version = "1.0.18"
1313
homepage = "https://github.com/eBay/HomeBlocks"
1414
description = "Block Store built on HomeStore"
1515
topics = ("ebay")

src/lib/volume/tests/test_common.hpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -213,12 +213,6 @@ class HBTestHelper {
213213
}
214214
}
215215

216-
static void validate_zeros(uint8_t const* buf, uint64_t size) {
217-
sisl::io_blob_safe blob(size, 512);
218-
std::memset(blob.bytes(), 0, size);
219-
RELEASE_ASSERT_EQ(std::memcmp(buf, blob.bytes(), size), 0, "data_buf mismatch");
220-
}
221-
222216
private:
223217
void init_devices(bool is_file, uint64_t dev_size = 0) {
224218
if (is_file) {

src/lib/volume/tests/test_volume_io.cpp

Lines changed: 27 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -174,19 +174,6 @@ class VolumeIOImpl {
174174
});
175175
}
176176

177-
<<<<<<< HEAD
178-
void verify_all_data() {
179-
for (auto& [lba, data_pattern] : m_lba_data) {
180-
auto buffer = iomanager.iobuf_alloc(512, 4096);
181-
vol_interface_req_ptr req(new vol_interface_req{buffer, lba, 1});
182-
183-
auto vol_mgr = g_helper->inst()->volume_manager();
184-
vol_mgr->read(m_vol_ptr, req).get();
185-
test_common::HBTestHelper::validate_data_buf(buffer, 4096, data_pattern);
186-
LOGDEBUG("Verify data vol={} lba={} pattern={} {}", m_vol_name, lba, data_pattern,
187-
*r_cast< uint64_t* >(buffer));
188-
iomanager.iobuf_free(buffer);
189-
=======
190177
void read_and_verify(lba_t start_lba, uint32_t nlbas) {
191178
auto sz = nlbas * m_vol_ptr->info()->page_size;
192179
sisl::io_blob_safe read_blob(sz, 512);
@@ -209,7 +196,7 @@ class VolumeIOImpl {
209196
}
210197
}
211198

212-
void verify_data(uint64_t nlbas_per_io = 1) {
199+
void verify_all_data(uint64_t nlbas_per_io = 1) {
213200
auto start_lba = m_lba_data.begin()->first;
214201
auto max_lba = m_lba_data.rbegin()->first;
215202
verify_data(start_lba, max_lba, nlbas_per_io);
@@ -221,7 +208,6 @@ class VolumeIOImpl {
221208
auto num_lbas_this_round = std::min(nlbas_per_io, max_lba - lba);
222209
read_and_verify(lba, num_lbas_this_round);
223210
num_lbas_verified += num_lbas_this_round;
224-
>>>>>>> read API implementation
225211
}
226212
LOGINFO("Verified {} lbas for volume {}", num_lbas_verified, m_vol_ptr->info()->name);
227213
}
@@ -283,36 +269,34 @@ class VolumeIOTest : public ::testing::Test {
283269
LOGINFO("IO completed");
284270
}
285271

286-
<<<<<<< HEAD
287-
void verify_all_data(shared< VolumeIOImpl > vol_impl = nullptr) {
288-
if (vol_impl) {
289-
vol_impl->verify_all_data();
290-
=======
291-
void verify_data(shared< VolumeIOImpl > vol_impl = nullptr, uint64_t nlbas_per_io = 1) {
272+
void verify_all_data(shared< VolumeIOImpl > vol_impl = nullptr, uint64_t nlbas_per_io = 1) {
292273
if (vol_impl) {
293-
vol_impl->verify_data(nlbas_per_io);
294-
>>>>>>> read API implementation
274+
vol_impl->verify_all_data(nlbas_per_io);
295275
return;
296276
}
297277

298278
for (auto& vol_impl : m_vols_impl) {
299-
<<<<<<< HEAD
300-
vol_impl->verify_all_data();
279+
vol_impl->verify_all_data(nlbas_per_io);
301280
}
302281
}
303282

304283
void restart(int shutdown_delay) {
305284
g_helper->restart(shutdown_delay);
306285
for (auto& vol_impl : m_vols_impl) {
307286
vol_impl->reset();
308-
=======
309-
vol_impl->verify_data(nlbas_per_io);
310-
>>>>>>> read API implementation
311287
}
312288
}
313289

314290
std::vector< shared< VolumeIOImpl > >& volume_list() { return m_vols_impl; }
315291

292+
template < typename T >
293+
T get_random_number(T min, T max) {
294+
static std::random_device rd;
295+
static std::mt19937 gen(rd());
296+
std::uniform_int_distribution< T > dis(min, max);
297+
return dis(gen);
298+
}
299+
316300
private:
317301
std::vector< shared< VolumeIOImpl > > m_vols_impl;
318302
};
@@ -333,34 +317,25 @@ TEST_F(VolumeIOTest, SingleVolumeWriteData) {
333317
restart(5);
334318

335319
LOGINFO("Verify data");
336-
<<<<<<< HEAD
337320
verify_all_data(vol);
338-
=======
339-
verify_data(vol, 30 /* nlbas_per_io */);
340-
>>>>>>> read API implementation
321+
//verify_data(vol, 30 /* nlbas_per_io */);
341322

342323
// Write and verify again on same LBA range to single volume multiple times.
343324
LOGINFO("Write and verify data with num_iter={} start={} nblks={}", num_iter, start_lba, nblks);
344325
for (uint32_t i = 0; i < num_iter; i++) {
345326
generate_io_single(vol, start_lba, nblks);
346327
}
347-
<<<<<<< HEAD
348328

349-
verify_all_data(vol);
350-
=======
351-
verify_data(vol);
352-
353-
// verify random lba ranges
329+
verify_all_data(vol, 30 /* nlbas_per_io */);
354330

355-
>>>>>>> read API implementation
356331
LOGINFO("SingleVolumeWriteData test done.");
357332
}
358333

359334
TEST_F(VolumeIOTest, SingleVolumeReadData) {
360335
// Write and verify fixed LBA range to single volume multiple times.
361336
auto vol = volume_list().back();
362-
uint32_t nblks = 500;
363-
lba_t start_lba = 1000;
337+
uint32_t nblks = 5000;
338+
lba_t start_lba = 500;
364339
uint32_t num_iter = 1;
365340
LOGINFO("Write and verify data with num_iter={} start={} nblks={}", num_iter, start_lba, nblks);
366341
for (uint32_t i = 0; i < num_iter; i++) {
@@ -371,7 +346,17 @@ TEST_F(VolumeIOTest, SingleVolumeReadData) {
371346
vol->verify_data(2000, 3000, 40);
372347
vol->verify_data(800, 1800, 40);
373348

374-
LOGINFO("SingleVolumeReadHoles test done.");
349+
// random reads
350+
num_iter = 100;
351+
for(uint32_t i = 0; i < num_iter; i++) {
352+
auto start_lba = get_random_number< lba_t >(0, 10000);
353+
auto nblks = get_random_number< uint32_t >(1, 64);
354+
auto no_lbas_per_io = get_random_number< uint64_t >(1, 50);
355+
LOGINFO("iter {}: Read data start={} nblks={} no_lbas_per_io {}", i, start_lba, nblks, no_lbas_per_io);
356+
vol->verify_data(start_lba, start_lba + nblks, no_lbas_per_io);
357+
}
358+
359+
LOGINFO("SingleVolumeRead test done.");
375360
}
376361

377362
TEST_F(VolumeIOTest, MultipleVolumeWriteData) {

src/lib/volume_mgr.cpp

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -259,26 +259,29 @@ VolumeManager::NullAsyncResult HomeBlocksImpl::read(const VolumePtr& vol, const
259259
// TODO: check if the system is accepting ios (shutdown in progress etc)
260260
RELEASE_ASSERT(vol != nullptr, "VolumePtr is null");
261261
// Step 1: get the blk ids from index table
262-
std::vector< std::pair< VolumeIndexKey, VolumeIndexValue > > out_vector;
263-
if(auto index_resp = read_from_index(vol, req, out_vector); index_resp.hasError()) {
262+
std::vector< std::pair< VolumeIndexKey, VolumeIndexValue > > index_kvs;
263+
if(auto index_resp = read_from_index(vol, req, index_kvs); index_resp.hasError()) {
264264
LOGE("Failed to read from index table for range=[{}, {}], volume id: {}, error: {}",
265265
req->lba, req->end_lba(), boost::uuids::to_string(vol->id()), index_resp.error());
266266
return index_resp;
267267
}
268+
if (index_kvs.empty()) {
269+
return folly::Unit();
270+
}
268271

269272
// Step 2: Consolidate the blk ids and issue read requests
270273
std::vector< folly::Future< std::error_code > > futs;
271274
auto* read_buf = req->buffer;
272275
DEBUG_ASSERT(read_buf != nullptr, "Read buffer is null");
273276
auto cur_lba = req->lba;
274-
for (uint32_t i = 0, blk_count = 0, start_idx = 0; i < out_vector.size(); ++i, ++cur_lba) {
275-
auto const& [key, value] = out_vector[i];
277+
for (uint32_t i = 0, blk_count = 0, start_idx = 0; i < index_kvs.size(); ++i, ++cur_lba) {
278+
auto const& [key, value] = index_kvs[i];
276279
// cur_lba is used to keep track of the holes
277280
// move the read buffer by the size of the holes
278281
if(cur_lba != key.key()) {
279282
if(blk_count > 0) {
280283
// submit the read for the previous blkids
281-
submit_read_to_backend(read_buf, futs, out_vector[start_idx], blk_count, vol, req->part_of_batch);
284+
submit_read_to_backend(read_buf, futs, index_kvs[start_idx], blk_count, vol, req->part_of_batch);
282285
start_idx = i;
283286
blk_count = 0;
284287
}
@@ -288,30 +291,30 @@ VolumeManager::NullAsyncResult HomeBlocksImpl::read(const VolumePtr& vol, const
288291
}
289292

290293
// Contiguous blkids are merged into a single read request
291-
bool is_contiguous = (i == 0 || value.blkid().blk_num() == out_vector[i-1].second.blkid().blk_num() + 1);
294+
bool is_contiguous = (i == 0 || (value.blkid().blk_num() == index_kvs[i-1].second.blkid().blk_num() + 1
295+
&& value.blkid().chunk_num() == index_kvs[i-1].second.blkid().chunk_num()));
292296
if(is_contiguous) {
293297
blk_count++;
294-
if(i < out_vector.size() - 1) {
298+
if(i < index_kvs.size() - 1) {
295299
continue;
296300
}
297301
}
298302
// submit the read for the previous blkids
299-
submit_read_to_backend(read_buf, futs, out_vector[start_idx], blk_count, vol, req->part_of_batch);
300-
if(out_vector[start_idx].second.blkid().blk_num() + blk_count - 1 == value.blkid().blk_num()) {
301-
// this is the last entry in the out vector
303+
submit_read_to_backend(read_buf, futs, index_kvs[start_idx], blk_count, vol, req->part_of_batch);
304+
if(index_kvs[start_idx].second.blkid().blk_num() + blk_count - 1 == value.blkid().blk_num()) {
305+
// this is the last entry in the index_kvs
302306
continue;
303307
}
304308

305309
// reset the blkids and size for the next read
306310
blk_count = 0;
307311
start_idx = i;
308-
if(i == out_vector.size() - 1) {
309-
submit_read_to_backend(read_buf, futs, out_vector[start_idx], 1, vol, req->part_of_batch);
312+
if(i == index_kvs.size() - 1) {
313+
submit_read_to_backend(read_buf, futs, index_kvs[start_idx], 1, vol, req->part_of_batch);
310314
}
311315
}
312316

313-
return out_vector.empty() ? folly::Unit() :
314-
folly::collectAllUnsafe(futs).thenValue([out_vector = std::move(out_vector), buf = req->buffer
317+
return folly::collectAllUnsafe(futs).thenValue([index_kvs = std::move(index_kvs), buf = req->buffer
315318
, start_lba = req->lba, blk_size = vol->rd()->get_blk_size()](auto&& vf) -> VolumeManager::Result< folly::Unit > {
316319
for (auto const& err_c : vf) {
317320
if (sisl_unlikely(err_c.value())) {
@@ -320,8 +323,8 @@ VolumeManager::NullAsyncResult HomeBlocksImpl::read(const VolumePtr& vol, const
320323
}
321324
// verify the checksum
322325
auto read_buf = buf;
323-
for(uint64_t cur_lba = start_lba, i = 0; i < out_vector.size(); ++i, ++cur_lba) {
324-
auto const& [key, value] = out_vector[i];
326+
for(uint64_t cur_lba = start_lba, i = 0; i < index_kvs.size(); ++i, ++cur_lba) {
327+
auto const& [key, value] = index_kvs[i];
325328
// ignore the holes
326329
if(cur_lba != key.key()) {
327330
read_buf += (key.key() - cur_lba) * blk_size;

0 commit comments

Comments
 (0)