Skip to content

Commit 8b4b6d6

Browse files
committed
Add tests for nbd-client argument parsing
1 parent 31e30a8 commit 8b4b6d6

2 files changed

Lines changed: 285 additions & 2 deletions

File tree

tests/code/Makefile.am

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
TESTS = clientacl dup mask size trim
2-
check_PROGRAMS = clientacl dup mask size trim
1+
TESTS = clientacl dup mask size trim args_test
2+
check_PROGRAMS = clientacl dup mask size trim args_test
33
EXTRA_DIST = macro.h
44

55
AM_CFLAGS = @CFLAGS@ @GLIB_CFLAGS@
@@ -19,3 +19,7 @@ size_LDADD = $(top_builddir)/libnbdsrv.la $(top_builddir)/libcliserv.la @GLIB_LI
1919

2020
trim_SOURCES = trim.c
2121
trim_LDADD = $(top_builddir)/libnbdsrv.la $(top_builddir)/libcliserv.la @GLIB_LIBS@
22+
23+
args_test_SOURCES = args_test.c ../../args.c
24+
args_test_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/tests/code
25+
args_test_LDADD = @GLIB_LIBS@

tests/code/args_test.c

Lines changed: 279 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,279 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <string.h>
4+
#include <assert.h>
5+
#include "../../args.h"
6+
7+
// Test helper functions
8+
static int test_count = 0;
9+
static int test_passed = 0;
10+
11+
#define TEST_ASSERT(condition, message) \
12+
do { \
13+
test_count++; \
14+
if (condition) { \
15+
test_passed++; \
16+
printf("PASS: %s\n", message); \
17+
} else { \
18+
printf("FAIL: %s\n", message); \
19+
} \
20+
} while(0)
21+
22+
#define TEST_ASSERT_STR_EQ(actual, expected, message) \
23+
do { \
24+
test_count++; \
25+
if (strcmp(actual, expected) == 0) { \
26+
test_passed++; \
27+
printf("PASS: %s\n", message); \
28+
} else { \
29+
printf("FAIL: %s (expected '%s', got '%s')\n", message, expected, actual); \
30+
} \
31+
} while(0)
32+
33+
void test_nbd0_argument() {
34+
printf("\n=== Testing nbd-client nbd0 argument parsing ===\n");
35+
36+
CLIENT client;
37+
init_client(&client);
38+
39+
char *argv[] = {"nbd-client", "nbd0"};
40+
int argc = sizeof(argv) / sizeof(argv[0]);
41+
42+
parse_result_t result = parse_nbd_client_args(argc, argv, &client);
43+
44+
// The key test: nbd0 should be recognized as a device
45+
TEST_ASSERT_STR_EQ(client.hostn, "nbd0", "nbd0 should be set as hostn");
46+
TEST_ASSERT_STR_EQ(client.dev, "nbd0", "nbd0 should also be set as dev (nbdtab logic)");
47+
TEST_ASSERT(!result.should_exit, "Should not exit for nbd0 argument");
48+
TEST_ASSERT(!result.check_conn, "Should not be check_conn");
49+
TEST_ASSERT(!result.need_disconnect, "Should not need disconnect");
50+
TEST_ASSERT(!result.list_exports, "Should not list exports");
51+
52+
free_client_fields(&client);
53+
}
54+
55+
void test_dev_nbd0_argument() {
56+
printf("\n=== Testing nbd-client /dev/nbd0 argument parsing ===\n");
57+
58+
CLIENT client;
59+
init_client(&client);
60+
61+
char *argv[] = {"nbd-client", "/dev/nbd0"};
62+
int argc = sizeof(argv) / sizeof(argv[0]);
63+
64+
parse_result_t result = parse_nbd_client_args(argc, argv, &client);
65+
66+
// The key test: /dev/nbd0 should be recognized as a device
67+
TEST_ASSERT_STR_EQ(client.hostn, "/dev/nbd0", "/dev/nbd0 should be set as hostn");
68+
TEST_ASSERT_STR_EQ(client.dev, "/dev/nbd0", "/dev/nbd0 should also be set as dev (nbdtab logic)");
69+
TEST_ASSERT(!result.should_exit, "Should not exit for /dev/nbd0 argument");
70+
TEST_ASSERT(!result.check_conn, "Should not be check_conn");
71+
TEST_ASSERT(!result.need_disconnect, "Should not need disconnect");
72+
TEST_ASSERT(!result.list_exports, "Should not list exports");
73+
74+
free_client_fields(&client);
75+
}
76+
77+
void test_normal_connection() {
78+
printf("\n=== Testing normal connection arguments ===\n");
79+
80+
CLIENT client;
81+
init_client(&client);
82+
83+
char *argv[] = {"nbd-client", "localhost", "10809", "/dev/nbd0"};
84+
int argc = sizeof(argv) / sizeof(argv[0]);
85+
86+
parse_result_t result = parse_nbd_client_args(argc, argv, &client);
87+
88+
TEST_ASSERT_STR_EQ(client.hostn, "localhost", "Host should be localhost");
89+
TEST_ASSERT_STR_EQ(client.port, "10809", "Port should be 10809");
90+
TEST_ASSERT_STR_EQ(client.dev, "/dev/nbd0", "Device should be /dev/nbd0");
91+
TEST_ASSERT(!result.should_exit, "Should not exit for normal connection");
92+
93+
free_client_fields(&client);
94+
}
95+
96+
void test_with_options() {
97+
printf("\n=== Testing arguments with options ===\n");
98+
99+
CLIENT client;
100+
init_client(&client);
101+
102+
char *argv[] = {"nbd-client", "-N", "export", "-b", "1024", "-timeout", "30", "localhost", "/dev/nbd0"};
103+
int argc = sizeof(argv) / sizeof(argv[0]);
104+
105+
parse_result_t result = parse_nbd_client_args(argc, argv, &client);
106+
107+
TEST_ASSERT_STR_EQ(client.name, "export", "Export name should be set");
108+
TEST_ASSERT(client.bs == 1024, "Block size should be 1024");
109+
TEST_ASSERT(client.timeout == 30, "Timeout should be 30");
110+
TEST_ASSERT_STR_EQ(client.hostn, "localhost", "Host should be localhost");
111+
TEST_ASSERT_STR_EQ(client.dev, "/dev/nbd0", "Device should be /dev/nbd0");
112+
113+
free_client_fields(&client);
114+
}
115+
116+
void test_check_connection() {
117+
printf("\n=== Testing check connection option ===\n");
118+
119+
CLIENT client;
120+
init_client(&client);
121+
122+
char *argv[] = {"nbd-client", "-c", "/dev/nbd0"};
123+
int argc = sizeof(argv) / sizeof(argv[0]);
124+
125+
parse_result_t result = parse_nbd_client_args(argc, argv, &client);
126+
127+
TEST_ASSERT(result.check_conn, "Should set check_conn flag");
128+
TEST_ASSERT_STR_EQ(result.check_device, "/dev/nbd0", "Check device should be /dev/nbd0");
129+
130+
free_client_fields(&client);
131+
}
132+
133+
void test_disconnect() {
134+
printf("\n=== Testing disconnect option ===\n");
135+
136+
CLIENT client;
137+
init_client(&client);
138+
139+
char *argv[] = {"nbd-client", "-d", "/dev/nbd0"};
140+
int argc = sizeof(argv) / sizeof(argv[0]);
141+
142+
parse_result_t result = parse_nbd_client_args(argc, argv, &client);
143+
144+
TEST_ASSERT(result.need_disconnect, "Should set need_disconnect flag");
145+
TEST_ASSERT_STR_EQ(client.dev, "/dev/nbd0", "Device should be /dev/nbd0");
146+
147+
free_client_fields(&client);
148+
}
149+
150+
void test_list_exports() {
151+
printf("\n=== Testing list exports option ===\n");
152+
153+
CLIENT client;
154+
init_client(&client);
155+
156+
char *argv[] = {"nbd-client", "-l", "localhost"};
157+
int argc = sizeof(argv) / sizeof(argv[0]);
158+
159+
parse_result_t result = parse_nbd_client_args(argc, argv, &client);
160+
161+
TEST_ASSERT(result.list_exports, "Should set list_exports flag");
162+
TEST_ASSERT_STR_EQ(client.hostn, "localhost", "Host should be localhost");
163+
TEST_ASSERT_STR_EQ(client.dev, "", "Device should be empty string for list");
164+
165+
free_client_fields(&client);
166+
}
167+
168+
void test_version() {
169+
printf("\n=== Testing version option ===\n");
170+
171+
CLIENT client;
172+
init_client(&client);
173+
174+
char *argv[] = {"nbd-client", "-V"};
175+
int argc = sizeof(argv) / sizeof(argv[0]);
176+
177+
parse_result_t result = parse_nbd_client_args(argc, argv, &client);
178+
179+
TEST_ASSERT(result.show_version, "Should set show_version flag");
180+
181+
free_client_fields(&client);
182+
}
183+
184+
void test_netlink_options() {
185+
printf("\n=== Testing HAVE_NETLINK conditional options ===\n");
186+
187+
CLIENT client;
188+
init_client(&client);
189+
190+
// Test -i (identifier) option - should work when HAVE_NETLINK is defined
191+
char *argv1[] = {"nbd-client", "-i", "test_id", "localhost", "/dev/nbd0"};
192+
int argc1 = sizeof(argv1) / sizeof(argv1[0]);
193+
194+
parse_result_t result1 = parse_nbd_client_args(argc1, argv1, &client);
195+
196+
#ifdef HAVE_NETLINK
197+
TEST_ASSERT(!result1.should_exit, "Should not exit for -i option when HAVE_NETLINK");
198+
TEST_ASSERT_STR_EQ(result1.identifier, "test_id", "Identifier should be set");
199+
#else
200+
TEST_ASSERT(result1.should_exit, "Should exit for -i option when HAVE_NETLINK is not defined");
201+
TEST_ASSERT(result1.exit_code == 1, "Should have exit code 1 when HAVE_NETLINK is not defined");
202+
#endif
203+
204+
free_client_fields(&client);
205+
206+
// Test -L (nonetlink) option - should work when HAVE_NETLINK is defined
207+
init_client(&client);
208+
char *argv2[] = {"nbd-client", "-L", "-c", "/dev/nbd0"};
209+
int argc2 = sizeof(argv2) / sizeof(argv2[0]);
210+
211+
parse_result_t result2 = parse_nbd_client_args(argc2, argv2, &client);
212+
213+
#ifdef HAVE_NETLINK
214+
TEST_ASSERT(!result2.should_exit, "Should not exit for -L option when HAVE_NETLINK");
215+
TEST_ASSERT(result2.nonetlink, "Nonetlink flag should be set");
216+
#else
217+
TEST_ASSERT(result2.should_exit, "Should exit for -L option when HAVE_NETLINK is not defined");
218+
TEST_ASSERT(result2.exit_code == 1, "Should have exit code 1 when HAVE_NETLINK is not defined");
219+
#endif
220+
221+
free_client_fields(&client);
222+
}
223+
224+
void test_error_cases() {
225+
printf("\n=== Testing error cases ===\n");
226+
227+
CLIENT client;
228+
229+
// Test invalid blocksize
230+
init_client(&client);
231+
char *argv1[] = {"nbd-client", "-b", "513", "localhost", "/dev/nbd0"};
232+
parse_result_t result1 = parse_nbd_client_args(sizeof(argv1)/sizeof(argv1[0]), argv1, &client);
233+
TEST_ASSERT(result1.should_exit, "Should exit for invalid blocksize");
234+
TEST_ASSERT(result1.exit_code == 1, "Should have exit code 1");
235+
free_client_fields(&client);
236+
237+
// Test too many arguments
238+
init_client(&client);
239+
char *argv2[] = {"nbd-client", "localhost", "10809", "/dev/nbd0", "extra"};
240+
parse_result_t result2 = parse_nbd_client_args(sizeof(argv2)/sizeof(argv2[0]), argv2, &client);
241+
TEST_ASSERT(result2.should_exit, "Should exit for too many arguments");
242+
free_client_fields(&client);
243+
244+
// Test no arguments
245+
init_client(&client);
246+
char *argv3[] = {"nbd-client"};
247+
parse_result_t result3 = parse_nbd_client_args(sizeof(argv3)/sizeof(argv3[0]), argv3, &client);
248+
TEST_ASSERT(result3.should_exit, "Should exit for no arguments");
249+
free_client_fields(&client);
250+
}
251+
252+
int main() {
253+
printf("=== NBD Client Argument Parsing Tests ===\n");
254+
printf("Testing the refactored argument parsing functionality\n");
255+
256+
// Run all tests
257+
test_nbd0_argument();
258+
test_dev_nbd0_argument();
259+
test_normal_connection();
260+
test_with_options();
261+
test_check_connection();
262+
test_disconnect();
263+
test_list_exports();
264+
test_version();
265+
test_netlink_options();
266+
test_error_cases();
267+
268+
// Print summary
269+
printf("\n=== Test Summary ===\n");
270+
printf("Tests passed: %d/%d\n", test_passed, test_count);
271+
272+
if (test_passed == test_count) {
273+
printf("All tests PASSED!\n");
274+
return 0;
275+
} else {
276+
printf("Some tests FAILED!\n");
277+
return 1;
278+
}
279+
}

0 commit comments

Comments
 (0)