-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implemented first draft of multiplayer functional tests + moved test …
…assets out of editor folder
- Loading branch information
1 parent
48dc938
commit 86780fc
Showing
28 changed files
with
641 additions
and
2 deletions.
There are no files selected for viewing
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file modified
BIN
-289 Bytes
(85%)
Content/Editor/Tests/Core/DT_DataTableFunctionsTestTable.uasset
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
137 changes: 137 additions & 0 deletions
137
Source/OUUTestUtilities/Private/Multiplayer/OUUMultiplayerFunctionalTest.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
// Copyright (c) 2024 Jonas Reich & Contributors | ||
|
||
#include "Multiplayer/OUUMultiplayerFunctionalTest.h" | ||
|
||
#include "Animation/BoneChainRange.h" | ||
#include "Multiplayer/OUUMultiplayerTestClientSignal.h" | ||
#include "Multiplayer/OUUMultiplayerTestController.h" | ||
#include "Net/UnrealNetwork.h" | ||
|
||
AOUUMultiplayerFunctionalTest::AOUUMultiplayerFunctionalTest() | ||
{ | ||
bReplicates = true; | ||
} | ||
|
||
int32 AOUUMultiplayerFunctionalTest::AdvanceLocalSyncMarker() | ||
{ | ||
LastLocalSyncMarker++; | ||
if (HasAuthority()) | ||
{ | ||
// DO NOT acknowledge yet! | ||
// wait for client markers first... | ||
// LastServerAcknowledgedSyncMarker = LastLocalSyncMarker; | ||
UOUUMultiplayerTestController::Get().MarkHeartbeatActive( | ||
FString::Printf(TEXT("[SERVER] Sync Marker %i"), LastLocalSyncMarker)); | ||
} | ||
else | ||
{ | ||
int32 NumSignalActors = 0; | ||
for (auto Signal : TActorRange<AOUUMultiplayerTestClientSignal>(GetWorld())) | ||
{ | ||
NumSignalActors++; | ||
// find the signal actor we can use to send RPCs to the server | ||
if (Signal->GetOwner()) | ||
{ | ||
Signal->Server_NotifySyncPointReached(this, LastLocalSyncMarker); | ||
return LastLocalSyncMarker; | ||
} | ||
} | ||
checkf(false, TEXT("None of the %i client signals have automous proxy role for this client"), NumSignalActors); | ||
} | ||
return LastLocalSyncMarker; | ||
} | ||
|
||
void AOUUMultiplayerFunctionalTest::ServerNotifyClientSyncMarkerReached( | ||
APlayerController* ClientPlayer, | ||
int32 SyncMarker) | ||
{ | ||
UOUUMultiplayerTestController::Get().MarkHeartbeatActive( | ||
FString::Printf(TEXT("[SERVER] Client Sync Marker %i"), SyncMarker)); | ||
auto& UpdateEntry = ClientSyncMarkerLocations.FindOrAdd(ClientPlayer, -1); | ||
|
||
// check expected sync marker state. If this check fails, some sync marker was skipped. | ||
ensure(UpdateEntry == -1 || UpdateEntry == SyncMarker - 1 || UpdateEntry == SyncMarker); | ||
UpdateEntry = SyncMarker; | ||
|
||
// #TODO make parameter | ||
if (ClientSyncMarkerLocations.Num() < 2) | ||
{ | ||
// not enough clients. | ||
// only relevant for first sync point until the map is filled with all players. | ||
return; | ||
} | ||
|
||
int32 LastClientAcknowledgedMarker = -1; | ||
for (auto& Entry : ClientSyncMarkerLocations) | ||
{ | ||
if (LastClientAcknowledgedMarker == -1) | ||
{ | ||
LastClientAcknowledgedMarker = Entry.Value; | ||
} | ||
else | ||
{ | ||
LastClientAcknowledgedMarker = FMath::Min(Entry.Value, LastClientAcknowledgedMarker); | ||
} | ||
UE_LOG(LogTemp, Log, TEXT("%i"), Entry.Value); | ||
} | ||
UE_LOG(LogTemp, Log, TEXT("Last ACK Marker %i"), LastClientAcknowledgedMarker); | ||
|
||
if (LastClientAcknowledgedMarker == LastLocalSyncMarker) | ||
{ | ||
LastServerAcknowledgedSyncMarker = LastLocalSyncMarker; | ||
UOUUMultiplayerTestController::Get().MarkHeartbeatActive( | ||
FString::Printf(TEXT("[SERVER] ACK Sync Marker %i"), LastServerAcknowledgedSyncMarker)); | ||
|
||
OnSyncMarkerReached.Broadcast(LastClientAcknowledgedMarker); | ||
} | ||
} | ||
bool AOUUMultiplayerFunctionalTest::RunTest(const TArray<FString>& Params) | ||
{ | ||
UOUUMultiplayerTestController::Get().NotifyFunctionalTestStarted(); | ||
return Super::RunTest(Params); | ||
} | ||
|
||
void AOUUMultiplayerFunctionalTest::FinishTest(EFunctionalTestResult TestResult, const FString& Message) | ||
{ | ||
ensureMsgf( | ||
HasAuthority(), | ||
TEXT("The FinishTest function should only ever be called on Authority! Use snyc point nodes for all " | ||
"intermediate steps you want to ensure synchronicity.")); | ||
UOUUMultiplayerTestController::Get().NotifyFunctionalTestEnded(TestResult); | ||
Super::FinishTest(TestResult, Message); | ||
} | ||
|
||
void AOUUMultiplayerFunctionalTest::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const | ||
{ | ||
Super::GetLifetimeReplicatedProps(OutLifetimeProps); | ||
DOREPLIFETIME(AOUUMultiplayerFunctionalTest, LastServerAcknowledgedSyncMarker); | ||
} | ||
|
||
void AOUUMultiplayerFunctionalTest::OnRep_ServerSyncMarker() const | ||
{ | ||
ensure(LastServerAcknowledgedSyncMarker == LastLocalSyncMarker); | ||
if (OnSyncMarkerReached.IsBound()) | ||
{ | ||
OnSyncMarkerReached.Broadcast(LastServerAcknowledgedSyncMarker); | ||
} | ||
} | ||
|
||
UOUUMultiplayerTestWaitForAll* UOUUMultiplayerTestWaitForAll::WaitForAll(AOUUMultiplayerFunctionalTest* InOwningTest) | ||
{ | ||
UOUUMultiplayerTestWaitForAll* Proxy = NewObject<UOUUMultiplayerTestWaitForAll>(); | ||
Proxy->OwningTest = InOwningTest; | ||
return Proxy; | ||
} | ||
|
||
void UOUUMultiplayerTestWaitForAll::Activate() | ||
{ | ||
OwningTest->OnSyncMarkerReached.AddUObject(this, &UOUUMultiplayerTestWaitForAll::HandleSyncMarkerReached); | ||
MarkerIdx = OwningTest->AdvanceLocalSyncMarker(); | ||
} | ||
|
||
void UOUUMultiplayerTestWaitForAll::HandleSyncMarkerReached(int32 Marker) const | ||
{ | ||
ensure(MarkerIdx == Marker); | ||
OwningTest->OnSyncMarkerReached.RemoveAll(this); | ||
OnComplete.Broadcast(); | ||
} |
44 changes: 44 additions & 0 deletions
44
Source/OUUTestUtilities/Private/Multiplayer/OUUMultiplayerTestClientSignal.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// Copyright (c) 2024 Jonas Reich & Contributors | ||
|
||
#include "Multiplayer/OUUMultiplayerTestClientSignal.h" | ||
|
||
#include "GameFramework/PlayerController.h" | ||
#include "Multiplayer/OUUMultiplayerFunctionalTest.h" | ||
#include "Multiplayer/OUUMultiplayerTestController.h" | ||
|
||
AOUUMultiplayerTestClientSignal::AOUUMultiplayerTestClientSignal() | ||
{ | ||
bReplicates = true; | ||
bAlwaysRelevant = true; | ||
NetUpdateFrequency = 1.f; | ||
} | ||
|
||
void AOUUMultiplayerTestClientSignal::BeginPlay() | ||
{ | ||
Super::BeginPlay(); | ||
if (HasAuthority()) | ||
{ | ||
// ??? | ||
} | ||
else if (GetOwner()) | ||
{ | ||
Server_NotifySignalOnClientSpawned(); | ||
} | ||
} | ||
|
||
void AOUUMultiplayerTestClientSignal::Server_NotifySignalOnClientSpawned_Implementation() | ||
{ | ||
UOUUMultiplayerTestController::Get().NotifyServerPostSignalReplicated(); | ||
} | ||
|
||
void AOUUMultiplayerTestClientSignal::Server_NotifySyncPointReached_Implementation( | ||
AOUUMultiplayerFunctionalTest* Test, | ||
int32 SyncPoint) | ||
{ | ||
if (!ensure(Test)) | ||
return; | ||
|
||
auto* OwningPlayer = Cast<APlayerController> (GetOwner()); | ||
check(OwningPlayer); | ||
Test->ServerNotifyClientSyncMarkerReached(OwningPlayer, SyncPoint); | ||
} |
Oops, something went wrong.