Skip to content

Commit 1d41cb5

Browse files
committed
bd - Added util classes for composing block devices
ChainingBlockDevice - Supports chaining multiple block devices together with a sequential address space. Useful for combining multiple memory devices together to expand storage capacity. SlicingBlockDevice - Supports mapping a slice of a block device to a new block device. Useful for repurposing regions of a block device for less aware algorithms. ClusteringBlockDevice - Supports clustering small blocks into larger blocks. Useful for matching the required block size of less aware algorithms. DividingBlockDevice - Supports dividing large blocks into smaller blocks. Uses internal buffer to hold large blocks.
1 parent 882d9d4 commit 1d41cb5

File tree

9 files changed

+1247
-0
lines changed

9 files changed

+1247
-0
lines changed
Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
#include "mbed.h"
2+
#include "greentea-client/test_env.h"
3+
#include "unity.h"
4+
#include "utest.h"
5+
6+
#include "HeapBlockDevice.h"
7+
#include "SlicingBlockDevice.h"
8+
#include "ChainingBlockDevice.h"
9+
#include "ClusteringBlockDevice.h"
10+
#include "DividingBlockDevice.h"
11+
#include <stdlib.h>
12+
13+
using namespace utest::v1;
14+
15+
#define BLOCK_SIZE 512
16+
uint8_t write_block[BLOCK_SIZE];
17+
uint8_t read_block[BLOCK_SIZE];
18+
19+
20+
void test_slicing() {
21+
HeapBlockDevice bd(BLOCK_SIZE, 16);
22+
23+
// Test with first slice of block device
24+
SlicingBlockDevice slice1(&bd, 0, 8);
25+
26+
int err = slice1.init();
27+
TEST_ASSERT_EQUAL(0, err);
28+
29+
TEST_ASSERT_EQUAL(BLOCK_SIZE, slice1.get_block_size());
30+
TEST_ASSERT_EQUAL(8, slice1.get_block_count());
31+
32+
// Fill with random sequence
33+
srand(1);
34+
for (int i = 0; i < BLOCK_SIZE; i++) {
35+
write_block[i] = 0xff & rand();
36+
}
37+
38+
// Write, sync, and read the block
39+
err = slice1.write(write_block, 0, 1);
40+
TEST_ASSERT_EQUAL(1, err);
41+
42+
err = slice1.sync();
43+
TEST_ASSERT_EQUAL(0, err);
44+
45+
err = slice1.read(read_block, 0, 1);
46+
TEST_ASSERT_EQUAL(1, err);
47+
48+
// Check that the data was unmodified
49+
srand(1);
50+
for (int i = 0; i < BLOCK_SIZE; i++) {
51+
TEST_ASSERT_EQUAL(0xff & rand(), read_block[i]);
52+
}
53+
54+
// Check with original block device
55+
err = bd.read(read_block, 0, 1);
56+
TEST_ASSERT_EQUAL(1, err);
57+
58+
// Check that the data was unmodified
59+
srand(1);
60+
for (int i = 0; i < BLOCK_SIZE; i++) {
61+
TEST_ASSERT_EQUAL(0xff & rand(), read_block[i]);
62+
}
63+
64+
err = slice1.deinit();
65+
TEST_ASSERT_EQUAL(0, err);
66+
67+
68+
// Test with second slice of block device
69+
SlicingBlockDevice slice2(&bd, 8, 16);
70+
71+
err = slice2.init();
72+
TEST_ASSERT_EQUAL(0, err);
73+
74+
TEST_ASSERT_EQUAL(BLOCK_SIZE, slice2.get_block_size());
75+
TEST_ASSERT_EQUAL(8, slice2.get_block_count());
76+
77+
// Fill with random sequence
78+
srand(1);
79+
for (int i = 0; i < BLOCK_SIZE; i++) {
80+
write_block[i] = 0xff & rand();
81+
}
82+
83+
// Write, sync, and read the block
84+
err = slice2.write(write_block, 0, 1);
85+
TEST_ASSERT_EQUAL(1, err);
86+
87+
err = slice2.sync();
88+
TEST_ASSERT_EQUAL(0, err);
89+
90+
err = slice2.read(read_block, 0, 1);
91+
TEST_ASSERT_EQUAL(1, err);
92+
93+
// Check that the data was unmodified
94+
srand(1);
95+
for (int i = 0; i < BLOCK_SIZE; i++) {
96+
TEST_ASSERT_EQUAL(0xff & rand(), read_block[i]);
97+
}
98+
99+
// Check with original block device
100+
err = bd.read(read_block, 8, 1);
101+
TEST_ASSERT_EQUAL(1, err);
102+
103+
// Check that the data was unmodified
104+
srand(1);
105+
for (int i = 0; i < BLOCK_SIZE; i++) {
106+
TEST_ASSERT_EQUAL(0xff & rand(), read_block[i]);
107+
}
108+
109+
err = slice2.deinit();
110+
TEST_ASSERT_EQUAL(0, err);
111+
}
112+
113+
void test_chaining() {
114+
HeapBlockDevice bd1(BLOCK_SIZE, 8);
115+
HeapBlockDevice bd2(BLOCK_SIZE, 8);
116+
117+
// Test with chain of block device
118+
BlockDevice *bds[] = {&bd1, &bd2};
119+
ChainingBlockDevice chain(bds);
120+
121+
int err = chain.init();
122+
TEST_ASSERT_EQUAL(0, err);
123+
124+
TEST_ASSERT_EQUAL(BLOCK_SIZE, chain.get_block_size());
125+
TEST_ASSERT_EQUAL(16, chain.get_block_count());
126+
127+
// Fill with random sequence
128+
srand(1);
129+
for (int i = 0; i < BLOCK_SIZE; i++) {
130+
write_block[i] = 0xff & rand();
131+
}
132+
133+
// Write, sync, and read the block
134+
err = chain.write(write_block, 0, 1);
135+
TEST_ASSERT_EQUAL(1, err);
136+
137+
err = chain.sync();
138+
TEST_ASSERT_EQUAL(0, err);
139+
140+
err = chain.read(read_block, 0, 1);
141+
TEST_ASSERT_EQUAL(1, err);
142+
143+
// Check that the data was unmodified
144+
srand(1);
145+
for (int i = 0; i < BLOCK_SIZE; i++) {
146+
TEST_ASSERT_EQUAL(0xff & rand(), read_block[i]);
147+
}
148+
149+
// Write, sync, and read the block
150+
err = chain.write(write_block, 8, 1);
151+
TEST_ASSERT_EQUAL(1, err);
152+
153+
err = chain.sync();
154+
TEST_ASSERT_EQUAL(0, err);
155+
156+
err = chain.read(read_block, 8, 1);
157+
TEST_ASSERT_EQUAL(1, err);
158+
159+
// Check that the data was unmodified
160+
srand(1);
161+
for (int i = 0; i < BLOCK_SIZE; i++) {
162+
TEST_ASSERT_EQUAL(0xff & rand(), read_block[i]);
163+
}
164+
165+
err = chain.deinit();
166+
TEST_ASSERT_EQUAL(0, err);
167+
}
168+
169+
void test_clustering() {
170+
HeapBlockDevice bd(BLOCK_SIZE/2, 32);
171+
172+
// Test with clustering block device
173+
ClusteringBlockDevice cluster(&bd, BLOCK_SIZE);
174+
175+
int err = cluster.init();
176+
TEST_ASSERT_EQUAL(0, err);
177+
178+
TEST_ASSERT_EQUAL(BLOCK_SIZE, cluster.get_block_size());
179+
TEST_ASSERT_EQUAL(16, cluster.get_block_count());
180+
181+
// Fill with random sequence
182+
srand(1);
183+
for (int i = 0; i < BLOCK_SIZE; i++) {
184+
write_block[i] = 0xff & rand();
185+
}
186+
187+
// Write, sync, and read the block
188+
err = cluster.write(write_block, 0, 1);
189+
TEST_ASSERT_EQUAL(1, err);
190+
191+
err = cluster.sync();
192+
TEST_ASSERT_EQUAL(0, err);
193+
194+
err = cluster.read(read_block, 0, 1);
195+
TEST_ASSERT_EQUAL(1, err);
196+
197+
// Check that the data was unmodified
198+
srand(1);
199+
for (int i = 0; i < BLOCK_SIZE; i++) {
200+
TEST_ASSERT_EQUAL(0xff & rand(), read_block[i]);
201+
}
202+
203+
err = cluster.deinit();
204+
TEST_ASSERT_EQUAL(0, err);
205+
}
206+
207+
void test_dividing() {
208+
HeapBlockDevice bd(BLOCK_SIZE*2, 8);
209+
210+
// Test with dividing block device
211+
DividingBlockDevice divide(&bd, BLOCK_SIZE);
212+
213+
int err = divide.init();
214+
TEST_ASSERT_EQUAL(0, err);
215+
216+
TEST_ASSERT_EQUAL(BLOCK_SIZE, divide.get_block_size());
217+
TEST_ASSERT_EQUAL(16, divide.get_block_count());
218+
219+
// Fill with random sequence
220+
srand(1);
221+
for (int i = 0; i < BLOCK_SIZE; i++) {
222+
write_block[i] = 0xff & rand();
223+
}
224+
225+
// Write, sync, and read the block
226+
err = divide.write(write_block, 0, 1);
227+
TEST_ASSERT_EQUAL(1, err);
228+
229+
err = divide.sync();
230+
TEST_ASSERT_EQUAL(0, err);
231+
232+
err = divide.read(read_block, 0, 1);
233+
TEST_ASSERT_EQUAL(1, err);
234+
235+
// Check that the data was unmodified
236+
srand(1);
237+
for (int i = 0; i < BLOCK_SIZE; i++) {
238+
TEST_ASSERT_EQUAL(0xff & rand(), read_block[i]);
239+
}
240+
241+
err = divide.deinit();
242+
TEST_ASSERT_EQUAL(0, err);
243+
}
244+
245+
246+
// Test setup
247+
utest::v1::status_t test_setup(const size_t number_of_cases) {
248+
GREENTEA_SETUP(10, "default_auto");
249+
return verbose_test_setup_handler(number_of_cases);
250+
}
251+
252+
Case cases[] = {
253+
Case("Testing slicing of a block device", test_slicing),
254+
Case("Testing chaining of block devices", test_chaining),
255+
Case("Testing clustering a block device", test_clustering),
256+
Case("Testing dividing a block device", test_dividing),
257+
};
258+
259+
Specification specification(test_setup, cases);
260+
261+
int main() {
262+
return !Harness::run(specification);
263+
}

0 commit comments

Comments
 (0)