浏览代码
Renamed AuthenticationManager to Auth to avoid conflct with a System API
Renamed AuthenticationManager to Auth to avoid conflct with a System API
Reframed the LobbyManager to maintain the life cycle of the remote Lobby. -Is now responsible for maintaining the reference to the latest cache of the remote Lobby, -Will automatically set up the heartbeat for host, -Also Works to prevent RateLimit Errors by creating cooldowns for each Lobby API Call -Adjusted Roundtrip tests accordingly. Moved Data synchronizastion to LobbySynchronizer -Checks for local and remote changes and pushes/pulls player and lobby data accordingly./main/staging/2021_Upgrade/Async_Refactor
当前提交
6702d4b4
共有 12 个文件被更改,包括 569 次插入 和 486 次删除
-
22Assets/Scripts/GameLobby/Game/GameManager.cs
-
3Assets/Scripts/GameLobby/Game/LocalLobby.cs
-
4Assets/Scripts/GameLobby/Lobby/LobbyConverters.cs
-
641Assets/Scripts/GameLobby/Lobby/LobbyManager.cs
-
100Assets/Scripts/GameLobby/Lobby/LobbySynchronizer.cs
-
2Assets/Scripts/GameLobby/Relay/RelayUtpSetup.cs
-
262Assets/Scripts/GameLobby/Tests/PlayMode/LobbyRoundtripTests.cs
-
1Assets/Scripts/GameLobby/Tests/PlayMode/RelayRoundTripTests.cs
-
18Assets/Scripts/GameLobby/Tests/PlayMode/UtpTests.cs
-
2Assets/Scripts/GameLobby/UI/RateLimitVisibility.cs
-
0/Assets/Scripts/GameLobby/Auth/Auth.cs
-
0/Assets/Scripts/GameLobby/Auth/Auth.cs.meta
|
|||
using NUnit.Framework; |
|||
using System.Collections; |
|||
using System.Collections.Generic; |
|||
using System.Diagnostics; |
|||
using System.Threading.Tasks; |
|||
using Unity.Services.Core; |
|||
using Unity.Services.Authentication; |
|||
using Debug = UnityEngine.Debug; |
|||
/// <summary>
|
|||
/// Accesses the Authentication and Lobby services in order to ensure lobbies can be created and deleted.
|
|||
/// LobbyAsyncRequests wraps the Lobby API, so go through that in practice. This simply ensures the connection to the Lobby service is functional.
|
|||
///
|
|||
/// If the tests pass, you can assume you are connecting to the Lobby service itself properly.
|
|||
/// </summary>
|
|||
public class LobbyRoundtripTests |
|||
{ |
|||
string m_workingLobbyId; |
|||
bool m_didSigninComplete = false; |
|||
string playerID; |
|||
Dictionary<string, PlayerDataObject> m_mockUserData; // This is handled in the LobbyAsyncRequest calls normally, but we need to supply this for the direct Lobby API calls.
|
|||
LobbyUser m_LocalUser; |
|||
LobbyManager m_LobbyManager; |
|||
[OneTimeSetUp] |
|||
public IEnumerator Setup() |
|||
{ |
|||
/// <summary>
|
|||
/// Accesses the Authentication and Lobby services in order to ensure lobbies can be created and deleted.
|
|||
/// LobbyAsyncRequests wraps the Lobby API, so go through that in practice. This simply ensures the connection to the Lobby service is functional.
|
|||
///
|
|||
/// If the tests pass, you can assume you are connecting to the Lobby service itself properly.
|
|||
/// </summary>
|
|||
public class LobbyRoundtripTests |
|||
{ |
|||
string playerID; |
|||
m_mockUserData = new Dictionary<string, PlayerDataObject>(); |
|||
m_mockUserData.Add("DisplayName", new PlayerDataObject(PlayerDataObject.VisibilityOptions.Member, "TestUser123")); |
|||
m_LocalUser = new LobbyUser(true); |
|||
return TestAuthSetup(); |
|||
} |
|||
Dictionary<string, PlayerDataObject> |
|||
m_mockUserData; // This is handled in the LobbyAsyncRequest calls normally, but we need to supply this for the direct Lobby API calls.
|
|||
IEnumerator TestAuthSetup() |
|||
{ |
|||
yield return AsyncTestHelper.Await(async ()=> await UnityServices.InitializeAsync()); |
|||
yield return AsyncTestHelper.Await(async () => await AuthenticationService.Instance.SignInAnonymouslyAsync()); |
|||
m_didSigninComplete = true; |
|||
} |
|||
LobbyUser m_LocalUser; |
|||
LobbyManager m_LobbyManager; |
|||
[UnityTearDown] |
|||
public IEnumerator PerTestTeardown() |
|||
{ |
|||
if (m_workingLobbyId != null) |
|||
{ yield return AsyncTestHelper.Await(async ()=> await m_LobbyManager.LeaveLobbyAsync(m_workingLobbyId)); |
|||
m_workingLobbyId = null; |
|||
} |
|||
yield return new WaitForSeconds(0.5f); // We need a yield anyway, so wait long enough to probably delete the lobby. There currently (6/22/2021) aren't other tests that would have issues if this took longer.
|
|||
} |
|||
[OneTimeSetUp] |
|||
public void Setup() |
|||
{ |
|||
m_mockUserData = new Dictionary<string, PlayerDataObject>(); |
|||
m_mockUserData.Add("DisplayName", |
|||
new PlayerDataObject(PlayerDataObject.VisibilityOptions.Member, "TestUser123")); |
|||
m_LocalUser = new LobbyUser(true); |
|||
m_LobbyManager = new LobbyManager(); |
|||
#pragma warning disable 4014
|
|||
TestAuthSetup(); |
|||
#pragma warning restore 4014
|
|||
} |
|||
async Task TestAuthSetup() |
|||
{ |
|||
await Auth.Authenticate("test"); |
|||
} |
|||
/// <summary>
|
|||
/// Make sure the entire roundtrip for Lobby works: Once signed in, create a lobby, query to make sure it exists, then delete it.
|
|||
/// </summary>
|
|||
[UnityTest] |
|||
public IEnumerator DoRoundtrip() |
|||
{ |
|||
#region Setup
|
|||
[UnityTearDown] |
|||
public IEnumerator PerTestTeardown() |
|||
{ |
|||
if (m_LobbyManager.CurrentLobby != null) |
|||
{ |
|||
yield return AsyncTestHelper.Await(async () => await m_LobbyManager.LeaveLobbyAsync()); |
|||
} |
|||
} |
|||
// Wait a reasonable amount of time for sign-in to complete.
|
|||
if (!m_didSigninComplete) |
|||
yield return new WaitForSeconds(3); |
|||
if (!m_didSigninComplete) |
|||
Assert.Fail("Did not sign in."); |
|||
// Since we're signed in through the same pathway as the actual game, the list of lobbies will include any that have been made in the game itself, so we should account for those.
|
|||
// If you want to get around this, consider having a secondary project using the same assets with its own credentials.
|
|||
yield return |
|||
new WaitForSeconds( |
|||
1); // To prevent a possible 429 with the upcoming Query request, in case a previous test had one; Query requests can only occur at a rate of 1 per second.
|
|||
QueryResponse queryResponse = null; |
|||
Debug.Log("Getting Lobby List 1"); |
|||
/// <summary>
|
|||
/// Make sure the entire roundtrip for Lobby works: Once signed in, create a lobby, query to make sure it exists, then delete it.
|
|||
/// </summary>
|
|||
[UnityTest] |
|||
public IEnumerator DoRoundtrip() |
|||
{ |
|||
#region Setup
|
|||
yield return AsyncTestHelper.Await(async () => queryResponse = await m_LobbyManager.RetrieveLobbyListAsync()); |
|||
yield return AsyncTestHelper.Await(async () => await Auth.Authenticating()); |
|||
// Since we're signed in through the same pathway as the actual game, the list of lobbies will include any that have been made in the game itself, so we should account for those.
|
|||
// If you want to get around this, consider having a secondary project using the same assets with its own credentials.
|
|||
yield return |
|||
new WaitForSeconds( |
|||
1); // To prevent a possible 429 with the upcoming Query request, in case a previous test had one; Query requests can only occur at a rate of 1 per second.
|
|||
QueryResponse queryResponse = null; |
|||
Debug.Log("Getting Lobby List 1"); |
|||
Assert.IsNotNull(queryResponse, "QueryAllLobbiesAsync should return a non-null result. (#0)"); |
|||
int numLobbiesIni = queryResponse.Results?.Count ?? 0; |
|||
yield return AsyncTestHelper.Await( |
|||
async () => queryResponse = await m_LobbyManager.RetrieveLobbyListAsync()); |
|||
#endregion
|
|||
// Create a test lobby.
|
|||
Lobby createResponse = null; |
|||
string lobbyName = "TestLobby-JustATest-123"; |
|||
Assert.IsNotNull(queryResponse, "QueryAllLobbiesAsync should return a non-null result. (#0)"); |
|||
int numLobbiesIni = queryResponse.Results?.Count ?? 0; |
|||
yield return AsyncTestHelper.Await(async () => |
|||
createResponse = await m_LobbyManager.CreateLobbyAsync( |
|||
lobbyName, |
|||
100, |
|||
false, |
|||
m_LocalUser)); |
|||
#endregion
|
|||
Assert.IsNotNull(createResponse, "CreateLobbyAsync should return a non-null result."); |
|||
m_workingLobbyId = createResponse.Id; |
|||
Assert.AreEqual(lobbyName, createResponse.Name, "Created lobby should match the provided name."); |
|||
// Query for the test lobby via QueryAllLobbies.
|
|||
yield return new WaitForSeconds(1); // To prevent a possible 429 with the upcoming Query request.
|
|||
Debug.Log("Getting Lobby List 2"); |
|||
// Create a test lobby.
|
|||
Lobby createLobby = null; |
|||
string lobbyName = "TestLobby-JustATest-123"; |
|||
yield return AsyncTestHelper.Await(async () => queryResponse = await m_LobbyManager.RetrieveLobbyListAsync()); |
|||
yield return AsyncTestHelper.Await(async () => |
|||
createLobby = await m_LobbyManager.CreateLobbyAsync( |
|||
lobbyName, |
|||
100, |
|||
false, |
|||
m_LocalUser)); |
|||
Assert.IsNotNull(queryResponse, "QueryAllLobbiesAsync should return a non-null result. (#1)"); |
|||
Assert.AreEqual(1 + numLobbiesIni, queryResponse.Results.Count, "Queried lobbies list should contain the test lobby."); |
|||
Assert.IsTrue(queryResponse.Results.Where(r => r.Name == lobbyName).Count() == 1, "Checking queried lobby for name."); |
|||
Assert.IsTrue(queryResponse.Results.Where(r => r.Id == m_workingLobbyId).Count() == 1, "Checking queried lobby for ID."); |
|||
Assert.IsNotNull(createLobby, "CreateLobbyAsync should return a non-null result."); |
|||
Assert.AreEqual(lobbyName, createLobby.Name, "Created lobby should match the provided name."); |
|||
var createLobbyId = createLobby.Id; |
|||
// Query for the test lobby via QueryAllLobbies.
|
|||
Debug.Log("Getting Lobby List 2"); |
|||
yield return AsyncTestHelper.Await( |
|||
async () => queryResponse = await m_LobbyManager.RetrieveLobbyListAsync()); |
|||
Debug.Log("Getting current Lobby"); |
|||
Assert.IsNotNull(queryResponse, "QueryAllLobbiesAsync should return a non-null result. (#1)"); |
|||
Assert.AreEqual(1 + numLobbiesIni, queryResponse.Results.Count, |
|||
"Queried lobbies list should contain the test lobby."); |
|||
Assert.IsTrue(queryResponse.Results.Where(r => r.Name == lobbyName).Count() == 1, |
|||
"Checking queried lobby for name."); |
|||
Assert.IsTrue(queryResponse.Results.Where(r => r.Id == createLobbyId).Count() == 1, |
|||
"Checking queried lobby for ID."); |
|||
Lobby currentLobby = null; |
|||
Assert.IsNotNull(currentLobby, "GetLobbyAsync should return a non-null result."); |
|||
Assert.AreEqual(lobbyName, currentLobby.Name, "Checking the lobby we got for name."); |
|||
Assert.AreEqual(m_workingLobbyId, currentLobby.Id, "Checking the lobby we got for ID."); |
|||
|
|||
Debug.Log("Getting current Lobby"); |
|||
|
|||
Lobby currentLobby = m_LobbyManager.CurrentLobby; |
|||
Assert.IsNotNull(currentLobby, "GetLobbyAsync should return a non-null result."); |
|||
Assert.AreEqual(lobbyName, currentLobby.Name, "Checking the lobby we got for name."); |
|||
Assert.AreEqual(createLobbyId, currentLobby.Id, "Checking the lobby we got for ID."); |
|||
|
|||
Debug.Log("Deleting current Lobby"); |
|||
// Delete the test lobby.
|
|||
yield return AsyncTestHelper.Await(async () => await m_LobbyManager.LeaveLobbyAsync()); |
|||
Debug.Log("Deleting current Lobby"); |
|||
// Delete the test lobby.
|
|||
yield return AsyncTestHelper.Await(async ()=> await m_LobbyManager.LeaveLobbyAsync(m_workingLobbyId)); |
|||
createLobbyId = null; |
|||
Debug.Log("Getting Lobby List 3"); |
|||
yield return AsyncTestHelper.Await( |
|||
async () => queryResponse = await m_LobbyManager.RetrieveLobbyListAsync()); |
|||
m_workingLobbyId = null; |
|||
Debug.Log("Getting Lobby List 3"); |
|||
yield return AsyncTestHelper.Await(async () => queryResponse = await m_LobbyManager.RetrieveLobbyListAsync()); |
|||
Assert.IsNotNull(queryResponse, "QueryAllLobbiesAsync should return a non-null result. (#2)"); |
|||
Assert.AreEqual(numLobbiesIni, queryResponse.Results.Count, "Queried lobbies list should be empty."); |
|||
Assert.IsNotNull(queryResponse, "QueryAllLobbiesAsync should return a non-null result. (#2)"); |
|||
Assert.AreEqual(numLobbiesIni, queryResponse.Results.Count, "Queried lobbies list should be empty."); |
|||
} |
|||
// Some error messages might be asynchronous, so to reduce spillover into other tests, just wait here for a bit before proceeding.
|
|||
yield return new WaitForSeconds(3); |
|||
} |
|||
/// <summary>
|
|||
/// If the Lobby create call fails, we return null
|
|||
/// </summary>
|
|||
[UnityTest] |
|||
public IEnumerator CreateFailsWithNull() |
|||
{ |
|||
yield return AsyncTestHelper.Await(async () => await Auth.Authenticating()); |
|||
/// <summary>
|
|||
/// If the Lobby create call fails, we return null
|
|||
/// </summary>
|
|||
[UnityTest] |
|||
public IEnumerator CreateFailsWithNull() |
|||
{ |
|||
if (!m_didSigninComplete) |
|||
yield return new WaitForSeconds(3); |
|||
if (!m_didSigninComplete) |
|||
Assert.Fail("Did not sign in."); |
|||
LogAssert.ignoreFailingMessages = true; // Multiple errors will appears for the exception.
|
|||
Lobby createLobby = null; |
|||
yield return AsyncTestHelper.Await(async () => |
|||
createLobby = await m_LobbyManager.CreateLobbyAsync( |
|||
"lobby name", |
|||
123, |
|||
false, |
|||
m_LocalUser)); |
|||
LogAssert.ignoreFailingMessages = true; // Multiple errors will appears for the exception.
|
|||
Lobby createLobby = null; |
|||
yield return AsyncTestHelper.Await(async () => |
|||
createLobby = await m_LobbyManager.CreateLobbyAsync( |
|||
"lobby name", |
|||
123, |
|||
false, |
|||
m_LocalUser)); |
|||
LogAssert.ignoreFailingMessages = false; |
|||
Assert.Null(createLobby, "The returned object will be null, so expect to need to handle it."); |
|||
yield return new WaitForSeconds(3); //Since CreateLobby cannot be queued, we need to give this a buffer before moving on to other tests.
|
|||
LogAssert.ignoreFailingMessages = false; |
|||
} |
|||
Assert.Null(createLobby, "The returned object will be null, so expect to need to handle it."); |
|||
} |
|||
[UnityTest] |
|||
public IEnumerator CooldownTest() |
|||
{ |
|||
var rateLimiter = new RateLimiter(3); |
|||
Stopwatch timer = new Stopwatch(); |
|||
timer.Start(); |
|||
//pass Through the first request, which triggers the cooldown.
|
|||
yield return AsyncTestHelper.Await(async () => await rateLimiter.WaitUntilCooldown()); |
|||
//Should wait for one second total
|
|||
yield return AsyncTestHelper.Await(async () => await rateLimiter.WaitUntilCooldown()); |
|||
timer.Stop(); |
|||
var elapsedMS = timer.ElapsedMilliseconds; |
|||
Debug.Log($"Cooldown took {elapsedMS}/{rateLimiter.coolDownMS} milliseconds."); |
|||
var difference = Mathf.Abs(elapsedMS - rateLimiter.coolDownMS); |
|||
Assert.IsTrue(difference<50&&difference>=0); |
|||
[UnityTest] |
|||
public IEnumerator LobbyPlayerDataUpdated() |
|||
{ |
|||
yield return null; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
撰写
预览
正在加载...
取消
保存
Reference in new issue