Skip to content

Commit 7c28654

Browse files
authored
Merge pull request #1059 from PlayEveryWare/tests/native-render
test: Native Render
2 parents addb1d8 + c973a00 commit 7c28654

File tree

10 files changed

+598
-1
lines changed

10 files changed

+598
-1
lines changed

lib/NativeCode/DynamicLibraryLoaderHelper/DynamicLibraryLoaderHelper.sln

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ManagedPluginCode", "Manage
1313
EndProject
1414
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ManagedToUnmanagedBridge", "ManagedToUnmanagedBridge\ManagedToUnmanagedBridge.vcxproj", "{4421F72C-9585-4245-BD8D-FEF6CE45C7D6}"
1515
EndProject
16+
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Tests", "Tests\Tests.vcxproj", "{184A7D0B-6552-41F9-BB60-5621903AD0D6}"
17+
EndProject
1618
Global
1719
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1820
Debug|x64 = Debug|x64
@@ -55,6 +57,14 @@ Global
5557
{4421F72C-9585-4245-BD8D-FEF6CE45C7D6}.Debug|x86.Build.0 = Debug|Win32
5658
{4421F72C-9585-4245-BD8D-FEF6CE45C7D6}.Release|x64.ActiveCfg = Release|x64
5759
{4421F72C-9585-4245-BD8D-FEF6CE45C7D6}.Release|x86.ActiveCfg = Release|Win32
60+
{184A7D0B-6552-41F9-BB60-5621903AD0D6}.Debug|x64.ActiveCfg = Debug|x64
61+
{184A7D0B-6552-41F9-BB60-5621903AD0D6}.Debug|x64.Build.0 = Debug|x64
62+
{184A7D0B-6552-41F9-BB60-5621903AD0D6}.Debug|x86.ActiveCfg = Debug|Win32
63+
{184A7D0B-6552-41F9-BB60-5621903AD0D6}.Debug|x86.Build.0 = Debug|Win32
64+
{184A7D0B-6552-41F9-BB60-5621903AD0D6}.Release|x64.ActiveCfg = Release|x64
65+
{184A7D0B-6552-41F9-BB60-5621903AD0D6}.Release|x64.Build.0 = Release|x64
66+
{184A7D0B-6552-41F9-BB60-5621903AD0D6}.Release|x86.ActiveCfg = Release|Win32
67+
{184A7D0B-6552-41F9-BB60-5621903AD0D6}.Release|x86.Build.0 = Release|Win32
5868
EndGlobalSection
5969
GlobalSection(SolutionProperties) = preSolution
6070
HideSolutionNode = FALSE

lib/NativeCode/DynamicLibraryLoaderHelper/ManagedPluginCode/Application.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ internal static class Application
3333
/// This is the path of the streaming assets directory relative to the
3434
/// output directory of this class library.
3535
/// </summary>
36-
public static readonly string streamingAssetsPath = @"..\..\..\..\Assets\StreamingAssets\";
36+
public static readonly string streamingAssetsPath = @"..\..\..\..\..\..\Assets\StreamingAssets\";
3737

3838
/// <summary>
3939
/// For the purposes of this class library, this field member must be
Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
#ifndef TESTS_COMMON_HPP
2+
#define TESTS_COMMON_HPP
3+
/*
4+
* Copyright (c) 2024 PlayEveryWare
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
#include "pch.h"
26+
27+
#include "eos_helpers.h"
28+
29+
namespace pew::eos::tests
30+
{
31+
// Helper trait to detect if a type supports the << operator
32+
template<typename T, typename Stream, typename = void>
33+
struct supports_streaming : std::false_type {};
34+
35+
// Specialization if the << operator is valid
36+
template<typename T, typename Stream>
37+
struct supports_streaming<T, Stream, std::void_t<decltype(std::declval<Stream&>() << std::declval<T>())>> : std::true_type {};
38+
39+
template<typename T, typename Stream>
40+
inline constexpr bool supports_streaming_v = supports_streaming<T, Stream>::value;
41+
42+
/**
43+
* \brief Utility to convert unsupported types for wide streams.
44+
*/
45+
struct WideStreamHelper {
46+
static std::wstring Convert(const std::string& str) {
47+
return std::wstring(str.begin(), str.end()); // Naive conversion for ASCII strings
48+
}
49+
50+
static const std::wstring& Convert(const std::wstring& str) {
51+
return str;
52+
}
53+
54+
template <typename T>
55+
static const T& Convert(const T& value) {
56+
return value; // Pass through for types that are natively streamable
57+
}
58+
};
59+
60+
/**
61+
* \brief Construct a message to display if an equality assert fails.
62+
* \tparam T1 The type of the unmanaged value.
63+
* \tparam T2 The type of the managed value.
64+
* \param name The name for the value.
65+
* \param unmanaged_value The unmanaged value.
66+
* \param managed_value The managed value.
67+
* \return A string message describing the inequality between two values.
68+
*/
69+
template<typename T1, typename T2,
70+
std::enable_if_t<
71+
(supports_streaming_v<decltype(WideStreamHelper::Convert(std::declval<T1>())), std::wostream>&&
72+
supports_streaming_v<decltype(WideStreamHelper::Convert(std::declval<T2>())), std::wostream>),
73+
int> = 0>
74+
static std::wstring ConstructMessage(const wchar_t* name, const T1& unmanaged_value, const T2& managed_value)
75+
{
76+
std::wstringbuf buffer;
77+
std::wostream os(&buffer);
78+
79+
os << name << L" is not equal (Native: "
80+
<< WideStreamHelper::Convert(unmanaged_value)
81+
<< L", Managed: "
82+
<< WideStreamHelper::Convert(managed_value)
83+
<< L").";
84+
85+
return buffer.str();
86+
}
87+
88+
/**
89+
* @brief Determine whether the value with the indicated name is equal from managed and unmanaged.
90+
* @param name Checks the equality of two values.
91+
* @param c_str The unmanaged value.
92+
* @param str The managed value.
93+
*/
94+
inline void CheckEquality(const wchar_t* name, const char* c_str, System::String^ str)
95+
{
96+
const auto managed = msclr::interop::marshal_as<std::string>(str);
97+
const std::string unmanaged = c_str;
98+
99+
EXPECT_TRUE(managed == unmanaged) << ConstructMessage(name, unmanaged, managed);
100+
}
101+
102+
/**
103+
* This function will check equality between a const char* value and a Utf8String, but it will consider a nullptr Utf8String to be equal to "" for the sake of
104+
* comparison.
105+
*
106+
* @param name The name of the property being examined for equality.
107+
* @param c_str The const char* version of the string.
108+
* @param str The Utf8String object.
109+
*/
110+
inline void CheckEquality(const wchar_t* name, const char* c_str, Epic::OnlineServices::Utf8String^ str)
111+
{
112+
System::String^ string_value = "";
113+
if (str != nullptr)
114+
{
115+
string_value = str->ToString();
116+
}
117+
118+
CheckEquality(name, c_str, string_value);
119+
}
120+
121+
/**
122+
* @brief Determine whether the value with the indicated name is equal from managed and unmanaged.
123+
* @param name Checks the equality of two values.
124+
* @param unmanaged_value The unmanaged value.
125+
* @param managed_value The managed value.
126+
*/
127+
inline void CheckEquality(const wchar_t* name, const uint64_t& unmanaged_value, const uint64_t& managed_value)
128+
{
129+
EXPECT_TRUE(unmanaged_value == managed_value) << ConstructMessage(name, unmanaged_value, managed_value);
130+
}
131+
132+
/**
133+
* @brief Determine whether the value with the indicated name is equal from managed and unmanaged.
134+
* @param name Checks the equality of two values.
135+
* @param unmanaged_value The unmanaged value.
136+
* @param managed_value The managed value.
137+
*/
138+
inline void CheckEquality(const wchar_t* name, const uint32_t& unmanaged_value, const unsigned int managed_value)
139+
{
140+
EXPECT_TRUE(unmanaged_value == managed_value) << ConstructMessage(name, unmanaged_value, managed_value);
141+
}
142+
143+
/**
144+
* @brief Determine whether the value with the indicated name is equal from managed and unmanaged.
145+
* @param name Checks the equality of two values.
146+
* @param unmanaged_value The unmanaged value.
147+
* @param managed_value The managed value.
148+
*/
149+
inline void CheckEquality(const wchar_t* name, const double* unmanaged_value, System::Nullable<double>& managed_value)
150+
{
151+
// Helper to extract value or default for System::Nullable<double>
152+
auto get_managed_value = [](System::Nullable<double>& value, double default_value = 0.0) -> double {
153+
return value.HasValue ? value.Value : default_value;
154+
};
155+
156+
// Helper to extract value or default for unmanaged pointer
157+
auto get_unmanaged_value = [](const double* value, double default_value = 0.0) -> double {
158+
return value ? *value : default_value;
159+
};
160+
161+
// If both are "null," they are considered equal
162+
if (!unmanaged_value && !managed_value.HasValue)
163+
{
164+
return; // Equal; no need to proceed
165+
}
166+
167+
// If only one is "null," they cannot be equal
168+
if (!unmanaged_value || !managed_value.HasValue)
169+
{
170+
EXPECT_TRUE(false) << "Mismatch: "
171+
<< (unmanaged_value ? *unmanaged_value : NAN)
172+
<< " vs. "
173+
<< (managed_value.HasValue ? managed_value.Value : NAN)
174+
<< " (unmanaged vs. managed).";
175+
return;
176+
}
177+
178+
// Extract the actual values
179+
double unmanaged_dbl_value = get_unmanaged_value(unmanaged_value);
180+
double managed_dbl_value = get_managed_value(managed_value);
181+
182+
// Construct message for failure reporting
183+
const auto message = ConstructMessage(name, unmanaged_dbl_value, managed_dbl_value);
184+
185+
// Assert equality
186+
EXPECT_TRUE(unmanaged_dbl_value == managed_dbl_value) << message;
187+
}
188+
189+
/**
190+
* @brief Determine whether the value with the indicated name is equal from managed and unmanaged.
191+
* @param name Checks the equality of two values.
192+
* @param unmanaged_value The unmanaged value.
193+
* @param managed_value The managed value.
194+
*/
195+
inline void CheckEquality(const wchar_t* name, const EOS_Bool& unmanaged_value, const bool managed_value)
196+
{
197+
bool unmanaged_bool_value = (unmanaged_value == 1);
198+
199+
EXPECT_TRUE(unmanaged_bool_value == managed_value) << ConstructMessage(name, unmanaged_value, managed_value);
200+
}
201+
202+
/**
203+
* @brief Determine whether the value with the indicated name is equal from managed and unmanaged.
204+
* @param name Checks the equality of two values.
205+
* @param unmanaged_value The unmanaged value.
206+
* @param managed_value The managed value.
207+
*/
208+
inline void CheckEquality(const wchar_t* name, const int32_t& unmanaged_value, const int32_t& managed_value)
209+
{
210+
EXPECT_TRUE(unmanaged_value == managed_value) << ConstructMessage(name, unmanaged_value, managed_value);
211+
}
212+
}
213+
214+
#endif
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
#ifndef CONFIG_EQUALITY_TESTS_HPP
2+
#define CONFIG_EQUALITY_TESTS_HPP
3+
4+
/*
5+
* Copyright (c) 2024 PlayEveryWare
6+
*
7+
* Permission is hereby granted, free of charge, to any person obtaining a copy
8+
* of this software and associated documentation files (the "Software"), to deal
9+
* in the Software without restriction, including without limitation the rights
10+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
* copies of the Software, and to permit persons to whom the Software is
12+
* furnished to do so, subject to the following conditions:
13+
*
14+
* The above copyright notice and this permission notice shall be included in
15+
* all copies or substantial portions of the Software.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23+
* SOFTWARE.
24+
*/
25+
26+
#include "pch.h"
27+
28+
#include "ConfigurationUtilityBridge.hpp"
29+
#include "CppUnitTest.h"
30+
#include "eos_helpers.h"
31+
#include "Common.hpp"
32+
33+
namespace pew::eos::tests
34+
{
35+
/**
36+
* \brief Initialize the Common Language Runtime.
37+
*/
38+
static void InitializeCLR()
39+
{
40+
gcnew String(L"CLR initialized");
41+
}
42+
43+
/**
44+
* @brief This test checks to see that the native component of the plugin
45+
* and the managed component of the plugin both generate the same initialize
46+
* options for initializing the EOS SDK.
47+
*/
48+
TEST(NativeRenderConfigMatchesUnityConfig, Test_Initialize_Options_Are_Equal)
49+
{
50+
InitializeCLR();
51+
const auto native_initialize_options = PEW_EOS_Get_InitializeOptions();
52+
const auto managed_platform_initialize_options = ConfigurationUtilityBridge::get_initialize_options();
53+
54+
// Check the product name and product version for equality.
55+
CheckEquality(L"ProductName", native_initialize_options.ProductName, managed_platform_initialize_options->ProductName->ToString());
56+
CheckEquality(L"ProductVersion", native_initialize_options.ProductVersion, managed_platform_initialize_options->ProductVersion->ToString());
57+
58+
// If the override thread affinity is set, then check equality for each value.
59+
if (nullptr != native_initialize_options.OverrideThreadAffinity)
60+
{
61+
CheckEquality(L"OverrideThreadAffinity.NetworkWork", native_initialize_options.OverrideThreadAffinity->NetworkWork, managed_platform_initialize_options->OverrideThreadAffinity.Value.NetworkWork);
62+
CheckEquality(L"OverrideThreadAffinity.StorageIo", native_initialize_options.OverrideThreadAffinity->StorageIo, managed_platform_initialize_options->OverrideThreadAffinity.Value.StorageIo);
63+
CheckEquality(L"OverrideThreadAffinity.WebSocketIo", native_initialize_options.OverrideThreadAffinity->WebSocketIo, managed_platform_initialize_options->OverrideThreadAffinity.Value.WebSocketIo);
64+
CheckEquality(L"OverrideThreadAffinity.P2PIo", native_initialize_options.OverrideThreadAffinity->P2PIo, managed_platform_initialize_options->OverrideThreadAffinity.Value.P2PIo);
65+
CheckEquality(L"OverrideThreadAffinity.HttpRequestIo", native_initialize_options.OverrideThreadAffinity->HttpRequestIo, managed_platform_initialize_options->OverrideThreadAffinity.Value.HttpRequestIo);
66+
CheckEquality(L"OverrideThreadAffinity.RTCIo", native_initialize_options.OverrideThreadAffinity->RTCIo, managed_platform_initialize_options->OverrideThreadAffinity.Value.RTCIo);
67+
CheckEquality(L"OverrideThreadAffinity.EmbeddedOverlayMainThread", native_initialize_options.OverrideThreadAffinity->EmbeddedOverlayMainThread, managed_platform_initialize_options->OverrideThreadAffinity.Value.EmbeddedOverlayMainThread);
68+
CheckEquality(L"OverrideThreadAffinity.EmbeddedOverlayWorkerThreads", native_initialize_options.OverrideThreadAffinity->EmbeddedOverlayWorkerThreads, managed_platform_initialize_options->OverrideThreadAffinity.Value.EmbeddedOverlayWorkerThreads);
69+
}
70+
}
71+
72+
/**
73+
* @brief This test checks to see that the create options that are generated
74+
* by the native render and the managed component of the unity plugin are the
75+
* same.
76+
*/
77+
TEST(NativeRenderConfigMatchesUnityConfig, Test_Create_Options_Are_Equal)
78+
{
79+
InitializeCLR();
80+
81+
const auto native_create_options = PEW_EOS_Get_CreateOptions();
82+
const auto managed_create_options = ConfigurationUtilityBridge::get_windows_options();
83+
84+
// TODO: Note that CacheDirectory is different since it is determined differently
85+
// CheckEquality(L"CacheDirectory", native_create_options.CacheDirectory, managed_create_options->CacheDirectory->ToString());
86+
87+
// Check the primary deployment values.
88+
CheckEquality(L"DeploymentId", native_create_options.DeploymentId, managed_create_options->DeploymentId->ToString());
89+
CheckEquality(L"SandboxId", native_create_options.SandboxId, managed_create_options->SandboxId->ToString());
90+
91+
// Check the flags.
92+
CheckEquality(L"Flags", native_create_options.Flags, static_cast<uint64_t>(managed_create_options->Flags));
93+
94+
// Check the product id.
95+
CheckEquality(L"ProductId", native_create_options.ProductId, managed_create_options->ProductId->ToString());
96+
97+
// Check the client credentials and file encryption key.
98+
CheckEquality(L"ClientId", native_create_options.ClientCredentials.ClientId, managed_create_options->ClientCredentials.ClientId->ToString());
99+
CheckEquality(L"ClientSecret", native_create_options.ClientCredentials.ClientSecret, managed_create_options->ClientCredentials.ClientSecret->ToString());
100+
CheckEquality(L"EncryptionKey", native_create_options.EncryptionKey, managed_create_options->EncryptionKey->ToString());
101+
102+
// Check the timeout values.
103+
CheckEquality(L"TickBudgetInMilliseconds", native_create_options.TickBudgetInMilliseconds, managed_create_options->TickBudgetInMilliseconds);
104+
CheckEquality(L"TaskNetworkTimeoutSeconds", native_create_options.TaskNetworkTimeoutSeconds, managed_create_options->TaskNetworkTimeoutSeconds);
105+
106+
// Check the deployment parameter indicating whether the deployment is a server or not.
107+
CheckEquality(L"IsServer", native_create_options.bIsServer, managed_create_options->IsServer);
108+
109+
// TODO: Checking the OverrideCountryCode and OverrideLocaleCode causes a strange error, but since they are not supported in the Unity editor they currently do not need to be tested.
110+
//CheckEquality(L"OverrideCountryCode", native_create_options.OverrideCountryCode, managed_create_options->OverrideCountryCode);
111+
//CheckEquality(L"OverrideLocaleCode", native_create_options.OverrideLocaleCode, managed_create_options->OverrideLocaleCode);
112+
113+
/* TODO: RTCOptions are currently not supported within the Unity Editor, so comparison of them does not make sense.
114+
bool native_rtc_is_null = native_create_options.RTCOptions == nullptr;
115+
bool managed_rtc_is_null = managed_create_options->RTCOptions.HasValue == false;
116+
117+
EXPECT_TRUE(native_rtc_is_null == managed_rtc_is_null) << ConstructMessage(L"RTCOptions (Is Null)", native_rtc_is_null, managed_rtc_is_null);
118+
119+
if (!native_rtc_is_null && !managed_rtc_is_null)
120+
{
121+
CheckEquality(L"RTCOptions.BackgroundMode", static_cast<int>(native_create_options.RTCOptions->BackgroundMode), static_cast<int>(managed_create_options->RTCOptions.Value.BackgroundMode));
122+
}
123+
*/
124+
}
125+
}
126+
127+
#endif

0 commit comments

Comments
 (0)