Files
o3de/Gems/GameLift/Code/Tests/GridMateGameLiftClientTest.cpp
T
2021-03-08 14:30:57 -08:00

341 lines
12 KiB
C++

/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <GameLift/Session/GameLiftClientService.h>
#include <GameLift/Session/GameLiftSessionRequest.h>
#include <GridMate/Replica/ReplicaFunctions.h>
#include <AzCore/std/parallel/thread.h>
#include <AzCore/UnitTest/UnitTest.h>
#include <aws/core/Aws.h>
///////////////////////////////////////////////////////////////////////////////
struct TestSettings
{
const char* m_accessKey = "";
const char* m_secretKey = "";
const char* m_region = "";
const char* m_fleetId = "";
const char* m_endpoint = "";
};
// Test constants
static const unsigned int s_maxTicks = 1000;
static const unsigned int s_tickDelayMs = 30;
// Global GameLift settings
static TestSettings s_gameLiftSettings;
// AWS Allocator
class AwsAllocator : public Aws::Utils::Memory::MemorySystemInterface
{
public:
void Begin() override {};
void End() override {};
void* AllocateMemory(std::size_t blockSize, std::size_t alignment, const char *allocationTag = nullptr) override
{
return AZ::AllocatorInstance<GridMate::GridMateAllocatorMP>::Get().Allocate(blockSize, alignment, 0, allocationTag);
}
void FreeMemory(void* memoryPtr) override
{
AZ::AllocatorInstance<GridMate::GridMateAllocatorMP>::Get().DeAllocate(memoryPtr);
}
};
static AwsAllocator s_awsAllocator;
///////////////////////////////////////////////////////////////////////////////
class GameLiftTest
: public GridMate::SessionEventBus::Handler
, public GridMate::GameLiftClientServiceEventsBus::Handler
{
public:
GameLiftTest()
: m_gridMate(nullptr)
, m_service(nullptr)
{
}
~GameLiftTest()
{
AZ_TEST_ASSERT(!m_service);
AZ_TEST_ASSERT(!m_gridMate);
}
void Init(const TestSettings& settings)
{
// Initializing system allocators
AZ::AllocatorInstance<AZ::OSAllocator>::Create();
AZ::AllocatorInstance<AZ::SystemAllocator>::Create();
// Creating Gridmate instance
GridMate::GridMateDesc gridmateDesc;
m_gridMate = GridMate::GridMateCreate(gridmateDesc);
// Initializing GridMate multiplayer service allocator
AZ::AllocatorInstance<GridMate::GridMateAllocatorMP>::Create();
// Subscribing for session events
GridMate::SessionEventBus::Handler::BusConnect(m_gridMate);
GridMate::GameLiftClientServiceEventsBus::Handler::BusConnect(m_gridMate);
// Starting GameLift multiplayer service
GridMate::GameLiftClientServiceDesc serviceDesc;
serviceDesc.m_accessKey = settings.m_accessKey;
serviceDesc.m_secretKey = settings.m_secretKey;
serviceDesc.m_fleetId = settings.m_fleetId;
serviceDesc.m_endpoint = settings.m_endpoint;
serviceDesc.m_region = settings.m_region;
Aws::SDKOptions awsSDKOptions;
awsSDKOptions.loggingOptions.logLevel = Aws::Utils::Logging::LogLevel::Trace;
awsSDKOptions.loggingOptions.defaultLogPrefix = "AWS";
awsSDKOptions.memoryManagementOptions.memoryManager = &s_awsAllocator;
Aws::InitAPI(awsSDKOptions);
m_service = GridMate::StartGridMateService<GridMate::GameLiftClientService>(m_gridMate, serviceDesc);
}
void Shutdown()
{
if (m_gridMate)
{
GridMate::GameLiftClientServiceEventsBus::Handler::BusDisconnect();
GridMate::SessionEventBus::Handler::BusDisconnect();
GridMateDestroy(m_gridMate);
Aws::SDKOptions awsSDKOptions;
awsSDKOptions.loggingOptions.logLevel = Aws::Utils::Logging::LogLevel::Trace;
awsSDKOptions.loggingOptions.defaultLogPrefix = "AWS";
awsSDKOptions.memoryManagementOptions.memoryManager = &s_awsAllocator;
Aws::ShutdownAPI(awsSDKOptions);
AZ::AllocatorInstance<GridMate::GridMateAllocatorMP>::Destroy();
AZ::AllocatorInstance<AZ::SystemAllocator>::Destroy();
AZ::AllocatorInstance<AZ::OSAllocator>::Destroy();
m_service = nullptr;
m_gridMate = nullptr;
}
}
protected:
GridMate::IGridMate* m_gridMate;
GridMate::GameLiftClientService* m_service;
};
class GameLiftSessionTest
: public GameLiftTest
{
public:
void run()
{
Init(s_gameLiftSettings);
// waiting till service is ready
int waitReady = 1000;
while (!m_isReady && waitReady--)
{
m_gridMate->Update();
AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds(s_tickDelayMs));
}
AZ_TEST_ASSERT(m_isReady);
GridMate::GameLiftSessionRequestParams reqParams;
reqParams.m_instanceName = "TestSession";
reqParams.m_numPublicSlots = 16;
reqParams.m_params[0].m_id = "param1";
reqParams.m_params[0].m_value = "value12";
reqParams.m_numParams = 1;
m_sessionRequest = m_service->RequestSession(reqParams);
while (m_numTicks < s_maxTicks)
{
if (m_numTicks == 500) // starting search
{
EBUS_EVENT_ID_RESULT(m_search, m_gridMate, GridMate::GameLiftClientServiceBus, StartSearch, GridMate::GameLiftSearchParams());
}
++m_numTicks;
m_gridMate->Update();
if (m_session)
{
m_session->GetReplicaMgr()->Unmarshal();
m_session->GetReplicaMgr()->UpdateFromReplicas();
m_session->GetReplicaMgr()->UpdateReplicas();
m_session->GetReplicaMgr()->Marshal();
}
AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds(s_tickDelayMs));
}
AZ_TEST_ASSERT(m_numSessionServiceReady == 1);
AZ_TEST_ASSERT(m_numSessionCreated == 1);
AZ_TEST_ASSERT(m_numSessionDeleted == 0);
AZ_TEST_ASSERT(m_numSessionErrors == 0);
AZ_TEST_ASSERT(m_numSearchCompleted == 2); // one for session request and one for the search
AZ_TEST_ASSERT(m_numSearchResults > 0); // at least one search result should've been returned (the session that client requested at startup)
AZ_TEST_ASSERT(m_session->GetNumParams() == 1);
AZ_TEST_ASSERT(strcmp(m_session->GetParam(0).m_id.c_str(), "param1") == 0);
AZ_TEST_ASSERT(strcmp(m_session->GetParam(0).m_value.c_str(), "value12") == 0);
Shutdown();
}
private:
void OnGameLiftSessionServiceReady(GridMate::GameLiftClientService*) override
{
AZ_Printf("GameLift", "Service is ready\n");
++m_numSessionServiceReady;
m_isReady = true;
}
void OnGameLiftSessionServiceFailed(GridMate::GameLiftClientService*) override
{
AZ_Printf("GameLift", "Service failed to initialize\n");
AZ_TEST_ASSERT(false);
}
void OnSessionCreated(GridMate::GridSession* session) override
{
(void)session;
AZ_Printf("GameLift", "Session created: %s\n", session->GetId().c_str());
++m_numSessionCreated;
}
void OnSessionDelete(GridMate::GridSession* session) override
{
(void)session;
AZ_Printf("GameLift", "Session deleted: %s\n", session->GetId().c_str());
++m_numSessionDeleted;
}
void OnSessionError(GridMate::GridSession* session, const GridMate::string& errorMsg) override
{
(void)session;
AZ_Printf("GameLift", "Session error: %s\n", errorMsg.c_str());
++m_numSessionErrors;
}
void OnGridSearchComplete(GridMate::GridSearch* gridSearch)
{
++m_numSearchCompleted;
if (gridSearch == m_sessionRequest) // got request result, can now join the session
{
GridMate::CarrierDesc carrierDesc;
carrierDesc.m_port = 33435;
carrierDesc.m_enableDisconnectDetection = true;
carrierDesc.m_connectionTimeoutMS = 10000;
carrierDesc.m_threadUpdateTimeMS = 30;
AZ_Printf("GridMateClient", "Request results returned: %u.\n", gridSearch->GetNumResults());
AZ_TEST_ASSERT(gridSearch->GetNumResults() == 1); // should get exactly one result from session request, just the session we requested
AZ_TEST_ASSERT(gridSearch->GetResult(0)->m_numParams == 1); // checking for the single parameter
AZ_TEST_ASSERT(strcmp(gridSearch->GetResult(0)->m_params[0].m_id.c_str(), "param1") == 0);
AZ_TEST_ASSERT(strcmp(gridSearch->GetResult(0)->m_params[0].m_value.c_str(), "value12") == 0);
const GridMate::GameLiftSearchInfo& gameliftSearchInfo = static_cast<const GridMate::GameLiftSearchInfo&>(*gridSearch->GetResult(0));
EBUS_EVENT_ID_RESULT(m_session,m_gridMate,GridMate::GameLiftClientServiceBus,JoinSessionBySearchInfo,gameliftSearchInfo,carrierDesc);
}
else if (gridSearch == m_search) // got search results
{
m_numSearchResults = gridSearch->GetNumResults();
AZ_Printf("GameLift", "Found %u game sessions.\n", m_numSearchResults);
}
}
GridMate::GridSession* m_session = nullptr;
unsigned int m_numTicks = 0;
bool m_isReady = false;
GridMate::GridSearch* m_sessionRequest = nullptr;
GridMate::GridSearch* m_search = nullptr;
// test values
unsigned int m_numSessionServiceReady = 0;
unsigned int m_numSessionCreated = 0;
unsigned int m_numSessionDeleted = 0;
unsigned int m_numSessionErrors = 0;
unsigned int m_numSearchResults = 0;
unsigned int m_numSearchCompleted = 0;
};
AZ_TEST_SUITE(GameLiftSession)
AZ_TEST(GameLiftSessionTest)
AZ_TEST_SUITE_END
void main(int argc, char* argv[])
{
if (argc <= 1)
{
AZ_Printf("GameLift", "Supported settings:\n"
" accessKey:<string> - AWS Access Key\n"
" secretKey:<string> - AWS Secret Key\n"
" region:<string> - AWS region\n"
" fleetId:<string> - GameLift fleet id\n"
" endpoint:<string> - GameLift endpoint\n"
);
::exit(-1);
}
for (int i = 1; i < argc; ++i)
{
char* pos = strchr(argv[i], ':');
if (!pos)
{
AZ_Printf("GameLift", "Invalid argument format: %s. Expected 'key:value'.", argv[i]);
continue;
}
*pos = '\0';
const char* paramName = argv[i];
const char* paramVal = pos + 1;
if (!azstricmp(paramName, "accessKey"))
{
s_gameLiftSettings.m_accessKey = paramVal;
}
else if (!azstricmp(paramName, "secretKey"))
{
s_gameLiftSettings.m_secretKey = paramVal;
}
else if (!azstricmp(paramName, "fleetId"))
{
s_gameLiftSettings.m_fleetId = paramVal;
}
else if (!azstricmp(paramName, "endpoint"))
{
s_gameLiftSettings.m_endpoint = paramVal;
}
else if (!azstricmp(paramName, "region"))
{
s_gameLiftSettings.m_region = paramVal;
}
else
{
AZ_Printf("GameLift", "Unsupported parameter: %s", argv[i]);
}
}
AZ_TEST_RUN_SUITE(GameLiftSession);
AZ_TEST_OUTPUT_RESULTS("GameLiftTest", "GameLiftTest.xml");
::exit(AZ_TEST_GET_STATUS ? 0 : 1);
}