void test_inquiry_block_limits(void) { int ret; struct scsi_inquiry_block_limits *bl; struct scsi_task *bl_task = NULL; struct scsi_inquiry_logical_block_provisioning *lbp = NULL; struct scsi_task *lbp_task = NULL; logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, "Test of the INQUIRY Block Limits"); CHECK_FOR_SBC; logging(LOG_VERBOSE, "Block device. Verify that we can read Block Limits VPD"); ret = inquiry(iscsic, tgt_lun, 1, SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS, 64, &bl_task); CU_ASSERT_EQUAL(ret, 0); if (ret != 0) { logging(LOG_NORMAL, "[FAILURE] failed to send inquiry."); goto finished; } bl = scsi_datain_unmarshall(bl_task); if (bl == NULL) { logging(LOG_NORMAL, "[FAILURE] failed to unmarshall inquiry " "datain blob."); CU_FAIL("[FAILURE] failed to unmarshall inquiry " "datain blob."); goto finished; } logging(LOG_VERBOSE, "Verify that the PageLength matches up with the size of the DATA-IN buffer."); CU_ASSERT_EQUAL(bl_task->datain.size, bl_task->datain.data[3] + 4); if (bl_task->datain.size != bl_task->datain.data[3] + 4) { logging(LOG_NORMAL, "[FAILURE] Invalid PageLength returned. " "Was %d but expected %d", bl_task->datain.data[3], bl_task->datain.size - 4); } else { logging(LOG_VERBOSE, "[SUCCESS] PageLength matches DataIn buffer size"); } logging(LOG_VERBOSE, "Verify that the PageLength matches SCSI-level."); /* if it is not SBC3 then we assume it must be SBC2 */ if (sbc3_support) { logging(LOG_VERBOSE, "Device claims SBC-3. Verify that " "PageLength == 0x3C"); } else { logging(LOG_VERBOSE, "Device is not SBC-3. Verify that " "PageLength == 0x0C (but allow 0x3C too. Some SBC-2 " "devices support some SBC-3 features."); } switch (bl_task->datain.data[3]) { case 0x3c: /* accept 0x3c (==SBC-3) for all levels */ if (!sbc3_support) { logging(LOG_NORMAL, "[WARNING] SBC-3 pagelength (0x3C) " "returned but SBC-3 support was not claimed " "in the standard inquiry page."); } break; case 0x0c: /* only accept 0x0c for levels < SBC-3 */ if (!sbc3_support) { break; } /* fallthrough */ default: CU_FAIL("[FAILED] Invalid pagelength returned"); logging(LOG_NORMAL, "[FAILURE] Invalid PageLength returned."); } if (bl_task->datain.data[3] != 0x3c) { goto finished; } /* * MAXIMUM UNMAP LBA COUNT * MAXIMUM UNMAP BLOCK DESCRIPTOR COUNT */ logging(LOG_VERBOSE, "Try reading the logical block provisioning VPD"); ret = inquiry(iscsic, tgt_lun, 1, SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING, 64, &lbp_task); if (ret == 0) { lbp = scsi_datain_unmarshall(lbp_task); if (lbp == NULL) { logging(LOG_NORMAL, "[FAILURE] failed to unmarshall " "inquiry datain blob."); } } if (lbp && lbp->lbpu) { /* We support UNMAP so MAXIMUM UNMAP LBA COUNT and * MAXIMUM UNMAP BLOCK DESCRIPTOR COUNT. * They must be > 0. * It can be 0xffffffff which means no limit, but if there is * an explicit limit set, then we check that it looks sane. * Sane here means < 1M. */ logging(LOG_VERBOSE, "Device claims UNMAP support via LBPU"); logging(LOG_VERBOSE, "Verify that MAXIMUM UNMAP LBA COUNT is " "not 0"); CU_ASSERT_NOT_EQUAL(bl->max_unmap, 0); logging(LOG_VERBOSE, "Verify that MAXIMUM UNMAP LBA COUNT is " "at least 2^LBPPBE"); CU_ASSERT_EQUAL(bl->max_unmap >= (1U << rc16->lbppbe), 1); if (bl->max_unmap != 0xffffffff) { logging(LOG_VERBOSE, "Verify that MAXIMUM UNMAP LBA " "COUNT is not insanely big"); CU_ASSERT_TRUE(bl->max_unmap <= 1024*1024); } logging(LOG_VERBOSE, "Verify that MAXIMUM UNMAP BLOCK " "DESCRIPTOR COUNT is not 0"); CU_ASSERT_NOT_EQUAL(bl->max_unmap_bdc, 0); if (bl->max_unmap_bdc != 0xffffffff) { logging(LOG_VERBOSE, "Verify that MAXIMUM UNMAP " "BLOCK DESCRIPTOR COUNT is not insanely big"); CU_ASSERT_TRUE(bl->max_unmap_bdc <= 1024*1024); } } else { logging(LOG_VERBOSE, "Device does not claim UNMAP support via " "LBPU"); logging(LOG_VERBOSE, "Verify that MAXIMUM UNMAP LBA COUNT is " "0"); CU_ASSERT_EQUAL(bl->max_unmap, 0); logging(LOG_VERBOSE, "Verify that MAXIMUM UNMAP BLOCK " "DESCRIPTOR COUNT is 0"); CU_ASSERT_EQUAL(bl->max_unmap_bdc, 0); } finished: if (bl_task != NULL) { scsi_free_scsi_task(bl_task); } if (lbp_task != NULL) { scsi_free_scsi_task(lbp_task); } }
void test_canon_x(void) { CALC_ELEMENT *t1; double a, b; /* addition x + a * x */ t1 = create_bin_op('+', create_x(), create_bin_op('*', create_number(2.5), create_x())); CU_ASSERT_EQUAL(canonical_form(&t1), 0); CU_ASSERT_EQUAL(t1->calc_t, CALC_X); CU_ASSERT_EQUAL(t1->status, STATUS_X_PRESENT); CU_ASSERT_EQUAL(t1->value, 3.5); free_calc_element(t1); /* addition a * x + b */ t1 = create_bin_op('+', create_bin_op('*', create_number(1.25), create_x()), create_number(14)); CU_ASSERT_EQUAL(canonical_form(&t1), 0); CU_ASSERT_EQUAL(t1->calc_t, CALC_BIN_OP); CU_ASSERT_EQUAL(t1->status, STATUS_X_PRESENT); CU_ASSERT_EQUAL(get_ax_b(t1, &a, &b), 0); CU_ASSERT_EQUAL(a, 1.25); CU_ASSERT_EQUAL(b, 14); free_calc_element(t1); /* addition a * x + b + c */ t1 = create_bin_op('+', create_bin_op('+', create_bin_op('*', create_number(0.75), create_x()), create_number(6)), create_number(-3.5)); CU_ASSERT_EQUAL(canonical_form(&t1), 0); CU_ASSERT_EQUAL(t1->calc_t, CALC_BIN_OP); CU_ASSERT_EQUAL(t1->status, STATUS_X_PRESENT); CU_ASSERT_EQUAL(get_ax_b(t1, &a, &b), 0); CU_ASSERT_EQUAL(a, 0.75); CU_ASSERT_EQUAL(b, 2.5); free_calc_element(t1); /* addition (a1 * x + b1) + (a2 * x + b2) */ t1 = create_bin_op('+', create_ax_b(9.0, -1.25), create_ax_b(2.0, 6.5)); CU_ASSERT_EQUAL(canonical_form(&t1), 0); CU_ASSERT_EQUAL(t1->calc_t, CALC_BIN_OP); CU_ASSERT_EQUAL(t1->status, STATUS_X_PRESENT); CU_ASSERT_EQUAL(get_ax_b(t1, &a, &b), 0); CU_ASSERT_EQUAL(a, 11.0); CU_ASSERT_EQUAL(b, 5.25); free_calc_element(t1); /* multiplication a * x */ t1 = create_bin_op('*', create_x(), create_number(-9.0)); CU_ASSERT_EQUAL(canonical_form(&t1), 0); CU_ASSERT_EQUAL(t1->calc_t, CALC_X); CU_ASSERT_EQUAL(t1->status, STATUS_X_PRESENT); CU_ASSERT_EQUAL(get_ax_b(t1, &a, &b), 0); CU_ASSERT_EQUAL(a, -9.0); CU_ASSERT_EQUAL(b, 0); free_calc_element(t1); /* multiplication x * a */ t1 = create_bin_op('*', create_number(7.5), create_x()); CU_ASSERT_EQUAL(canonical_form(&t1), 0); CU_ASSERT_EQUAL(t1->calc_t, CALC_X); CU_ASSERT_EQUAL(t1->status, STATUS_X_PRESENT); CU_ASSERT_EQUAL(get_ax_b(t1, &a, &b), 0); CU_ASSERT_EQUAL(a, 7.5); CU_ASSERT_EQUAL(b, 0); free_calc_element(t1); /* multiplication c * (a * x + b) */ t1 = create_bin_op('*', create_number(19), create_ax_b(4, -0.5)); CU_ASSERT_EQUAL(canonical_form(&t1), 0); CU_ASSERT_EQUAL(t1->calc_t, CALC_BIN_OP); CU_ASSERT_EQUAL(t1->status, STATUS_X_PRESENT); CU_ASSERT_EQUAL(get_ax_b(t1, &a, &b), 0); CU_ASSERT_EQUAL(a, 76); CU_ASSERT_EQUAL(b, -9.5); free_calc_element(t1); /* multiplication (a * x + b) * c */ t1 = create_bin_op('*', create_ax_b(-6, 4.5), create_number(0.5)); CU_ASSERT_EQUAL(canonical_form(&t1), 0); CU_ASSERT_EQUAL(t1->calc_t, CALC_BIN_OP); CU_ASSERT_EQUAL(t1->status, STATUS_X_PRESENT); CU_ASSERT_EQUAL(get_ax_b(t1, &a, &b), 0); CU_ASSERT_EQUAL(a, -3.0); CU_ASSERT_EQUAL(b, 2.25); free_calc_element(t1); /* multiplication x * x */ t1 = create_bin_op('*', create_x(), create_x()); CU_ASSERT_NOT_EQUAL(canonical_form(&t1), 0); CU_ASSERT_EQUAL(t1->calc_t, CALC_BIN_OP); CU_ASSERT_EQUAL(t1->status, STATUS_X_NON_LINEAR | STATUS_X_PRESENT); free_calc_element(t1); /* multiplication x * (a * x + b) */ t1 = create_bin_op('*', create_x(), create_x()); CU_ASSERT_NOT_EQUAL(canonical_form(&t1), 0); CU_ASSERT_EQUAL(t1->calc_t, CALC_BIN_OP); CU_ASSERT_EQUAL(t1->status, STATUS_X_NON_LINEAR | STATUS_X_PRESENT); free_calc_element(t1); /* multiplication (2*x - (2*x - 3)) * (3x - 4) - false square, actually linear */ t1 = create_bin_op('*', create_bin_op('-', create_ax_b(2.0, 0.0), create_ax_b(2, -3)), create_ax_b(3.0, -4.0)); CU_ASSERT_EQUAL(canonical_form(&t1), 0); CU_ASSERT_EQUAL(t1->calc_t, CALC_BIN_OP); CU_ASSERT_EQUAL(get_ax_b(t1, &a, &b), 0); CU_ASSERT_EQUAL(a, 9.0); CU_ASSERT_EQUAL(b, -12.0); free_calc_element(t1); /* division x / a */ t1 = create_bin_op('/', create_x(), create_number(2.0)); CU_ASSERT_NOT_EQUAL(canonical_form(&t1), 0); CU_ASSERT_EQUAL(t1->calc_t, CALC_BIN_OP); CU_ASSERT_EQUAL(t1->status, STATUS_X_IN_DIV | STATUS_X_PRESENT); free_calc_element(t1); /* log (ax + b) */ t1 = create_log(create_ax_b(9.0, -3.0)); CU_ASSERT_NOT_EQUAL(canonical_form(&t1), 0); CU_ASSERT_EQUAL(t1->calc_t, CALC_LOG); CU_ASSERT_EQUAL(t1->status, STATUS_X_IN_LOG | STATUS_X_PRESENT); free_calc_element(t1); }
void test_parser(void) { CALC_ELEMENT *e1 = NULL, *e2 = NULL; double a, b; strcpy(in_line, "(3+(4-1))*5"); line_len = 11; CU_ASSERT_EQUAL(parse_line(&e1, &e2), 0); CU_ASSERT_PTR_NOT_NULL(e1); CU_ASSERT_PTR_NULL(e2); CU_ASSERT_EQUAL(canonical_form(&e1), 0); CU_ASSERT_EQUAL(e1->calc_t, CALC_NUM); CU_ASSERT_EQUAL(e1->value, 30); free_calc_element(e1); clear_line(); e1 = NULL; e2 = NULL; strcpy(in_line, "2 * x + 0.5 = 1"); line_len = 15; CU_ASSERT_EQUAL(parse_line(&e1, &e2), 0); CU_ASSERT_PTR_NOT_NULL(e1); CU_ASSERT_PTR_NOT_NULL(e2); CU_ASSERT_EQUAL(canonical_form(&e1), 0); CU_ASSERT_EQUAL(canonical_form(&e2), 0); CU_ASSERT_EQUAL(get_ax_b(e1, &a, &b), 0); CU_ASSERT_EQUAL(a, 2); CU_ASSERT_EQUAL(b, 0.5); CU_ASSERT_EQUAL(e2->calc_t, CALC_NUM); CU_ASSERT_EQUAL(e2->value, 1); free_calc_element(e1); free_calc_element(e2); clear_line(); e1 = NULL; e2 = NULL; strcpy(in_line, "2x + 1 = 2(1-x)"); line_len = 15; CU_ASSERT_EQUAL(parse_line(&e1, &e2), 0); CU_ASSERT_PTR_NOT_NULL(e1); CU_ASSERT_PTR_NOT_NULL(e2); CU_ASSERT_EQUAL(canonical_form(&e1), 0); CU_ASSERT_EQUAL(canonical_form(&e2), 0); CU_ASSERT_EQUAL(get_ax_b(e1, &a, &b), 0); CU_ASSERT_EQUAL(a, 2); CU_ASSERT_EQUAL(b, 1); CU_ASSERT_EQUAL(get_ax_b(e2, &a, &b), 0); CU_ASSERT_EQUAL(a, -2); CU_ASSERT_EQUAL(b, 2); free_calc_element(e1); free_calc_element(e2); clear_line(); e1 = NULL; e2 = NULL; strcpy(in_line, "14.9 + 1 - 2 3.44"); line_len = 17; CU_ASSERT_NOT_EQUAL(parse_line(&e1, &e2), 0); clear_line(); e1 = NULL; e2 = NULL; strcpy(in_line, "((12)"); line_len = 5; CU_ASSERT_NOT_EQUAL(parse_line(&e1, &e2), 0); clear_line(); e1 = NULL; e2 = NULL; strcpy(in_line, "3x + -"); line_len = 6; CU_ASSERT_NOT_EQUAL(parse_line(&e1, &e2), 0); clear_line(); e1 = NULL; e2 = NULL; strcpy(in_line, "60/5/3*8/4"); line_len = 10; CU_ASSERT_EQUAL(parse_line(&e1, &e2), 0); CU_ASSERT_EQUAL(canonical_form(&e1), 0); CU_ASSERT_EQUAL(e1->calc_t, CALC_NUM); CU_ASSERT_EQUAL(e1->value, 8); free_calc_element(e1); clear_line(); e1 = NULL; e2 = NULL; /* log torturing */ strcpy(in_line, "log 5)"); line_len = 6; CU_ASSERT_NOT_EQUAL(parse_line(&e1, &e2), 0); clear_line(); e1 = NULL; e2 = NULL; strcpy(in_line, "log(9 "); line_len = 6; CU_ASSERT_NOT_EQUAL(parse_line(&e1, &e2), 0); clear_line(); e1 = NULL; e2 = NULL; strcpy(in_line, "leg(9)"); line_len = 6; CU_ASSERT_NOT_EQUAL(parse_line(&e1, &e2), 0); clear_line(); e1 = NULL; e2 = NULL; strcpy(in_line, "(2x - 2x + 6) * 4x = 12"); line_len = 23; CU_ASSERT_EQUAL(parse_line(&e1, &e2), 0); CU_ASSERT_EQUAL(canonical_form(&e1), 0); CU_ASSERT_EQUAL(get_ax_b(e1, &a, &b), 0); CU_ASSERT_EQUAL(a, 24); CU_ASSERT_EQUAL(b, 0); clear_line(); free_calc_element(e1); free_calc_element(e2); e1 = NULL; e2 = NULL; }
static void testAircraftHandling (void) { const vec2_t destination = { 10, 10 }; campaign_t *campaign; base_t *base; aircraft_t *aircraft; aircraft_t *newAircraft; aircraft_t *aircraftTemplate; int firstIdx; int initialCount; int count; int newFound; ResetCampaignData(); campaign = GetCampaign(); base = CreateBase("unittestaircraft", destination); CU_ASSERT_PTR_NOT_NULL_FATAL(base); /** @todo we should not assume that initial base has aircraft. It's a campaign parameter */ aircraft = AIR_GetFirstFromBase(base); CU_ASSERT_PTR_NOT_NULL_FATAL(aircraft); /* aircraft should have a template */ aircraftTemplate = aircraft->tpl; CU_ASSERT_PTR_NOT_NULL_FATAL(aircraftTemplate); firstIdx = aircraft->idx; initialCount = AIR_BaseCountAircraft(base); /* test deletion (part 1) */ AIR_DeleteAircraft(aircraft); count = AIR_BaseCountAircraft(base); CU_ASSERT_EQUAL(count, initialCount - 1); /* test addition (part 1) */ newAircraft = AIR_NewAircraft(base, aircraftTemplate); CU_ASSERT_PTR_NOT_NULL_FATAL(newAircraft); count = AIR_BaseCountAircraft(base); CU_ASSERT_EQUAL(count, initialCount); /* new aircraft assigned to the right base */ CU_ASSERT_EQUAL(newAircraft->homebase, base); newFound = 0; AIR_Foreach(aircraft) { /* test deletion (part 2) */ CU_ASSERT_NOT_EQUAL(firstIdx, aircraft->idx); /* for test addition (part 2) */ if (aircraft->idx == newAircraft->idx) newFound++; } /* test addition (part 2) */ CU_ASSERT_EQUAL(newFound, 1); /* check if AIR_Foreach iterates through all aircraft */ AIR_Foreach(aircraft) { AIR_DeleteAircraft(aircraft); } aircraft = AIR_GetFirstFromBase(base); CU_ASSERT_PTR_NULL_FATAL(aircraft); count = AIR_BaseCountAircraft(base); CU_ASSERT_EQUAL(count, 0); /* cleanup for the following tests */ E_DeleteAllEmployees(NULL); base->founded = qfalse; }
static void test_ofp_packet_input_forwarding_to_output(void) { odp_packet_t pkt; odp_event_t ev; int res; /* Call ofp_packet_input using a pkt with destination ip * that does NOT match the local ip on ifnet and a route is found. * ARP is found for gateway IP. * Function returns OFP_PKT_PROCESSED and * packet is forwarded to ofp_ip_output.*/ unsigned char ll_addr[13] = "123456789012"; my_test_val = TEST_FORWARD_HOOK; CU_ASSERT_EQUAL( ofp_ipv4_lookup_mac(dst_ipaddr + 1, ll_addr, ifnet), -1); CU_ASSERT_EQUAL( ofp_arp_ipv4_insert(dst_ipaddr + 1, ll_addr, ifnet), 0); if (create_odp_packet_ip4(&pkt, test_frame, sizeof(test_frame), dst_ipaddr, 0)) { CU_FAIL("Fail to create packet"); return; } res = ofp_packet_input(pkt, interface_queue[port], ofp_eth_vlan_processing); CU_ASSERT_EQUAL(res, OFP_PKT_PROCESSED); CU_ASSERT_NOT_EQUAL(ev = odp_queue_deq(ifnet->outq_def), ODP_EVENT_INVALID); CU_ASSERT_EQUAL(odp_queue_deq(ifnet->outq_def), ODP_EVENT_INVALID); #ifdef SP CU_ASSERT_EQUAL(odp_queue_deq(ifnet->spq_def), ODP_EVENT_INVALID); #endif /* SP */ CU_ASSERT_EQUAL(odp_packet_len(pkt), sizeof(test_frame)); pkt = odp_packet_from_event(ev); struct ofp_ip *ip_in_pkt_data = (struct ofp_ip *)(in_pkt_data + OFP_ETHER_HDR_LEN); ip_in_pkt_data->ip_ttl--; #ifdef OFP_PERFORMANCE /*checksum is not filled on ip_output*/ ip_in_pkt_data->ip_sum = ((struct ofp_ip *)odp_packet_l3_ptr(pkt, NULL))->ip_sum; #else ip_in_pkt_data->ip_sum = 0; ip_in_pkt_data->ip_sum = ofp_cksum_buffer((uint16_t *)ip_in_pkt_data, ip_in_pkt_data->ip_hl<<2); #endif if (memcmp((uint8_t *)odp_packet_data(pkt) + odp_packet_l3_offset(pkt), in_pkt_data + OFP_ETHER_HDR_LEN, sizeof(test_frame) - OFP_ETHER_HDR_LEN)) CU_FAIL("corrupt l3 + data forwarded"); struct ofp_ether_header *eth = (struct ofp_ether_header *)odp_packet_l2_ptr(pkt, NULL); if (memcmp(eth->ether_dhost, ll_addr, OFP_ETHER_ADDR_LEN)) CU_FAIL("Bad destination mac address on the forwarded packet"); CU_ASSERT_EQUAL(eth->ether_type, odp_cpu_to_be_16(OFP_ETHERTYPE_IP)); CU_PASS("ofp_packet_input_forwarding_to_output"); }
void test_writeverify10_residuals(void) { struct scsi_task *task_ret; unsigned char buf[10000]; struct iscsi_data data; int ok; unsigned int i; logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, "Test WRITEVERIFY10 commands with residuals"); logging(LOG_VERBOSE, "Block size is %zu", block_size); CHECK_FOR_DATALOSS; CHECK_FOR_SBC; if (sd->iscsi_ctx == NULL) { const char *err = "[SKIPPED] This WRITEVERIFY10 test is only " "supported for iSCSI backends"; logging(LOG_NORMAL, "%s", err); CU_PASS(err); return; } /* check if writeverify10 is supported */ WRITEVERIFY10(sd, 0, 0, block_size, 0, 0, 0, 0, NULL, EXPECT_STATUS_GOOD); /* Try a writeverify10 of 1 block but xferlength == 0 */ task = malloc(sizeof(struct scsi_task)); CU_ASSERT_PTR_NOT_NULL_FATAL(task); memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_WRITE_VERIFY10; task->cdb[1] = 2; /* BYTCHK = 1 */ task->cdb[8] = 1; task->cdb_size = 10; task->xfer_dir = SCSI_XFER_WRITE; task->expxferlen = 0; /* * we don't want autoreconnect since some targets will drop the session * on this condition. */ iscsi_set_noautoreconnect(sd->iscsi_ctx, 1); logging(LOG_VERBOSE, "Try writing one block but with iSCSI expected transfer length==0"); task_ret = iscsi_scsi_command_sync(sd->iscsi_ctx, sd->iscsi_lun, task, NULL); CU_ASSERT_PTR_NOT_NULL_FATAL(task_ret); CU_ASSERT_NOT_EQUAL(task->status, SCSI_STATUS_CANCELLED); /* XXX redundant? */ if (task->status == SCSI_STATUS_CHECK_CONDITION && task->sense.key == SCSI_SENSE_ILLEGAL_REQUEST && task->sense.ascq == SCSI_SENSE_ASCQ_INVALID_OPERATION_CODE) { logging(LOG_NORMAL, "[SKIPPED] WRITEVERIFY10 is not implemented."); CU_PASS("WRITEVERIFY10 is not implemented."); return; } logging(LOG_VERBOSE, "Verify that the target returned SUCCESS"); if (task->status != SCSI_STATUS_GOOD) { logging(LOG_VERBOSE, "[FAILED] Target returned error %s", iscsi_get_error(sd->iscsi_ctx)); } CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD); logging(LOG_VERBOSE, "Verify residual overflow flag is set"); if (task->residual_status != SCSI_RESIDUAL_OVERFLOW) { logging(LOG_VERBOSE, "[FAILED] Target did not set residual " "overflow flag"); } CU_ASSERT_EQUAL(task->residual_status, SCSI_RESIDUAL_OVERFLOW); logging(LOG_VERBOSE, "Verify we got %zu bytes of residual overflow", block_size); if (task->residual != block_size) { logging(LOG_VERBOSE, "[FAILED] Target did not set correct " "amount of residual. Expected %zu but got %zu.", block_size, task->residual); } CU_ASSERT_EQUAL(task->residual, block_size); scsi_free_scsi_task(task); task = NULL; /* in case the previous test failed the session */ iscsi_set_noautoreconnect(sd->iscsi_ctx, 0); logging(LOG_VERBOSE, "Try writing one block but with iSCSI expected transfer length==10000"); task = malloc(sizeof(struct scsi_task)); CU_ASSERT_PTR_NOT_NULL_FATAL(task); memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_WRITE_VERIFY10; task->cdb[1] = 2; /* BYTCHK = 1 */ task->cdb[8] = 1; task->cdb_size = 10; task->xfer_dir = SCSI_XFER_WRITE; task->expxferlen = 10000; memset(buf, 0xa6, sizeof(buf)); data.size = task->expxferlen; data.data = &buf[0]; task_ret = iscsi_scsi_command_sync(sd->iscsi_ctx, sd->iscsi_lun, task, &data); CU_ASSERT_PTR_NOT_NULL_FATAL(task_ret); logging(LOG_VERBOSE, "Verify that the target returned SUCCESS"); if (task->status != SCSI_STATUS_GOOD) { logging(LOG_VERBOSE, "[FAILED] Target returned error %s", iscsi_get_error(sd->iscsi_ctx)); } CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD); logging(LOG_VERBOSE, "Verify residual underflow flag is set"); if (task->residual_status != SCSI_RESIDUAL_UNDERFLOW) { logging(LOG_VERBOSE, "[FAILED] Target did not set residual " "underflow flag"); } CU_ASSERT_EQUAL(task->residual_status, SCSI_RESIDUAL_UNDERFLOW); logging(LOG_VERBOSE, "Verify we got %zu bytes of residual underflow", 10000 - block_size); if (task->residual != 10000 - block_size) { logging(LOG_VERBOSE, "[FAILED] Target did not set correct " "amount of residual. Expected %zu but got %zu.", 10000 - block_size, task->residual); } CU_ASSERT_EQUAL(task->residual, 10000 - block_size); scsi_free_scsi_task(task); task = NULL; logging(LOG_VERBOSE, "Try writing one block but with iSCSI expected transfer length==200"); task = malloc(sizeof(struct scsi_task)); CU_ASSERT_PTR_NOT_NULL_FATAL(task); memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_WRITE_VERIFY10; task->cdb[1] = 2; /* BYTCHK = 1 */ task->cdb[8] = 1; task->cdb_size = 10; task->xfer_dir = SCSI_XFER_WRITE; task->expxferlen = 200; data.size = task->expxferlen; data.data = &buf[0]; task_ret = iscsi_scsi_command_sync(sd->iscsi_ctx, sd->iscsi_lun, task, &data); CU_ASSERT_PTR_NOT_NULL_FATAL(task_ret); logging(LOG_VERBOSE, "Verify that the target returned SUCCESS"); ok = task->status == SCSI_STATUS_GOOD || (task->status == SCSI_STATUS_CHECK_CONDITION && task->sense.key == SCSI_SENSE_ILLEGAL_REQUEST && task->sense.ascq == SCSI_SENSE_ASCQ_INVALID_FIELD_IN_INFORMATION_UNIT); if (!ok) { logging(LOG_VERBOSE, "[FAILED] Target returned error %s", iscsi_get_error(sd->iscsi_ctx)); } CU_ASSERT(ok); logging(LOG_VERBOSE, "Verify residual overflow flag is set"); if (task->residual_status != SCSI_RESIDUAL_OVERFLOW) { logging(LOG_VERBOSE, "[FAILED] Target did not set residual " "overflow flag"); } CU_ASSERT_EQUAL(task->residual_status, SCSI_RESIDUAL_OVERFLOW); logging(LOG_VERBOSE, "Verify we got %zu bytes of residual overflow", block_size - 200); if (task->residual != block_size - 200) { logging(LOG_VERBOSE, "[FAILED] Target did not set correct " "amount of residual. Expected %zu but got %zu.", block_size - 200, task->residual); } CU_ASSERT_EQUAL(task->residual, block_size - 200); scsi_free_scsi_task(task); task = NULL; logging(LOG_VERBOSE, "Try writing two blocks but iSCSI expected " "transfer length==%zu (==one block)", block_size); task = malloc(sizeof(struct scsi_task)); CU_ASSERT_PTR_NOT_NULL_FATAL(task); memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_WRITE_VERIFY10; task->cdb[1] = 2; /* BYTCHK = 1 */ task->cdb[8] = 2; task->cdb_size = 10; task->xfer_dir = SCSI_XFER_WRITE; task->expxferlen = block_size; data.size = task->expxferlen; data.data = &buf[0]; task_ret = iscsi_scsi_command_sync(sd->iscsi_ctx, sd->iscsi_lun, task, &data); CU_ASSERT_PTR_NOT_NULL_FATAL(task_ret); logging(LOG_VERBOSE, "Verify that the target returned SUCCESS"); if (task->status != SCSI_STATUS_GOOD) { logging(LOG_VERBOSE, "[FAILED] Target returned error %s", iscsi_get_error(sd->iscsi_ctx)); } CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD); logging(LOG_VERBOSE, "Verify residual overflow flag is set"); if (task->residual_status != SCSI_RESIDUAL_OVERFLOW) { logging(LOG_VERBOSE, "[FAILED] Target did not set residual " "overflow flag"); } CU_ASSERT_EQUAL(task->residual_status, SCSI_RESIDUAL_OVERFLOW); logging(LOG_VERBOSE, "Verify we got one block of residual overflow"); if (task->residual != block_size) { logging(LOG_VERBOSE, "[FAILED] Target did not set correct " "amount of residual. Expected %zu but got %zu.", block_size, task->residual); } CU_ASSERT_EQUAL(task->residual, block_size); scsi_free_scsi_task(task); task = NULL; logging(LOG_VERBOSE, "Verify that if iSCSI EDTL > SCSI TL then we only write SCSI TL amount of data"); logging(LOG_VERBOSE, "Write two blocks of 'a'"); memset(buf, 'a', 10000); WRITE10(sd, 0, 2 * block_size, block_size, 0, 0, 0, 0, 0, buf, EXPECT_STATUS_GOOD); logging(LOG_VERBOSE, "Write one block of 'b' but set iSCSI EDTL to 2 blocks."); task = malloc(sizeof(struct scsi_task)); CU_ASSERT_PTR_NOT_NULL_FATAL(task); memset(buf, 'b', 10000); memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_WRITE_VERIFY10; task->cdb[1] = 2; /* BYTCHK = 1 */ task->cdb[8] = 1; task->cdb_size = 10; task->xfer_dir = SCSI_XFER_WRITE; task->expxferlen = 2 * block_size; data.size = task->expxferlen; data.data = &buf[0]; task_ret = iscsi_scsi_command_sync(sd->iscsi_ctx, sd->iscsi_lun, task, &data); CU_ASSERT_PTR_NOT_NULL_FATAL(task_ret); logging(LOG_VERBOSE, "Verify that the target returned SUCCESS"); if (task->status != SCSI_STATUS_GOOD) { logging(LOG_VERBOSE, "[FAILED] Target returned error %s", iscsi_get_error(sd->iscsi_ctx)); } CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD); logging(LOG_VERBOSE, "Verify residual underflow flag is set"); if (task->residual_status != SCSI_RESIDUAL_UNDERFLOW) { logging(LOG_VERBOSE, "[FAILED] Target did not set residual " "underflow flag"); } CU_ASSERT_EQUAL(task->residual_status, SCSI_RESIDUAL_UNDERFLOW); logging(LOG_VERBOSE, "Verify we got one block of residual underflow"); if (task->residual != block_size) { logging(LOG_VERBOSE, "[FAILED] Target did not set correct " "amount of residual. Expected %zu but got %zu.", block_size, task->residual); } CU_ASSERT_EQUAL(task->residual, block_size); scsi_free_scsi_task(task); task = NULL; logging(LOG_VERBOSE, "Read the two blocks"); READ10(sd, NULL, 0, 2* block_size, block_size, 0, 0, 0, 0, 0, buf, EXPECT_STATUS_GOOD); logging(LOG_VERBOSE, "Verify that the first block was changed to 'b'"); for (i = 0; i < block_size; i++) { if (buf[i] != 'b') { logging(LOG_NORMAL, "First block did not contain expected 'b'"); CU_FAIL("Block was not written correctly"); break; } } logging(LOG_VERBOSE, "Verify that the second block was NOT overwritten and still contains 'a'"); for (i = block_size; i < 2 * block_size; i++) { if (buf[i] != 'a') { logging(LOG_NORMAL, "Second block was overwritten and no longer contain 'a'"); CU_FAIL("Second block was incorrectly overwritten"); break; } } logging(LOG_VERBOSE, "Verify that if iSCSI EDTL < SCSI TL then we only write iSCSI EDTL amount of data"); logging(LOG_VERBOSE, "Write two blocks of 'a'"); memset(buf, 'a', 10000); WRITE10(sd, 0, 2 * block_size, block_size, 0, 0, 0, 0, 0, buf, EXPECT_STATUS_GOOD); logging(LOG_VERBOSE, "Write two blocks of 'b' but set iSCSI EDTL to 1 blocks."); task = malloc(sizeof(struct scsi_task)); CU_ASSERT_PTR_NOT_NULL_FATAL(task); memset(buf, 'b', 10000); memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_WRITE_VERIFY10; task->cdb[1] = 2; /* BYTCHK = 1 */ task->cdb[8] = 2; task->cdb_size = 10; task->xfer_dir = SCSI_XFER_WRITE; task->expxferlen = block_size; data.size = task->expxferlen; data.data = &buf[0]; task_ret = iscsi_scsi_command_sync(sd->iscsi_ctx, sd->iscsi_lun, task, &data); CU_ASSERT_PTR_NOT_NULL_FATAL(task_ret); logging(LOG_VERBOSE, "Verify that the target returned SUCCESS"); if (task->status != SCSI_STATUS_GOOD) { logging(LOG_VERBOSE, "[FAILED] Target returned error %s", iscsi_get_error(sd->iscsi_ctx)); } CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD); logging(LOG_VERBOSE, "Verify residual overflow flag is set"); if (task->residual_status != SCSI_RESIDUAL_OVERFLOW) { logging(LOG_VERBOSE, "[FAILED] Target did not set residual " "overflow flag"); } CU_ASSERT_EQUAL(task->residual_status, SCSI_RESIDUAL_OVERFLOW); logging(LOG_VERBOSE, "Verify we got one block of residual overflow"); if (task->residual != block_size) { logging(LOG_VERBOSE, "[FAILED] Target did not set correct " "amount of residual. Expected %zu but got %zu.", block_size, task->residual); } CU_ASSERT_EQUAL(task->residual, block_size); scsi_free_scsi_task(task); task = NULL; logging(LOG_VERBOSE, "Read the two blocks"); READ10(sd, NULL, 0, 2* block_size, block_size, 0, 0, 0, 0, 0, buf, EXPECT_STATUS_GOOD); logging(LOG_VERBOSE, "Verify that the first block was changed to 'b'"); for (i = 0; i < block_size; i++) { if (buf[i] != 'b') { logging(LOG_NORMAL, "First block did not contain expected 'b'"); CU_FAIL("Block was not written correctly"); break; } } logging(LOG_VERBOSE, "Verify that the second block was NOT overwritten and still contains 'a'"); for (i = block_size; i < 2 * block_size; i++) { if (buf[i] != 'a') { logging(LOG_NORMAL, "Second block was overwritten and no longer contain 'a'"); CU_FAIL("Second block was incorrectly overwritten"); break; } } }
/* * caller need create/release: * pm4_src, resources, ib_info, and ibs_request * submit command stream described in ibs_request and wait for this IB accomplished */ static void amdgpu_test_exec_cs_helper(amdgpu_context_handle context_handle, unsigned ip_type, int instance, int pm4_dw, uint32_t *pm4_src, int res_cnt, amdgpu_bo_handle *resources, struct amdgpu_cs_ib_info *ib_info, struct amdgpu_cs_request *ibs_request) { int r; uint32_t expired; uint32_t *ring_ptr; amdgpu_bo_handle ib_result_handle; void *ib_result_cpu; uint64_t ib_result_mc_address; struct amdgpu_cs_fence fence_status = {0}; amdgpu_bo_handle *all_res = alloca(sizeof(resources[0]) * (res_cnt + 1)); amdgpu_va_handle va_handle; /* prepare CS */ CU_ASSERT_NOT_EQUAL(pm4_src, NULL); CU_ASSERT_NOT_EQUAL(resources, NULL); CU_ASSERT_NOT_EQUAL(ib_info, NULL); CU_ASSERT_NOT_EQUAL(ibs_request, NULL); CU_ASSERT_TRUE(pm4_dw <= 1024); /* allocate IB */ r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096, AMDGPU_GEM_DOMAIN_GTT, 0, &ib_result_handle, &ib_result_cpu, &ib_result_mc_address, &va_handle); CU_ASSERT_EQUAL(r, 0); /* copy PM4 packet to ring from caller */ ring_ptr = ib_result_cpu; memcpy(ring_ptr, pm4_src, pm4_dw * sizeof(*pm4_src)); ib_info->ib_mc_address = ib_result_mc_address; ib_info->size = pm4_dw; ibs_request->ip_type = ip_type; ibs_request->ring = instance; ibs_request->number_of_ibs = 1; ibs_request->ibs = ib_info; ibs_request->fence_info.handle = NULL; memcpy(all_res, resources, sizeof(resources[0]) * res_cnt); all_res[res_cnt] = ib_result_handle; r = amdgpu_bo_list_create(device_handle, res_cnt+1, all_res, NULL, &ibs_request->resources); CU_ASSERT_EQUAL(r, 0); CU_ASSERT_NOT_EQUAL(ibs_request, NULL); /* submit CS */ r = amdgpu_cs_submit(context_handle, 0, ibs_request, 1); CU_ASSERT_EQUAL(r, 0); r = amdgpu_bo_list_destroy(ibs_request->resources); CU_ASSERT_EQUAL(r, 0); fence_status.ip_type = ip_type; fence_status.ring = ibs_request->ring; fence_status.context = context_handle; fence_status.fence = ibs_request->seq_no; /* wait for IB accomplished */ r = amdgpu_cs_query_fence_status(&fence_status, AMDGPU_TIMEOUT_INFINITE, 0, &expired); CU_ASSERT_EQUAL(r, 0); CU_ASSERT_EQUAL(expired, true); r = amdgpu_bo_unmap_and_free(ib_result_handle, va_handle, ib_result_mc_address, 4096); CU_ASSERT_EQUAL(r, 0); }
void test_prout_clear_simple(void) { int ret = 0; uint32_t old_gen; const unsigned long long key = rand_key(); struct scsi_task *tsk; struct scsi_persistent_reserve_in_read_keys *rk = NULL; CHECK_FOR_DATALOSS; logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, "Test Persistent Reserve OUT CLEAR works."); /* register our reservation key with the target */ ret = prout_register_and_ignore(sd, key); if (ret == -2) { CU_PASS("PERSISTENT RESERVE OUT is not implemented."); return; } CU_ASSERT_EQUAL(ret, 0); ret = prin_read_keys(sd, &tsk, &rk, 16384); CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_NOT_EQUAL(rk, NULL); if (!rk) goto out; CU_ASSERT_NOT_EQUAL(rk->num_keys, 0); /* retain PR generation number to check for increments */ old_gen = rk->prgeneration; scsi_free_scsi_task(tsk); rk = NULL; /* freed with tsk */ /* reserve the target */ ret = prout_reserve(sd, key, SCSI_PERSISTENT_RESERVE_TYPE_EXCLUSIVE_ACCESS); CU_ASSERT_EQUAL(ret, 0); /* verify target reservation */ ret = prin_verify_reserved_as(sd, key, SCSI_PERSISTENT_RESERVE_TYPE_EXCLUSIVE_ACCESS); CU_ASSERT_EQUAL(ret, 0); /* clear reservation and registration */ ret = prout_clear(sd, key); CU_ASSERT_EQUAL(ret, 0); ret = prin_verify_not_reserved(sd); CU_ASSERT_EQUAL(ret, 0); ret = prin_read_keys(sd, &tsk, &rk, 16384); CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_NOT_EQUAL(rk, NULL); if (!rk) goto out; CU_ASSERT_EQUAL(rk->num_keys, 0); /* generation incremented once for CLEAR (not for RESERVE) */ CU_ASSERT_EQUAL(rk->prgeneration, old_gen + 1); out: scsi_free_scsi_task(tsk); rk = NULL; /* freed with tsk */ }
static void testSRC_MSG_UAD_INIT(void) { fd_set rfds; int ret; struct my_uad_src src; bool loop = true; struct timeval timeout; ret = io_src_msg_uad_init(&(src.uad_src), uad_cb, &(src.msg), sizeof(src.msg), "my_cool_socket_name_%d", 42); CU_ASSERT_EQUAL(ret, 0); ret = io_mon_init(&mon); CU_ASSERT_EQUAL(ret, 0); ret = io_mon_add_source(&mon, &(src.uad_src.src_msg.src)); CU_ASSERT_EQUAL(ret, 0); ret = io_mon_activate_out_source(&mon, &(src.uad_src.src_msg.src), 1); CU_ASSERT_EQUAL(ret, 0); /* normal use cases */ while (loop) { /* restore the timer */ timeout.tv_sec = 1; timeout.tv_usec = 0; /* restore the read file descriptor set */ FD_ZERO(&rfds); FD_SET(mon.epollfd, &rfds); ret = select(mon.epollfd + 1, &rfds, NULL, NULL, &timeout); /* error, not normal */ CU_ASSERT_NOT_EQUAL(ret, -1); if (-1 == ret) goto out; /* timeout, not normal */ CU_ASSERT_NOT_EQUAL(ret, 0); if (0 == ret) goto out; ret = io_mon_process_events(&mon); CU_ASSERT(ret >= 0); if (ret < 0) goto out; loop = STATE_ALL_DONE != state; } out: /* cleanup */ io_mon_clean(&mon); io_src_msg_uad_clean(&(src.uad_src)); /* debriefeing */ CU_ASSERT(state & STATE_MSG1_SENT); CU_ASSERT(state & STATE_MSG1_RECEIVED); CU_ASSERT(state & STATE_MSG2_SENT); CU_ASSERT(state & STATE_MSG2_RECEIVED); /* error use cases */ }
void test_verify16_dpo(void) { int ret, dpofua, usage_data_dpo; struct scsi_task *ms_task = NULL; struct scsi_mode_sense *ms; struct scsi_task *rso_task = NULL; struct scsi_report_supported_op_codes_one_command *rsoc; unsigned char *buf = alloca(block_size); logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, "Test VERIFY16 DPO flag"); CHECK_FOR_SBC; ret = read10(sd, NULL, 0, block_size, block_size, 0, 0, 0, 0, 0, buf, EXPECT_STATUS_GOOD); CU_ASSERT_EQUAL(ret, 0); logging(LOG_VERBOSE, "Read the DPOFUA flag from mode sense data"); ret = modesense6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT, SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 255, EXPECT_STATUS_GOOD); CU_ASSERT_EQUAL(ret, 0); logging(LOG_VERBOSE, "[SUCCESS] Mode sense returned status GOOD"); ms = scsi_datain_unmarshall(ms_task); dpofua = ms && (ms->device_specific_parameter & 0x10); scsi_free_scsi_task(ms_task); if (dpofua) { logging(LOG_VERBOSE, "DPOFUA flag is set. Device should allow " "DPO/FUA flags in CDBs"); } else { logging(LOG_VERBOSE, "DPOFUA flag is clear. Device should fail " "CDBs with DPO/FUA set"); } logging(LOG_VERBOSE, "Test VERIFY16 with DPO==1"); if (dpofua) { ret = verify16(sd, 0, block_size, block_size, 0, 1, 0, buf, EXPECT_STATUS_GOOD); if (ret == -2) { logging(LOG_NORMAL, "[SKIPPED] VERIFY16 is not implemented."); CU_PASS("VERIFY16 is not implemented."); return; } CU_ASSERT_EQUAL(ret, 0); } else { ret = verify16(sd, 0, block_size, block_size, 0, 1, 0, buf, EXPECT_INVALID_FIELD_IN_CDB); if (ret == -2) { logging(LOG_NORMAL, "[SKIPPED] VERIFY16 is not implemented."); CU_PASS("VERIFY16 is not implemented."); return; } CU_ASSERT_EQUAL(ret, 0); } logging(LOG_VERBOSE, "Try fetching REPORT_SUPPORTED_OPCODES " "for VERIFY16"); ret = report_supported_opcodes(sd, &rso_task, 0, SCSI_REPORT_SUPPORTING_OPCODE, SCSI_OPCODE_VERIFY16, 0, 65535, EXPECT_STATUS_GOOD); if (ret == -2) { logging(LOG_NORMAL, "REPORT_SUPPORTED_OPCODES not implemented. " "Skipping this part of the test"); return; } logging(LOG_VERBOSE, "Unmarshall the DATA-IN buffer"); rsoc = scsi_datain_unmarshall(rso_task); CU_ASSERT_NOT_EQUAL(rsoc, NULL); usage_data_dpo = rsoc ? rsoc->cdb_usage_data[1] & 0x10 : -1; if (dpofua) { logging(LOG_VERBOSE, "DPOFUA is set. Verify the DPO flag " "is set in the CDB_USAGE_DATA"); CU_ASSERT_EQUAL(usage_data_dpo, 0x10); } else { logging(LOG_VERBOSE, "DPOFUA is clear. Verify the DPO " "flag is clear in the CDB_USAGE_DATA"); CU_ASSERT_EQUAL(usage_data_dpo, 0x00); } scsi_free_scsi_task(rso_task); }