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 ARE 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_cunit.h" 35 #include "spdk/string.h" 36 #include "spdk/stdinc.h" 37 38 #include "blobfs/bdev/blobfs_bdev.c" 39 40 int g_fserrno; 41 42 bool g_bdev_open_ext_fail = false; 43 bool g_bdev_create_bs_dev_from_desc_fail = false; 44 bool g_fs_load_fail = false; 45 bool g_fs_unload_fail = false; 46 bool g_bs_bdev_claim_fail = false; 47 bool g_blobfs_fuse_start_fail = false; 48 struct blobfs_bdev_operation_ctx *g_fs_ctx; 49 50 const char *g_bdev_name = "ut_bdev"; 51 52 int 53 spdk_bdev_open_ext(const char *bdev_name, bool write, spdk_bdev_event_cb_t event_cb, 54 void *event_ctx, struct spdk_bdev_desc **_desc) 55 { 56 if (g_bdev_open_ext_fail) { 57 return -1; 58 } 59 60 return 0; 61 } 62 63 static void 64 bs_dev_destroy(struct spdk_bs_dev *dev) 65 { 66 } 67 68 struct spdk_bs_dev * 69 spdk_bdev_create_bs_dev_from_desc(struct spdk_bdev_desc *desc) 70 { 71 static struct spdk_bs_dev bs_dev; 72 73 if (g_bdev_create_bs_dev_from_desc_fail) { 74 return NULL; 75 } 76 77 bs_dev.destroy = bs_dev_destroy; 78 return &bs_dev; 79 } 80 81 void 82 spdk_fs_load(struct spdk_bs_dev *dev, fs_send_request_fn send_request_fn, 83 spdk_fs_op_with_handle_complete cb_fn, void *cb_arg) 84 { 85 int rc = 0; 86 87 if (g_fs_load_fail) { 88 rc = -1; 89 } 90 91 cb_fn(cb_arg, NULL, rc); 92 93 return; 94 } 95 96 void 97 spdk_fs_unload(struct spdk_filesystem *fs, spdk_fs_op_complete cb_fn, void *cb_arg) 98 { 99 int rc = 0; 100 101 if (g_fs_unload_fail) { 102 rc = -1; 103 } 104 105 cb_fn(cb_arg, rc); 106 return; 107 } 108 109 void 110 spdk_fs_init(struct spdk_bs_dev *dev, struct spdk_blobfs_opts *opt, 111 fs_send_request_fn send_request_fn, 112 spdk_fs_op_with_handle_complete cb_fn, void *cb_arg) 113 { 114 int rc = 0; 115 116 if (g_fs_load_fail) { 117 rc = -1; 118 } 119 120 cb_fn(cb_arg, NULL, rc); 121 return; 122 } 123 124 int 125 spdk_bs_bdev_claim(struct spdk_bs_dev *bs_dev, struct spdk_bdev_module *module) 126 { 127 if (g_bs_bdev_claim_fail) { 128 return -1; 129 } 130 131 return 0; 132 } 133 134 int 135 blobfs_fuse_start(const char *bdev_name, const char *mountpoint, struct spdk_filesystem *fs, 136 blobfs_fuse_unmount_cb cb_fn, void *cb_arg, struct spdk_blobfs_fuse **_bfuse) 137 { 138 if (g_blobfs_fuse_start_fail) { 139 return -1; 140 } 141 142 /* store the ctx for unmount operation */ 143 g_fs_ctx = cb_arg; 144 145 return 0; 146 } 147 148 void 149 spdk_bdev_close(struct spdk_bdev_desc *desc) 150 { 151 } 152 153 int 154 spdk_thread_send_msg(const struct spdk_thread *thread, spdk_msg_fn fn, void *ctx) 155 { 156 fn(ctx); 157 return 0; 158 } 159 160 struct spdk_thread * 161 spdk_get_thread(void) 162 { 163 struct spdk_thread *thd = (struct spdk_thread *)0x1; 164 165 return thd; 166 } 167 168 const char * 169 spdk_bdev_get_name(const struct spdk_bdev *bdev) 170 { 171 return g_bdev_name; 172 } 173 174 void 175 spdk_fs_opts_init(struct spdk_blobfs_opts *opts) 176 { 177 } 178 179 void 180 blobfs_fuse_send_request(fs_request_fn fn, void *arg) 181 { 182 } 183 184 void 185 blobfs_fuse_stop(struct spdk_blobfs_fuse *bfuse) 186 { 187 } 188 189 static void 190 blobfs_bdev_op_complete(void *cb_arg, int fserrno) 191 { 192 g_fserrno = fserrno; 193 } 194 195 static void 196 spdk_blobfs_bdev_detect_test(void) 197 { 198 /* spdk_bdev_open_ext() fails */ 199 g_bdev_open_ext_fail = true; 200 spdk_blobfs_bdev_detect(g_bdev_name, blobfs_bdev_op_complete, NULL); 201 CU_ASSERT(g_fserrno != 0); 202 203 g_bdev_open_ext_fail = false; 204 205 /* spdk_bdev_create_bs_dev_from_desc() fails */ 206 g_bdev_create_bs_dev_from_desc_fail = true; 207 spdk_blobfs_bdev_detect(g_bdev_name, blobfs_bdev_op_complete, NULL); 208 CU_ASSERT(g_fserrno != 0); 209 210 g_bdev_create_bs_dev_from_desc_fail = false; 211 212 /* spdk_fs_load() fails */ 213 g_fs_load_fail = true; 214 spdk_blobfs_bdev_detect(g_bdev_name, blobfs_bdev_op_complete, NULL); 215 CU_ASSERT(g_fserrno != 0); 216 217 g_fs_load_fail = false; 218 219 /* spdk_fs_unload() fails */ 220 g_fs_unload_fail = true; 221 spdk_blobfs_bdev_detect(g_bdev_name, blobfs_bdev_op_complete, NULL); 222 CU_ASSERT(g_fserrno != 0); 223 224 g_fs_unload_fail = false; 225 226 /* no fail */ 227 spdk_blobfs_bdev_detect(g_bdev_name, blobfs_bdev_op_complete, NULL); 228 CU_ASSERT(g_fserrno == 0); 229 } 230 231 static void 232 spdk_blobfs_bdev_create_test(void) 233 { 234 uint32_t cluster_sz = 1024 * 1024; 235 236 /* spdk_bdev_open_ext() fails */ 237 g_bdev_open_ext_fail = true; 238 spdk_blobfs_bdev_create(g_bdev_name, cluster_sz, blobfs_bdev_op_complete, NULL); 239 CU_ASSERT(g_fserrno != 0); 240 241 g_bdev_open_ext_fail = false; 242 243 /* spdk_bdev_create_bs_dev_from_desc() fails */ 244 g_bdev_create_bs_dev_from_desc_fail = true; 245 spdk_blobfs_bdev_create(g_bdev_name, cluster_sz, blobfs_bdev_op_complete, NULL); 246 CU_ASSERT(g_fserrno != 0); 247 248 g_bdev_create_bs_dev_from_desc_fail = false; 249 250 /* spdk_bs_bdev_claim() fails */ 251 g_bs_bdev_claim_fail = true; 252 spdk_blobfs_bdev_create(g_bdev_name, cluster_sz, blobfs_bdev_op_complete, NULL); 253 CU_ASSERT(g_fserrno != 0); 254 255 g_bs_bdev_claim_fail = false; 256 257 /* spdk_fs_init() fails */ 258 g_fs_load_fail = true; 259 spdk_blobfs_bdev_create(g_bdev_name, cluster_sz, blobfs_bdev_op_complete, NULL); 260 CU_ASSERT(g_fserrno != 0); 261 262 g_fs_load_fail = false; 263 264 /* spdk_fs_unload() fails */ 265 g_fs_unload_fail = true; 266 spdk_blobfs_bdev_create(g_bdev_name, cluster_sz, blobfs_bdev_op_complete, NULL); 267 CU_ASSERT(g_fserrno != 0); 268 269 g_fs_unload_fail = false; 270 271 /* no fail */ 272 spdk_blobfs_bdev_create(g_bdev_name, cluster_sz, blobfs_bdev_op_complete, NULL); 273 CU_ASSERT(g_fserrno == 0); 274 } 275 276 static void 277 spdk_blobfs_bdev_mount_test(void) 278 { 279 #ifdef SPDK_CONFIG_FUSE 280 const char *mountpoint = "/mnt"; 281 282 /* spdk_bdev_open_ext() fails */ 283 g_bdev_open_ext_fail = true; 284 spdk_blobfs_bdev_mount(g_bdev_name, mountpoint, blobfs_bdev_op_complete, NULL); 285 CU_ASSERT(g_fserrno != 0); 286 287 g_bdev_open_ext_fail = false; 288 289 /* spdk_bdev_create_bs_dev_from_desc() fails */ 290 g_bdev_create_bs_dev_from_desc_fail = true; 291 spdk_blobfs_bdev_mount(g_bdev_name, mountpoint, blobfs_bdev_op_complete, NULL); 292 CU_ASSERT(g_fserrno != 0); 293 294 g_bdev_create_bs_dev_from_desc_fail = false; 295 296 /* spdk_bs_bdev_claim() fails */ 297 g_bs_bdev_claim_fail = true; 298 spdk_blobfs_bdev_mount(g_bdev_name, mountpoint, blobfs_bdev_op_complete, NULL); 299 CU_ASSERT(g_fserrno != 0); 300 301 g_bs_bdev_claim_fail = false; 302 303 /* spdk_fs_load() fails */ 304 g_fs_load_fail = true; 305 spdk_blobfs_bdev_mount(g_bdev_name, mountpoint, blobfs_bdev_op_complete, NULL); 306 CU_ASSERT(g_fserrno != 0); 307 308 g_fs_load_fail = false; 309 310 /* blobfs_fuse_start() fails */ 311 g_blobfs_fuse_start_fail = true; 312 spdk_blobfs_bdev_mount(g_bdev_name, mountpoint, blobfs_bdev_op_complete, NULL); 313 CU_ASSERT(g_fserrno != 0); 314 315 g_blobfs_fuse_start_fail = false; 316 317 /* no fail */ 318 spdk_blobfs_bdev_mount(g_bdev_name, mountpoint, blobfs_bdev_op_complete, NULL); 319 CU_ASSERT(g_fserrno == 0); 320 CU_ASSERT(g_fs_ctx != NULL); 321 322 /* after mount operation success , we need make sure unmount operation success */ 323 blobfs_bdev_unmount(g_fs_ctx); 324 CU_ASSERT(g_fserrno == 0); 325 #endif 326 } 327 328 int main(int argc, char **argv) 329 { 330 CU_pSuite suite = NULL; 331 unsigned int num_failures; 332 333 CU_set_error_action(CUEA_ABORT); 334 CU_initialize_registry(); 335 336 suite = CU_add_suite("blobfs_bdev_ut", NULL, NULL); 337 338 CU_ADD_TEST(suite, spdk_blobfs_bdev_detect_test); 339 CU_ADD_TEST(suite, spdk_blobfs_bdev_create_test); 340 CU_ADD_TEST(suite, spdk_blobfs_bdev_mount_test); 341 342 CU_basic_set_mode(CU_BRM_VERBOSE); 343 CU_basic_run_tests(); 344 num_failures = CU_get_number_of_failures(); 345 CU_cleanup_registry(); 346 347 return num_failures; 348 } 349