]>
Commit | Line | Data |
---|---|---|
f67539c2 TL |
1 | /*- |
2 | * BSD LICENSE | |
3 | * | |
4 | * Copyright (c) Intel Corporation. | |
5 | * All rights reserved. | |
6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | |
10 | * | |
11 | * * Redistributions of source code must retain the above copyright | |
12 | * notice, this list of conditions and the following disclaimer. | |
13 | * * Redistributions in binary form must reproduce the above copyright | |
14 | * notice, this list of conditions and the following disclaimer in | |
15 | * the documentation and/or other materials provided with the | |
16 | * distribution. | |
17 | * * Neither the name of Intel Corporation nor the names of its | |
18 | * contributors may be used to endorse or promote products derived | |
19 | * from this software without specific prior written permission. | |
20 | * | |
21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
22 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
23 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
24 | * A PARTICULAR PURPOSE AiRE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
25 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
27 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
28 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
29 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
30 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
31 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
32 | */ | |
33 | ||
34 | #include "spdk/stdinc.h" | |
35 | #include "spdk_cunit.h" | |
36 | #include "spdk/env.h" | |
37 | #include "spdk_internal/mock.h" | |
38 | ||
39 | #include "bdev/raid/raid5.c" | |
40 | ||
41 | DEFINE_STUB_V(raid_bdev_module_list_add, (struct raid_bdev_module *raid_module)); | |
42 | DEFINE_STUB_V(raid_bdev_io_complete, (struct raid_bdev_io *raid_io, | |
43 | enum spdk_bdev_io_status status)); | |
44 | ||
45 | struct raid5_params { | |
46 | uint8_t num_base_bdevs; | |
47 | uint64_t base_bdev_blockcnt; | |
48 | uint32_t base_bdev_blocklen; | |
49 | uint32_t strip_size; | |
50 | }; | |
51 | ||
52 | static struct raid5_params *g_params; | |
53 | static size_t g_params_count; | |
54 | ||
55 | #define ARRAY_FOR_EACH(a, e) \ | |
56 | for (e = a; e < a + SPDK_COUNTOF(a); e++) | |
57 | ||
58 | #define RAID5_PARAMS_FOR_EACH(p) \ | |
59 | for (p = g_params; p < g_params + g_params_count; p++) | |
60 | ||
61 | static int | |
62 | test_setup(void) | |
63 | { | |
64 | uint8_t num_base_bdevs_values[] = { 3, 4, 5 }; | |
65 | uint64_t base_bdev_blockcnt_values[] = { 1, 1024, 1024 * 1024 }; | |
66 | uint32_t base_bdev_blocklen_values[] = { 512, 4096 }; | |
67 | uint32_t strip_size_kb_values[] = { 1, 4, 128 }; | |
68 | uint8_t *num_base_bdevs; | |
69 | uint64_t *base_bdev_blockcnt; | |
70 | uint32_t *base_bdev_blocklen; | |
71 | uint32_t *strip_size_kb; | |
72 | struct raid5_params *params; | |
73 | ||
74 | g_params_count = SPDK_COUNTOF(num_base_bdevs_values) * | |
75 | SPDK_COUNTOF(base_bdev_blockcnt_values) * | |
76 | SPDK_COUNTOF(base_bdev_blocklen_values) * | |
77 | SPDK_COUNTOF(strip_size_kb_values); | |
78 | g_params = calloc(g_params_count, sizeof(*g_params)); | |
79 | if (!g_params) { | |
80 | return -ENOMEM; | |
81 | } | |
82 | ||
83 | params = g_params; | |
84 | ||
85 | ARRAY_FOR_EACH(num_base_bdevs_values, num_base_bdevs) { | |
86 | ARRAY_FOR_EACH(base_bdev_blockcnt_values, base_bdev_blockcnt) { | |
87 | ARRAY_FOR_EACH(base_bdev_blocklen_values, base_bdev_blocklen) { | |
88 | ARRAY_FOR_EACH(strip_size_kb_values, strip_size_kb) { | |
89 | params->num_base_bdevs = *num_base_bdevs; | |
90 | params->base_bdev_blockcnt = *base_bdev_blockcnt; | |
91 | params->base_bdev_blocklen = *base_bdev_blocklen; | |
92 | params->strip_size = *strip_size_kb * 1024 / *base_bdev_blocklen; | |
93 | if (params->strip_size == 0 || | |
94 | params->strip_size > *base_bdev_blockcnt) { | |
95 | g_params_count--; | |
96 | continue; | |
97 | } | |
98 | params++; | |
99 | } | |
100 | } | |
101 | } | |
102 | } | |
103 | ||
104 | return 0; | |
105 | } | |
106 | ||
107 | static int | |
108 | test_cleanup(void) | |
109 | { | |
110 | free(g_params); | |
111 | return 0; | |
112 | } | |
113 | ||
114 | static struct raid_bdev * | |
115 | create_raid_bdev(struct raid5_params *params) | |
116 | { | |
117 | struct raid_bdev *raid_bdev; | |
118 | struct raid_base_bdev_info *base_info; | |
119 | ||
120 | raid_bdev = calloc(1, sizeof(*raid_bdev)); | |
121 | SPDK_CU_ASSERT_FATAL(raid_bdev != NULL); | |
122 | ||
123 | raid_bdev->module = &g_raid5_module; | |
124 | raid_bdev->num_base_bdevs = params->num_base_bdevs; | |
125 | raid_bdev->base_bdev_info = calloc(raid_bdev->num_base_bdevs, | |
126 | sizeof(struct raid_base_bdev_info)); | |
127 | SPDK_CU_ASSERT_FATAL(raid_bdev->base_bdev_info != NULL); | |
128 | ||
129 | RAID_FOR_EACH_BASE_BDEV(raid_bdev, base_info) { | |
130 | base_info->bdev = calloc(1, sizeof(*base_info->bdev)); | |
131 | SPDK_CU_ASSERT_FATAL(base_info->bdev != NULL); | |
132 | ||
133 | base_info->bdev->blockcnt = params->base_bdev_blockcnt; | |
134 | base_info->bdev->blocklen = params->base_bdev_blocklen; | |
135 | } | |
136 | ||
137 | raid_bdev->strip_size = params->strip_size; | |
138 | raid_bdev->strip_size_shift = spdk_u32log2(raid_bdev->strip_size); | |
139 | raid_bdev->bdev.blocklen = params->base_bdev_blocklen; | |
140 | ||
141 | return raid_bdev; | |
142 | } | |
143 | ||
144 | static void | |
145 | delete_raid_bdev(struct raid_bdev *raid_bdev) | |
146 | { | |
147 | struct raid_base_bdev_info *base_info; | |
148 | ||
149 | RAID_FOR_EACH_BASE_BDEV(raid_bdev, base_info) { | |
150 | free(base_info->bdev); | |
151 | } | |
152 | free(raid_bdev->base_bdev_info); | |
153 | free(raid_bdev); | |
154 | } | |
155 | ||
156 | static struct raid5_info * | |
157 | create_raid5(struct raid5_params *params) | |
158 | { | |
159 | struct raid_bdev *raid_bdev = create_raid_bdev(params); | |
160 | ||
161 | SPDK_CU_ASSERT_FATAL(raid5_start(raid_bdev) == 0); | |
162 | ||
163 | return raid_bdev->module_private; | |
164 | } | |
165 | ||
166 | static void | |
167 | delete_raid5(struct raid5_info *r5info) | |
168 | { | |
169 | struct raid_bdev *raid_bdev = r5info->raid_bdev; | |
170 | ||
171 | raid5_stop(raid_bdev); | |
172 | ||
173 | delete_raid_bdev(raid_bdev); | |
174 | } | |
175 | ||
176 | static void | |
177 | test_raid5_start(void) | |
178 | { | |
179 | struct raid5_params *params; | |
180 | ||
181 | RAID5_PARAMS_FOR_EACH(params) { | |
182 | struct raid5_info *r5info; | |
183 | ||
184 | r5info = create_raid5(params); | |
185 | ||
186 | CU_ASSERT_EQUAL(r5info->stripe_blocks, params->strip_size * (params->num_base_bdevs - 1)); | |
187 | CU_ASSERT_EQUAL(r5info->total_stripes, params->base_bdev_blockcnt / params->strip_size); | |
188 | CU_ASSERT_EQUAL(r5info->raid_bdev->bdev.blockcnt, | |
189 | (params->base_bdev_blockcnt - params->base_bdev_blockcnt % params->strip_size) * | |
190 | (params->num_base_bdevs - 1)); | |
191 | CU_ASSERT_EQUAL(r5info->raid_bdev->bdev.optimal_io_boundary, r5info->stripe_blocks); | |
192 | ||
193 | delete_raid5(r5info); | |
194 | } | |
195 | } | |
196 | ||
197 | int | |
198 | main(int argc, char **argv) | |
199 | { | |
200 | CU_pSuite suite = NULL; | |
201 | unsigned int num_failures; | |
202 | ||
203 | CU_set_error_action(CUEA_ABORT); | |
204 | CU_initialize_registry(); | |
205 | ||
206 | suite = CU_add_suite("raid5", test_setup, test_cleanup); | |
207 | CU_ADD_TEST(suite, test_raid5_start); | |
208 | ||
209 | CU_basic_set_mode(CU_BRM_VERBOSE); | |
210 | CU_basic_run_tests(); | |
211 | num_failures = CU_get_number_of_failures(); | |
212 | CU_cleanup_registry(); | |
213 | return num_failures; | |
214 | } |