diff --git a/templates/uscript_test_mutator.jinja b/templates/uscript_test_mutator.jinja index e9247f4..2e53bc6 100644 --- a/templates/uscript_test_mutator.jinja +++ b/templates/uscript_test_mutator.jinja @@ -31,18 +31,48 @@ var array<{{ message.name }}> MsgQueue_{{ message.name }}; var bool bClientServerDone_{{ message.name }}; {% endfor %} +enum ETestState +{ + ETS_None, +{% for message in messages %} + ETS_Sending_{{ message.name }}, + ETS_WaitingFor_{{ message.name }}, +{% endfor %} +}; + +var ETestState TestState; + var int TotalFailures; var int TotalMessagesToSend; var int TotalMessagesReceived; var int NumTestRounds; var bool bDone; var bool bLocalDone; +var array BytesToSend; event Tick(float DeltaTime) { super.Tick(DeltaTime); + `ulog("TestState:" @ TestState, TestState != ETS_None); + switch (TestState) + { +{% for message in messages %} + case ETS_Sending_{{ message.name }}: + `ulog("MsgQueue_{{ message.name }}.Length:" @ MsgQueue_{{ message.name }}.Length); + SendMsg_{{ message.name }}(); + break; + case ETS_WaitingFor_{{ message.name }}: + if (MessageReady_{{ message.name }}()) + { + TotalFailures += CheckMessage_{{ message.name }}(); + } + break; +{% endfor %} + default: + return; + } } function bool MutatorIsAllowed() @@ -109,7 +139,7 @@ final static function string RandomString(int Size) {% set msg1 = "TESTVAR_" + message.name + "_Msg1" %} {% set msg2 = "TESTVAR_" + message.name + "_Msg2" %} {% set cls = "class'" + class_name + "'.static." %} -final simulated function int Test_{{ message.name }}() +final function int Test_{{ message.name }}() { local int Failures; local int X; @@ -254,6 +284,12 @@ function PreBeginPlay() `ulog("##ERROR##: Failed to spawn UMBTestsTcpLink"); Failures += 1; } + else + { + Link.TargetHost = "127.0.0.1"; + Link.TargetPort = 55555; + Link.ConnectToServer(); + } // Local tests. for (Round = 0; Round < NumTestRounds; ++Round) @@ -281,100 +317,106 @@ function PreBeginPlay() bLocalDone = True; - RunClientServerTests(); + SetTimer(0.5, True, nameof(Quit)); +} + +function PostBeginPlay() +{ + super.PostBeginPlay(); - SetTimer(2.0, True, nameof(Quit)); + RunClientServerTests(); } -function SendMsg() +{% for message in messages %} +final function SendMsg_{{ message.name }}() { + local {{ message.name }} Msg; + + if (MsgQueue_{{ message.name }}.Length > 0) + { + Msg = MsgQueue_{{ message.name }}[MsgQueue_{{ message.name }}.Length - 1]; + class'{{ class_name }}'.static.{{ message.name }}_ToMultiBytes(Msg, BytesToSend); + MsgQueue_{{ message.name }}.Remove(MsgQueue_{{ message.name }}.Length - 1, 1); + + // TODO: Store in temp var for comparison later in CheckMessage_XYZ. + + Link.SendBytes(BytesToSend); + } + else + { + bClientServerDone_{{ message.name }} = True; + } + TestState = ETS_WaitingFor_{{ message.name }}; } -function bool IsMsgReceived() +final function bool MessageReady_{{ message.name }}() { - return False; + // TODO: check from Link. + return True; } -function bool CheckMessage() +/* +// TODO: move this check to a dedicated function! E.g. final test state. +`ulog("### ### ### ### ### ### ### ### ### ### ### ### ### ###"); +`ulog("TotalMessagesToSend :" @ TotalMessagesToSend); +`ulog("TotalMessagesReceived :" @ TotalMessagesReceived); +`ulog("### ### ### ### ### ### ### ### ### ### ### ### ### ###"); +TotalFailures += int(TotalMessagesToSend == TotalMessagesReceived); + +`ulog("##TOTAL TEST RESULTS##: TotalFailures=" $ TotalFailures); +if (TotalFailures > 0) +{ + `ulog("##TOTAL TEST RESULTS##: TEST SUITE(S) FAILED"); +} +else { - return False; + `ulog("##TOTAL TEST RESULTS##: ALL TESTS PASSED"); } -{% for message in messages %} -state Sending_{{ message.name }} +// Done with all message types, exit. +TestState = ETS_None; +bDone = True; +`ulog("quitting"); +ConsoleCommand("QUIT", True); +*/ + +final function int CheckMessage_{{ message.name }}() { - function SendMsg() - { - if (MsgQueue_{{ message.name }}.Length > 0) - { - // Send with Link. + // TODO: read from link and compare. + ++TotalMessagesReceived; - GotoState('WaitingFor_{{ message.name }}'); - } - else - { + if (bClientServerDone_{{ message.name }}) + { {% if loop.is_last %} - `ulog("### ### ### ### ### ### ### ### ### ### ### ### ### ###"); - `ulog("TotalMessagesToSend :" @ TotalMessagesToSend); - `ulog("TotalMessagesReceived :" @ TotalMessagesReceived); - `ulog("### ### ### ### ### ### ### ### ### ### ### ### ### ###"); - TotalFailures += int(TotalMessagesToSend == TotalMessagesReceived); - - `ulog("##TOTAL TEST RESULTS##: TotalFailures=" $ TotalFailures); - if (TotalFailures > 0) - { - `ulog("##TOTAL TEST RESULTS##: TEST SUITE(S) FAILED"); - } - else - { - `ulog("##TOTAL TEST RESULTS##: ALL TESTS PASSED"); - } - - // Done with all message types, exit. - GotoState(''); - bDone = True; - `ulog("quitting"); - ConsoleCommand("QUIT", True); + // Done with all message types, exit. TODO: move exit away from here. + Link.Close(); + TestState = ETS_None; + bDone = True; {% else %} - bClientServerDone_{{ message.name }} = True; - // Done with this type, go to next type's queue. - GotoState('WaitingFor_{{ at(messages, loop.index + 1).name }}'); + // Done with this type. Move to next type's queue. + TestState = ETS_Sending_{{ at(messages, loop.index + 1).name }}; {% endif %} - } - } - -Begin: - `ulog("Begin state Sending_{{ message.name }}"); -} - -state WaitingFor_{{ message.name }} -{ - function bool IsMsgReceived() - { - // Check if Link has message ready for us. - - return False; } - - function bool CheckMessage() + else { - // Check that message is valid. - - GotoState('Sending_{{ message.name }}'); - - return False; + TestState = ETS_Sending_{{ message.name }}; } -Begin: - `ulog("Begin state WaitingFor_{{ message.name }}"); + return 0; } -// --------------------------------------------------------------------------- -{% endfor %} +{% endfor -%} final function RunClientServerTests() { + if (Link.LinkState != STATE_Connected) + { + `ulog("Link not connected yet, state:" @ Link.LinkState); + SetTimer(0.01, False, nameof(RunClientServerTests)); + return; + } + TotalMessagesToSend = 0; {% for message in messages %} @@ -382,16 +424,14 @@ final function RunClientServerTests() {% endfor %} `ulog("TotalMessagesToSend:" @ TotalMessagesToSend); - // TODO: move this elsewhere. - bDone = True; - `ulog("quitting"); - ConsoleCommand("QUIT", True); + TestState = ETS_Sending_{{ messages.0.name }}; } final function Quit() { if (bDone) { + `ulog("quitting"); ConsoleCommand("QUIT", True); } } diff --git a/tests/UDKTests/UMBTestsTcpLink.uc b/tests/UDKTests/UMBTestsTcpLink.uc index ab6f37e..20ecb78 100644 --- a/tests/UDKTests/UMBTestsTcpLink.uc +++ b/tests/UDKTests/UMBTestsTcpLink.uc @@ -20,220 +20,39 @@ class UMBTestsTcpLink extends TcpLink; var private int ClientPort; -var private array Responses; - -var private int TransactionID; -var private array TransactionStack; - -var bool bDone; - -struct PendingCheck -{ - var string TestName; - var int TransactionID; - var string GMPOperandName; - var array BigIntOperand; -}; - -var private array PendingChecks; -var private PendingCheck CurrentCheck; - var string TargetHost; var int TargetPort; -var private array R_Array; -var private string R_TID; -var private string R_GMPOperandName; -var private string R_Result; -var private array R_ResultBytes; - -var private int Failures; -var private int LastFailuresLogged; - -var private int ChecksDone; -var private int RequiredChecks; - -const ID_PRIME = "PRIME"; -const TID_PRIME = "TPRIME"; - -var delegate RandPrimeDelegate; -delegate OnRandPrimeReceived(const out array P); - -simulated event Tick(float DeltaTime) -{ - /* - local int I; - // local int J; - // local int K; - // local int LenResult; - // local string ByteS; - local int Fail; - - for (I = 0; I < Responses.Length; ++I) - { - if (Responses[I] == "SERVER_ERROR") - { - `ulog("##ERROR##: SERVER ERROR!"); - PendingChecks.Remove(0, 1); // TODO: should do checks in a loop? - ++ChecksDone; - ++Failures; - continue; - } - - ParseStringIntoArray(Responses[I], R_Array, " ", False); - R_TID = R_Array[0]; - R_GMPOperandName = R_Array[1]; - R_Result = R_Array[2]; - - if (Len(R_Result) < 3) - { - R_ResultBytes.Length = 1; - R_ResultBytes[0] = class'WebAdminUtils'.static.FromHex(R_Result); - } - else - { - // LenResult = Len(R_Result); - // if ((LenResult % 2) != 0) - // { - // R_Result = "0" $ R_Result; - // ++LenResult; - // } - // K = 0; - // J = 0; - // R_ResultBytes.Length = LenResult / 2; - // while (J < LenResult) - // { - // ByteS = Mid(R_Result, J, 2); - // R_ResultBytes[K++] = class'WebAdminUtils'.static.FromHex(ByteS); - // J += 2; - // } - class'FCryptoBigInt'.static.BytesFromHex(R_ResultBytes, R_Result); - } - - if (R_TID == ID_PRIME) - { - RandPrimeDelegate(R_ResultBytes); - continue; - } - - // `ulog(Responses[I]); - // class'FCryptoTestMutator'.static.LogBytes(R_ResultBytes); - - CurrentCheck = PendingChecks[0]; - - Fail = class'FCryptoTestMutator'.static.CheckEqz( - CurrentCheck.BigIntOperand, - R_ResultBytes - ); - - if (Fail > 0) - { - `ulog("##ERROR##: CurrentCheck.TestName :" @ CurrentCheck.TestName); - `ulog("##ERROR##: CurrentCheck.TID :" @ CurrentCheck.TransactionID); - `ulog("##ERROR##: CurrentCheck.GMPOperandName :" @ CurrentCheck.GMPOperandName); - `ulog("##ERROR##: R_TID :" @ R_TID); - `ulog("##ERROR##: R_Result :" @ R_Result); - `ulog("##ERROR##: R_GMPOperandName :" @ R_GMPOperandName); - `ulog("##ERROR##: Response :" @ Responses[I]); - Failures += Fail; - } - - PendingChecks.Remove(0, 1); // TODO: should do checks in a loop? - ++ChecksDone; - } - - if (I > 0) - { - Responses.Remove(0, I); - } - - if (Failures > 0 && LastFailuresLogged < (Failures - 1)) - { - `ulog("##ERROR##: ---" @ Failures @ "FAILURES DETECTED! ---"); - LastFailuresLogged = Failures; - } - - if (ChecksDone > 0 && (ChecksDone % 25) == 0) - { - `ulog("---" @ ChecksDone @ "checks done so far. ---"); - } +var int Idx; +var int NumSent; +var int NumToSend; +var byte OutBuf[255]; - if (ChecksDone > 0 && (ChecksDone >= RequiredChecks)) - { - `ulog("--- ALL CHECKS DONE" @ ChecksDone $ "/" $ RequiredChecks @ "---"); - ChecksDone = 0; - RequiredChecks = 0; - - if (Failures > 0) - { - `ulog("##ERROR##: ---" @ Failures @ "FAILURES DETECTED! ---"); - } - } - - super.Tick(DeltaTime); - */ -} - -final simulated function ConnectToServer() +final function ConnectToServer() { LinkMode = MODE_Binary; ReceiveMode = RMODE_Event; Resolve(TargetHost); } -final simulated function Begin() -{ - ++TransactionID; -} +// TODO: dedicated function for sending static bytes. -final simulated function End() +final function SendBytes( + const out array Bytes) { - local string Str; - local int I; - - // Actually push the stuff here. - Str = "T" $ TransactionID; - for (I = 0; I < TransactionStack.Length; ++I) + // The easy case. + if (Bytes.Length <= 255) { - Str @= "[" $ TransactionStack[I] $ "]"; - } - - // `ulog("sending" @ TransactionID); - SendText(Str); - TransactionStack.Length = 0; -} - -final simulated function Var(string VarName, string Value) -{ - TransactionStack.AddItem("var" @ VarName @ "'" $ Value $ "'"); -} - -final simulated function Op(string Op, string Dst, string A, string B) -{ - TransactionStack.AddItem("op" @ Op @ Dst @ A @ B ); -} - -final simulated function Eq(string GMPOperandName, const out array B, - string TestName = "Unnamed") -{ - local PendingCheck Check; - - Check.TransactionID = TransactionID; - Check.GMPOperandName = GMPOperandName; - Check.BigIntOperand = B; - - PendingChecks.AddItem(Check); - RequiredChecks = PendingChecks.Length; -} + for (Idx = 0; Idx < Bytes.Length; ++Idx) + { + OutBuf[Idx] = Bytes[Idx]; + } -final simulated function RandPrime(int Size) -{ - SendText( - TID_PRIME - @ "[var s '" $ ToHex(Size) $ "']" - @ "[var x '0']" - @ "[op rand_prime x s s]" - ); + NumToSend = Bytes.Length; + NumSent = SendBinary(NumToSend, OutBuf); + `ulog("Sent" @ NumSent @ "bytes"); + return; + } } event Resolved(IpAddr Addr) @@ -275,7 +94,7 @@ event ReceivedBinary(int Count, byte B[255]) local int MessageType; local int I; - `ulog("Count:" @ Count); + `ulog("Count :" @ Count); Size = B[0]; Part = B[1]; @@ -290,15 +109,8 @@ event ReceivedBinary(int Count, byte B[255]) DefaultProperties { - bDone=False - - ChecksDone=0 - Failures=0 - LastFailuresLogged=0 - TargetHost="127.0.0.1" - TargetPort=65432 - TransactionID=0 + TargetPort=55555 TickGroup=TG_DuringAsyncWork } diff --git a/tests/umb_echo_server.cpp b/tests/umb_echo_server.cpp index bc6af25..1e4ff92 100644 --- a/tests/umb_echo_server.cpp +++ b/tests/umb_echo_server.cpp @@ -66,6 +66,11 @@ awaitable echo(tcp::socket socket) { try { + std::cout + << std::format("connection: {}:{}\n", + socket.remote_endpoint().address().to_string(), + socket.remote_endpoint().port()); + std::shared_ptr msg; // TODO: should we read into a larger buffer? std::array data{}; @@ -125,28 +130,32 @@ awaitable echo(tcp::socket socket) msg = std::make_shared(); msg->from_bytes(payload); break; - case testmessages::umb::MessageType::BoolPackingMessage: - msg = std::make_shared(); + case testmessages::umb::MessageType::GetSomeStuffResp: + msg = std::make_shared(); + msg->from_bytes(payload); + break; + case testmessages::umb::MessageType::JustAnotherTestMessage: + msg = std::make_shared(); msg->from_bytes(payload); break; case testmessages::umb::MessageType::testmsg: msg = std::make_shared(); msg->from_bytes(payload); break; - case testmessages::umb::MessageType::JustAnotherTestMessage: - msg = std::make_shared(); + case testmessages::umb::MessageType::BoolPackingMessage: + msg = std::make_shared(); msg->from_bytes(payload); break; - case testmessages::umb::MessageType::DualStringMessage: - msg = std::make_shared(); + case testmessages::umb::MessageType::STATIC_BoolPackingMessage: + msg = std::make_shared(); msg->from_bytes(payload); break; case testmessages::umb::MessageType::MultiStringMessage: msg = std::make_shared(); msg->from_bytes(payload); break; - case testmessages::umb::MessageType::STATIC_BoolPackingMessage: - msg = std::make_shared(); + case testmessages::umb::MessageType::DualStringMessage: + msg = std::make_shared(); msg->from_bytes(payload); break;