FreeRDP
Loading...
Searching...
No Matches
TestClientCmdLine.c
1#include <freerdp/client.h>
2#include <freerdp/client/cmdline.h>
3#include <freerdp/settings.h>
4#include <winpr/cmdline.h>
5#include <winpr/spec.h>
6#include <winpr/strlst.h>
7#include <winpr/collections.h>
8
9typedef BOOL (*validate_settings_pr)(rdpSettings* settings);
10typedef void (*setup_settings_pr)(rdpSettings* settings);
11
12#define printref() printf("%s:%d: in function %-40s:", __FILE__, __LINE__, __func__)
13
14#define TEST_ERROR(format, ...) \
15 do \
16 { \
17 (void)fprintf(stderr, format, ##__VA_ARGS__); \
18 printref(); \
19 (void)printf(format, ##__VA_ARGS__); \
20 (void)fflush(stdout); \
21 } while (0)
22
23#define TEST_FAILURE(format, ...) \
24 do \
25 { \
26 printref(); \
27 (void)printf(" FAILURE "); \
28 (void)printf(format, ##__VA_ARGS__); \
29 (void)fflush(stdout); \
30 } while (0)
31
32static void print_test_title(int argc, char** argv)
33{
34 printf("Running test:");
35
36 for (int i = 0; i < argc; i++)
37 {
38 printf(" %s", argv[i]);
39 }
40
41 printf("\n");
42}
43
44static inline BOOL testcase(const char* name, char** argv, size_t argc, int expected_return,
45 validate_settings_pr validate_settings,
46 setup_settings_pr setup_settings)
47{
48 int status = 0;
49 BOOL valid_settings = TRUE;
50 rdpSettings* settings = freerdp_settings_new(0);
51
52 WINPR_ASSERT(argc <= INT_MAX);
53
54 print_test_title((int)argc, argv);
55
56 if (!settings)
57 {
58 TEST_ERROR("Test %s could not allocate settings!\n", name);
59 return FALSE;
60 }
61
62 if (setup_settings)
63 setup_settings(settings);
64
65 status = freerdp_client_settings_parse_command_line(settings, (int)argc, argv, FALSE);
66
67 if (validate_settings)
68 {
69 valid_settings = validate_settings(settings);
70 }
71
72 freerdp_settings_free(settings);
73
74 if (status == expected_return)
75 {
76 if (!valid_settings)
77 {
78 return FALSE;
79 }
80 }
81 else
82 {
83 TEST_FAILURE("Expected status %d, got status %d\n", expected_return, status);
84 return FALSE;
85 }
86
87 return TRUE;
88}
89
90#if defined(_WIN32)
91#define DRIVE_REDIRECT_PATH "c:\\Windows"
92#else
93#define DRIVE_REDIRECT_PATH "/tmp"
94#endif
95
96static BOOL check_settings_gateway_response_timeout(rdpSettings* settings, UINT32 expected)
97{
98 const UINT32 val = freerdp_settings_get_uint32(settings, FreeRDP_GatewayResponseTimeout);
99
100 if (val != expected)
101 {
102 TEST_FAILURE("Expected GatewayResponseTimeout = %" PRIu32 ", but got %" PRIu32 "!\n",
103 expected, val);
104 return FALSE;
105 }
106
107 return TRUE;
108}
109
110static BOOL check_settings_gateway_response_timeout_default(rdpSettings* settings)
111{
112 return check_settings_gateway_response_timeout(settings, 15000);
113}
114
115static BOOL check_settings_gateway_response_timeout_custom(rdpSettings* settings)
116{
117 return check_settings_gateway_response_timeout(settings, 120000);
118}
119
120static BOOL check_settings_smartcard_no_redirection(rdpSettings* settings)
121{
122 BOOL result = TRUE;
123
124 if (freerdp_settings_get_bool(settings, FreeRDP_RedirectSmartCards))
125 {
126 TEST_FAILURE("Expected RedirectSmartCards = FALSE, but RedirectSmartCards = TRUE!\n");
127 result = FALSE;
128 }
129
130 if (freerdp_device_collection_find_type(settings, RDPDR_DTYP_SMARTCARD))
131 {
132 TEST_FAILURE("Expected no SMARTCARD device, but found at least one!\n");
133 result = FALSE;
134 }
135
136 return result;
137}
138
139#ifndef TEST_SOURCE_DIR
140#error "TEST_SOURCE_DIR must be defined to the test source directory"
141#endif
142#define DISABLED_DISPLAY_OPTIONS_RDP TEST_SOURCE_DIR "/rdp-cmdline/disabled-display-options.rdp"
143
144static BOOL check_settings_multimon_disabled(rdpSettings* settings)
145{
146 BOOL result = TRUE;
147
148 if (freerdp_settings_get_bool(settings, FreeRDP_UseMultimon))
149 {
150 TEST_FAILURE("Expected UseMultimon = FALSE, but UseMultimon = TRUE!\n");
151 result = FALSE;
152 }
153
154 if (freerdp_settings_get_bool(settings, FreeRDP_ForceMultimon))
155 {
156 TEST_FAILURE("Expected ForceMultimon = FALSE, but ForceMultimon = TRUE!\n");
157 result = FALSE;
158 }
159
160 if (!freerdp_settings_get_bool(settings, FreeRDP_SmartSizing))
161 {
162 TEST_FAILURE("Expected SmartSizing = TRUE, but SmartSizing = FALSE!\n");
163 result = FALSE;
164 }
165
166 return result;
167}
168
169static BOOL check_settings_smart_sizing_disabled(rdpSettings* settings)
170{
171 BOOL result = TRUE;
172
173 if (freerdp_settings_get_bool(settings, FreeRDP_SmartSizing))
174 {
175 TEST_FAILURE("Expected SmartSizing = FALSE, but SmartSizing = TRUE!\n");
176 result = FALSE;
177 }
178
179 if (!freerdp_settings_get_bool(settings, FreeRDP_DynamicResolutionUpdate))
180 {
181 TEST_FAILURE(
182 "Expected DynamicResolutionUpdate = TRUE, but DynamicResolutionUpdate = FALSE!\n");
183 result = FALSE;
184 }
185
186 if (!freerdp_settings_get_bool(settings, FreeRDP_UseMultimon))
187 {
188 TEST_FAILURE("Expected UseMultimon = TRUE, but UseMultimon = FALSE!\n");
189 result = FALSE;
190 }
191
192 return result;
193}
194
195static BOOL check_settings_multimon_enabled(rdpSettings* settings)
196{
197 BOOL result = TRUE;
198
199 if (!freerdp_settings_get_bool(settings, FreeRDP_UseMultimon))
200 {
201 TEST_FAILURE("Expected UseMultimon = TRUE, but UseMultimon = FALSE!\n");
202 result = FALSE;
203 }
204
205 return result;
206}
207
208static void setup_settings_multimon_force(rdpSettings* settings)
209{
210 (void)freerdp_settings_set_bool(settings, FreeRDP_ForceMultimon, TRUE);
211}
212
213static BOOL check_settings_multimon_force(rdpSettings* settings)
214{
215 BOOL result = TRUE;
216
217 if (!freerdp_settings_get_bool(settings, FreeRDP_UseMultimon))
218 {
219 TEST_FAILURE("Expected UseMultimon = TRUE, but UseMultimon = FALSE!\n");
220 result = FALSE;
221 }
222
223 if (!freerdp_settings_get_bool(settings, FreeRDP_ForceMultimon))
224 {
225 TEST_FAILURE("Expected ForceMultimon = TRUE, but ForceMultimon = FALSE!\n");
226 result = FALSE;
227 }
228
229 return result;
230}
231
232static BOOL check_settings_smart_sizing_size(rdpSettings* settings)
233{
234 BOOL result = TRUE;
235
236 if (!freerdp_settings_get_bool(settings, FreeRDP_SmartSizing))
237 {
238 TEST_FAILURE("Expected SmartSizing = TRUE, but SmartSizing = FALSE!\n");
239 result = FALSE;
240 }
241
242 if (freerdp_settings_get_uint32(settings, FreeRDP_SmartSizingWidth) != 1024)
243 {
244 TEST_FAILURE("Expected SmartSizingWidth = 1024, but SmartSizingWidth = %u!\n",
245 (unsigned)freerdp_settings_get_uint32(settings, FreeRDP_SmartSizingWidth));
246 result = FALSE;
247 }
248
249 if (freerdp_settings_get_uint32(settings, FreeRDP_SmartSizingHeight) != 768)
250 {
251 TEST_FAILURE("Expected SmartSizingHeight = 768, but SmartSizingHeight = %u!\n",
252 (unsigned)freerdp_settings_get_uint32(settings, FreeRDP_SmartSizingHeight));
253 result = FALSE;
254 }
255
256 return result;
257}
258
259typedef struct
260{
261 int expected_status;
262 validate_settings_pr validate_settings;
263 const char* command_line[128];
264 struct
265 {
266 int index;
267 const char* expected_value;
268 } modified_arguments[8];
269 setup_settings_pr setup_settings;
270} test;
271
272// NOLINTBEGIN(bugprone-suspicious-missing-comma)
273static const test tests[] = {
274 { COMMAND_LINE_STATUS_PRINT_HELP,
275 check_settings_smartcard_no_redirection,
276 { "testfreerdp", "--help", nullptr },
277 { WINPR_C_ARRAY_INIT } },
278 { COMMAND_LINE_STATUS_PRINT_HELP,
279 check_settings_smartcard_no_redirection,
280 { "testfreerdp", "/help", nullptr },
281 { WINPR_C_ARRAY_INIT } },
282 { COMMAND_LINE_STATUS_PRINT_HELP,
283 check_settings_smartcard_no_redirection,
284 { "testfreerdp", "-help", nullptr },
285 { WINPR_C_ARRAY_INIT } },
286 { COMMAND_LINE_STATUS_PRINT_VERSION,
287 check_settings_smartcard_no_redirection,
288 { "testfreerdp", "--version", nullptr },
289 { WINPR_C_ARRAY_INIT } },
290 { COMMAND_LINE_STATUS_PRINT_VERSION,
291 check_settings_smartcard_no_redirection,
292 { "testfreerdp", "/version", nullptr },
293 { WINPR_C_ARRAY_INIT } },
294 { COMMAND_LINE_STATUS_PRINT_VERSION,
295 check_settings_smartcard_no_redirection,
296 { "testfreerdp", "-version", nullptr },
297 { WINPR_C_ARRAY_INIT } },
298 { 0,
299 check_settings_smartcard_no_redirection,
300 { "testfreerdp", "-v", "test.freerdp.com", nullptr },
301 { WINPR_C_ARRAY_INIT } },
302 { 0,
303 check_settings_smartcard_no_redirection,
304 { "testfreerdp", "--v", "test.freerdp.com", nullptr },
305 { WINPR_C_ARRAY_INIT } },
306 { 0,
307 check_settings_smartcard_no_redirection,
308 { "testfreerdp", "/v:test.freerdp.com", nullptr },
309 { WINPR_C_ARRAY_INIT } },
310 { 0,
311 check_settings_smartcard_no_redirection,
312 { "testfreerdp", "/sound", "/drive:media," DRIVE_REDIRECT_PATH, "/v:test.freerdp.com",
313 nullptr },
314 { WINPR_C_ARRAY_INIT } },
315 { 0,
316 check_settings_smartcard_no_redirection,
317 { "testfreerdp", "-u", "test", "-p", "test", "-v", "test.freerdp.com", nullptr },
318 { { 4, "****" }, WINPR_C_ARRAY_INIT } },
319 { 0,
320 check_settings_smartcard_no_redirection,
321 { "testfreerdp", "/u:test", "/p:test", "/v:test.freerdp.com", nullptr },
322 { { 2, "/p:****" }, WINPR_C_ARRAY_INIT } },
323 { COMMAND_LINE_ERROR_NO_KEYWORD,
324 check_settings_smartcard_no_redirection,
325 { "testfreerdp", "-invalid", nullptr },
326 { WINPR_C_ARRAY_INIT } },
327 { COMMAND_LINE_ERROR_NO_KEYWORD,
328 check_settings_smartcard_no_redirection,
329 { "testfreerdp", "--invalid", nullptr },
330 { WINPR_C_ARRAY_INIT } },
331#if defined(WITH_FREERDP_DEPRECATED_CMDLINE)
332 { COMMAND_LINE_STATUS_PRINT,
333 check_settings_smartcard_no_redirection,
334 { "testfreerdp", "/kbd-list", 0 },
335 { WINPR_C_ARRAY_INIT } },
336 { COMMAND_LINE_STATUS_PRINT,
337 check_settings_smartcard_no_redirection,
338 { "testfreerdp", "/monitor-list", 0 },
339 { WINPR_C_ARRAY_INIT } },
340#endif
341 { COMMAND_LINE_STATUS_PRINT,
342 check_settings_smartcard_no_redirection,
343 { "testfreerdp", "/list:kbd", nullptr },
344 { WINPR_C_ARRAY_INIT } },
345 { COMMAND_LINE_STATUS_PRINT,
346 check_settings_smartcard_no_redirection,
347 { "testfreerdp", "/list:monitor", nullptr },
348 { WINPR_C_ARRAY_INIT } },
349 { 0,
350 check_settings_smartcard_no_redirection,
351 { "testfreerdp", "/sound", "/drive:media:" DRIVE_REDIRECT_PATH, "/v:test.freerdp.com",
352 nullptr },
353 { WINPR_C_ARRAY_INIT } },
354 { 0,
355 check_settings_smartcard_no_redirection,
356 { "testfreerdp", "/sound", "/drive:media,/foo/bar/blabla", "/v:test.freerdp.com", nullptr },
357 { WINPR_C_ARRAY_INIT } },
358 { 0,
359 check_settings_gateway_response_timeout_default,
360 { "testfreerdp", "/gateway:type:arm,g:gw.contoso.com", "/v:test.freerdp.com", nullptr },
361 { WINPR_C_ARRAY_INIT } },
362 { 0,
363 check_settings_gateway_response_timeout_custom,
364 { "testfreerdp", "/gateway:type:arm,g:gw.contoso.com,timeout:120000", "/v:test.freerdp.com",
365 nullptr },
366 { WINPR_C_ARRAY_INIT } },
367 { 0,
368 check_settings_gateway_response_timeout_custom,
369 { "testfreerdp", "/gateway:type:http,g:gw.contoso.com,timeout:120000", "/v:test.freerdp.com",
370 nullptr },
371 { WINPR_C_ARRAY_INIT } },
372 { COMMAND_LINE_ERROR,
373 check_settings_gateway_response_timeout_default,
374 { "testfreerdp", "/gateway:type:arm,g:gw.contoso.com,timeout:0", "/v:test.freerdp.com",
375 nullptr },
376 { WINPR_C_ARRAY_INIT } },
377 { COMMAND_LINE_ERROR,
378 check_settings_gateway_response_timeout_default,
379 { "testfreerdp", "/gateway:type:arm,g:gw.contoso.com,timeout:abc", "/v:test.freerdp.com",
380 nullptr },
381 { WINPR_C_ARRAY_INIT } },
382 { 0,
383 check_settings_multimon_disabled,
384 { "testfreerdp", DISABLED_DISPLAY_OPTIONS_RDP, "/multimon:off", nullptr },
385 { WINPR_C_ARRAY_INIT },
386 setup_settings_multimon_force },
387 { 0,
388 check_settings_multimon_disabled,
389 { "testfreerdp", DISABLED_DISPLAY_OPTIONS_RDP, "-multimon", nullptr },
390 { WINPR_C_ARRAY_INIT },
391 setup_settings_multimon_force },
392 { 0,
393 check_settings_smart_sizing_disabled,
394 { "testfreerdp", DISABLED_DISPLAY_OPTIONS_RDP, "-smart-sizing", nullptr },
395 { WINPR_C_ARRAY_INIT } },
396 { 0,
397 check_settings_smart_sizing_disabled,
398 { "testfreerdp", DISABLED_DISPLAY_OPTIONS_RDP, "/smart-sizing:off", nullptr },
399 { WINPR_C_ARRAY_INIT } },
400 { 0,
401 check_settings_multimon_force,
402 { "testfreerdp", "--multimon", "force", nullptr },
403 { WINPR_C_ARRAY_INIT } },
404 { 0,
405 check_settings_smart_sizing_size,
406 { "testfreerdp", "--smart-sizing", "1024x768", nullptr },
407 { WINPR_C_ARRAY_INIT } },
408 { COMMAND_LINE_ERROR_UNEXPECTED_VALUE,
409 check_settings_smartcard_no_redirection,
410 { "testfreerdp", "/multimon:garbage", nullptr },
411 { WINPR_C_ARRAY_INIT } },
412 { COMMAND_LINE_ERROR_UNEXPECTED_VALUE,
413 check_settings_smartcard_no_redirection,
414 { "testfreerdp", "/smart-sizing:garbage", nullptr },
415 { WINPR_C_ARRAY_INIT } },
416 { COMMAND_LINE_ERROR_UNEXPECTED_VALUE,
417 check_settings_smartcard_no_redirection,
418 { "testfreerdp", "/multimon:", nullptr },
419 { WINPR_C_ARRAY_INIT } },
420 { COMMAND_LINE_ERROR_UNEXPECTED_VALUE,
421 check_settings_smartcard_no_redirection,
422 { "testfreerdp", "/smart-sizing:", nullptr },
423 { WINPR_C_ARRAY_INIT } },
424 { 0,
425 check_settings_multimon_enabled,
426 { "testfreerdp", "+multimon", nullptr },
427 { WINPR_C_ARRAY_INIT } },
428};
429// NOLINTEND(bugprone-suspicious-missing-comma)
430
431static void check_modified_arguments(const test* test, char** command_line, int* rc)
432{
433 const char* expected_argument = nullptr;
434
435 for (int k = 0; (expected_argument = test->modified_arguments[k].expected_value); k++)
436 {
437 int index = test->modified_arguments[k].index;
438 char* actual_argument = command_line[index];
439
440 if (0 != strcmp(actual_argument, expected_argument))
441 {
442 printref();
443 printf("Failure: overridden argument %d is %s but it should be %s\n", index,
444 actual_argument, expected_argument);
445 (void)fflush(stdout);
446 *rc = -1;
447 }
448 }
449}
450
451int TestClientCmdLine(int argc, char* argv[])
452{
453 int rc = 0;
454
455 WINPR_UNUSED(argc);
456 WINPR_UNUSED(argv);
457 for (size_t i = 0; i < ARRAYSIZE(tests); i++)
458 {
459 const test* current = &tests[i];
460 int failure = 0;
461 char** command_line = string_list_copy(current->command_line);
462
463 const int len = string_list_length((const char* const*)command_line);
464 if (!testcase(__func__, command_line, WINPR_ASSERTING_INT_CAST(size_t, len),
465 current->expected_status, current->validate_settings,
466 current->setup_settings))
467 {
468 TEST_FAILURE("parsing arguments.\n");
469 failure = 1;
470 }
471
472 check_modified_arguments(current, command_line, &failure);
473
474 if (failure)
475 {
476 string_list_print(stdout, (const char* const*)command_line);
477 rc = -1;
478 }
479
480 string_list_free(command_line);
481 }
482
483 return rc;
484}
FREERDP_API rdpSettings * freerdp_settings_new(DWORD flags)
creates a new setting struct
WINPR_ATTR_NODISCARD FREERDP_API BOOL freerdp_settings_set_bool(rdpSettings *settings, FreeRDP_Settings_Keys_Bool id, BOOL val)
Sets a BOOL settings value.
FREERDP_API void freerdp_settings_free(rdpSettings *settings)
Free a settings struct with all data in it.
WINPR_ATTR_NODISCARD FREERDP_API UINT32 freerdp_settings_get_uint32(const rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id)
Returns a UINT32 settings value.
WINPR_ATTR_NODISCARD FREERDP_API BOOL freerdp_settings_get_bool(const rdpSettings *settings, FreeRDP_Settings_Keys_Bool id)
Returns a boolean settings value.