mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-15 00:44:19 +09:00
[client,common] add settings json
Use freerdp_settings_(de)serialize to compare result of rdpFile parsing.
This commit is contained in:
@@ -10,6 +10,7 @@ set(${MODULE_PREFIX}_TESTS TestClientRdpFile.c TestClientChannels.c TestClientCm
|
||||
create_test_sourcelist(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_DRIVER} ${${MODULE_PREFIX}_TESTS})
|
||||
|
||||
add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
|
||||
target_compile_definitions(${MODULE_NAME} PRIVATE TEST_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
|
||||
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} freerdp-client freerdp)
|
||||
|
||||
|
||||
@@ -261,6 +261,255 @@ static char* append(const char* fmt, ...)
|
||||
return dst;
|
||||
}
|
||||
|
||||
static FILE* test_fopen(const char* name, const char* mode)
|
||||
{
|
||||
#ifndef TEST_SOURCE_DIR
|
||||
#error "TEST_SOURCE_DIR must be defined to the test source directory"
|
||||
#endif
|
||||
|
||||
char* path = GetCombinedPath(TEST_SOURCE_DIR, name);
|
||||
FILE* fp = winpr_fopen(path, mode);
|
||||
free(path);
|
||||
return fp;
|
||||
}
|
||||
|
||||
static void* read_rdp_data(const char* name, size_t* plen)
|
||||
{
|
||||
FILE* fp = test_fopen(name, "r");
|
||||
if (!fp)
|
||||
return NULL;
|
||||
fseek(fp, 0, SEEK_END);
|
||||
const size_t pos = _ftelli64(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
char* json = calloc(pos + 1, sizeof(char));
|
||||
if (!json)
|
||||
goto fail;
|
||||
fread(json, 1, pos, fp);
|
||||
*plen = pos;
|
||||
fail:
|
||||
fclose(fp);
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
static bool save_settings(const rdpSettings* settings, const char* name)
|
||||
{
|
||||
bool rc = false;
|
||||
size_t datalen = 0;
|
||||
char* data = freerdp_settings_serialize(settings, TRUE, &datalen);
|
||||
if (!data)
|
||||
return false;
|
||||
|
||||
FILE* fp = test_fopen(name, "w");
|
||||
if (fp)
|
||||
{
|
||||
const size_t res = fwrite(data, 1, datalen, fp);
|
||||
(void)fclose(fp);
|
||||
rc = res == datalen;
|
||||
}
|
||||
|
||||
free(data);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static char* get_json_name(const char* base, bool unchecked)
|
||||
{
|
||||
size_t namelen = 0;
|
||||
char* name = NULL;
|
||||
winpr_asprintf(&name, &namelen, "%s%s.json", base, unchecked ? ".unchecked" : "");
|
||||
return name;
|
||||
}
|
||||
|
||||
static rdpSettings* read_json(const char* name)
|
||||
{
|
||||
size_t datalen = 0;
|
||||
void* data = read_rdp_data(name, &datalen);
|
||||
rdpSettings* settings = freerdp_settings_deserialize(data, datalen);
|
||||
fail:
|
||||
free(data);
|
||||
return settings;
|
||||
}
|
||||
|
||||
static rdpSettings* load_from(const void* data, size_t len, bool unchecked)
|
||||
{
|
||||
BOOL rc = false;
|
||||
rdpFile* file = freerdp_client_rdp_file_new();
|
||||
rdpSettings* settings = read_json("default-settings.json");
|
||||
if (!settings)
|
||||
{
|
||||
settings = freerdp_settings_new(0);
|
||||
if (settings)
|
||||
{
|
||||
save_settings(settings, "default-settings.json");
|
||||
}
|
||||
}
|
||||
if (!file || !settings)
|
||||
goto fail;
|
||||
|
||||
if (!freerdp_client_parse_rdp_file_buffer(file, data, len))
|
||||
goto fail;
|
||||
|
||||
if (unchecked)
|
||||
{
|
||||
if (!freerdp_client_populate_settings_from_rdp_file_unchecked(file, settings))
|
||||
goto fail;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!freerdp_client_populate_settings_from_rdp_file(file, settings))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = true;
|
||||
fail:
|
||||
freerdp_client_rdp_file_free(file);
|
||||
if (!rc)
|
||||
{
|
||||
freerdp_settings_free(settings);
|
||||
return NULL;
|
||||
}
|
||||
return settings;
|
||||
}
|
||||
|
||||
static rdpSettings* load_from_file(const char* name, bool unchecked)
|
||||
{
|
||||
size_t datalen = 0;
|
||||
void* data = read_rdp_data(name, &datalen);
|
||||
if (!data)
|
||||
return NULL;
|
||||
rdpSettings* settings = load_from(data, datalen, unchecked);
|
||||
free(data);
|
||||
return settings;
|
||||
}
|
||||
|
||||
static bool test_data(const char* json, const void* data, size_t len, bool unchecked)
|
||||
{
|
||||
bool rc = false;
|
||||
|
||||
rdpSettings* settings = load_from(data, len, unchecked);
|
||||
rdpSettings* expect = read_json(json);
|
||||
if (!settings || !expect)
|
||||
goto fail;
|
||||
|
||||
wLog* log = WLog_Get(__func__);
|
||||
WLog_Print(log, WLOG_INFO, "Test cast '%s'", json);
|
||||
if (freerdp_settings_print_diff(log, WLOG_ERROR, expect, settings))
|
||||
goto fail;
|
||||
rc = true;
|
||||
fail:
|
||||
freerdp_settings_free(settings);
|
||||
freerdp_settings_free(expect);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static HANDLE FindFirstFileUTF8(LPCSTR pszSearchPath, WIN32_FIND_DATAW* FindData)
|
||||
{
|
||||
HANDLE hdl = INVALID_HANDLE_VALUE;
|
||||
if (!pszSearchPath)
|
||||
return hdl;
|
||||
WCHAR* wpath = ConvertUtf8ToWCharAlloc(pszSearchPath, NULL);
|
||||
if (!wpath)
|
||||
return hdl;
|
||||
|
||||
hdl = FindFirstFileW(wpath, FindData);
|
||||
free(wpath);
|
||||
|
||||
return hdl;
|
||||
}
|
||||
|
||||
static bool test_rdp_file(const char* base, bool allowCreate, bool unchecked)
|
||||
{
|
||||
bool rc = false;
|
||||
|
||||
size_t rdplen = 0;
|
||||
char* rdp = NULL;
|
||||
winpr_asprintf(&rdp, &rdplen, "%s.rdp", base);
|
||||
char* json = get_json_name(base, unchecked);
|
||||
size_t datalen = 0;
|
||||
void* data = read_rdp_data(rdp, &datalen);
|
||||
|
||||
if (!data)
|
||||
goto fail;
|
||||
|
||||
rc = test_data(json, data, datalen, unchecked);
|
||||
if (!rc && allowCreate)
|
||||
{
|
||||
rdpSettings* expect = read_json(json);
|
||||
if (expect)
|
||||
{
|
||||
freerdp_settings_free(expect);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rdpSettings* settings = load_from_file(rdp, unchecked);
|
||||
if (!settings)
|
||||
goto fail;
|
||||
|
||||
rc = save_settings(settings, json);
|
||||
}
|
||||
fail:
|
||||
free(data);
|
||||
free(json);
|
||||
free(rdp);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static bool test_rdp_files(bool allowCreate)
|
||||
{
|
||||
bool rc = false;
|
||||
/* Load RDP files from directory, compare to JSON in same directory.
|
||||
* If JSON does not exist, create it.
|
||||
*/
|
||||
#ifndef TEST_SOURCE_DIR
|
||||
#error "TEST_SOURCE_DIR must be defined to the test source directory"
|
||||
#endif
|
||||
|
||||
HANDLE hdl = INVALID_HANDLE_VALUE;
|
||||
char* path = GetCombinedPath(TEST_SOURCE_DIR, "rdp-testcases/*.rdp");
|
||||
if (!path)
|
||||
goto fail;
|
||||
|
||||
WIN32_FIND_DATAW FindData = { 0 };
|
||||
hdl = FindFirstFileUTF8(path, &FindData);
|
||||
|
||||
if (hdl == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
WLog_INFO(
|
||||
__func__,
|
||||
"no RDP files found in %s. Add RDP files to generate settings JSON for comparison.",
|
||||
path);
|
||||
rc = true;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
if ((FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
|
||||
{
|
||||
char cFileName[6 * MAX_PATH] = { 0 };
|
||||
char rdp[6 * MAX_PATH] = { 0 };
|
||||
ConvertWCharToUtf8(FindData.cFileName, cFileName, sizeof(cFileName));
|
||||
const size_t len = strnlen(cFileName, sizeof(cFileName));
|
||||
if (len < 4)
|
||||
continue;
|
||||
strcpy(rdp, "rdp-testcases/");
|
||||
strncpy(&rdp[14], cFileName, len - 4);
|
||||
|
||||
if (!test_rdp_file(rdp, allowCreate, false))
|
||||
goto fail;
|
||||
if (!test_rdp_file(rdp, allowCreate, true))
|
||||
goto fail;
|
||||
}
|
||||
} while (FindNextFileW(hdl, &FindData));
|
||||
|
||||
rc = true;
|
||||
|
||||
fail:
|
||||
FindClose(hdl);
|
||||
free(path);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int TestClientRdpFile(int argc, char* argv[])
|
||||
{
|
||||
int rc = -1;
|
||||
@@ -280,56 +529,29 @@ int TestClientRdpFile(int argc, char* argv[])
|
||||
WINPR_UNUSED(argv);
|
||||
winpr_RAND(&id, sizeof(id));
|
||||
|
||||
/* UTF8 */
|
||||
#if defined(CHANNEL_URBDRC_CLIENT) && defined(CHANNEL_RDPECAM_CLIENT)
|
||||
if (!test_data("testRdpFileUTF8.json", testRdpFileUTF8, sizeof(testRdpFileUTF8), false))
|
||||
return -1;
|
||||
if (!test_data("testRdpFileUTF8.unchecked.json", testRdpFileUTF8, sizeof(testRdpFileUTF8),
|
||||
true))
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
/* Unicode */
|
||||
file = freerdp_client_rdp_file_new();
|
||||
settings = freerdp_settings_new(0);
|
||||
#if defined(CHANNEL_URBDRC_CLIENT)
|
||||
if (!test_data("testRdpFileUTF16.json", testRdpFileUTF16, sizeof(testRdpFileUTF16), false))
|
||||
return -1;
|
||||
if (!test_data("testRdpFileUTF16.unchecked.json", testRdpFileUTF16, sizeof(testRdpFileUTF16),
|
||||
true))
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
if (!file || !settings)
|
||||
{
|
||||
printf("rdp_file_new failed\n");
|
||||
goto fail;
|
||||
}
|
||||
#if defined(CHANNEL_URBDRC_CLIENT) && defined(CHANNEL_RDPECAM_CLIENT)
|
||||
if (!test_rdp_files(argc > 1))
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
if (!freerdp_client_parse_rdp_file_buffer(file, testRdpFileUTF16, sizeof(testRdpFileUTF16)))
|
||||
goto fail;
|
||||
|
||||
if (!freerdp_client_populate_settings_from_rdp_file(file, settings))
|
||||
goto fail;
|
||||
|
||||
if (freerdp_settings_get_bool(settings, FreeRDP_UseMultimon))
|
||||
{
|
||||
printf("UseMultiMon mismatch: Actual: %" PRIu32 ", Expected: 0\n",
|
||||
freerdp_settings_get_bool(settings, FreeRDP_UseMultimon));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!freerdp_settings_get_bool(settings, FreeRDP_Fullscreen))
|
||||
{
|
||||
printf("ScreenModeId mismatch: Actual: %" PRIu32 ", Expected: TRUE\n",
|
||||
freerdp_settings_get_bool(settings, FreeRDP_Fullscreen));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (strcmp(freerdp_settings_get_string(settings, FreeRDP_GatewayHostname),
|
||||
"LAB1-W2K8R2-GW.lab1.awake.local") != 0)
|
||||
{
|
||||
printf("GatewayHostname mismatch: Actual: %s, Expected: %s\n",
|
||||
freerdp_settings_get_string(settings, FreeRDP_GatewayHostname),
|
||||
"LAB1-W2K8R2-GW.lab1.awake.local");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (strcmp(freerdp_settings_get_string(settings, FreeRDP_ServerHostname),
|
||||
"LAB1-W7-DM-01.lab1.awake.local") != 0)
|
||||
{
|
||||
printf("ServerHostname mismatch: Actual: %s, Expected: %s\n",
|
||||
freerdp_settings_get_string(settings, FreeRDP_ServerHostname),
|
||||
"LAB1-W7-DM-01.lab1.awake.local");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
freerdp_client_rdp_file_free(file);
|
||||
freerdp_settings_free(settings);
|
||||
/* Ascii */
|
||||
file = freerdp_client_rdp_file_new();
|
||||
settings = freerdp_settings_new(0);
|
||||
|
||||
1377
client/common/test/default-settings.json
Normal file
1377
client/common/test/default-settings.json
Normal file
File diff suppressed because it is too large
Load Diff
8
client/common/test/rdp-testcases/README.txt
Normal file
8
client/common/test/rdp-testcases/README.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
This directory should contain RDP files that are checked by TestClientRdpFile
|
||||
|
||||
Adding new test works like this:
|
||||
|
||||
1. place a .rdp file in this folder
|
||||
2. run TestClient TestClientRdpFile generate to generate a settings JSON from the RDP file
|
||||
3. git add .rdp .json && git commit .
|
||||
4. now the unit test is run and the result is compared
|
||||
1521
client/common/test/rdp-testcases/test1.json
Normal file
1521
client/common/test/rdp-testcases/test1.json
Normal file
File diff suppressed because it is too large
Load Diff
38
client/common/test/rdp-testcases/test1.rdp
Normal file
38
client/common/test/rdp-testcases/test1.rdp
Normal file
@@ -0,0 +1,38 @@
|
||||
gatewayusagemethod:i:1
|
||||
gatewayprofileusagemethod:i:1
|
||||
authentication level:i:1
|
||||
gatewaybrokeringtype:i:1
|
||||
wvd endpoint pool:s:11112222-0815-1234-abcd-123456789abc
|
||||
geo:s:EU
|
||||
armpath:s:/subscriptions/584e4430-82fd-41aa-b87a-efc8b62f890c/resourcegroups/f6cfbbf2-efed-4756-a9c8-3c547bc4eb50/providers/Microsoft.DesktopVirtualization/hostpools/3367af18e772425b82d958c4f06d8023
|
||||
aadtenantid:s:77064fd5-2634-4a0d-b310-2fa3c1d0472d
|
||||
full address:s:rdgateway-r1.wvd.microsoft.com
|
||||
alternate full address:s:rdgateway-r1.wvd.microsoft.com
|
||||
diagnosticserviceurl:s:https://rdweb-g-eu-r1.wvd.microsoft.com/api/arm/DiagnosticEvents/v1
|
||||
hubdiscoverygeourl:s:https://rdweb-g-eu-r1.wvd.microsoft.com/api/arm/hubdiscovery?resourceId=16e1fb18-0f41-4e0c-acf8-5046124affe9
|
||||
resourceprovider:s:arm
|
||||
gatewayhostname:s:afdfp-rdgateway-r1.wvd.microsoft.com:443
|
||||
loadbalanceinfo:s:mth://localhost/b47b47c1-b81e-4dfa-ac1b-a8a195d43f26/16e1fb18-0f41-4e0c-acf8-5046124affe9
|
||||
workspace id:s:cd2471f8-135b-405b-ac04-c2e1564ef354
|
||||
activityhint:s:ms-wvd-ep:16e1fb18-0f41-4e0c-acf8-5046124affe9?ScaleUnitPath={"Geo"%3a"EU"%2c"Ring"%3a1%2c"Region"%3a"westeurope"%2c"ScaleUnit"%3a100}
|
||||
promptcredentialonce:i:1
|
||||
gatewaycredentialssource:i:0
|
||||
remoteapplicationprogram:s:||40d51148-8d2c-4222-aeb3-7ad10be11650
|
||||
remotedesktopname:s:Cloud PC Enterprise 8vCPU/32GB/512GB
|
||||
remoteapplicationmode:i:0
|
||||
audiomode:i:0
|
||||
redirectclipboard:i:1
|
||||
redirectprinters:i:1
|
||||
redirectsmartcards:i:1
|
||||
dynamic resolution:i:1
|
||||
audiocapturemode:i:1
|
||||
camerastoredirect:s:*
|
||||
devicestoredirect:s:*
|
||||
redirectcomports:i:1
|
||||
drivestoredirect:s:*
|
||||
usbdevicestoredirect:s:*
|
||||
singlemoninwindowedmode:i:1
|
||||
redirectlocation:i:1
|
||||
targetisaadjoined:i:1
|
||||
enablerdsaadauth:i:0
|
||||
clientrejectinjectedinput:i:0
|
||||
1521
client/common/test/rdp-testcases/test1.unchecked.json
Normal file
1521
client/common/test/rdp-testcases/test1.unchecked.json
Normal file
File diff suppressed because it is too large
Load Diff
1377
client/common/test/testRdpFileUTF16.json
Normal file
1377
client/common/test/testRdpFileUTF16.json
Normal file
File diff suppressed because it is too large
Load Diff
1377
client/common/test/testRdpFileUTF16.unchecked.json
Normal file
1377
client/common/test/testRdpFileUTF16.unchecked.json
Normal file
File diff suppressed because it is too large
Load Diff
1433
client/common/test/testRdpFileUTF8.json
Normal file
1433
client/common/test/testRdpFileUTF8.json
Normal file
File diff suppressed because it is too large
Load Diff
1433
client/common/test/testRdpFileUTF8.unchecked.json
Normal file
1433
client/common/test/testRdpFileUTF8.unchecked.json
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user