Module: wine Branch: master Commit: b99c35c0e84bbfb4c37fa49aa391758845cb7921 URL: http://source.winehq.org/git/wine.git/?a=commit;h=b99c35c0e84bbfb4c37fa49aa3...
Author: Vincent Povirk vincent@codeweavers.com Date: Mon Feb 22 15:04:02 2016 -0600
mscoree/tests: Check if the runtime is usable before loading it.
Unfortunately, Mono calls exit(1) if it can't load its class libraries, which is the way Wine fails on x86_64, meaning we have to spawn another process to check if the runtime works.
Signed-off-by: Vincent Povirk vincent@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/mscoree/tests/mscoree.c | 110 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 109 insertions(+), 1 deletion(-)
diff --git a/dlls/mscoree/tests/mscoree.c b/dlls/mscoree/tests/mscoree.c index 106577e..6923f2a 100644 --- a/dlls/mscoree/tests/mscoree.c +++ b/dlls/mscoree/tests/mscoree.c @@ -17,6 +17,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#include <stdio.h> + #define COBJMACROS
#include "corerror.h" @@ -72,6 +74,97 @@ static BOOL init_functionpointers(void) return TRUE; }
+static int check_runtime(void) +{ + ICLRMetaHost *metahost; + ICLRRuntimeInfo *runtimeinfo; + ICorRuntimeHost *runtimehost; + HRESULT hr; + + if (!pCLRCreateInstance) + { + win_skip("Function CLRCreateInstance not found.\n"); + return 1; + } + + hr = pCLRCreateInstance(&CLSID_CLRMetaHost, &IID_ICLRMetaHost, (void **)&metahost); + if (hr == E_NOTIMPL) + { + win_skip("CLRCreateInstance not implemented\n"); + return 1; + } + ok(SUCCEEDED(hr), "CLRCreateInstance failed, hr=%#.8x\n", hr); + if (FAILED(hr)) + return 1; + + hr = ICLRMetaHost_GetRuntime(metahost, v4_0, &IID_ICLRRuntimeInfo, (void **)&runtimeinfo); + ok(SUCCEEDED(hr), "ICLRMetaHost::GetRuntime failed, hr=%#.8x\n", hr); + if (FAILED(hr)) + return 1; + + hr = ICLRRuntimeInfo_GetInterface(runtimeinfo, &CLSID_CorRuntimeHost, &IID_ICorRuntimeHost, + (void **)&runtimehost); + ok(SUCCEEDED(hr), "ICLRRuntimeInfo::GetInterface failed, hr=%#.8x\n", hr); + if (FAILED(hr)) + return 1; + + hr = ICorRuntimeHost_Start(runtimehost); + ok(SUCCEEDED(hr), "ICorRuntimeHost::Start failed, hr=%#.8x\n", hr); + if (FAILED(hr)) + return 1; + + ICorRuntimeHost_Release(runtimehost); + + ICLRRuntimeInfo_Release(runtimeinfo); + + ICLRMetaHost_ExitProcess(metahost, 0); + + ok(0, "ICLRMetaHost_ExitProcess is not supposed to return\n"); + return 1; +} + +static BOOL runtime_is_usable(void) +{ + static const char cmdline_format[] = ""%s" mscoree check_runtime"; + char** argv; + char cmdline[MAX_PATH + sizeof(cmdline_format)]; + STARTUPINFOA si = {0}; + PROCESS_INFORMATION pi; + BOOL ret; + DWORD exitcode; + + winetest_get_mainargs(&argv); + + sprintf(cmdline, cmdline_format, argv[0]); + + si.cb = sizeof(si); + + ret = CreateProcessA(NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); + ok(ret, "CreateProcessA failed\n"); + if (!ret) + return FALSE; + + CloseHandle(pi.hThread); + + WaitForSingleObject(pi.hProcess, INFINITE); + + ret = GetExitCodeProcess(pi.hProcess, &exitcode); + CloseHandle(pi.hProcess); + + ok(ret, "GetExitCodeProcess failed\n"); + + if (!ret || exitcode != 0) + { +#ifndef __i386__ + todo_wine +#endif + win_skip(".NET 4.0 runtime is not usable\n"); + return FALSE; + } + + return TRUE; +} + static void test_versioninfo(void) { const WCHAR v9_0[] = {'v','9','.','0','.','3','0','3','1','9',0}; @@ -520,14 +613,29 @@ static void test_createdomain(void)
START_TEST(mscoree) { + int argc; + char** argv; + if (!init_functionpointers()) return;
+ argc = winetest_get_mainargs(&argv); + if (argc >= 3 && !strcmp(argv[2], "check_runtime")) + { + int result = check_runtime(); + FreeLibrary(hmscoree); + exit(result); + } + test_versioninfo(); test_loadlibraryshim(); test_createconfigstream(); test_createinstance(); - test_createdomain(); + + if (runtime_is_usable()) + { + test_createdomain(); + }
FreeLibrary(hmscoree); }