Skip to content

Commit

Permalink
Add UnrealPlugin test project (#165)
Browse files Browse the repository at this point in the history
  • Loading branch information
tculotta committed Feb 14, 2024
1 parent ecf17ac commit ca26f5b
Show file tree
Hide file tree
Showing 39 changed files with 3,472 additions and 21 deletions.
16 changes: 13 additions & 3 deletions UnrealPlugin/Source/PlayFabGSDK/Private/GSDKConfiguration.h
Expand Up @@ -39,7 +39,11 @@ class FConfiguration
static constexpr const TCHAR* SHARED_CONTENT_FOLDER_ENV_VAR = TEXT("SHARED_CONTENT_FOLDER");
};

class FConfigurationBase : public FConfiguration
class
#if (WITH_DEV_AUTOMATION_TESTS && WITH_EDITOR)
PLAYFABGSDK_API
#endif
FConfigurationBase : public FConfiguration
{
public:
FConfigurationBase();
Expand Down Expand Up @@ -90,7 +94,11 @@ class FEnvironmentVariableConfiguration : public FConfigurationBase
FGameServerConnectionInfo ConnectionInfo;
};

class FJsonFileConfiguration : public FConfigurationBase
class
#if (WITH_DEV_AUTOMATION_TESTS && WITH_EDITOR)
PLAYFABGSDK_API
#endif
FJsonFileConfiguration : public FConfigurationBase
{
public:
FJsonFileConfiguration(const FString& FileName);
Expand All @@ -107,7 +115,9 @@ class FJsonFileConfiguration : public FConfigurationBase
virtual const FString& GetFullyQualifiedDomainName() override;
virtual const FGameServerConnectionInfo& GetGameServerConnectionInfo() override;

private:
protected:
FJsonFileConfiguration() = default;

FString HeartbeatEndpoint;
FString ServerId;
FString LogFolder;
Expand Down
34 changes: 27 additions & 7 deletions UnrealPlugin/Source/PlayFabGSDK/Private/GSDKInternal.cpp
Expand Up @@ -91,6 +91,7 @@ FGSDKInternal::FGSDKInternal()
HttpHeaders.Add(TEXT("Accept"), TEXT("application/json"));
HttpHeaders.Add(TEXT("Content-Type"), TEXT("application/json; charset=utf-8"));

#if !(WITH_DEV_AUTOMATION_TESTS && WITH_EDITOR)
SignalHeartbeatEvent->Reset();

KeepHeartbeatRunning = ConfigPtr->ShouldHeartbeat();
Expand All @@ -101,6 +102,7 @@ FGSDKInternal::FGSDKInternal()
HeartbeatAsyncTaskFunction();
}
);
#endif
}

FGSDKInternal::~FGSDKInternal()
Expand Down Expand Up @@ -274,6 +276,7 @@ void FGSDKInternal::DecodeHeartbeatResponse(const FString& ResponseJson)
if (!FJsonSerializer::Deserialize(Reader, HeartbeatResponseJson))
{
UE_LOG(LogPlayFabGSDK, Error, TEXT("Failed to parse heartbeat"));
UE_LOG(LogPlayFabGSDK, Error, TEXT("%s"), *ResponseJson);
return;
}

Expand Down Expand Up @@ -352,7 +355,16 @@ void FGSDKInternal::DecodeHeartbeatResponse(const FString& ResponseJson)

if (HeartbeatResponseJson->HasField(TEXT("operation")))
{
EOperation NextOperation = OperationMap[HeartbeatResponseJson->GetStringField(TEXT("operation"))];
auto operation = HeartbeatResponseJson->GetStringField(TEXT("operation"));

if (!OperationMap.Contains(operation))
{
UE_LOG(LogPlayFabGSDK, Error, TEXT("An error occured while processing heartbeat operation."));
UE_LOG(LogPlayFabGSDK, Error, TEXT("Message: %s"), *ResponseJson);
return;
}

EOperation NextOperation = OperationMap[operation];

bool bWasOperationValid = true;

Expand All @@ -366,14 +378,18 @@ void FGSDKInternal::DecodeHeartbeatResponse(const FString& ResponseJson)
{
if (HeartbeatRequest.CurrentGameState != EGameState::Active)
{
#if !(WITH_DEV_AUTOMATION_TESTS && WITH_EDITOR)
AsyncTask(ENamedThreads::GameThread, [this]()
{
SetState(EGameState::Active);
if (this->OnServerActive.IsBound())
{
this->OnServerActive.Execute();
}
});
#endif
SetState(EGameState::Active);
if (this->OnServerActive.IsBound())
{
this->OnServerActive.Execute();
}
#if !(WITH_DEV_AUTOMATION_TESTS && WITH_EDITOR)
});
#endif
}
break;
}
Expand Down Expand Up @@ -484,12 +500,16 @@ void FGSDKInternal::SetConnectedPlayers(const TArray<FConnectedPlayer>& CurrentC
void FGSDKInternal::ReadyForPlayers()
{
UE_LOG(LogPlayFabGSDK, Display, TEXT("ReadyForPlayers, setting game state to StandingBy!"));
#if !(WITH_DEV_AUTOMATION_TESTS && WITH_EDITOR)
AsyncTask(ENamedThreads::GameThread, [this]()
{
#endif
SetState(EGameState::StandingBy);
if (OnReadyForPlayers.IsBound())
{
OnReadyForPlayers.Execute();
}
#if !(WITH_DEV_AUTOMATION_TESTS && WITH_EDITOR)
});
#endif
}
23 changes: 21 additions & 2 deletions UnrealPlugin/Source/PlayFabGSDK/Private/PlayFabGSDK.cpp
Expand Up @@ -2,7 +2,7 @@

#include "PlayFabGSDK.h"

#if UE_SERVER
#if UE_SERVER || (WITH_DEV_AUTOMATION_TESTS && WITH_EDITOR)
#define PLAYFAB_GSDK_SERVER true
#else
#define PLAYFAB_GSDK_SERVER false
Expand All @@ -21,6 +21,12 @@ DEFINE_LOG_CATEGORY(LogPlayFabGSDK);
#define LOCTEXT_NAMESPACE "FPlayFabGSDKModule"

void FPlayFabGSDKModule::StartupModule()
#if (WITH_DEV_AUTOMATION_TESTS && WITH_EDITOR)
{
}

void FPlayFabGSDKModule::ManualStartupModule()
#endif
{
#if PLAYFAB_GSDK_SERVER
if (FParse::Param(FCommandLine::Get(), TEXT("noGSDK")) || FParse::Param(FCommandLine::Get(), TEXT("nogsdk")))
Expand Down Expand Up @@ -60,7 +66,7 @@ void FPlayFabGSDKModule::StartupModule()
return OnHealthCheck.Execute();
}

return false;
return true;
});
GSDKInternal->OnMaintenance.BindLambda([this](const FDateTime& Time)
{
Expand Down Expand Up @@ -143,6 +149,19 @@ const TArray<FString> FPlayFabGSDKModule::GetInitialPlayers()
#endif
}

#if (WITH_DEV_AUTOMATION_TESTS && WITH_EDITOR)
void FPlayFabGSDKModule::ResetInternalState()
{
GSDKInternal.Reset(nullptr);

OnShutdown.Unbind();
OnServerActive.Unbind();
OnReadyForPlayers.Unbind();
OnHealthCheck.Unbind();
OnMaintenance.Unbind();
}
#endif

#undef LOCTEXT_NAMESPACE

IMPLEMENT_MODULE(FPlayFabGSDKModule, PlayFabGSDK)
21 changes: 14 additions & 7 deletions UnrealPlugin/Source/PlayFabGSDK/Public/GSDKInternal.h
Expand Up @@ -111,7 +111,11 @@ struct FHeartbeatResponse
FDateTime NextScheduledMaintenanceUtc;
};

class FGSDKInternal
class
#if (WITH_DEV_AUTOMATION_TESTS && WITH_EDITOR)
PLAYFABGSDK_API
#endif
FGSDKInternal
{
public:
// These must be public for unique_ptr to work
Expand Down Expand Up @@ -153,8 +157,8 @@ class FGSDKInternal
FOnReadyForPlayers OnReadyForPlayers;
FOnMaintenance OnMaintenance;
FOnHealthCheck OnHealthCheck;
private:

private:
#define ADD_OPERATION_MAP(VAR) ReturnMap.Add(TEXT(#VAR), EOperation::VAR);
static TMap<FString, EOperation> InitializeOperationMap()
{
Expand Down Expand Up @@ -209,13 +213,16 @@ class FGSDKInternal
void SendHeartbeat();
void ReceiveHeartbeat();

// These two methods are used for unit testing as well as regular operation.
FString EncodeHeartbeatRequest();
void DecodeHeartbeatResponse(const FString& ResponseJson);
int32 NextHeartbeatIntervalMs;

FDateTime ParseDate(const FString& DateStr);


void TriggerShutdown();

#if (WITH_DEV_AUTOMATION_TESTS && WITH_EDITOR)
public:
#endif
int32 NextHeartbeatIntervalMs;
// These two methods are used for unit testing as well as regular operation.
FString EncodeHeartbeatRequest();
void DecodeHeartbeatResponse(const FString& ResponseJson);
};
14 changes: 12 additions & 2 deletions UnrealPlugin/Source/PlayFabGSDK/Public/PlayFabGSDK.h
Expand Up @@ -15,14 +15,23 @@ DECLARE_LOG_CATEGORY_EXTERN(LogPlayFabGSDK, Log, All);



class FPlayFabGSDKModule : public IModuleInterface
class
#if (WITH_DEV_AUTOMATION_TESTS && WITH_EDITOR)
PLAYFABGSDK_API
#endif
FPlayFabGSDKModule : public IModuleInterface
{
public:

/** IModuleInterface implementation */
virtual void StartupModule() override;
virtual void ShutdownModule() override;

#if (WITH_DEV_AUTOMATION_TESTS && WITH_EDITOR)
void ManualStartupModule();
void ResetInternalState();
#endif

static FPlayFabGSDKModule& Get() { return FModuleManager::LoadModuleChecked<FPlayFabGSDKModule>(TEXT("PlayFabGSDK"));}

// Sets state to StandBy to mark end of server initialization. Name follows convention of GSDK where once
Expand Down Expand Up @@ -96,8 +105,9 @@ class FPlayFabGSDKModule : public IModuleInterface
static constexpr const TCHAR* SESSION_COOKIE_KEY = TEXT("sessionCookie");
static constexpr const TCHAR* SESSION_ID_KEY = TEXT("sessionId";)

#if !(WITH_DEV_AUTOMATION_TESTS && WITH_EDITOR)
private:

#endif
TUniquePtr<FGSDKInternal> GSDKInternal = nullptr;

bool NoGSDK = false;
Expand Down
77 changes: 77 additions & 0 deletions UnrealPlugin/TestingProject/.gitignore
@@ -0,0 +1,77 @@
# Visual Studio 2015 user specific files
.vs/

# Compiled Object files
*.slo
*.lo
*.o
*.obj

# Precompiled Headers
*.gch
*.pch

# Compiled Dynamic libraries
*.so
*.dylib
*.dll

# Fortran module files
*.mod

# Compiled Static libraries
*.lai
*.la
*.a
*.lib

# Executables
*.exe
*.out
*.app
*.ipa

# These project files can be generated by the engine
*.xcodeproj
*.xcworkspace
*.sln
*.suo
*.opensdf
*.sdf
*.VC.db
*.VC.opendb

# Precompiled Assets
SourceArt/**/*.png
SourceArt/**/*.tga

# Binary Files
Binaries/*
Plugins/*/Binaries/*

# Builds
Build/*

# Whitelist PakBlacklist-<BuildConfiguration>.txt files
!Build/*/
Build/*/**
!Build/*/PakBlacklist*.txt

# Don't ignore icon files in Build
!Build/**/*.ico

# Built data for maps
*_BuiltData.uasset

# Configuration files generated by the Editor
Saved/*

# Compiled source files for the engine to use
Intermediate/*
Plugins/*/Intermediate/*

# Cache files for the editor to use
DerivedDataCache/*

# Config from unit testing
*testConfig.json
16 changes: 16 additions & 0 deletions UnrealPlugin/TestingProject/.vsconfig
@@ -0,0 +1,16 @@
{
"version": "1.0",
"components": [
"Microsoft.Net.Component.4.6.2.TargetingPack",
"Microsoft.VisualStudio.Component.VC.14.34.17.4.ARM64",
"Microsoft.VisualStudio.Component.VC.14.34.17.4.x86.x64",
"Microsoft.VisualStudio.Component.VC.Tools.ARM64",
"Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
"Microsoft.VisualStudio.Component.Windows10SDK",
"Microsoft.VisualStudio.Workload.CoreEditor",
"Microsoft.VisualStudio.Workload.ManagedDesktop",
"Microsoft.VisualStudio.Workload.NativeDesktop",
"Microsoft.VisualStudio.Workload.NativeGame",
"Microsoft.VisualStudio.Workload.Universal"
]
}

0 comments on commit ca26f5b

Please sign in to comment.