xref: /spdk/test/unit/lib/iscsi/param.c/param_ut.c (revision ea941caeaf896fdf2aef7685f86f37023060faed)
1488570ebSJim Harris /*   SPDX-License-Identifier: BSD-3-Clause
2a6dbe372Spaul luse  *   Copyright (C) 2016 Intel Corporation.
3144ba3a1SDaniel Verkamp  *   All rights reserved.
4144ba3a1SDaniel Verkamp  */
5144ba3a1SDaniel Verkamp 
6144ba3a1SDaniel Verkamp #include "spdk/stdinc.h"
7144ba3a1SDaniel Verkamp 
8144ba3a1SDaniel Verkamp #include "spdk/scsi.h"
9144ba3a1SDaniel Verkamp 
10ae431e31SKonrad Sztyber #include "spdk_internal/cunit.h"
11144ba3a1SDaniel Verkamp 
12144ba3a1SDaniel Verkamp #include "../common.c"
13144ba3a1SDaniel Verkamp #include "iscsi/param.c"
14144ba3a1SDaniel Verkamp 
1569bef7f7SShuhei Matsumoto #include "spdk_internal/mock.h"
1669bef7f7SShuhei Matsumoto 
17be1489b9SShuhei Matsumoto struct spdk_iscsi_globals g_iscsi;
18144ba3a1SDaniel Verkamp 
196a313725SShuhei Matsumoto DEFINE_STUB(iscsi_find_tgt_node, struct spdk_iscsi_tgt_node *,
2069bef7f7SShuhei Matsumoto 	    (const char *target_name), NULL);
21144ba3a1SDaniel Verkamp 
226a313725SShuhei Matsumoto DEFINE_STUB(iscsi_tgt_node_access, bool,
2369bef7f7SShuhei Matsumoto 	    (struct spdk_iscsi_conn *conn, struct spdk_iscsi_tgt_node *target,
2469bef7f7SShuhei Matsumoto 	     const char *iqn, const char *addr),
2569bef7f7SShuhei Matsumoto 	    false);
26144ba3a1SDaniel Verkamp 
276a313725SShuhei Matsumoto DEFINE_STUB(iscsi_send_tgts, int,
2869bef7f7SShuhei Matsumoto 	    (struct spdk_iscsi_conn *conn, const char *iiqn, const char *iaddr,
2969bef7f7SShuhei Matsumoto 	     const char *tiqn, uint8_t *data, int alloc_len, int data_len),
3069bef7f7SShuhei Matsumoto 	    0);
31144ba3a1SDaniel Verkamp 
32144ba3a1SDaniel Verkamp static void
burst_length_param_negotiation(int FirstBurstLength,int MaxBurstLength,int initialR2T)33c9c7c281SJosh Soref burst_length_param_negotiation(int FirstBurstLength, int MaxBurstLength,
34144ba3a1SDaniel Verkamp 			       int initialR2T)
35144ba3a1SDaniel Verkamp {
36144ba3a1SDaniel Verkamp 	struct spdk_iscsi_sess sess;
37144ba3a1SDaniel Verkamp 	struct spdk_iscsi_conn conn;
38144ba3a1SDaniel Verkamp 	struct iscsi_param *params;
39144ba3a1SDaniel Verkamp 	struct iscsi_param **params_p;
40144ba3a1SDaniel Verkamp 	char data[8192];
41144ba3a1SDaniel Verkamp 	int rc;
42144ba3a1SDaniel Verkamp 	int total, len;
43144ba3a1SDaniel Verkamp 
44144ba3a1SDaniel Verkamp 	total = 0;
45144ba3a1SDaniel Verkamp 	params = NULL;
46144ba3a1SDaniel Verkamp 	params_p = &params;
47144ba3a1SDaniel Verkamp 
48144ba3a1SDaniel Verkamp 	memset(&sess, 0, sizeof(sess));
49144ba3a1SDaniel Verkamp 	memset(&conn, 0, sizeof(conn));
50144ba3a1SDaniel Verkamp 	memset(data, 0, 8192);
51144ba3a1SDaniel Verkamp 
52144ba3a1SDaniel Verkamp 	sess.ExpCmdSN = 0;
53144ba3a1SDaniel Verkamp 	sess.MaxCmdSN = 64;
54144ba3a1SDaniel Verkamp 	sess.session_type = SESSION_TYPE_NORMAL;
55144ba3a1SDaniel Verkamp 	sess.params = NULL;
56144ba3a1SDaniel Verkamp 	sess.MaxBurstLength = 65536;
57372c5e1eSShuhei Matsumoto 	sess.InitialR2T = true;
58144ba3a1SDaniel Verkamp 	sess.FirstBurstLength = SPDK_ISCSI_FIRST_BURST_LENGTH;
59144ba3a1SDaniel Verkamp 	sess.MaxOutstandingR2T = 1;
60144ba3a1SDaniel Verkamp 
61144ba3a1SDaniel Verkamp 	/* set default params */
62be05a820SShuhei Matsumoto 	rc = iscsi_sess_params_init(&sess.params);
63144ba3a1SDaniel Verkamp 	CU_ASSERT(rc == 0);
64144ba3a1SDaniel Verkamp 
65be05a820SShuhei Matsumoto 	rc = iscsi_param_set_int(sess.params, "FirstBurstLength",
66144ba3a1SDaniel Verkamp 				 sess.FirstBurstLength);
67144ba3a1SDaniel Verkamp 	CU_ASSERT(rc == 0);
68144ba3a1SDaniel Verkamp 
69be05a820SShuhei Matsumoto 	rc = iscsi_param_set_int(sess.params, "MaxBurstLength",
70144ba3a1SDaniel Verkamp 				 sess.MaxBurstLength);
71144ba3a1SDaniel Verkamp 	CU_ASSERT(rc == 0);
72144ba3a1SDaniel Verkamp 
73be05a820SShuhei Matsumoto 	rc = iscsi_param_set(sess.params, "InitialR2T",
74144ba3a1SDaniel Verkamp 			     sess.InitialR2T ? "Yes" : "No");
75144ba3a1SDaniel Verkamp 	CU_ASSERT(rc == 0);
76144ba3a1SDaniel Verkamp 
77144ba3a1SDaniel Verkamp 	conn.full_feature = 1;
78144ba3a1SDaniel Verkamp 	conn.sess = &sess;
79144ba3a1SDaniel Verkamp 	conn.MaxRecvDataSegmentLength = 65536;
80144ba3a1SDaniel Verkamp 
81be05a820SShuhei Matsumoto 	rc = iscsi_conn_params_init(&conn.params);
82144ba3a1SDaniel Verkamp 	CU_ASSERT(rc == 0);
83144ba3a1SDaniel Verkamp 
84144ba3a1SDaniel Verkamp 	/* construct the data */
85144ba3a1SDaniel Verkamp 	len = snprintf(data + total, 8192 - total, "%s=%d",
86144ba3a1SDaniel Verkamp 		       "FirstBurstLength", FirstBurstLength);
87144ba3a1SDaniel Verkamp 	total += len + 1;
88144ba3a1SDaniel Verkamp 
89144ba3a1SDaniel Verkamp 	len = snprintf(data + total, 8192 - total, "%s=%d",
90144ba3a1SDaniel Verkamp 		       "MaxBurstLength", MaxBurstLength);
91144ba3a1SDaniel Verkamp 	total += len + 1;
92144ba3a1SDaniel Verkamp 
93144ba3a1SDaniel Verkamp 	len = snprintf(data + total, 8192 - total, "%s=%d",
94144ba3a1SDaniel Verkamp 		       "InitialR2T", initialR2T);
95144ba3a1SDaniel Verkamp 	total += len + 1;
96144ba3a1SDaniel Verkamp 
97144ba3a1SDaniel Verkamp 	/* add one extra NUL byte at the end to match real iSCSI params */
98144ba3a1SDaniel Verkamp 	total++;
99144ba3a1SDaniel Verkamp 
100144ba3a1SDaniel Verkamp 	/* store incoming parameters */
101be05a820SShuhei Matsumoto 	rc = iscsi_parse_params(params_p, data, total, false, NULL);
102144ba3a1SDaniel Verkamp 	CU_ASSERT(rc == 0);
103144ba3a1SDaniel Verkamp 
104144ba3a1SDaniel Verkamp 	/* negotiate parameters */
105be05a820SShuhei Matsumoto 	rc = iscsi_negotiate_params(&conn, params_p,
106144ba3a1SDaniel Verkamp 				    data, 8192, rc);
107144ba3a1SDaniel Verkamp 	CU_ASSERT(rc > 0);
108144ba3a1SDaniel Verkamp 
109be05a820SShuhei Matsumoto 	rc = iscsi_copy_param2var(&conn);
110144ba3a1SDaniel Verkamp 	CU_ASSERT(rc == 0);
111144ba3a1SDaniel Verkamp 	CU_ASSERT(conn.sess->FirstBurstLength <= SPDK_ISCSI_FIRST_BURST_LENGTH);
112144ba3a1SDaniel Verkamp 	CU_ASSERT(conn.sess->FirstBurstLength <= conn.sess->MaxBurstLength);
113144ba3a1SDaniel Verkamp 	CU_ASSERT(conn.sess->MaxBurstLength <= SPDK_ISCSI_MAX_BURST_LENGTH);
114144ba3a1SDaniel Verkamp 	CU_ASSERT(conn.sess->MaxOutstandingR2T == 1);
115144ba3a1SDaniel Verkamp 
116be05a820SShuhei Matsumoto 	iscsi_param_free(sess.params);
117be05a820SShuhei Matsumoto 	iscsi_param_free(conn.params);
118be05a820SShuhei Matsumoto 	iscsi_param_free(*params_p);
119144ba3a1SDaniel Verkamp }
120144ba3a1SDaniel Verkamp 
121144ba3a1SDaniel Verkamp static void
param_negotiation_test(void)122144ba3a1SDaniel Verkamp param_negotiation_test(void)
123144ba3a1SDaniel Verkamp {
124c9c7c281SJosh Soref 	burst_length_param_negotiation(8192, 16384, 0);
125c9c7c281SJosh Soref 	burst_length_param_negotiation(8192, 16384, 1);
126c9c7c281SJosh Soref 	burst_length_param_negotiation(8192, 1024, 1);
127c9c7c281SJosh Soref 	burst_length_param_negotiation(8192, 1024, 0);
128c9c7c281SJosh Soref 	burst_length_param_negotiation(512, 1024, 1);
129c9c7c281SJosh Soref 	burst_length_param_negotiation(512, 1024, 0);
130144ba3a1SDaniel Verkamp }
131144ba3a1SDaniel Verkamp 
132144ba3a1SDaniel Verkamp static void
list_negotiation_test(void)133144ba3a1SDaniel Verkamp list_negotiation_test(void)
134144ba3a1SDaniel Verkamp {
135144ba3a1SDaniel Verkamp 	int add_param_value = 0;
136144ba3a1SDaniel Verkamp 	struct iscsi_param param = {};
137144ba3a1SDaniel Verkamp 	char *new_val;
138144ba3a1SDaniel Verkamp 	char valid_list_buf[1024];
139144ba3a1SDaniel Verkamp 	char in_val_buf[1024];
140144ba3a1SDaniel Verkamp 
141144ba3a1SDaniel Verkamp #define TEST_LIST(valid_list, in_val, expected_result) \
142144ba3a1SDaniel Verkamp 	do { \
143144ba3a1SDaniel Verkamp 		snprintf(valid_list_buf, sizeof(valid_list_buf), "%s", valid_list); \
144144ba3a1SDaniel Verkamp 		snprintf(in_val_buf, sizeof(in_val_buf), "%s", in_val); \
145893e02a5SShuhei Matsumoto 		new_val = iscsi_negotiate_param_list(&add_param_value, &param, valid_list_buf, in_val_buf, NULL); \
146144ba3a1SDaniel Verkamp 		if (expected_result) { \
147144ba3a1SDaniel Verkamp 			SPDK_CU_ASSERT_FATAL(new_val != NULL); \
148144ba3a1SDaniel Verkamp 			CU_ASSERT_STRING_EQUAL(new_val, expected_result); \
149144ba3a1SDaniel Verkamp 		} \
150144ba3a1SDaniel Verkamp 	} while (0)
151144ba3a1SDaniel Verkamp 
152144ba3a1SDaniel Verkamp 	TEST_LIST("None", "None", "None");
153144ba3a1SDaniel Verkamp 	TEST_LIST("CHAP,None", "None", "None");
154144ba3a1SDaniel Verkamp 	TEST_LIST("CHAP,None", "CHAP", "CHAP");
155144ba3a1SDaniel Verkamp 	TEST_LIST("KRB5,SRP,CHAP,None", "SRP,CHAP,None", "SRP");
156144ba3a1SDaniel Verkamp 	TEST_LIST("KRB5,SRP,CHAP,None", "CHAP,SRP,None", "CHAP");
157144ba3a1SDaniel Verkamp 	TEST_LIST("KRB5,SRP,CHAP,None", "SPKM1,SRP,CHAP,None", "SRP");
158144ba3a1SDaniel Verkamp 	TEST_LIST("KRB5,SRP,None", "CHAP,None", "None");
159144ba3a1SDaniel Verkamp }
160144ba3a1SDaniel Verkamp 
161144ba3a1SDaniel Verkamp #define PARSE(strconst, partial_enabled, partial_text) \
162144ba3a1SDaniel Verkamp 	data = strconst; \
1637d1db86fSJim Harris 	len = sizeof(strconst) - 1; \
164be05a820SShuhei Matsumoto 	rc = iscsi_parse_params(&params, data, len, partial_enabled, partial_text)
165144ba3a1SDaniel Verkamp 
166144ba3a1SDaniel Verkamp #define EXPECT_VAL(key, expected_value) \
167144ba3a1SDaniel Verkamp 	{ \
168be05a820SShuhei Matsumoto 		const char *val = iscsi_param_get_val(params, key); \
169144ba3a1SDaniel Verkamp 		CU_ASSERT(val != NULL); \
170144ba3a1SDaniel Verkamp 		if (val != NULL) { \
171144ba3a1SDaniel Verkamp 			CU_ASSERT(strcmp(val, expected_value) == 0); \
172144ba3a1SDaniel Verkamp 		} \
173144ba3a1SDaniel Verkamp 	}
174144ba3a1SDaniel Verkamp 
175144ba3a1SDaniel Verkamp #define EXPECT_NULL(key) \
176be05a820SShuhei Matsumoto 	CU_ASSERT(iscsi_param_get_val(params, key) == NULL)
177144ba3a1SDaniel Verkamp 
178144ba3a1SDaniel Verkamp static void
parse_valid_test(void)179144ba3a1SDaniel Verkamp parse_valid_test(void)
180144ba3a1SDaniel Verkamp {
181144ba3a1SDaniel Verkamp 	struct iscsi_param *params = NULL;
182144ba3a1SDaniel Verkamp 	int rc;
183144ba3a1SDaniel Verkamp 	char *data;
184144ba3a1SDaniel Verkamp 	int len;
185144ba3a1SDaniel Verkamp 	char *partial_parameter = NULL;
186144ba3a1SDaniel Verkamp 
187144ba3a1SDaniel Verkamp 	/* simple test with a single key=value */
188144ba3a1SDaniel Verkamp 	PARSE("Abc=def\0", false, NULL);
189144ba3a1SDaniel Verkamp 	CU_ASSERT(rc == 0);
190144ba3a1SDaniel Verkamp 	EXPECT_VAL("Abc", "def");
191144ba3a1SDaniel Verkamp 
192144ba3a1SDaniel Verkamp 	/* multiple key=value pairs */
193144ba3a1SDaniel Verkamp 	PARSE("Aaa=bbbbbb\0Xyz=test\0", false, NULL);
194144ba3a1SDaniel Verkamp 	CU_ASSERT(rc == 0);
195144ba3a1SDaniel Verkamp 	EXPECT_VAL("Aaa", "bbbbbb");
196144ba3a1SDaniel Verkamp 	EXPECT_VAL("Xyz", "test");
197144ba3a1SDaniel Verkamp 
198144ba3a1SDaniel Verkamp 	/* value with embedded '=' */
199144ba3a1SDaniel Verkamp 	PARSE("A=b=c\0", false, NULL);
200144ba3a1SDaniel Verkamp 	CU_ASSERT(rc == 0);
201144ba3a1SDaniel Verkamp 	EXPECT_VAL("A", "b=c");
202144ba3a1SDaniel Verkamp 
203144ba3a1SDaniel Verkamp 	/* CHAP_C=AAAA.... with value length 8192 */
204144ba3a1SDaniel Verkamp 	len = strlen("CHAP_C=") + ISCSI_TEXT_MAX_VAL_LEN + 1/* null terminators */;
205144ba3a1SDaniel Verkamp 	data = malloc(len);
206144ba3a1SDaniel Verkamp 	SPDK_CU_ASSERT_FATAL(data != NULL);
207144ba3a1SDaniel Verkamp 	memset(data, 'A', len);
208474fcf64SJim Harris 	memcpy(data, "CHAP_C", 6);
209144ba3a1SDaniel Verkamp 	data[6] = '=';
210144ba3a1SDaniel Verkamp 	data[len - 1] = '\0';
211be05a820SShuhei Matsumoto 	rc = iscsi_parse_params(&params, data, len, false, NULL);
212144ba3a1SDaniel Verkamp 	CU_ASSERT(rc == 0);
213144ba3a1SDaniel Verkamp 	free(data);
214144ba3a1SDaniel Verkamp 
215144ba3a1SDaniel Verkamp 	/* partial parameter: value is partial */
216144ba3a1SDaniel Verkamp 	PARSE("C=AAA\0D=B", true, &partial_parameter);
217144ba3a1SDaniel Verkamp 	SPDK_CU_ASSERT_FATAL(partial_parameter != NULL);
218144ba3a1SDaniel Verkamp 	CU_ASSERT_STRING_EQUAL(partial_parameter, "D=B");
219144ba3a1SDaniel Verkamp 	CU_ASSERT(rc == 0);
220144ba3a1SDaniel Verkamp 	EXPECT_VAL("C", "AAA");
221144ba3a1SDaniel Verkamp 	EXPECT_NULL("D");
222144ba3a1SDaniel Verkamp 	PARSE("XXXX\0E=UUUU\0", false, &partial_parameter);
223144ba3a1SDaniel Verkamp 	CU_ASSERT(rc == 0);
224144ba3a1SDaniel Verkamp 	EXPECT_VAL("D", "BXXXX");
225144ba3a1SDaniel Verkamp 	EXPECT_VAL("E", "UUUU");
226144ba3a1SDaniel Verkamp 	CU_ASSERT_PTR_NULL(partial_parameter);
227144ba3a1SDaniel Verkamp 
228144ba3a1SDaniel Verkamp 	/* partial parameter: key is partial */
229144ba3a1SDaniel Verkamp 	PARSE("IAMAFAK", true, &partial_parameter);
230144ba3a1SDaniel Verkamp 	CU_ASSERT_STRING_EQUAL(partial_parameter, "IAMAFAK");
231144ba3a1SDaniel Verkamp 	CU_ASSERT(rc == 0);
232144ba3a1SDaniel Verkamp 	EXPECT_NULL("IAMAFAK");
233144ba3a1SDaniel Verkamp 	PARSE("EDKEY=TTTT\0F=IIII", false, &partial_parameter);
234144ba3a1SDaniel Verkamp 	CU_ASSERT(rc == 0);
235144ba3a1SDaniel Verkamp 	EXPECT_VAL("IAMAFAKEDKEY", "TTTT");
236144ba3a1SDaniel Verkamp 	EXPECT_VAL("F", "IIII");
237144ba3a1SDaniel Verkamp 	CU_ASSERT_PTR_NULL(partial_parameter);
238144ba3a1SDaniel Verkamp 
239f3fd56fcSTomasz Zawadzki 	/* partial parameter: NULL data */
240f3fd56fcSTomasz Zawadzki 	/* It is technically allowed to have a TEXT PDU with no data, yet
241f3fd56fcSTomasz Zawadzki 	 * CONTINUE bit is enabled - make sure we handle that case correctly.
242f3fd56fcSTomasz Zawadzki 	 */
243f3fd56fcSTomasz Zawadzki 	rc = iscsi_parse_params(&params, NULL, 0, true, &partial_parameter);
244f3fd56fcSTomasz Zawadzki 	CU_ASSERT(rc == 0);
245f3fd56fcSTomasz Zawadzki 	CU_ASSERT_PTR_NULL(partial_parameter);
246f3fd56fcSTomasz Zawadzki 
247144ba3a1SDaniel Verkamp 	/* Second partial parameter is the only parameter */
248144ba3a1SDaniel Verkamp 	PARSE("OOOO", true, &partial_parameter);
249144ba3a1SDaniel Verkamp 	CU_ASSERT_STRING_EQUAL(partial_parameter, "OOOO");
250144ba3a1SDaniel Verkamp 	CU_ASSERT(rc == 0);
251144ba3a1SDaniel Verkamp 	EXPECT_NULL("OOOO");
252144ba3a1SDaniel Verkamp 	PARSE("LL=MMMM", false, &partial_parameter);
253144ba3a1SDaniel Verkamp 	CU_ASSERT(rc == 0);
254144ba3a1SDaniel Verkamp 	EXPECT_VAL("OOOOLL", "MMMM");
255144ba3a1SDaniel Verkamp 	CU_ASSERT_PTR_NULL(partial_parameter);
256144ba3a1SDaniel Verkamp 
2577d1db86fSJim Harris 	partial_parameter = NULL;
2587d1db86fSJim Harris 	data = "PartialKey=";
2597d1db86fSJim Harris 	len = 7;
260be05a820SShuhei Matsumoto 	rc = iscsi_parse_params(&params, data, len, true, &partial_parameter);
2617d1db86fSJim Harris 	CU_ASSERT(rc == 0);
2627d1db86fSJim Harris 	CU_ASSERT_STRING_EQUAL(partial_parameter, "Partial");
2637d1db86fSJim Harris 	EXPECT_NULL("PartialKey");
2647d1db86fSJim Harris 	PARSE("Key=Value", false, &partial_parameter);
2657d1db86fSJim Harris 	CU_ASSERT(rc == 0);
2667d1db86fSJim Harris 	EXPECT_VAL("PartialKey", "Value");
2677d1db86fSJim Harris 	CU_ASSERT_PTR_NULL(partial_parameter);
2687d1db86fSJim Harris 
269be05a820SShuhei Matsumoto 	iscsi_param_free(params);
270144ba3a1SDaniel Verkamp }
271144ba3a1SDaniel Verkamp 
272144ba3a1SDaniel Verkamp static void
parse_invalid_test(void)273144ba3a1SDaniel Verkamp parse_invalid_test(void)
274144ba3a1SDaniel Verkamp {
275144ba3a1SDaniel Verkamp 	struct iscsi_param *params = NULL;
276144ba3a1SDaniel Verkamp 	int rc;
277144ba3a1SDaniel Verkamp 	char *data;
278144ba3a1SDaniel Verkamp 	int len;
279144ba3a1SDaniel Verkamp 
280144ba3a1SDaniel Verkamp 	/* key without '=' */
281144ba3a1SDaniel Verkamp 	PARSE("Abc\0", false, NULL);
282144ba3a1SDaniel Verkamp 	CU_ASSERT(rc != 0);
283144ba3a1SDaniel Verkamp 	EXPECT_NULL("Abc");
284144ba3a1SDaniel Verkamp 
285144ba3a1SDaniel Verkamp 	/* multiple key=value pairs, one missing '=' */
286144ba3a1SDaniel Verkamp 	PARSE("Abc=def\0Xyz\0Www=test\0", false, NULL);
287144ba3a1SDaniel Verkamp 	CU_ASSERT(rc != 0);
288144ba3a1SDaniel Verkamp 	EXPECT_VAL("Abc", "def");
289144ba3a1SDaniel Verkamp 	EXPECT_NULL("Xyz");
290144ba3a1SDaniel Verkamp 	EXPECT_NULL("Www");
291144ba3a1SDaniel Verkamp 
292144ba3a1SDaniel Verkamp 	/* empty key */
293144ba3a1SDaniel Verkamp 	PARSE("=abcdef", false, NULL);
294144ba3a1SDaniel Verkamp 	CU_ASSERT(rc != 0);
295144ba3a1SDaniel Verkamp 	EXPECT_NULL("");
296144ba3a1SDaniel Verkamp 
297144ba3a1SDaniel Verkamp 	/* CHAP_C=AAAA.... with value length 8192 + 1 */
298144ba3a1SDaniel Verkamp 	len = strlen("CHAP_C=") + ISCSI_TEXT_MAX_VAL_LEN + 1 /* max value len + 1 */ +
299144ba3a1SDaniel Verkamp 	      1 /* null terminators */;
300144ba3a1SDaniel Verkamp 	data = malloc(len);
301144ba3a1SDaniel Verkamp 	SPDK_CU_ASSERT_FATAL(data != NULL);
302144ba3a1SDaniel Verkamp 	memset(data, 'A', len);
303474fcf64SJim Harris 	memcpy(data, "CHAP_C", 6);
304144ba3a1SDaniel Verkamp 	data[6] = '=';
305144ba3a1SDaniel Verkamp 	data[len - 1] = '\0';
306be05a820SShuhei Matsumoto 	rc = iscsi_parse_params(&params, data, len, false, NULL);
307144ba3a1SDaniel Verkamp 	free(data);
308144ba3a1SDaniel Verkamp 	CU_ASSERT(rc != 0);
309144ba3a1SDaniel Verkamp 	EXPECT_NULL("CHAP_C");
310144ba3a1SDaniel Verkamp 
311144ba3a1SDaniel Verkamp 	/* Test simple value, length of value bigger than 255 */
312144ba3a1SDaniel Verkamp 	len = strlen("A=") + ISCSI_TEXT_MAX_SIMPLE_VAL_LEN + 1 /* max simple value len + 1 */ +
313144ba3a1SDaniel Verkamp 	      1 /* null terminators */;
314144ba3a1SDaniel Verkamp 	data = malloc(len);
315144ba3a1SDaniel Verkamp 	SPDK_CU_ASSERT_FATAL(data != NULL);
316144ba3a1SDaniel Verkamp 	memset(data, 'A', len);
317144ba3a1SDaniel Verkamp 	data[1] = '=';
318144ba3a1SDaniel Verkamp 	data[len - 1] = '\0';
319be05a820SShuhei Matsumoto 	rc = iscsi_parse_params(&params, data, len, false, NULL);
320144ba3a1SDaniel Verkamp 	free(data);
321144ba3a1SDaniel Verkamp 	CU_ASSERT(rc != 0);
322144ba3a1SDaniel Verkamp 	EXPECT_NULL("A");
323144ba3a1SDaniel Verkamp 
324144ba3a1SDaniel Verkamp 	/* key length bigger than 63 */
325144ba3a1SDaniel Verkamp 	len = ISCSI_TEXT_MAX_KEY_LEN + 1 /* max key length + 1 */ + 1 /* = */ + 1 /* A */ +
326144ba3a1SDaniel Verkamp 	      1 /* null terminators */;
327144ba3a1SDaniel Verkamp 	data = malloc(len);
328144ba3a1SDaniel Verkamp 	SPDK_CU_ASSERT_FATAL(data != NULL);
329144ba3a1SDaniel Verkamp 	memset(data, 'A', len);
330144ba3a1SDaniel Verkamp 	data[64] = '=';
331144ba3a1SDaniel Verkamp 	data[len - 1] = '\0';
332be05a820SShuhei Matsumoto 	rc = iscsi_parse_params(&params, data, len, false, NULL);
333144ba3a1SDaniel Verkamp 	free(data);
334144ba3a1SDaniel Verkamp 	CU_ASSERT(rc != 0);
335144ba3a1SDaniel Verkamp 	EXPECT_NULL("A");
336144ba3a1SDaniel Verkamp 
337144ba3a1SDaniel Verkamp 	/* duplicated key */
338144ba3a1SDaniel Verkamp 	PARSE("B=BB", false, NULL);
339144ba3a1SDaniel Verkamp 	CU_ASSERT(rc == 0);
340144ba3a1SDaniel Verkamp 	PARSE("B=BBBB", false, NULL);
341144ba3a1SDaniel Verkamp 	CU_ASSERT(rc != 0);
342144ba3a1SDaniel Verkamp 	EXPECT_VAL("B", "BB");
343144ba3a1SDaniel Verkamp 
344a95f3413SJim Harris 	/* Test where data buffer has non-NULL characters past the end of
345a95f3413SJim Harris 	 * the valid data region.  This can happen with SPDK iSCSI target,
346a95f3413SJim Harris 	 * since data buffers are reused and we do not zero the data buffers
347a95f3413SJim Harris 	 * after they are freed since it would be too expensive.  Added as
348a95f3413SJim Harris 	 * part of fixing an intermittent Calsoft failure that triggered this
349a95f3413SJim Harris 	 * bug.
350a95f3413SJim Harris 	 */
351a95f3413SJim Harris 	data = "MaxRecvDataSegmentLength=81928";
352a95f3413SJim Harris 	len = strlen(data) - 1;
353be05a820SShuhei Matsumoto 	rc = iscsi_parse_params(&params, data, len, false, NULL);
354a95f3413SJim Harris 	EXPECT_VAL("MaxRecvDataSegmentLength", "8192");
355a95f3413SJim Harris 	CU_ASSERT(rc == 0);
356be05a820SShuhei Matsumoto 	iscsi_param_free(params);
357144ba3a1SDaniel Verkamp }
358144ba3a1SDaniel Verkamp 
359144ba3a1SDaniel Verkamp int
main(int argc,char ** argv)360144ba3a1SDaniel Verkamp main(int argc, char **argv)
361144ba3a1SDaniel Verkamp {
362144ba3a1SDaniel Verkamp 	CU_pSuite	suite = NULL;
363144ba3a1SDaniel Verkamp 	unsigned int	num_failures;
364144ba3a1SDaniel Verkamp 
36578b696bcSVitaliy Mysak 	CU_initialize_registry();
366144ba3a1SDaniel Verkamp 
367144ba3a1SDaniel Verkamp 	suite = CU_add_suite("iscsi_suite", NULL, NULL);
368144ba3a1SDaniel Verkamp 
369dcf0ca15SVitaliy Mysak 	CU_ADD_TEST(suite, param_negotiation_test);
370dcf0ca15SVitaliy Mysak 	CU_ADD_TEST(suite, list_negotiation_test);
371dcf0ca15SVitaliy Mysak 	CU_ADD_TEST(suite, parse_valid_test);
372dcf0ca15SVitaliy Mysak 	CU_ADD_TEST(suite, parse_invalid_test);
373144ba3a1SDaniel Verkamp 
374*ea941caeSKonrad Sztyber 	num_failures = spdk_ut_run_tests(argc, argv, NULL);
375144ba3a1SDaniel Verkamp 	CU_cleanup_registry();
376144ba3a1SDaniel Verkamp 	return num_failures;
377144ba3a1SDaniel Verkamp }
378