From: Eric Pouech eric.pouech@gmail.com
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- programs/winetest/main.c | 145 +++++++++++++++++++++++---------------- 1 file changed, 87 insertions(+), 58 deletions(-)
diff --git a/programs/winetest/main.c b/programs/winetest/main.c index 74b596b237b..711f38d06e6 100644 --- a/programs/winetest/main.c +++ b/programs/winetest/main.c @@ -54,13 +54,19 @@ struct wine_test char *maindllpath; };
+struct winetest_image +{ + const char *target_dir; + HMODULE module; + struct wine_test *wine_tests; + int nr_of_files, nr_of_tests, nr_of_skips; +}; + char *tag = NULL; char *description = NULL; char *url = NULL; char *email = NULL; BOOL aborting = FALSE; -static struct wine_test *wine_tests; -static int nr_of_files, nr_of_tests, nr_of_skips; static int nr_native_dlls; static const char whitespace[] = " \t\r\n"; static const char testexe[] = "_test.exe"; @@ -640,15 +646,15 @@ static const char* get_test_source_file(const char* test, const char* subtest) return buffer; }
-static void* extract_rcdata (LPCSTR name, LPCSTR type, DWORD* size) +static void* extract_rcdata (HMODULE module, LPCSTR name, LPCSTR type, DWORD* size) { HRSRC rsrc; HGLOBAL hdl; LPVOID addr; - - if (!(rsrc = FindResourceA(NULL, name, type)) || - !(*size = SizeofResource (0, rsrc)) || - !(hdl = LoadResource (0, rsrc)) || + + if (!(rsrc = FindResourceA(module, name, type)) || + !(*size = SizeofResource (module, rsrc)) || + !(hdl = LoadResource (module, rsrc)) || !(addr = LockResource (hdl))) return NULL; return addr; @@ -656,7 +662,7 @@ static void* extract_rcdata (LPCSTR name, LPCSTR type, DWORD* size)
/* Fills in the name and exename fields */ static void -extract_test (struct wine_test *test, const char *dir, LPSTR res_name) +extract_test (struct winetest_image *image, struct wine_test *test, LPSTR res_name) { BYTE* code; DWORD size; @@ -664,11 +670,11 @@ extract_test (struct wine_test *test, const char *dir, LPSTR res_name) HANDLE hfile; DWORD written;
- code = extract_rcdata (res_name, "TESTRES", &size); + code = extract_rcdata (image->module, res_name, "TESTRES", &size); if (!code) report (R_FATAL, "Can't find test resource %s: %d", res_name, GetLastError ()); test->name = xstrdup( res_name ); - test->exename = strmake (NULL, "%s\%s", dir, test->name); + test->exename = strmake (NULL, "%s\%s", image->target_dir, test->name); exepos = strstr (test->name, testexe); if (!exepos) report (R_FATAL, "Not an .exe file: %s", test->name); *exepos = 0; @@ -844,17 +850,18 @@ get_subtests (const char *tempdir, struct wine_test *test, LPSTR res_name) return 0; }
-static void +static BOOL run_test (struct wine_test* test, const char* subtest, HANDLE out_file, const char *tempdir) { /* Build the source filename so analysis tools can link to it */ const char* file = get_test_source_file(test->name, subtest); + BOOL did_run = TRUE;
if (test_filtered_out( test->name, subtest )) { report (R_STEP, "Skipping: %s:%s", test->name, subtest); xprintf ("%s:%s skipped %s\n", test->name, subtest, file); - nr_of_skips++; + did_run = FALSE; } else { @@ -891,6 +898,7 @@ run_test (struct wine_test* test, const char* subtest, HANDLE out_file, const ch else if (status) failures++; } if (failures) report (R_STATUS, "Running tests - %u failures", failures); + return did_run; }
static BOOL CALLBACK @@ -975,7 +983,7 @@ static void get_dll_path(HMODULE dll, char **path, char *filename) static BOOL CALLBACK extract_test_proc (HMODULE hModule, LPCSTR lpszType, LPSTR lpszName, LONG_PTR lParam) { - const char *tempdir = (const char *)lParam; + struct winetest_image *image = (struct winetest_image *)lParam; char dllname[MAX_PATH]; char filename[MAX_PATH]; WCHAR dllnameW[MAX_PATH]; @@ -994,11 +1002,11 @@ extract_test_proc (HMODULE hModule, LPCSTR lpszType, LPSTR lpszName, LONG_PTR lP
if (test_filtered_out( lpszName, NULL )) { - nr_of_skips++; + image->nr_of_skips++; if (exclude_tests) xprintf (" %s=skipped\n", dllname); return TRUE; } - extract_test (&wine_tests[nr_of_files], tempdir, lpszName); + extract_test (image, &image->wine_tests[image->nr_of_files], lpszName);
if (pCreateActCtxA != NULL && pActivateActCtx != NULL && pDeactivateActCtx != NULL && pReleaseActCtx != NULL) @@ -1007,7 +1015,7 @@ extract_test_proc (HMODULE hModule, LPCSTR lpszType, LPSTR lpszName, LONG_PTR lP memset(&actctxinfo, 0, sizeof(ACTCTXA)); actctxinfo.cbSize = sizeof(ACTCTXA); actctxinfo.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID; - actctxinfo.lpSource = wine_tests[nr_of_files].exename; + actctxinfo.lpSource = image->wine_tests[image->nr_of_files].exename; actctxinfo.lpResourceName = (LPSTR)CREATEPROCESS_MANIFEST_RESOURCE_ID; actctx = pCreateActCtxA(&actctxinfo); if (actctx != INVALID_HANDLE_VALUE && @@ -1018,18 +1026,18 @@ extract_test_proc (HMODULE hModule, LPCSTR lpszType, LPSTR lpszName, LONG_PTR lP } } else actctx = INVALID_HANDLE_VALUE;
- wine_tests[nr_of_files].maindllpath = NULL; + image->wine_tests[image->nr_of_files].maindllpath = NULL; strcpy(filename, dllname); dll = LoadLibraryExA(dllname, NULL, LOAD_LIBRARY_AS_DATAFILE);
- if (!dll) dll = load_com_dll(dllname, &wine_tests[nr_of_files].maindllpath, filename); + if (!dll) dll = load_com_dll(dllname, &image->wine_tests[image->nr_of_files].maindllpath, filename);
if (!dll && pLoadLibraryShim) { MultiByteToWideChar(CP_ACP, 0, dllname, -1, dllnameW, MAX_PATH); if (SUCCEEDED( pLoadLibraryShim(dllnameW, NULL, NULL, &dll) ) && dll) { - get_dll_path(dll, &wine_tests[nr_of_files].maindllpath, filename); + get_dll_path(dll, &image->wine_tests[image->nr_of_files].maindllpath, filename); FreeLibrary(dll); dll = LoadLibraryExA(filename, NULL, LOAD_LIBRARY_AS_DATAFILE); } @@ -1055,13 +1063,13 @@ extract_test_proc (HMODULE hModule, LPCSTR lpszType, LPSTR lpszName, LONG_PTR lP
if (run) { - err = get_subtests( tempdir, &wine_tests[nr_of_files], lpszName ); + err = get_subtests( image->target_dir, &image->wine_tests[image->nr_of_files], lpszName ); switch (err) { case 0: xprintf (" %s=%s\n", dllname, get_file_version(filename)); - nr_of_tests += wine_tests[nr_of_files].subtest_count; - nr_of_files++; + image->nr_of_tests += image->wine_tests[image->nr_of_files].subtest_count; + image->nr_of_files++; break; case STATUS_DLL_NOT_FOUND: xprintf (" %s=dll is missing\n", dllname); @@ -1090,8 +1098,40 @@ extract_test_proc (HMODULE hModule, LPCSTR lpszType, LPSTR lpszName, LONG_PTR lP return TRUE; }
+static BOOL init_image(struct winetest_image *image, const char *target_dir) +{ + image->target_dir = target_dir; + image->module = NULL; + image->nr_of_files = image->nr_of_tests = image->nr_of_skips = 0; + report (R_STATUS, "Counting tests"); + if (!EnumResourceNamesA (image->module, "TESTRES", EnumTestFileProc, (LPARAM)&image->nr_of_files)) + report (R_FATAL, "Can't enumerate test files: %d", + GetLastError ()); + image->wine_tests = xalloc(image->nr_of_files * sizeof image->wine_tests[0]); + return TRUE; +} + +static BOOL load_image(struct winetest_image *image, const char *tempdir) +{ + if (!init_image(image, tempdir)) return FALSE; + report (R_STATUS, "Extracting tests"); + report (R_PROGRESS, 0, image->nr_of_files); + image->nr_of_files = 0; + if (!EnumResourceNamesA (image->module, "TESTRES", extract_test_proc, (LPARAM)image)) + report (R_FATAL, "Can't enumerate test files: %d", + GetLastError ()); + return TRUE; +} + +static void dispose_image(struct winetest_image *image) +{ + free(image->wine_tests); + FreeLibrary(image->module); + memset(image, 0, sizeof(*image)); +} + static char * -run_tests (char *logname, char *outdir) +run_tests (char *logname, char *outdir, int *nr_of_skips) { int i; char *strres, *eol, *nextline; @@ -1100,6 +1140,7 @@ run_tests (char *logname, char *outdir) BOOL newdir; DWORD needed; HMODULE kernel32; + struct winetest_image image;
/* Get the current PATH only once */ needed = GetEnvironmentVariableA("PATH", NULL, 0); @@ -1155,7 +1196,7 @@ run_tests (char *logname, char *outdir) xprintf ("Archive: -\n"); /* no longer used */ xprintf ("Tag: %s\n", tag); xprintf ("Build info:\n"); - strres = extract_rcdata ("BUILD_INFO", "STRINGRES", &strsize); + strres = extract_rcdata (NULL, "BUILD_INFO", "STRINGRES", &strsize); while (strres) { eol = memchr (strres, '\n', strsize); if (!eol) { @@ -1174,12 +1215,6 @@ run_tests (char *logname, char *outdir) print_language (); xprintf ("Dll info:\n" );
- report (R_STATUS, "Counting tests"); - if (!EnumResourceNamesA (NULL, "TESTRES", EnumTestFileProc, (LPARAM)&nr_of_files)) - report (R_FATAL, "Can't enumerate test files: %d", - GetLastError ()); - wine_tests = xalloc(nr_of_files * sizeof wine_tests[0]); - /* Do this only once during extraction (and version checking) */ hmscoree = LoadLibraryA("mscoree.dll"); pLoadLibraryShim = NULL; @@ -1191,14 +1226,7 @@ run_tests (char *logname, char *outdir) pDeactivateActCtx = (void *)GetProcAddress(kernel32, "DeactivateActCtx"); pReleaseActCtx = (void *)GetProcAddress(kernel32, "ReleaseActCtx");
- report (R_STATUS, "Extracting tests"); - report (R_PROGRESS, 0, nr_of_files); - nr_of_files = 0; - nr_of_tests = 0; - nr_of_skips = 0; - if (!EnumResourceNamesA (NULL, "TESTRES", extract_test_proc, (LPARAM)tempdir)) - report (R_FATAL, "Can't enumerate test files: %d", - GetLastError ()); + load_image(&image, tempdir);
FreeLibrary(hmscoree);
@@ -1212,9 +1240,9 @@ run_tests (char *logname, char *outdir) report( R_WARNING, "Some dlls are configured as native, you won't be able to submit results." );
report (R_STATUS, "Running tests"); - report (R_PROGRESS, 1, nr_of_tests); - for (i = 0; i < nr_of_files; i++) { - struct wine_test *test = wine_tests + i; + report (R_PROGRESS, 1, image.nr_of_tests); + for (i = 0; i < image.nr_of_files; i++) { + struct wine_test *test = image.wine_tests + i; int j;
if (aborting) break; @@ -1226,7 +1254,8 @@ run_tests (char *logname, char *outdir)
for (j = 0; j < test->subtest_count; j++) { if (aborting) break; - run_test (test, test->subtests[j], logfile, tempdir); + if (!run_test (test, test->subtests[j], logfile, tempdir)) + image.nr_of_skips++; }
if (test->maindllpath) { @@ -1241,7 +1270,8 @@ run_tests (char *logname, char *outdir) logfile = 0; if (newdir) remove_dir (tempdir); - free(wine_tests); + if (nr_of_skips) *nr_of_skips = image.nr_of_skips; + dispose_image(&image); free(curpath);
return logname; @@ -1261,7 +1291,7 @@ static BOOL WINAPI ctrl_handler(DWORD ctrl_type) static BOOL CALLBACK extract_only_proc (HMODULE hModule, LPCSTR lpszType, LPSTR lpszName, LONG_PTR lParam) { - const char *target_dir = (const char *)lParam; + struct winetest_image *image = (struct winetest_image *)lParam; char filename[MAX_PATH];
if (test_filtered_out( lpszName, NULL )) return TRUE; @@ -1269,13 +1299,14 @@ extract_only_proc (HMODULE hModule, LPCSTR lpszType, LPSTR lpszName, LONG_PTR lP strcpy(filename, lpszName); CharLowerA(filename);
- extract_test( &wine_tests[nr_of_files], target_dir, filename ); - nr_of_files++; + extract_test( image, &image->wine_tests[image->nr_of_files], filename ); + image->nr_of_files++; return TRUE; }
static void extract_only (const char *target_dir) { + struct winetest_image image; BOOL res;
report (R_DIR, target_dir); @@ -1283,20 +1314,17 @@ static void extract_only (const char *target_dir) if (!res && GetLastError() != ERROR_ALREADY_EXISTS) report (R_FATAL, "Could not create directory: %s (%d)", target_dir, GetLastError ());
- nr_of_files = 0; - report (R_STATUS, "Counting tests"); - if (!EnumResourceNamesA(NULL, "TESTRES", EnumTestFileProc, (LPARAM)&nr_of_files)) - report (R_FATAL, "Can't enumerate test files: %d", GetLastError ()); - - wine_tests = xalloc(nr_of_files * sizeof wine_tests[0] ); + if (!init_image(&image, target_dir)) return;
report (R_STATUS, "Extracting tests"); - report (R_PROGRESS, 0, nr_of_files); - nr_of_files = 0; - if (!EnumResourceNamesA(NULL, "TESTRES", extract_only_proc, (LPARAM)target_dir)) + report (R_PROGRESS, 0, image.nr_of_files); + image.nr_of_files = 0; + if (!EnumResourceNamesA(image.module, "TESTRES", extract_only_proc, (LPARAM)&image)) report (R_FATAL, "Can't enumerate test files: %d", GetLastError ());
report (R_DELTA, 0, "Extracting: Done"); + + dispose_image(&image); }
static void @@ -1494,7 +1522,7 @@ int __cdecl main( int argc, char *argv[] )
if (nb_filters && !exclude_tests) { - run_tests( logname, outdir ); + run_tests( logname, outdir, NULL ); exit( failures ? 3 : 0 ); }
@@ -1521,7 +1549,8 @@ int __cdecl main( int argc, char *argv[] ) "To submit results, winetest needs to be built from a git checkout." );
if (!logname) { - logname = run_tests (NULL, outdir); + int nr_of_skips; + logname = run_tests (NULL, outdir, &nr_of_skips); if (aborting) { DeleteFileA(logname); exit (0); @@ -1543,7 +1572,7 @@ int __cdecl main( int argc, char *argv[] ) } else { - run_tests (logname, outdir); + run_tests ( logname, outdir, NULL ); report (R_STATUS, "Finished - %u failures", failures); } if (prev_crash_dialog) restore_crash_dialog( prev_crash_dialog );