4 * Copyright (c) Intel Corporation.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
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.
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.
38 #include "spdk/scsi.h"
40 #include "spdk_cunit.h"
42 #include "../common.c"
43 #include "iscsi/param.c"
45 struct spdk_iscsi_globals g_spdk_iscsi
;
47 struct spdk_iscsi_tgt_node
*
48 spdk_iscsi_find_tgt_node(const char *target_name
)
54 spdk_iscsi_tgt_node_access(struct spdk_iscsi_conn
*conn
,
55 struct spdk_iscsi_tgt_node
*target
,
56 const char *iqn
, const char *addr
)
62 spdk_iscsi_send_tgts(struct spdk_iscsi_conn
*conn
, const char *iiqn
,
64 const char *tiqn
, uint8_t *data
, int alloc_len
, int data_len
)
70 burst_length_param_negotation(int FirstBurstLength
, int MaxBurstLength
,
73 struct spdk_iscsi_sess sess
;
74 struct spdk_iscsi_conn conn
;
75 struct iscsi_param
*params
;
83 memset(&sess
, 0, sizeof(sess
));
84 memset(&conn
, 0, sizeof(conn
));
85 memset(data
, 0, 8192);
89 sess
.session_type
= SESSION_TYPE_NORMAL
;
91 sess
.MaxBurstLength
= 65536;
93 sess
.FirstBurstLength
= SPDK_ISCSI_FIRST_BURST_LENGTH
;
94 sess
.MaxOutstandingR2T
= 1;
96 /* set default params */
97 rc
= spdk_iscsi_sess_params_init(&sess
.params
);
100 rc
= spdk_iscsi_param_set_int(sess
.params
, "FirstBurstLength",
101 sess
.FirstBurstLength
);
104 rc
= spdk_iscsi_param_set_int(sess
.params
, "MaxBurstLength",
105 sess
.MaxBurstLength
);
108 rc
= spdk_iscsi_param_set(sess
.params
, "InitialR2T",
109 sess
.InitialR2T
? "Yes" : "No");
112 conn
.full_feature
= 1;
114 conn
.MaxRecvDataSegmentLength
= 65536;
116 rc
= spdk_iscsi_conn_params_init(&conn
.params
);
119 /* construct the data*/
120 len
= snprintf(data
+ total
, 8192 - total
, "%s=%d",
121 "FirstBurstLength", FirstBurstLength
);
124 len
= snprintf(data
+ total
, 8192 - total
, "%s=%d",
125 "MaxBurstLength", MaxBurstLength
);
128 len
= snprintf(data
+ total
, 8192 - total
, "%s=%d",
129 "InitialR2T", initialR2T
);
132 /* add one extra NUL byte at the end to match real iSCSI params */
135 /* store incoming parameters */
136 rc
= spdk_iscsi_parse_params(¶ms
, data
, total
, false, NULL
);
139 /* negotiate parameters */
140 rc
= spdk_iscsi_negotiate_params(&conn
, params
,
144 rc
= spdk_iscsi_copy_param2var(&conn
);
146 CU_ASSERT(conn
.sess
->FirstBurstLength
<= SPDK_ISCSI_FIRST_BURST_LENGTH
);
147 CU_ASSERT(conn
.sess
->FirstBurstLength
<= conn
.sess
->MaxBurstLength
);
148 CU_ASSERT(conn
.sess
->MaxBurstLength
<= SPDK_ISCSI_MAX_BURST_LENGTH
);
149 CU_ASSERT(conn
.sess
->MaxOutstandingR2T
== 1);
151 spdk_iscsi_param_free(sess
.params
);
152 spdk_iscsi_param_free(conn
.params
);
153 spdk_iscsi_param_free(params
);
157 param_negotiation_test(void)
159 burst_length_param_negotation(8192, 16384, 0);
160 burst_length_param_negotation(8192, 16384, 1);
161 burst_length_param_negotation(8192, 1024, 1);
162 burst_length_param_negotation(8192, 1024, 0);
163 burst_length_param_negotation(512, 1024, 1);
164 burst_length_param_negotation(512, 1024, 0);
168 list_negotiation_test(void)
170 int add_param_value
= 0;
171 struct iscsi_param param
= {};
173 char valid_list_buf
[1024];
174 char in_val_buf
[1024];
176 #define TEST_LIST(valid_list, in_val, expected_result) \
178 snprintf(valid_list_buf, sizeof(valid_list_buf), "%s", valid_list); \
179 snprintf(in_val_buf, sizeof(in_val_buf), "%s", in_val); \
180 new_val = spdk_iscsi_negotiate_param_list(&add_param_value, ¶m, valid_list_buf, in_val_buf, NULL); \
181 if (expected_result) { \
182 SPDK_CU_ASSERT_FATAL(new_val != NULL); \
183 CU_ASSERT_STRING_EQUAL(new_val, expected_result); \
187 TEST_LIST("None", "None", "None");
188 TEST_LIST("CHAP,None", "None", "None");
189 TEST_LIST("CHAP,None", "CHAP", "CHAP");
190 TEST_LIST("KRB5,SRP,CHAP,None", "SRP,CHAP,None", "SRP");
191 TEST_LIST("KRB5,SRP,CHAP,None", "CHAP,SRP,None", "CHAP");
192 TEST_LIST("KRB5,SRP,CHAP,None", "SPKM1,SRP,CHAP,None", "SRP");
193 TEST_LIST("KRB5,SRP,None", "CHAP,None", "None");
196 #define PARSE(strconst, partial_enabled, partial_text) \
198 len = sizeof(strconst); \
199 rc = spdk_iscsi_parse_params(¶ms, data, len, partial_enabled, partial_text)
201 #define EXPECT_VAL(key, expected_value) \
203 const char *val = spdk_iscsi_param_get_val(params, key); \
204 CU_ASSERT(val != NULL); \
206 CU_ASSERT(strcmp(val, expected_value) == 0); \
210 #define EXPECT_NULL(key) \
211 CU_ASSERT(spdk_iscsi_param_get_val(params, key) == NULL)
214 parse_valid_test(void)
216 struct iscsi_param
*params
;
222 char *partial_parameter
= NULL
;
224 /* simple test with a single key=value */
225 PARSE("Abc=def\0", false, NULL
);
227 EXPECT_VAL("Abc", "def");
229 /* multiple key=value pairs */
230 PARSE("Aaa=bbbbbb\0Xyz=test\0", false, NULL
);
232 EXPECT_VAL("Aaa", "bbbbbb");
233 EXPECT_VAL("Xyz", "test");
235 /* value with embedded '=' */
236 PARSE("A=b=c\0", false, NULL
);
238 EXPECT_VAL("A", "b=c");
240 /* CHAP_C=AAAA.... with value length 8192 */
241 len
= strlen("CHAP_C=") + ISCSI_TEXT_MAX_VAL_LEN
+ 1/* null terminators */;
243 SPDK_CU_ASSERT_FATAL(data
!= NULL
);
244 memset(data
, 'A', len
);
245 strcpy(data
, "CHAP_C");
247 data
[len
- 1] = '\0';
248 rc
= spdk_iscsi_parse_params(¶ms
, data
, len
, false, NULL
);
252 /* partial parameter: value is partial*/
253 PARSE("C=AAA\0D=B", true, &partial_parameter
);
254 SPDK_CU_ASSERT_FATAL(partial_parameter
!= NULL
);
255 CU_ASSERT_STRING_EQUAL(partial_parameter
, "D=B");
257 EXPECT_VAL("C", "AAA");
259 PARSE("XXXX\0E=UUUU\0", false, &partial_parameter
);
261 EXPECT_VAL("D", "BXXXX");
262 EXPECT_VAL("E", "UUUU");
263 CU_ASSERT_PTR_NULL(partial_parameter
);
265 /* partial parameter: key is partial*/
266 PARSE("IAMAFAK", true, &partial_parameter
);
267 CU_ASSERT_STRING_EQUAL(partial_parameter
, "IAMAFAK");
269 EXPECT_NULL("IAMAFAK");
270 PARSE("EDKEY=TTTT\0F=IIII", false, &partial_parameter
);
272 EXPECT_VAL("IAMAFAKEDKEY", "TTTT");
273 EXPECT_VAL("F", "IIII");
274 CU_ASSERT_PTR_NULL(partial_parameter
);
276 /* Second partial parameter is the only parameter */
277 PARSE("OOOO", true, &partial_parameter
);
278 CU_ASSERT_STRING_EQUAL(partial_parameter
, "OOOO");
281 PARSE("LL=MMMM", false, &partial_parameter
);
283 EXPECT_VAL("OOOOLL", "MMMM");
284 CU_ASSERT_PTR_NULL(partial_parameter
);
286 spdk_iscsi_param_free(params
);
290 parse_invalid_test(void)
292 struct iscsi_param
*params
;
299 /* key without '=' */
300 PARSE("Abc\0", false, NULL
);
304 /* multiple key=value pairs, one missing '=' */
305 PARSE("Abc=def\0Xyz\0Www=test\0", false, NULL
);
307 EXPECT_VAL("Abc", "def");
312 PARSE("=abcdef", false, NULL
);
316 /* CHAP_C=AAAA.... with value length 8192 + 1 */
317 len
= strlen("CHAP_C=") + ISCSI_TEXT_MAX_VAL_LEN
+ 1 /* max value len + 1 */ +
318 1 /* null terminators */;
320 SPDK_CU_ASSERT_FATAL(data
!= NULL
);
321 memset(data
, 'A', len
);
322 strcpy(data
, "CHAP_C");
324 data
[len
- 1] = '\0';
325 rc
= spdk_iscsi_parse_params(¶ms
, data
, len
, false, NULL
);
328 EXPECT_NULL("CHAP_C");
330 /* Test simple value, length of value bigger than 255*/
331 len
= strlen("A=") + ISCSI_TEXT_MAX_SIMPLE_VAL_LEN
+ 1 /* max simple value len + 1 */ +
332 1 /* null terminators */;
334 SPDK_CU_ASSERT_FATAL(data
!= NULL
);
335 memset(data
, 'A', len
);
337 data
[len
- 1] = '\0';
338 rc
= spdk_iscsi_parse_params(¶ms
, data
, len
, false, NULL
);
343 /* key length bigger than 63 */
344 len
= ISCSI_TEXT_MAX_KEY_LEN
+ 1 /*max key length + 1*/ + 1 /* = */ + 1 /* A */ +
345 1/* null terminators */;
347 SPDK_CU_ASSERT_FATAL(data
!= NULL
);
348 memset(data
, 'A', len
);
350 data
[len
- 1] = '\0';
351 rc
= spdk_iscsi_parse_params(¶ms
, data
, len
, false, NULL
);
357 PARSE("B=BB", false, NULL
);
359 PARSE("B=BBBB", false, NULL
);
361 EXPECT_VAL("B", "BB");
363 spdk_iscsi_param_free(params
);
367 main(int argc
, char **argv
)
369 CU_pSuite suite
= NULL
;
370 unsigned int num_failures
;
372 if (CU_initialize_registry() != CUE_SUCCESS
) {
373 return CU_get_error();
376 suite
= CU_add_suite("iscsi_suite", NULL
, NULL
);
378 CU_cleanup_registry();
379 return CU_get_error();
383 CU_add_test(suite
, "param negotiation test",
384 param_negotiation_test
) == NULL
||
385 CU_add_test(suite
, "list negotation test",
386 list_negotiation_test
) == NULL
||
387 CU_add_test(suite
, "parse valid test",
388 parse_valid_test
) == NULL
||
389 CU_add_test(suite
, "parse invalid test",
390 parse_invalid_test
) == NULL
392 CU_cleanup_registry();
393 return CU_get_error();
396 CU_basic_set_mode(CU_BRM_VERBOSE
);
397 CU_basic_run_tests();
398 num_failures
= CU_get_number_of_failures();
399 CU_cleanup_registry();