static void nvmf_test_create_subsystem(void) { char nqn[256]; struct spdk_nvmf_subsystem *subsystem; strncpy(nqn, "nqn.2016-06.io.spdk:subsystem1", sizeof(nqn)); subsystem = spdk_nvmf_create_subsystem(nqn, SPDK_NVMF_SUBTYPE_NVME, NVMF_SUBSYSTEM_MODE_DIRECT, NULL, NULL, NULL); SPDK_CU_ASSERT_FATAL(subsystem != NULL); CU_ASSERT_STRING_EQUAL(subsystem->subnqn, nqn); spdk_nvmf_delete_subsystem(subsystem); /* Longest valid name */ strncpy(nqn, "nqn.2016-06.io.spdk:", sizeof(nqn)); memset(nqn + strlen(nqn), 'a', 222 - strlen(nqn)); nqn[222] = '\0'; CU_ASSERT(strlen(nqn) == 222); subsystem = spdk_nvmf_create_subsystem(nqn, SPDK_NVMF_SUBTYPE_NVME, NVMF_SUBSYSTEM_MODE_DIRECT, NULL, NULL, NULL); SPDK_CU_ASSERT_FATAL(subsystem != NULL); CU_ASSERT_STRING_EQUAL(subsystem->subnqn, nqn); spdk_nvmf_delete_subsystem(subsystem); /* Name that is one byte longer than allowed */ strncpy(nqn, "nqn.2016-06.io.spdk:", sizeof(nqn)); memset(nqn + strlen(nqn), 'a', 223 - strlen(nqn)); nqn[223] = '\0'; CU_ASSERT(strlen(nqn) == 223); subsystem = spdk_nvmf_create_subsystem(nqn, SPDK_NVMF_SUBTYPE_NVME, NVMF_SUBSYSTEM_MODE_DIRECT, NULL, NULL, NULL); CU_ASSERT(subsystem == NULL); }
static struct spdk_conf * spdk_config_init_scsi_params(char *key, char *value) { struct spdk_conf *spdk_config; FILE *f; int fd, rc; char filename[] = "/tmp/scsi_init_ut.XXXXXX"; /* Create temporary file to hold config */ fd = mkstemp(filename); SPDK_CU_ASSERT_FATAL(fd != -1); f = fdopen(fd, "wb+"); SPDK_CU_ASSERT_FATAL(f != NULL); fprintf(f, "[Scsi]\n"); fprintf(f, "%s %s\n", key, value); fclose(f); spdk_config = spdk_conf_allocate(); SPDK_CU_ASSERT_FATAL(spdk_config != NULL); rc = spdk_conf_read(spdk_config, filename); SPDK_CU_ASSERT_FATAL(rc == 0); spdk_conf_set_as_default(spdk_config); remove(filename); return spdk_config; }
static void nvmf_test_init(void) { int rc = 0; struct spdk_nvme_ctrlr *ctrlr; uint32_t i; request_mempool = NULL; /* test that NVMf library will trap if mempool not created */ rc = nvmf_initialize(); CU_ASSERT(rc < 0); request_mempool = malloc(sizeof(struct rte_mempool)); rc = nvmf_initialize(); CU_ASSERT(rc == 0); free(request_mempool); /* create faked controller */ ctrlr = malloc(sizeof(struct spdk_nvme_ctrlr)); SPDK_CU_ASSERT_FATAL(ctrlr != NULL); ctrlr->num_ns = NS_PER_CTRLR; for (i = 0; i < ctrlr->num_ns; i++) { ctrlr->ns[i].ctrlr = ctrlr; ctrlr->ns[i].id = i + 1; } ctrlr->attached = 1; spdk_nvmf_ctrlr_create("Nvme0", 0, 0, 1, 2, ctrlr); }
/* * Only memset up to (but not including) the children * TAILQ_ENTRY. children, and following members, are * only used as part of I/O splitting so we avoid * memsetting them until it is actually needed. * They will be initialized in nvme_request_add_child() * if the request is split. */ memset(req, 0, offsetof(struct nvme_request, children)); req->cb_fn = cb_fn; req->cb_arg = cb_arg; req->payload = *payload; req->payload_size = payload_size; req->pid = getpid(); return req; } struct nvme_request * nvme_allocate_request_contig(void *buffer, uint32_t payload_size, spdk_nvme_cmd_cb cb_fn, void *cb_arg) { struct nvme_payload payload; payload.type = NVME_PAYLOAD_TYPE_CONTIG; payload.u.contig = buffer; return nvme_allocate_request(&payload, payload_size, cb_fn, cb_arg); } struct nvme_request * nvme_allocate_request_null(spdk_nvme_cmd_cb cb_fn, void *cb_arg) { return nvme_allocate_request_contig(NULL, 0, cb_fn, cb_arg); } void nvme_free_request(struct nvme_request *req) { spdk_mempool_put(_g_nvme_driver.request_mempool, req); } void nvme_request_remove_child(struct nvme_request *parent, struct nvme_request *child) { parent->num_children--; TAILQ_REMOVE(&parent->children, child, child_tailq); } int nvme_transport_qpair_enable(struct spdk_nvme_qpair *qpair) { return 0; } int nvme_transport_qpair_disable(struct spdk_nvme_qpair *qpair) { return 0; } int nvme_transport_qpair_fail(struct spdk_nvme_qpair *qpair) { return 0; } int nvme_transport_qpair_submit_request(struct spdk_nvme_qpair *qpair, struct nvme_request *req) { // TODO return 0; } int32_t nvme_transport_qpair_process_completions(struct spdk_nvme_qpair *qpair, uint32_t max_completions) { // TODO return 0; } static void prepare_submit_request_test(struct spdk_nvme_qpair *qpair, struct spdk_nvme_ctrlr *ctrlr) { memset(ctrlr, 0, sizeof(*ctrlr)); ctrlr->free_io_qids = NULL; TAILQ_INIT(&ctrlr->active_io_qpairs); TAILQ_INIT(&ctrlr->active_procs); nvme_qpair_construct(qpair, 1, 128, ctrlr, 0); ut_fail_vtophys = false; } static void cleanup_submit_request_test(struct spdk_nvme_qpair *qpair) { } #if 0 /* TODO: move to PCIe-specific unit test */ static void ut_insert_cq_entry(struct spdk_nvme_qpair *qpair, uint32_t slot) { struct nvme_request *req; struct nvme_tracker *tr; struct spdk_nvme_cpl *cpl; req = spdk_mempool_get(_g_nvme_driver.request_mempool); SPDK_CU_ASSERT_FATAL(req != NULL); memset(req, 0, sizeof(*req)); tr = TAILQ_FIRST(&qpair->free_tr); TAILQ_REMOVE(&qpair->free_tr, tr, tq_list); /* remove tr from free_tr */ TAILQ_INSERT_HEAD(&qpair->outstanding_tr, tr, tq_list); req->cmd.cid = tr->cid; tr->req = req; qpair->tr[tr->cid].active = true; cpl = &qpair->cpl[slot]; cpl->status.p = qpair->phase; cpl->cid = tr->cid; } #endif static void expected_success_callback(void *arg, const struct spdk_nvme_cpl *cpl) { CU_ASSERT(!spdk_nvme_cpl_is_error(cpl)); } static void expected_failure_callback(void *arg, const struct spdk_nvme_cpl *cpl) { CU_ASSERT(spdk_nvme_cpl_is_error(cpl)); } static void test3(void) { struct spdk_nvme_qpair qpair = {}; struct nvme_request *req; struct spdk_nvme_ctrlr ctrlr = {}; prepare_submit_request_test(&qpair, &ctrlr); req = nvme_allocate_request_null(expected_success_callback, NULL); SPDK_CU_ASSERT_FATAL(req != NULL); CU_ASSERT(nvme_qpair_submit_request(&qpair, req) == 0); nvme_free_request(req); cleanup_submit_request_test(&qpair); } #if 0 /* TODO: move to PCIe-specific unit test */ static void test4(void) { struct spdk_nvme_qpair qpair = {}; struct nvme_request *req; struct spdk_nvme_ctrlr ctrlr = {}; char payload[4096]; prepare_submit_request_test(&qpair, &ctrlr); req = nvme_allocate_request_contig(payload, sizeof(payload), expected_failure_callback, NULL); SPDK_CU_ASSERT_FATAL(req != NULL); /* Force vtophys to return a failure. This should * result in the nvme_qpair manually failing * the request with error status to signify * a bad payload buffer. */ ut_fail_vtophys = true; CU_ASSERT(qpair.sq_tail == 0); CU_ASSERT(nvme_qpair_submit_request(&qpair, req) != 0); CU_ASSERT(qpair.sq_tail == 0); cleanup_submit_request_test(&qpair); }
static void test4(void) { struct nvme_qpair qpair = {}; struct nvme_request *req; struct spdk_nvme_ctrlr ctrlr = {}; struct spdk_nvme_registers regs = {}; char payload[4096]; prepare_submit_request_test(&qpair, &ctrlr, ®s); req = nvme_allocate_request_contig(payload, sizeof(payload), expected_failure_callback, NULL); SPDK_CU_ASSERT_FATAL(req != NULL); /* Force vtophys to return a failure. This should * result in the nvme_qpair manually failing * the request with error status to signify * a bad payload buffer. */ fail_vtophys = true; outbuf[0] = '\0'; CU_ASSERT(qpair.sq_tail == 0); nvme_qpair_submit_request(&qpair, req); CU_ASSERT(qpair.sq_tail == 0); /* Assert that command/completion data was printed to log. */ CU_ASSERT(strlen(outbuf) > 0); cleanup_submit_request_test(&qpair); }
static void test_1bit(void) { struct spdk_bit_array *ba; ba = spdk_bit_array_create(1); SPDK_CU_ASSERT_FATAL(ba != NULL); CU_ASSERT(spdk_bit_array_capacity(ba) == 1); CU_ASSERT(spdk_bit_array_get(ba, 0) == false); CU_ASSERT(spdk_bit_array_find_first_set(ba, 0) == UINT32_MAX); /* Set bit 0 */ CU_ASSERT(spdk_bit_array_set(ba, 0) == 0); CU_ASSERT(spdk_bit_array_get(ba, 0) == true); CU_ASSERT(spdk_bit_array_find_first_set(ba, 0) == 0); /* Clear bit 0 */ spdk_bit_array_clear(ba, 0); CU_ASSERT(spdk_bit_array_get(ba, 0) == false); CU_ASSERT(spdk_bit_array_find_first_set(ba, 0) == UINT32_MAX); spdk_bit_array_free(&ba); CU_ASSERT(ba == NULL); }
static void nvmf_test_create_session(void) { int fake_session_count = 5; int i; struct nvmf_session *session; struct spdk_nvmf_subsystem *subsystem; /* create session in non-exist subsystem */ CU_ASSERT_PTR_NULL(nvmf_create_session("subsystem2")); /* create session and check init values */ subsystem = nvmf_find_subsystem("subsystem1"); session = nvmf_create_session("subsystem1"); SPDK_CU_ASSERT_FATAL(session != NULL); CU_ASSERT_EQUAL(session->cntlid, SS_SC_CNTLID); CU_ASSERT_TRUE(session->is_valid); CU_ASSERT_EQUAL(session->num_connections, 0); CU_ASSERT_EQUAL(session->active_queues, 0); CU_ASSERT_EQUAL(subsystem->num_sessions, 1); /* add multi-sessions to one subsystem * if multi-sessions is not suported in the future * we need to change the check condition. */ for (i = 0; i != fake_session_count; i++) { nvmf_create_session("subsystem1"); } CU_ASSERT_EQUAL(session->subsys->num_sessions, fake_session_count + 1); }
static void test_ctrlr_failed(void) { struct nvme_qpair qpair = {}; struct nvme_request *req; struct spdk_nvme_ctrlr ctrlr = {}; struct spdk_nvme_registers regs = {}; char payload[4096]; prepare_submit_request_test(&qpair, &ctrlr, ®s); req = nvme_allocate_request_contig(payload, sizeof(payload), expected_failure_callback, NULL); SPDK_CU_ASSERT_FATAL(req != NULL); /* Disable the queue and set the controller to failed. * Set the controller to resetting so that the qpair won't get re-enabled. */ qpair.is_enabled = false; ctrlr.is_failed = true; ctrlr.is_resetting = true; outbuf[0] = '\0'; CU_ASSERT(qpair.sq_tail == 0); nvme_qpair_submit_request(&qpair, req); CU_ASSERT(qpair.sq_tail == 0); /* Assert that command/completion data was printed to log. */ CU_ASSERT(strlen(outbuf) > 0); cleanup_submit_request_test(&qpair); }
static void test_find(void) { struct spdk_bit_array *ba; uint32_t i; ba = spdk_bit_array_create(256); SPDK_CU_ASSERT_FATAL(ba != NULL); CU_ASSERT(spdk_bit_array_capacity(ba) == 256); /* Set all bits */ for (i = 0; i < 256; i++) { CU_ASSERT(spdk_bit_array_set(ba, i) == 0); } /* Verify that find_first_set and find_first_clear work for each starting position */ for (i = 0; i < 256; i++) { CU_ASSERT(spdk_bit_array_find_first_set(ba, i) == i); CU_ASSERT(spdk_bit_array_find_first_clear(ba, i) == 256); } CU_ASSERT(spdk_bit_array_find_first_set(ba, 256) == UINT32_MAX); CU_ASSERT(spdk_bit_array_find_first_clear(ba, 256) == 256); /* Clear bits 0 through 31 */ for (i = 0; i < 32; i++) { spdk_bit_array_clear(ba, i); } for (i = 0; i < 32; i++) { CU_ASSERT(spdk_bit_array_find_first_set(ba, i) == 32); CU_ASSERT(spdk_bit_array_find_first_clear(ba, i) == i); } for (i = 32; i < 256; i++) { CU_ASSERT(spdk_bit_array_find_first_set(ba, i) == i); CU_ASSERT(spdk_bit_array_find_first_clear(ba, i) == 256); } /* Clear bit 255 */ spdk_bit_array_clear(ba, 255); for (i = 0; i < 32; i++) { CU_ASSERT(spdk_bit_array_find_first_set(ba, i) == 32); CU_ASSERT(spdk_bit_array_find_first_clear(ba, i) == i); } for (i = 32; i < 255; i++) { CU_ASSERT(spdk_bit_array_find_first_set(ba, i) == i); CU_ASSERT(spdk_bit_array_find_first_clear(ba, i) == 255); } CU_ASSERT(spdk_bit_array_find_first_clear(ba, 256) == 256); spdk_bit_array_free(&ba); }
static void nvmf_test_delete_subsystem(void) { struct spdk_nvmf_subsystem *subsystem; struct nvmf_session *sess; sess = nvmf_create_session("subsystem1"); SPDK_CU_ASSERT_FATAL(sess != NULL); subsystem = nvmf_find_subsystem("subsystem1"); CU_ASSERT_EQUAL(nvmf_delete_subsystem(subsystem), 0); }
static void nvmf_test_process_io_cmd(void) { struct spdk_nvme_cmd nvmf_cmd = {}; struct nvmf_session *sess; struct nvmf_request nvmf_req = {}; struct nvme_read_cdw12 *cdw12; struct spdk_nvmf_subsystem *tmp; int buf_len = 64; uint8_t *buf; nvmf_cmd.opc = SPDK_NVME_OPC_READ; nvmf_cmd.nsid = 2; nvmf_cmd.cid = 3; nvmf_req.rsp = malloc(sizeof(union nvmf_c2h_msg)); nvmf_req.cb_fn = io_nvmf_cmd_complete; nvmf_req.cid = nvmf_cmd.cid; cdw12 = (struct nvme_read_cdw12 *)&nvmf_cmd.cdw12; cdw12->nlb = 16; //read 16 lb, check in nvme read buf = malloc(buf_len); SPDK_CU_ASSERT_FATAL(buf != NULL); sess = nvmf_find_session_by_id("subsystem1", SS_SC_CNTLID); sess->vcprop.csts.bits.rdy = 1; CU_ASSERT_EQUAL(nvmf_process_io_cmd(sess, &nvmf_cmd, buf, buf_len, &nvmf_req), 0); CU_ASSERT_STRING_EQUAL(buf, "hello"); nvmf_cmd.cid = 4; nvmf_cmd.opc = SPDK_NVME_OPC_WRITE; CU_ASSERT_EQUAL(nvmf_process_io_cmd(sess, &nvmf_cmd, buf, buf_len, &nvmf_req), 0); nvmf_cmd.opc = 0xff; nvmf_cmd.cid = 5; CU_ASSERT_EQUAL(nvmf_process_io_cmd(sess, &nvmf_cmd, buf, buf_len, &nvmf_req), 0); sess->vcprop.csts.bits.rdy = 0; nvmf_cmd.cid = 6; CU_ASSERT_EQUAL(nvmf_process_io_cmd(sess, &nvmf_cmd, buf, buf_len, &nvmf_req), -1); CU_ASSERT_EQUAL(nvmf_req.rsp->nvme_cpl.status.sc, SPDK_NVME_SC_NAMESPACE_NOT_READY); sess->vcprop.csts.bits.rdy = 1; /* nsid = 0 */ nvmf_cmd.nsid = 0; nvmf_cmd.cid = 7; CU_ASSERT_EQUAL(nvmf_process_io_cmd(sess, &nvmf_cmd, buf, buf_len, &nvmf_req), -1); CU_ASSERT_NOT_EQUAL(nvmf_req.rsp->nvme_cpl.status.sc, SPDK_NVME_SC_SUCCESS); /* set sess->subsys to NULL */ tmp = sess->subsys; sess->subsys = NULL; nvmf_cmd.nsid = 1; nvmf_cmd.cid = 8; CU_ASSERT_EQUAL(nvmf_process_io_cmd(sess, &nvmf_cmd, buf, buf_len, &nvmf_req), -1); CU_ASSERT_NOT_EQUAL(nvmf_req.rsp->nvme_cpl.status.sc, SPDK_NVME_SC_SUCCESS); sess->subsys = tmp; free(buf); free(nvmf_req.rsp); }
static void test3(void) { struct spdk_nvme_qpair qpair = {}; struct nvme_request *req; struct nvme_tracker *tr; struct spdk_nvme_ctrlr ctrlr = {}; struct spdk_nvme_registers regs = {}; uint16_t cid; prepare_submit_request_test(&qpair, &ctrlr, ®s); req = nvme_allocate_request_null(expected_success_callback, NULL); SPDK_CU_ASSERT_FATAL(req != NULL); CU_ASSERT(qpair.sq_tail == 0); nvme_qpair_submit_request(&qpair, req); CU_ASSERT(qpair.sq_tail == 1); /* * Since sq_tail was 0 when the command was submitted, it is in cmd[0]. * Extract its command ID to retrieve its tracker. */ cid = qpair.cmd[0].cid; tr = qpair.act_tr[cid]; SPDK_CU_ASSERT_FATAL(tr != NULL); /* * Complete the tracker so that it is returned to the free list. * This also frees the request. */ nvme_qpair_manual_complete_tracker(&qpair, tr, SPDK_NVME_SCT_GENERIC, SPDK_NVME_SC_SUCCESS, 0, false); cleanup_submit_request_test(&qpair); }
static void nvmf_test_create_subsystem(void) { char correct_name[] = "subsystem1"; char wrong_name[512]; struct spdk_nvmf_subsystem *subsystem; struct spdk_nvmf_ctrlr *nvmf_ctrlr; subsystem = nvmf_create_subsystem(1, correct_name); SPDK_CU_ASSERT_FATAL(subsystem != NULL); CU_ASSERT_EQUAL(subsystem->num, 1); CU_ASSERT_STRING_EQUAL(subsystem->subnqn, correct_name); nvmf_ctrlr = spdk_nvmf_ctrlr_claim("Nvme0"); SPDK_CU_ASSERT_FATAL(nvmf_ctrlr != NULL); nvmf_subsystem_add_ns(subsystem, nvmf_ctrlr->ctrlr); /* test long name */ memset(wrong_name, 'a', 512); subsystem = nvmf_create_subsystem(2, wrong_name); SPDK_CU_ASSERT_FATAL(subsystem != NULL); CU_ASSERT_EQUAL(subsystem->num, 2); CU_ASSERT_STRING_NOT_EQUAL(subsystem->subnqn, wrong_name); CU_ASSERT_EQUAL(strlen(subsystem->subnqn) + 1, MAX_NQN_SIZE); }
static void test3(void) { struct spdk_nvme_qpair qpair = {}; struct nvme_request *req; struct spdk_nvme_ctrlr ctrlr = {}; prepare_submit_request_test(&qpair, &ctrlr); req = nvme_allocate_request_null(expected_success_callback, NULL); SPDK_CU_ASSERT_FATAL(req != NULL); CU_ASSERT(nvme_qpair_submit_request(&qpair, req) == 0); nvme_free_request(req); cleanup_submit_request_test(&qpair); }
static void nvmf_test_delete_session(void) { int i; int fake_session_count = 5; struct nvmf_session *session; struct spdk_nvmf_subsystem *subsystem; subsystem = nvmf_find_subsystem("subsystem1"); for (i = 0; i != fake_session_count + 1; i++) { session = nvmf_find_session_by_id("subsystem1", (subsystem->num << NVMF_CNTLID_SUBS_SHIFT) + (i + 1)); SPDK_CU_ASSERT_FATAL(session != NULL); nvmf_delete_session(session); } CU_ASSERT_EQUAL(subsystem->num_sessions, 0); CU_ASSERT_PTR_NULL(subsystem->sessions.tqh_first); }
static void scsi_init_sp_null(void) { struct spdk_conf *config; int rc; config = spdk_conf_allocate(); SPDK_CU_ASSERT_FATAL(config != NULL); spdk_conf_set_as_default(config); rc = spdk_scsi_subsystem_init(); /* sp = null; set default scsi params */ CU_ASSERT_EQUAL(rc, 0); spdk_conf_set_as_default(NULL); spdk_conf_free(config); }
static void test_64bit(void) { struct spdk_bit_array *ba; ba = spdk_bit_array_create(64); SPDK_CU_ASSERT_FATAL(ba != NULL); CU_ASSERT(spdk_bit_array_capacity(ba) == 64); CU_ASSERT(spdk_bit_array_get(ba, 0) == false); CU_ASSERT(spdk_bit_array_get(ba, 63) == false); CU_ASSERT(spdk_bit_array_get(ba, 64) == false); CU_ASSERT(spdk_bit_array_get(ba, 1000) == false); CU_ASSERT(spdk_bit_array_find_first_set(ba, 0) == UINT32_MAX); /* Set bit 1 */ CU_ASSERT(spdk_bit_array_set(ba, 1) == 0); CU_ASSERT(spdk_bit_array_get(ba, 0) == false); CU_ASSERT(spdk_bit_array_get(ba, 1) == true); CU_ASSERT(spdk_bit_array_find_first_set(ba, 0) == 1); /* Set bit 63 (1 still set) */ CU_ASSERT(spdk_bit_array_set(ba, 63) == 0); CU_ASSERT(spdk_bit_array_get(ba, 0) == false); CU_ASSERT(spdk_bit_array_get(ba, 1) == true); CU_ASSERT(spdk_bit_array_get(ba, 63) == true); CU_ASSERT(spdk_bit_array_find_first_set(ba, 0) == 1); /* Clear bit 1 (63 still set) */ spdk_bit_array_clear(ba, 1); CU_ASSERT(spdk_bit_array_get(ba, 1) == false); CU_ASSERT(spdk_bit_array_find_first_set(ba, 0) == 63); /* Clear bit 63 (no bits set) */ spdk_bit_array_clear(ba, 63); CU_ASSERT(spdk_bit_array_get(ba, 63) == false); CU_ASSERT(spdk_bit_array_find_first_set(ba, 0) == UINT32_MAX); spdk_bit_array_free(&ba); }
/* * Only memset up to (but not including) the children * TAILQ_ENTRY. children, and following members, are * only used as part of I/O splitting so we avoid * memsetting them until it is actually needed. * They will be initialized in nvme_request_add_child() * if the request is split. */ memset(req, 0, offsetof(struct nvme_request, children)); req->cb_fn = cb_fn; req->cb_arg = cb_arg; req->payload = *payload; req->payload_size = payload_size; req->pid = getpid(); return req; } struct nvme_request * nvme_allocate_request_contig(void *buffer, uint32_t payload_size, spdk_nvme_cmd_cb cb_fn, void *cb_arg) { struct nvme_payload payload; payload.type = NVME_PAYLOAD_TYPE_CONTIG; payload.u.contig = buffer; return nvme_allocate_request(&payload, payload_size, cb_fn, cb_arg); } struct nvme_request * nvme_allocate_request_null(spdk_nvme_cmd_cb cb_fn, void *cb_arg) { return nvme_allocate_request_contig(NULL, 0, cb_fn, cb_arg); } void nvme_free_request(struct nvme_request *req) { spdk_mempool_put(_g_nvme_driver.request_mempool, req); } void nvme_request_remove_child(struct nvme_request *parent, struct nvme_request *child) { parent->num_children--; TAILQ_REMOVE(&parent->children, child, child_tailq); } int nvme_transport_qpair_enable(struct spdk_nvme_qpair *qpair) { return 0; } int nvme_transport_qpair_disable(struct spdk_nvme_qpair *qpair) { return 0; } int nvme_transport_qpair_fail(struct spdk_nvme_qpair *qpair) { return 0; } int nvme_transport_qpair_submit_request(struct spdk_nvme_qpair *qpair, struct nvme_request *req) { // TODO return 0; } int32_t nvme_transport_qpair_process_completions(struct spdk_nvme_qpair *qpair, uint32_t max_completions) { // TODO return 0; } static void prepare_submit_request_test(struct spdk_nvme_qpair *qpair, struct spdk_nvme_ctrlr *ctrlr) { memset(ctrlr, 0, sizeof(*ctrlr)); ctrlr->free_io_qids = NULL; TAILQ_INIT(&ctrlr->active_io_qpairs); TAILQ_INIT(&ctrlr->active_procs); nvme_qpair_construct(qpair, 1, 128, ctrlr, 0); ut_fail_vtophys = false; } static void cleanup_submit_request_test(struct spdk_nvme_qpair *qpair) { } #if 0 /* TODO: move to PCIe-specific unit test */ static void ut_insert_cq_entry(struct spdk_nvme_qpair *qpair, uint32_t slot) { struct nvme_request *req; struct nvme_tracker *tr; struct spdk_nvme_cpl *cpl; req = spdk_mempool_get(_g_nvme_driver.request_mempool); SPDK_CU_ASSERT_FATAL(req != NULL); memset(req, 0, sizeof(*req)); tr = TAILQ_FIRST(&qpair->free_tr); TAILQ_REMOVE(&qpair->free_tr, tr, tq_list); /* remove tr from free_tr */ TAILQ_INSERT_HEAD(&qpair->outstanding_tr, tr, tq_list); req->cmd.cid = tr->cid; tr->req = req; qpair->tr[tr->cid].active = true; cpl = &qpair->cpl[slot]; cpl->status.p = qpair->phase; cpl->cid = tr->cid; }
static void ut_insert_cq_entry(struct nvme_qpair *qpair, uint32_t slot) { struct nvme_request *req; struct nvme_tracker *tr; struct spdk_nvme_cpl *cpl; nvme_alloc_request(&req); SPDK_CU_ASSERT_FATAL(req != NULL); memset(req, 0, sizeof(*req)); req->cmd.cid = slot; tr = LIST_FIRST(&qpair->free_tr); LIST_REMOVE(tr, list); /* remove tr from free_tr */ LIST_INSERT_HEAD(&qpair->outstanding_tr, tr, list); tr->cid = slot; tr->req = req; qpair->act_tr[tr->cid] = tr; cpl = &qpair->cpl[slot]; cpl->status.p = qpair->phase; cpl->cid = slot; }
static void test_ctrlr_failed(void) { struct spdk_nvme_qpair qpair = {}; struct nvme_request *req; struct spdk_nvme_ctrlr ctrlr = {}; char payload[4096]; prepare_submit_request_test(&qpair, &ctrlr); req = nvme_allocate_request_contig(payload, sizeof(payload), expected_failure_callback, NULL); SPDK_CU_ASSERT_FATAL(req != NULL); /* Set the controller to failed. * Set the controller to resetting so that the qpair won't get re-enabled. */ ctrlr.is_failed = true; ctrlr.is_resetting = true; CU_ASSERT(nvme_qpair_submit_request(&qpair, req) != 0); cleanup_submit_request_test(&qpair); }
static void parse_valid_test(void) { struct iscsi_param *params; int rc; params = NULL; char *data; int len; char *partial_parameter = NULL; /* simple test with a single key=value */ PARSE("Abc=def\0", false, NULL); CU_ASSERT(rc == 0); EXPECT_VAL("Abc", "def"); /* multiple key=value pairs */ PARSE("Aaa=bbbbbb\0Xyz=test\0", false, NULL); CU_ASSERT(rc == 0); EXPECT_VAL("Aaa", "bbbbbb"); EXPECT_VAL("Xyz", "test"); /* value with embedded '=' */ PARSE("A=b=c\0", false, NULL); CU_ASSERT(rc == 0); EXPECT_VAL("A", "b=c"); /* CHAP_C=AAAA.... with value length 8192 */ len = strlen("CHAP_C=") + ISCSI_TEXT_MAX_VAL_LEN + 1/* null terminators */; data = malloc(len); SPDK_CU_ASSERT_FATAL(data != NULL); memset(data, 'A', len); strcpy(data, "CHAP_C"); data[6] = '='; data[len - 1] = '\0'; rc = spdk_iscsi_parse_params(¶ms, data, len, false, NULL); CU_ASSERT(rc == 0); free(data); /* partial parameter: value is partial*/ PARSE("C=AAA\0D=B", true, &partial_parameter); SPDK_CU_ASSERT_FATAL(partial_parameter != NULL); CU_ASSERT_STRING_EQUAL(partial_parameter, "D=B"); CU_ASSERT(rc == 0); EXPECT_VAL("C", "AAA"); EXPECT_NULL("D"); PARSE("XXXX\0E=UUUU\0", false, &partial_parameter); CU_ASSERT(rc == 0); EXPECT_VAL("D", "BXXXX"); EXPECT_VAL("E", "UUUU"); CU_ASSERT_PTR_NULL(partial_parameter); /* partial parameter: key is partial*/ PARSE("IAMAFAK", true, &partial_parameter); CU_ASSERT_STRING_EQUAL(partial_parameter, "IAMAFAK"); CU_ASSERT(rc == 0); EXPECT_NULL("IAMAFAK"); PARSE("EDKEY=TTTT\0F=IIII", false, &partial_parameter); CU_ASSERT(rc == 0); EXPECT_VAL("IAMAFAKEDKEY", "TTTT"); EXPECT_VAL("F", "IIII"); CU_ASSERT_PTR_NULL(partial_parameter); /* Second partial parameter is the only parameter */ PARSE("OOOO", true, &partial_parameter); CU_ASSERT_STRING_EQUAL(partial_parameter, "OOOO"); CU_ASSERT(rc == 0); EXPECT_NULL("OOOO"); PARSE("LL=MMMM", false, &partial_parameter); CU_ASSERT(rc == 0); EXPECT_VAL("OOOOLL", "MMMM"); CU_ASSERT_PTR_NULL(partial_parameter); spdk_iscsi_param_free(params); }
static void test_hw_sgl_req(void) { struct spdk_nvme_qpair qpair = {}; struct nvme_request *req; struct spdk_nvme_ctrlr ctrlr = {}; struct nvme_payload payload = {}; struct nvme_tracker *sgl_tr = NULL; uint64_t i; struct io_request io_req = {}; payload.type = NVME_PAYLOAD_TYPE_SGL; payload.u.sgl.reset_sgl_fn = nvme_request_reset_sgl; payload.u.sgl.next_sge_fn = nvme_request_next_sge; payload.u.sgl.cb_arg = &io_req; prepare_submit_request_test(&qpair, &ctrlr); req = nvme_allocate_request(&payload, PAGE_SIZE, NULL, &io_req); SPDK_CU_ASSERT_FATAL(req != NULL); req->cmd.opc = SPDK_NVME_OPC_WRITE; req->cmd.cdw10 = 10000; req->cmd.cdw12 = 7 | 0; req->payload_offset = 0; ctrlr.flags |= SPDK_NVME_CTRLR_SGL_SUPPORTED; nvme_qpair_submit_request(&qpair, req); sgl_tr = TAILQ_FIRST(&qpair.outstanding_tr); CU_ASSERT(sgl_tr != NULL); CU_ASSERT(sgl_tr->u.sgl[0].generic.type == SPDK_NVME_SGL_TYPE_DATA_BLOCK); CU_ASSERT(sgl_tr->u.sgl[0].generic.subtype == 0); CU_ASSERT(sgl_tr->u.sgl[0].unkeyed.length == 4096); CU_ASSERT(sgl_tr->u.sgl[0].address == 0); CU_ASSERT(req->cmd.dptr.sgl1.generic.type == SPDK_NVME_SGL_TYPE_DATA_BLOCK); TAILQ_REMOVE(&qpair.outstanding_tr, sgl_tr, tq_list); cleanup_submit_request_test(&qpair); nvme_free_request(req); prepare_submit_request_test(&qpair, &ctrlr); req = nvme_allocate_request(&payload, NVME_MAX_SGL_DESCRIPTORS * PAGE_SIZE, NULL, &io_req); SPDK_CU_ASSERT_FATAL(req != NULL); req->cmd.opc = SPDK_NVME_OPC_WRITE; req->cmd.cdw10 = 10000; req->cmd.cdw12 = 2023 | 0; req->payload_offset = 0; ctrlr.flags |= SPDK_NVME_CTRLR_SGL_SUPPORTED; nvme_qpair_submit_request(&qpair, req); sgl_tr = TAILQ_FIRST(&qpair.outstanding_tr); CU_ASSERT(sgl_tr != NULL); for (i = 0; i < NVME_MAX_SGL_DESCRIPTORS; i++) { CU_ASSERT(sgl_tr->u.sgl[i].generic.type == SPDK_NVME_SGL_TYPE_DATA_BLOCK); CU_ASSERT(sgl_tr->u.sgl[i].generic.subtype == 0); CU_ASSERT(sgl_tr->u.sgl[i].unkeyed.length == 4096); CU_ASSERT(sgl_tr->u.sgl[i].address == i * 4096); } CU_ASSERT(req->cmd.dptr.sgl1.generic.type == SPDK_NVME_SGL_TYPE_LAST_SEGMENT); TAILQ_REMOVE(&qpair.outstanding_tr, sgl_tr, tq_list); cleanup_submit_request_test(&qpair); nvme_free_request(req); }
static void test_sgl_req(void) { struct spdk_nvme_qpair qpair = {}; struct nvme_request *req; struct spdk_nvme_ctrlr ctrlr = {}; struct nvme_payload payload = {}; struct nvme_tracker *sgl_tr = NULL; uint64_t i; struct io_request io_req = {}; payload.type = NVME_PAYLOAD_TYPE_SGL; payload.u.sgl.reset_sgl_fn = nvme_request_reset_sgl; payload.u.sgl.next_sge_fn = nvme_request_next_sge; payload.u.sgl.cb_arg = &io_req; prepare_submit_request_test(&qpair, &ctrlr); req = nvme_allocate_request(&payload, PAGE_SIZE, NULL, &io_req); SPDK_CU_ASSERT_FATAL(req != NULL); req->cmd.opc = SPDK_NVME_OPC_WRITE; req->cmd.cdw10 = 10000; req->cmd.cdw12 = 7 | 0; req->payload_offset = 1; CU_ASSERT(nvme_qpair_submit_request(&qpair, req) != 0); CU_ASSERT(qpair.sq_tail == 0); cleanup_submit_request_test(&qpair); prepare_submit_request_test(&qpair, &ctrlr); req = nvme_allocate_request(&payload, PAGE_SIZE, NULL, &io_req); SPDK_CU_ASSERT_FATAL(req != NULL); req->cmd.opc = SPDK_NVME_OPC_WRITE; req->cmd.cdw10 = 10000; req->cmd.cdw12 = 7 | 0; spdk_nvme_retry_count = 1; fail_next_sge = true; CU_ASSERT(nvme_qpair_submit_request(&qpair, req) != 0); CU_ASSERT(qpair.sq_tail == 0); cleanup_submit_request_test(&qpair); fail_next_sge = false; prepare_submit_request_test(&qpair, &ctrlr); req = nvme_allocate_request(&payload, 2 * PAGE_SIZE, NULL, &io_req); SPDK_CU_ASSERT_FATAL(req != NULL); req->cmd.opc = SPDK_NVME_OPC_WRITE; req->cmd.cdw10 = 10000; req->cmd.cdw12 = 15 | 0; req->payload_offset = 2; CU_ASSERT(nvme_qpair_submit_request(&qpair, req) != 0); CU_ASSERT(qpair.sq_tail == 0); cleanup_submit_request_test(&qpair); prepare_submit_request_test(&qpair, &ctrlr); req = nvme_allocate_request(&payload, (NVME_MAX_PRP_LIST_ENTRIES + 1) * PAGE_SIZE, NULL, &io_req); SPDK_CU_ASSERT_FATAL(req != NULL); req->cmd.opc = SPDK_NVME_OPC_WRITE; req->cmd.cdw10 = 10000; req->cmd.cdw12 = 4095 | 0; CU_ASSERT(nvme_qpair_submit_request(&qpair, req) == 0); CU_ASSERT(req->cmd.dptr.prp.prp1 == 0); CU_ASSERT(qpair.sq_tail == 1); sgl_tr = TAILQ_FIRST(&qpair.outstanding_tr); if (sgl_tr != NULL) { for (i = 0; i < NVME_MAX_PRP_LIST_ENTRIES; i++) { CU_ASSERT(sgl_tr->u.prp[i] == (PAGE_SIZE * (i + 1))); } TAILQ_REMOVE(&qpair.outstanding_tr, sgl_tr, tq_list); } cleanup_submit_request_test(&qpair); nvme_free_request(req); }
static void test_resize(void) { struct spdk_bit_array *ba; /* Start with a 0 bit array */ ba = spdk_bit_array_create(0); SPDK_CU_ASSERT_FATAL(ba != NULL); CU_ASSERT(spdk_bit_array_capacity(ba) == 0); CU_ASSERT(spdk_bit_array_get(ba, 0) == false); CU_ASSERT(spdk_bit_array_set(ba, 0) == -EINVAL); spdk_bit_array_clear(ba, 0); /* Increase size to 1 bit */ SPDK_CU_ASSERT_FATAL(spdk_bit_array_resize(&ba, 1) == 0); SPDK_CU_ASSERT_FATAL(ba != NULL); CU_ASSERT(spdk_bit_array_capacity(ba) == 1); CU_ASSERT(spdk_bit_array_get(ba, 0) == false); CU_ASSERT(spdk_bit_array_set(ba, 0) == 0); CU_ASSERT(spdk_bit_array_get(ba, 0) == true); /* Increase size to 2 bits */ SPDK_CU_ASSERT_FATAL(spdk_bit_array_resize(&ba, 2) == 0); SPDK_CU_ASSERT_FATAL(ba != NULL); CU_ASSERT(spdk_bit_array_capacity(ba) == 2); CU_ASSERT(spdk_bit_array_get(ba, 1) == false); CU_ASSERT(spdk_bit_array_set(ba, 1) == 0); CU_ASSERT(spdk_bit_array_get(ba, 1) == true); /* Shrink size back to 1 bit */ SPDK_CU_ASSERT_FATAL(spdk_bit_array_resize(&ba, 1) == 0); SPDK_CU_ASSERT_FATAL(ba != NULL); CU_ASSERT(spdk_bit_array_capacity(ba) == 1); CU_ASSERT(spdk_bit_array_get(ba, 0) == true); CU_ASSERT(spdk_bit_array_get(ba, 1) == false); /* Increase size to 65 bits */ SPDK_CU_ASSERT_FATAL(spdk_bit_array_resize(&ba, 65) == 0); SPDK_CU_ASSERT_FATAL(ba != NULL); CU_ASSERT(spdk_bit_array_capacity(ba) == 65); CU_ASSERT(spdk_bit_array_get(ba, 0) == true); CU_ASSERT(spdk_bit_array_get(ba, 1) == false); CU_ASSERT(spdk_bit_array_set(ba, 64) == 0); CU_ASSERT(spdk_bit_array_get(ba, 64) == true); /* Shrink size back to 0 bits */ SPDK_CU_ASSERT_FATAL(spdk_bit_array_resize(&ba, 0) == 0); SPDK_CU_ASSERT_FATAL(ba != NULL); CU_ASSERT(spdk_bit_array_capacity(ba) == 0); CU_ASSERT(spdk_bit_array_get(ba, 0) == false); CU_ASSERT(spdk_bit_array_get(ba, 1) == false); spdk_bit_array_free(&ba); }
static void test_sgl_req(void) { struct spdk_nvme_qpair qpair = {}; struct nvme_request *req; struct spdk_nvme_ctrlr ctrlr = {}; struct spdk_nvme_registers regs = {}; struct nvme_payload payload = {}; struct nvme_tracker *sgl_tr = NULL; uint64_t i; struct io_request io_req = {}; payload.type = NVME_PAYLOAD_TYPE_SGL; payload.u.sgl.reset_sgl_fn = nvme_request_reset_sgl; payload.u.sgl.next_sge_fn = nvme_request_next_sge; payload.u.sgl.cb_arg = &io_req; prepare_submit_request_test(&qpair, &ctrlr, ®s); req = nvme_allocate_request(&payload, PAGE_SIZE, NULL, &io_req); SPDK_CU_ASSERT_FATAL(req != NULL); req->cmd.opc = SPDK_NVME_OPC_WRITE; req->cmd.cdw10 = 10000; req->cmd.cdw12 = 255 | 0; req->payload_offset = 1; nvme_qpair_submit_request(&qpair, req); CU_ASSERT(req->cmd.psdt == SPDK_NVME_PSDT_PRP); CU_ASSERT(req->cmd.dptr.prp.prp1 == 7); CU_ASSERT(req->cmd.dptr.prp.prp2 == 4096); sgl_tr = LIST_FIRST(&qpair.outstanding_tr); LIST_REMOVE(sgl_tr, list); free(sgl_tr); cleanup_submit_request_test(&qpair); nvme_free_request(req); prepare_submit_request_test(&qpair, &ctrlr, ®s); req = nvme_allocate_request(&payload, PAGE_SIZE, NULL, &io_req); SPDK_CU_ASSERT_FATAL(req != NULL); req->cmd.opc = SPDK_NVME_OPC_WRITE; req->cmd.cdw10 = 10000; req->cmd.cdw12 = 255 | 0; spdk_nvme_retry_count = 1; fail_next_sge = true; nvme_qpair_submit_request(&qpair, req); CU_ASSERT(qpair.sq_tail == 0); cleanup_submit_request_test(&qpair); fail_next_sge = false; prepare_submit_request_test(&qpair, &ctrlr, ®s); req = nvme_allocate_request(&payload, 2 * PAGE_SIZE, NULL, &io_req); SPDK_CU_ASSERT_FATAL(req != NULL); req->cmd.opc = SPDK_NVME_OPC_WRITE; req->cmd.cdw10 = 10000; req->cmd.cdw12 = 255 | 0; req->payload_offset = 2; nvme_qpair_submit_request(&qpair, req); CU_ASSERT(qpair.sq_tail == 0); cleanup_submit_request_test(&qpair); prepare_submit_request_test(&qpair, &ctrlr, ®s); req = nvme_allocate_request(&payload, 33 * PAGE_SIZE, NULL, &io_req); SPDK_CU_ASSERT_FATAL(req != NULL); req->cmd.opc = SPDK_NVME_OPC_WRITE; req->cmd.cdw10 = 10000; req->cmd.cdw12 = 255 | 0; nvme_qpair_submit_request(&qpair, req); CU_ASSERT(req->cmd.dptr.prp.prp1 == 0); CU_ASSERT(qpair.sq_tail == 1); sgl_tr = LIST_FIRST(&qpair.outstanding_tr); if (sgl_tr != NULL) { for (i = 0; i < 32; i++) { CU_ASSERT(sgl_tr->u.prp[i] == (PAGE_SIZE * (i + 1))); } LIST_REMOVE(sgl_tr, list); free(sgl_tr); } cleanup_submit_request_test(&qpair); nvme_free_request(req); }
static void nvmf_test_connect(void) { uint64_t fabric_conn = 0; uint64_t fabric_conn_admin = 1; uint64_t fabric_conn_IO = 2; struct nvmf_session *sess, *io_sess; struct spdk_nvmf_fabric_connect_cmd connect = {}; struct spdk_nvmf_fabric_connect_data connect_data = {}; struct spdk_nvmf_fabric_connect_rsp response = {}; struct spdk_nvmf_fabric_connect_rsp expect_rsp = {}; connect.opcode = 0x7f; connect.cid = 0x01; connect.fctype = 0x01; connect_data.cntlid = 0xffff; connect.qid = 0; connect.sqsize = 64; /* change cmd field to do failure test first */ /* invalid subnqn and qid = 0*/ strcpy((char *)connect_data.subnqn, "fake"); CU_ASSERT_PTR_NULL(nvmf_connect((void *)fabric_conn, &connect, &connect_data, &response)); CU_ASSERT_NOT_EQUAL(response.status.sc, 0); /* valid subnqn and qid = 0 and cntlid != 0xfffff */ strcpy((char *)connect_data.subnqn, "subsystem1"); connect_data.cntlid = 0x000f; CU_ASSERT_PTR_NULL(nvmf_connect((void *)fabric_conn, &connect, &connect_data, &response)); CU_ASSERT_EQUAL(response.status.sc, SPDK_NVMF_FABRIC_SC_INVALID_PARAM); /* invalid subnqn and qid = 1 */ strcpy((char *)connect_data.subnqn, "fake"); connect.qid = 1; connect_data.cntlid = 0; CU_ASSERT_PTR_NULL(nvmf_connect((void *)fabric_conn, &connect, &connect_data, &response)); CU_ASSERT_EQUAL(response.status.sc, SPDK_NVMF_FABRIC_SC_RESTART_DISCOVERY); /* valid subnqn but session is not created. */ strcpy((char *)connect_data.subnqn, "subsystem1"); connect_data.cntlid = 0; CU_ASSERT_PTR_NULL(nvmf_connect((void *)fabric_conn, &connect, &connect_data, &response)); CU_ASSERT_EQUAL(response.status.sc, SPDK_NVMF_FABRIC_SC_RESTART_DISCOVERY); /* create admin connection */ connect.qid = 0; connect_data.cntlid = 0xffff; sess = nvmf_connect((void *)fabric_conn_admin, &connect, &connect_data, &response); SPDK_CU_ASSERT_FATAL(sess != NULL); nvmf_init_session_properties(sess, 64); sess->max_connections_allowed = 2; CU_ASSERT_EQUAL(sess->num_connections, 1); CU_ASSERT_PTR_EQUAL(sess->connections.tqh_first->fabric_conn, fabric_conn_admin); expect_rsp.status_code_specific.success.cntlid = SS_SC_CNTLID; expect_rsp.status.sc = 0; help_response_check(&response, &expect_rsp); /* create IO connection */ connect.cid = 0x02; connect.qid = 1; connect_data.cntlid = SS_SC_CNTLID; io_sess = nvmf_connect((void *)fabric_conn_IO, &connect, &connect_data, &response); SPDK_CU_ASSERT_FATAL(io_sess != NULL); CU_ASSERT_EQUAL(io_sess->num_connections, 2); /* check admin and io connection are in same session. */ CU_ASSERT_PTR_EQUAL(io_sess, sess); expect_rsp.status_code_specific.success.cntlid = SS_SC_CNTLID; expect_rsp.status.sc = 0; help_response_check(&response, &expect_rsp); /* right subnqn, session is created, but wrong cntlid */ connect_data.cntlid = 1; connect.qid = 2; CU_ASSERT_PTR_NULL(nvmf_connect((void *)&fabric_conn, &connect, &connect_data, &response)); CU_ASSERT_EQUAL(response.status.sc, SPDK_NVMF_FABRIC_SC_RESTART_DISCOVERY); }
static void test_discovery_log(void) { struct spdk_nvmf_subsystem *subsystem; uint8_t buffer[8192]; struct spdk_nvmf_discovery_log_page *disc_log; struct spdk_nvmf_discovery_log_page_entry *entry; /* Reset discovery-related globals */ g_discovery_genctr = 0; free(g_discovery_log_page); g_discovery_log_page = NULL; g_discovery_log_page_size = 0; /* Add one subsystem and verify that the discovery log contains it */ subsystem = spdk_nvmf_create_subsystem("nqn.2016-06.io.spdk:subsystem1", SPDK_NVMF_SUBTYPE_NVME, NVMF_SUBSYSTEM_MODE_DIRECT, NULL, NULL, NULL); SPDK_CU_ASSERT_FATAL(subsystem != NULL); SPDK_CU_ASSERT_FATAL(spdk_nvmf_subsystem_add_listener(subsystem, "test_transport1", "1234", "5678") == 0); /* Get only genctr (first field in the header) */ memset(buffer, 0xCC, sizeof(buffer)); disc_log = (struct spdk_nvmf_discovery_log_page *)buffer; spdk_nvmf_get_discovery_log_page(buffer, 0, sizeof(disc_log->genctr)); CU_ASSERT(disc_log->genctr == 2); /* one added subsystem + one added listen address */ /* Get only the header, no entries */ memset(buffer, 0xCC, sizeof(buffer)); disc_log = (struct spdk_nvmf_discovery_log_page *)buffer; spdk_nvmf_get_discovery_log_page(buffer, 0, sizeof(*disc_log)); CU_ASSERT(disc_log->genctr == 2); CU_ASSERT(disc_log->numrec == 1); /* Offset 0, exact size match */ memset(buffer, 0xCC, sizeof(buffer)); disc_log = (struct spdk_nvmf_discovery_log_page *)buffer; spdk_nvmf_get_discovery_log_page(buffer, 0, sizeof(*disc_log) + sizeof(disc_log->entries[0])); CU_ASSERT(disc_log->genctr != 0); CU_ASSERT(disc_log->numrec == 1); CU_ASSERT(disc_log->entries[0].trtype == 42); /* Offset 0, oversize buffer */ memset(buffer, 0xCC, sizeof(buffer)); disc_log = (struct spdk_nvmf_discovery_log_page *)buffer; spdk_nvmf_get_discovery_log_page(buffer, 0, sizeof(buffer)); CU_ASSERT(disc_log->genctr != 0); CU_ASSERT(disc_log->numrec == 1); CU_ASSERT(disc_log->entries[0].trtype == 42); CU_ASSERT(all_zero(buffer + sizeof(*disc_log) + sizeof(disc_log->entries[0]), sizeof(buffer) - (sizeof(*disc_log) + sizeof(disc_log->entries[0])))); /* Get just the first entry, no header */ memset(buffer, 0xCC, sizeof(buffer)); entry = (struct spdk_nvmf_discovery_log_page_entry *)buffer; spdk_nvmf_get_discovery_log_page(buffer, offsetof(struct spdk_nvmf_discovery_log_page, entries[0]), sizeof(*entry)); CU_ASSERT(entry->trtype == 42); }
static void parse_invalid_test(void) { struct iscsi_param *params; int rc; params = NULL; char *data; int len; /* key without '=' */ PARSE("Abc\0", false, NULL); CU_ASSERT(rc != 0); EXPECT_NULL("Abc"); /* multiple key=value pairs, one missing '=' */ PARSE("Abc=def\0Xyz\0Www=test\0", false, NULL); CU_ASSERT(rc != 0); EXPECT_VAL("Abc", "def"); EXPECT_NULL("Xyz"); EXPECT_NULL("Www"); /* empty key */ PARSE("=abcdef", false, NULL); CU_ASSERT(rc != 0); EXPECT_NULL(""); /* CHAP_C=AAAA.... with value length 8192 + 1 */ len = strlen("CHAP_C=") + ISCSI_TEXT_MAX_VAL_LEN + 1 /* max value len + 1 */ + 1 /* null terminators */; data = malloc(len); SPDK_CU_ASSERT_FATAL(data != NULL); memset(data, 'A', len); strcpy(data, "CHAP_C"); data[6] = '='; data[len - 1] = '\0'; rc = spdk_iscsi_parse_params(¶ms, data, len, false, NULL); free(data); CU_ASSERT(rc != 0); EXPECT_NULL("CHAP_C"); /* Test simple value, length of value bigger than 255*/ len = strlen("A=") + ISCSI_TEXT_MAX_SIMPLE_VAL_LEN + 1 /* max simple value len + 1 */ + 1 /* null terminators */; data = malloc(len); SPDK_CU_ASSERT_FATAL(data != NULL); memset(data, 'A', len); data[1] = '='; data[len - 1] = '\0'; rc = spdk_iscsi_parse_params(¶ms, data, len, false, NULL); free(data); CU_ASSERT(rc != 0); EXPECT_NULL("A"); /* key length bigger than 63 */ len = ISCSI_TEXT_MAX_KEY_LEN + 1 /*max key length + 1*/ + 1 /* = */ + 1 /* A */ + 1/* null terminators */; data = malloc(len); SPDK_CU_ASSERT_FATAL(data != NULL); memset(data, 'A', len); data[64] = '='; data[len - 1] = '\0'; rc = spdk_iscsi_parse_params(¶ms, data, len, false, NULL); free(data); CU_ASSERT(rc != 0); EXPECT_NULL("A"); /* duplicated key */ PARSE("B=BB", false, NULL); CU_ASSERT(rc == 0); PARSE("B=BBBB", false, NULL); CU_ASSERT(rc != 0); EXPECT_VAL("B", "BB"); spdk_iscsi_param_free(params); }