Add Mock CoreCLR (dotnet/core-setup#5823)
authorSteve MacLean <stmaclea@microsoft.com>
Sat, 13 Apr 2019 15:54:02 +0000 (11:54 -0400)
committerGitHub <noreply@github.com>
Sat, 13 Apr 2019 15:54:02 +0000 (11:54 -0400)
* Add Mock CoreCLR

* Add MockLog* macros

* Use SHARED_API

Commit migrated from https://github.com/dotnet/core-setup/commit/6e994af6195ac90c9050a54c317a6623a729962e

src/installer/corehost/cli/test/CMakeLists.txt
src/installer/corehost/cli/test/mockcoreclr/CMakeLists.txt [new file with mode: 0644]
src/installer/corehost/cli/test/mockcoreclr/mockcoreclr.cpp [new file with mode: 0644]
src/installer/corehost/cli/test/mockcoreclr/mockcoreclr.h [new file with mode: 0644]

index c898a29..4e1df27 100644 (file)
@@ -1,2 +1,3 @@
+add_subdirectory(mockcoreclr)
 add_subdirectory(mockhostpolicy)
-add_subdirectory(nativehost)
\ No newline at end of file
+add_subdirectory(nativehost)
diff --git a/src/installer/corehost/cli/test/mockcoreclr/CMakeLists.txt b/src/installer/corehost/cli/test/mockcoreclr/CMakeLists.txt
new file mode 100644 (file)
index 0000000..6e0294b
--- /dev/null
@@ -0,0 +1,17 @@
+# Licensed to the .NET Foundation under one or more agreements.
+# The .NET Foundation licenses this file to you under the MIT license.
+# See the LICENSE file in the project root for more information.
+
+cmake_minimum_required (VERSION 2.6)
+project(mockcoreclr)
+
+set(DOTNET_PROJECT_NAME "mockcoreclr")
+
+set(SOURCES
+    ./mockcoreclr.cpp
+)
+
+include(../testlib.cmake)
+
+install(TARGETS mockcoreclr DESTINATION corehost_test)
+install_symbols(mockcoreclr corehost_test)
diff --git a/src/installer/corehost/cli/test/mockcoreclr/mockcoreclr.cpp b/src/installer/corehost/cli/test/mockcoreclr/mockcoreclr.cpp
new file mode 100644 (file)
index 0000000..5fdcfa8
--- /dev/null
@@ -0,0 +1,214 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+#include "mockcoreclr.h"
+#include <iostream>
+#include "trace.h"
+
+#define MockLog(string) std::cout << "mock " << string << std::endl;
+#define MockLogArg(arg) std::cout << "mock " << #arg << ":" << arg << std::endl;
+#define MockLogEntry(dict, key, value) std::cout << "mock " << dict << "[" << key << "] = " << value << std::endl;
+
+SHARED_API pal::hresult_t STDMETHODCALLTYPE coreclr_initialize(
+    const char* exePath,
+    const char* appDomainFriendlyName,
+    int propertyCount,
+    const char** propertyKeys,
+    const char** propertyValues,
+    coreclr_t::host_handle_t* hostHandle,
+    unsigned int* domainId)
+{
+    MockLog("coreclr_initialize() called");
+    MockLogArg(exePath);
+    MockLogArg(appDomainFriendlyName);
+    MockLogArg(propertyCount);
+    MockLogArg(propertyKeys);
+    MockLogArg(propertyValues);
+    MockLogArg(hostHandle);
+    MockLogArg(domainId);
+
+    for (int i = 0; i < propertyCount; ++i)
+    {
+        MockLogEntry("property", propertyKeys[i], propertyValues[i]);
+    }
+
+    if (hostHandle != nullptr)
+    {
+        *hostHandle = (coreclr_t::host_handle_t*) 0xdeadbeef;
+    }
+
+    return StatusCode::Success;
+}
+
+
+// Prototype of the coreclr_shutdown function from coreclr.dll
+SHARED_API pal::hresult_t STDMETHODCALLTYPE coreclr_shutdown_2(
+    coreclr_t::host_handle_t hostHandle,
+    unsigned int domainId,
+    int* latchedExitCode)
+{
+    MockLog("coreclr_shutdown_2() called");
+    MockLogArg(hostHandle);
+    MockLogArg(domainId);
+
+    if (latchedExitCode != nullptr)
+    {
+        *latchedExitCode = 0;
+    }
+
+    return StatusCode::Success;
+}
+
+// Prototype of the coreclr_execute_assembly function from coreclr.dll
+SHARED_API pal::hresult_t STDMETHODCALLTYPE coreclr_execute_assembly(
+    coreclr_t::host_handle_t hostHandle,
+    unsigned int domainId,
+    int argc,
+    const char** argv,
+    const char* managedAssemblyPath,
+    unsigned int* exitCode)
+{
+    MockLog("coreclr_execute_assembly() called");
+    MockLogArg(hostHandle);
+    MockLogArg(domainId);
+    MockLogArg(argc);
+    MockLogArg(argv);
+    MockLogArg(managedAssemblyPath);
+
+    for (int i = 0; i < argc; ++i)
+    {
+        MockLogEntry("argv", i, argv[i]);
+    }
+
+    if (exitCode != nullptr)
+    {
+        *exitCode = 0;
+    }
+
+    return StatusCode::Success;
+}
+
+struct MockCoreClrDelegate
+{
+    MockCoreClrDelegate() {}
+    MockCoreClrDelegate(coreclr_t::host_handle_t hostHandle,
+                        unsigned int domainId,
+                        const char* entryPointAssemblyName,
+                        const char* entryPointTypeName,
+                        const char* entryPointMethodName) :
+    m_hostHandle(hostHandle),
+    m_domainId(domainId),
+    m_entryPointAssemblyName(entryPointAssemblyName),
+    m_entryPointTypeName(entryPointTypeName),
+    m_entryPointMethodName(entryPointMethodName),
+    initialized(true)
+    {}
+
+    coreclr_t::host_handle_t m_hostHandle;
+    unsigned int             m_domainId;
+    std::string              m_entryPointAssemblyName;
+    std::string              m_entryPointTypeName;
+    std::string              m_entryPointMethodName;
+    bool initialized;
+
+    void Echo()
+    {
+        MockLog("Delegate called");
+
+        if (!initialized)
+        {
+            MockLog("ERROR called unitialized delegate!!!");
+            return;
+        }
+
+        MockLogArg(m_hostHandle);
+        MockLogArg(m_domainId);
+        MockLogArg(m_entryPointAssemblyName);
+        MockLogArg(m_entryPointTypeName);
+        MockLogArg(m_entryPointMethodName);
+    }
+};
+
+typedef void (*CoreClrDelegate)();
+
+const int MaxDelegates = 16;
+
+MockCoreClrDelegate DelegateState[MaxDelegates];
+
+#define DelegateFunction(index)\
+void Delegate_ ## index() { DelegateState[index].Echo(); }
+
+DelegateFunction(0);
+DelegateFunction(1);
+DelegateFunction(2);
+DelegateFunction(3);
+DelegateFunction(4);
+DelegateFunction(5);
+DelegateFunction(6);
+DelegateFunction(7);
+DelegateFunction(8);
+DelegateFunction(9);
+DelegateFunction(10);
+DelegateFunction(11);
+DelegateFunction(12);
+DelegateFunction(13);
+DelegateFunction(14);
+DelegateFunction(15);
+
+#undef DelegateFunction
+
+// Prototype of the coreclr_create_delegate function from coreclr.dll
+SHARED_API pal::hresult_t STDMETHODCALLTYPE coreclr_create_delegate(
+    coreclr_t::host_handle_t hostHandle,
+    unsigned int domainId,
+    const char* entryPointAssemblyName,
+    const char* entryPointTypeName,
+    const char* entryPointMethodName,
+    void** delegate)
+{
+    MockLog("coreclr_create_delegate() called");
+    MockLogArg(hostHandle);
+    MockLogArg(domainId);
+    MockLogArg(entryPointAssemblyName);
+    MockLogArg(entryPointTypeName);
+    MockLogArg(entryPointMethodName);
+    MockLogArg(delegate);
+
+    static int nextDelegate = 0;
+    static CoreClrDelegate delegates[] =
+    {
+        Delegate_0,
+        Delegate_1,
+        Delegate_2,
+        Delegate_3,
+        Delegate_4,
+        Delegate_5,
+        Delegate_6,
+        Delegate_7,
+        Delegate_8,
+        Delegate_9,
+        Delegate_10,
+        Delegate_11,
+        Delegate_12,
+        Delegate_13,
+        Delegate_14,
+        Delegate_15
+    };
+
+    int delegateIndex = (nextDelegate++);
+
+    while (delegateIndex >= MaxDelegates)
+    {
+        delegateIndex -= MaxDelegates;
+        MockLog("MaxDelegates exceeded recycling older ones");
+    }
+
+    MockCoreClrDelegate delegateState(hostHandle, domainId, entryPointAssemblyName, entryPointTypeName, entryPointMethodName);
+
+    DelegateState[delegateIndex] = delegateState;
+
+    *delegate = (void*) delegates[delegateIndex];
+
+    return StatusCode::Success;
+}
diff --git a/src/installer/corehost/cli/test/mockcoreclr/mockcoreclr.h b/src/installer/corehost/cli/test/mockcoreclr/mockcoreclr.h
new file mode 100644 (file)
index 0000000..ffa02a2
--- /dev/null
@@ -0,0 +1,51 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+#ifndef _MOCKCORECLR_H_
+#define _MOCKCORECLR_H_
+
+#include "pal.h"
+#include "error_codes.h"
+
+namespace coreclr_t
+{
+    using host_handle_t = void*;
+    using domain_id_t = std::uint32_t;
+};
+
+// Prototype of the coreclr_initialize function from coreclr.dll
+SHARED_API pal::hresult_t STDMETHODCALLTYPE coreclr_initialize(
+    const char* exePath,
+    const char* appDomainFriendlyName,
+    int propertyCount,
+    const char** propertyKeys,
+    const char** propertyValues,
+    coreclr_t::host_handle_t* hostHandle,
+    unsigned int* domainId);
+
+// Prototype of the coreclr_shutdown function from coreclr.dll
+SHARED_API pal::hresult_t STDMETHODCALLTYPE coreclr_shutdown_2(
+    coreclr_t::host_handle_t hostHandle,
+    unsigned int domainId,
+    int* latchedExitCode);
+
+// Prototype of the coreclr_execute_assembly function from coreclr.dll
+SHARED_API pal::hresult_t STDMETHODCALLTYPE coreclr_execute_assembly(
+    coreclr_t::host_handle_t hostHandle,
+    unsigned int domainId,
+    int argc,
+    const char** argv,
+    const char* managedAssemblyPath,
+    unsigned int* exitCode);
+
+// Prototype of the coreclr_create_delegate function from coreclr.dll
+SHARED_API pal::hresult_t STDMETHODCALLTYPE coreclr_create_delegate(
+    coreclr_t::host_handle_t hostHandle,
+    unsigned int domainId,
+    const char* entryPointAssemblyName,
+    const char* entryPointTypeName,
+    const char* entryPointMethodName,
+    void** delegate);
+
+#endif // _MOCKCORECLR_H_