summaryrefslogtreecommitdiffstats
path: root/src/test/crimson/seastore/test_randomblock_manager.cc
blob: 26205e16487690902d669c9fab279aa1bf1c9df2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab

#include "test/crimson/gtest_seastar.h"

#include <random>

#include "crimson/common/log.h"
#include "crimson/os/seastore/random_block_manager/block_rb_manager.h"
#include "crimson/os/seastore/random_block_manager/rbm_device.h"

using namespace crimson;
using namespace crimson::os;
using namespace crimson::os::seastore;

namespace {
  [[maybe_unused]] seastar::logger& logger() {
    return crimson::get_logger(ceph_subsys_test);
  }
}

constexpr uint64_t DEFAULT_TEST_SIZE = 1 << 20;

struct rbm_test_t :
  public seastar_test_suite_t {
  std::unique_ptr<BlockRBManager> rbm_manager;
  std::unique_ptr<random_block_device::RBMDevice> device;

  struct rbm_transaction {
    void add_rbm_allocated_blocks(alloc_delta_t &d) {
      allocated_blocks.push_back(d);
    }
    void clear_rbm_allocated_blocks() {
      if (!allocated_blocks.empty()) {
	allocated_blocks.clear();
      }
    }
    const auto &get_rbm_allocated_blocks() {
      return allocated_blocks;
    }
    std::vector<alloc_delta_t> allocated_blocks;
  };

  std::default_random_engine generator;

  uint64_t block_size = 0;
  uint64_t size = 0;

  device_config_t config;

  rbm_test_t() = default;

  seastar::future<> set_up_fut() final {
    device = random_block_device::create_test_ephemeral(
      random_block_device::DEFAULT_TEST_CBJOURNAL_SIZE, DEFAULT_TEST_SIZE);
    block_size = device->get_block_size();
    size = device->get_available_size();
    rbm_manager.reset(new BlockRBManager(device.get(), std::string(), false));
    config = get_rbm_ephemeral_device_config(0, 1);
    return device->mkfs(config).handle_error(crimson::ct_error::assert_all{}
    ).then([this] {
      return device->mount().handle_error(crimson::ct_error::assert_all{}
      ).then([this] {
	return rbm_manager->open().handle_error(crimson::ct_error::assert_all{});
      });
    });
  }

  seastar::future<> tear_down_fut() final {
    rbm_manager->close().unsafe_get();
    device->close().unsafe_get();
    rbm_manager.reset();
    device.reset();
    return seastar::now();
  }

  auto mkfs() {
    return device->mkfs(config).unsafe_get();
  }

  auto read_rbm_superblock() {
    return device->read_rbm_superblock(RBM_START_ADDRESS).unsafe_get();
  }

  auto open() {
    device->mount().unsafe_get();
    return rbm_manager->open().unsafe_get();
  }

  auto write(uint64_t addr, bufferptr &ptr) {
    paddr_t paddr = convert_abs_addr_to_paddr(
      addr,
      rbm_manager->get_device_id());
    return rbm_manager->write(paddr, ptr).unsafe_get();
  }

  auto read(uint64_t addr, bufferptr &ptr) {
    paddr_t paddr = convert_abs_addr_to_paddr(
      addr,
      rbm_manager->get_device_id());
    return rbm_manager->read(paddr, ptr).unsafe_get();
  }

  bufferptr generate_extent(size_t blocks) {
    std::uniform_int_distribution<char> distribution(
      std::numeric_limits<char>::min(),
      std::numeric_limits<char>::max()
    );
    char contents = distribution(generator);
    return buffer::ptr(buffer::create(blocks * block_size, contents));
  }

  void close() {
    rbm_manager->close().unsafe_get();
    return;
  }

};

TEST_F(rbm_test_t, mkfs_test)
{
 run_async([this] {
   auto super = read_rbm_superblock();
   ASSERT_TRUE(
       super.block_size == block_size &&
       super.size == size
   );
   config.spec.id = DEVICE_ID_NULL;
   mkfs();
   super = read_rbm_superblock();
   ASSERT_TRUE(
       super.config.spec.id == DEVICE_ID_NULL &&
       super.size == size 
   );
 });
}

TEST_F(rbm_test_t, open_read_write_test)
{
 run_async([this] {
   auto content = generate_extent(1);
   {
     write(
	 block_size,
	 content
	 );
     auto bp = bufferptr(ceph::buffer::create_page_aligned(block_size));
     read(
	 block_size,
	 bp
	 );
     bufferlist bl;
     bufferlist block;
     bl.append(bp);
     block.append(content);
     ASSERT_EQ(
	  bl.begin().crc32c(bl.length(), 1),
	  block.begin().crc32c(block.length(), 1));
   }
   close();
   open();
   {
     auto bp = bufferptr(ceph::buffer::create_page_aligned(block_size));
     read(
	 block_size,
	 bp
	 );
     bufferlist bl;
     bufferlist block;
     bl.append(bp);
     block.append(content);
     ASSERT_EQ(
	  bl.begin().crc32c(bl.length(), 1),
	  block.begin().crc32c(block.length(), 1));
   }
 });
}