Skip to content

Commit

Permalink
SmartCMServerList must iterate all server candidates even when all ca…
Browse files Browse the repository at this point in the history
…ndidates have been marked bad
  • Loading branch information
azuisleet committed Nov 30, 2021
1 parent 483cf68 commit 2ef0773
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 3 deletions.
4 changes: 2 additions & 2 deletions SteamKit2/SteamKit2/Steam/Discovery/SmartCMServerList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -275,8 +275,8 @@ void MarkServerCore( ServerInfo serverInfo, ServerQuality quality )
let server = o.server
let index = o.index
where server.Protocol.HasFlagsFast( supportedProtocolTypes )
let lastBadConnectionTime = server.LastBadConnectionTimeUtc
orderby lastBadConnectionTime.HasValue, index
let lastBadConnectionTime = server.LastBadConnectionTimeUtc.GetValueOrDefault()
orderby lastBadConnectionTime, index
select new { EndPoint = server.Record.EndPoint, Protocol = server.Protocol };
var result = query.FirstOrDefault();

Expand Down
65 changes: 64 additions & 1 deletion SteamKit2/Tests/SmartCMServerListFacts.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Net;
using System.Threading;
using SteamKit2;
using SteamKit2.Discovery;
using Xunit;
Expand Down Expand Up @@ -181,6 +183,67 @@ public void GetNextServerCandidate_OnlyReturnsMatchingServerOfType()
Assert.Equal( ProtocolTypes.Tcp, endPoint.ProtocolTypes );
}

[Fact]
public void GetNextServerCandidate_MarkIterateAllCandidates()
{
serverList.GetAllEndPoints();

var recordA = ServerRecord.CreateWebSocketServer( "10.0.0.1:27030" );
var recordB = ServerRecord.CreateWebSocketServer( "10.0.0.2:27030" );
var recordC = ServerRecord.CreateWebSocketServer( "10.0.0.3:27030" );

// Add all candidates
serverList.ReplaceList( new List<ServerRecord>() { recordA, recordB, recordC } );

var candidatesReturned = new HashSet<ServerRecord>();

void DequeueAndMarkCandidate()
{
var candidate = serverList.GetNextServerCandidate( ProtocolTypes.WebSocket );
Assert.True( candidatesReturned.Add( candidate ), $"Candidate {candidate.EndPoint} already seen" );
Thread.Sleep( TimeSpan.FromMilliseconds( 10 ) );
serverList.TryMark( candidate.EndPoint, ProtocolTypes.WebSocket, ServerQuality.Bad );
}

// We must dequeue all servers as they all get marked bad
DequeueAndMarkCandidate();
DequeueAndMarkCandidate();
DequeueAndMarkCandidate();
Assert.True( candidatesReturned.Count == 3, "All candidates returned" );
}

[Fact]
public void GetNextServerCandidate_MarkIterateAllBadCandidates()
{
serverList.GetAllEndPoints();

var recordA = ServerRecord.CreateWebSocketServer( "10.0.0.1:27030" );
var recordB = ServerRecord.CreateWebSocketServer( "10.0.0.2:27030" );
var recordC = ServerRecord.CreateWebSocketServer( "10.0.0.3:27030" );

// Add all candidates and mark them bad
serverList.ReplaceList( new List<ServerRecord>() { recordA, recordB, recordC } );
serverList.TryMark( recordA.EndPoint, ProtocolTypes.WebSocket, ServerQuality.Bad );
serverList.TryMark( recordB.EndPoint, ProtocolTypes.WebSocket, ServerQuality.Bad );
serverList.TryMark( recordC.EndPoint, ProtocolTypes.WebSocket, ServerQuality.Bad );

var candidatesReturned = new HashSet<ServerRecord>();

void DequeueAndMarkCandidate()
{
var candidate = serverList.GetNextServerCandidate( ProtocolTypes.WebSocket );
Assert.True( candidatesReturned.Add( candidate ), $"Candidate {candidate.EndPoint} already seen" );
Thread.Sleep( TimeSpan.FromMilliseconds( 10 ) );
serverList.TryMark( candidate.EndPoint, ProtocolTypes.WebSocket, ServerQuality.Bad );
}

// We must dequeue all candidates from a bad list
DequeueAndMarkCandidate();
DequeueAndMarkCandidate();
DequeueAndMarkCandidate();
Assert.True( candidatesReturned.Count == 3, "All candidates returned" );
}

[Fact]
public void TryMark_ReturnsTrue_IfServerInList()
{
Expand Down

0 comments on commit 2ef0773

Please sign in to comment.