122 lines
4.5 KiB
C#
122 lines
4.5 KiB
C#
using System.Net;
|
|
using FinalFactory.Rendezvous.Contracts;
|
|
using FinalFactory.Rendezvous.Server.JoinAttempts;
|
|
using FinalFactory.Rendezvous.Server.Provisioning;
|
|
using FinalFactory.Rendezvous.Server.State;
|
|
using FinalFactory.Rendezvous.Tests.Provisioning;
|
|
using FinalFactory.Rendezvous.Tests.Sessions;
|
|
|
|
namespace FinalFactory.Rendezvous.Tests.JoinAttempts;
|
|
|
|
internal sealed class JoinAttemptFixture : IDisposable
|
|
{
|
|
private int _sequence;
|
|
|
|
public JoinAttemptFixture(
|
|
EphemeralStoreOptions? options = null,
|
|
GamePolicyOptions? joinPolicy = null)
|
|
{
|
|
Sessions = new(options);
|
|
Cursors = new();
|
|
GamePolicyRegistry policies = GamePolicyRegistry.Create([
|
|
joinPolicy ?? ProvisioningTestData.CreatePolicy(),
|
|
]);
|
|
Service = new(policies, Sessions.Store, Sessions.Capabilities, Cursors, Sessions.Clock);
|
|
ClientSubject = Service.CreateAnonymousClientSubject(IPAddress.Parse("198.51.100.40"));
|
|
}
|
|
|
|
public SessionLeaseFixture Sessions { get; }
|
|
public JoinAttemptCursorCodec Cursors { get; }
|
|
public JoinAttemptService Service { get; }
|
|
public string ClientSubject { get; }
|
|
|
|
public (RegisterSessionResponse Registration, StoredListing Listing) CreateHost(bool bindPresence = true)
|
|
{
|
|
RegisterSessionResponse registration = Sessions.Register();
|
|
if (bindPresence)
|
|
{
|
|
Assert.True(Sessions.BindPresence(registration).Succeeded);
|
|
}
|
|
|
|
StoredListing listing = Sessions.Store.GetListing(registration.ListingId, false).Value!;
|
|
return (registration, listing);
|
|
}
|
|
|
|
public CreateJoinAttemptRequest Request(
|
|
SessionListingId listingId,
|
|
string? idempotencyKey = null) => new()
|
|
{
|
|
IdempotencyKey = idempotencyKey ?? $"join-{Interlocked.Increment(ref _sequence)}",
|
|
GameId = Sessions.Scope.GameId,
|
|
EnvironmentId = Sessions.Scope.EnvironmentId,
|
|
ListingId = listingId,
|
|
ProtocolVersion = 7,
|
|
};
|
|
|
|
public CreateJoinAttemptResponse Create(
|
|
SessionListingId listingId,
|
|
string? idempotencyKey = null)
|
|
{
|
|
JoinAttemptServiceResult<CreateJoinAttemptResponse> result = Service.Create(
|
|
ClientSubject,
|
|
Request(listingId, idempotencyKey));
|
|
Assert.True(result.Succeeded);
|
|
return Assert.IsType<CreateJoinAttemptResponse>(result.Value);
|
|
}
|
|
|
|
public StoredJoinAttempt GetAttempt(
|
|
RegisterSessionResponse registration,
|
|
JoinAttemptId attemptId)
|
|
{
|
|
Assert.True(Sessions.Capabilities.TryFingerprint(
|
|
registration.LeaseToken,
|
|
out SecretFingerprint leaseFingerprint));
|
|
IReadOnlyList<StoredJoinAttempt> attempts = Sessions.Store.BrowseHostJoinAttempts(new(
|
|
registration.ListingId,
|
|
leaseFingerprint,
|
|
ContractLimits.BrowserPageMaxItems)).Value!;
|
|
return attempts.Single(attempt => attempt.AttemptId == attemptId);
|
|
}
|
|
|
|
public IntroductionEndpoints Introduce(
|
|
RegisterSessionResponse registration,
|
|
CreateJoinAttemptResponse created)
|
|
{
|
|
StoredJoinAttempt attempt = GetAttempt(registration, created.AttemptId);
|
|
HostJoinAttempt host = Service.BrowseForHost(
|
|
registration.ListingId,
|
|
ContractLimits.ContractVersion,
|
|
registration.LeaseToken,
|
|
ContractLimits.BrowserPageMaxItems,
|
|
null).Value!.Items.Single(item => item.AttemptId == created.AttemptId);
|
|
Assert.True(Sessions.Capabilities.TryFingerprint(
|
|
host.HostPunchCapability,
|
|
out SecretFingerprint hostFingerprint));
|
|
Assert.True(Sessions.Capabilities.TryFingerprint(
|
|
created.ClientPunchCapability,
|
|
out SecretFingerprint clientFingerprint));
|
|
Assert.True(Sessions.Store.BindAttemptEndpoint(new(
|
|
attempt.MediationHandle,
|
|
AttemptPeerRole.Host,
|
|
hostFingerprint,
|
|
new(AddressFamilyKind.Ipv4, "203.0.113.20", 41_000),
|
|
null)).Succeeded);
|
|
Assert.True(Sessions.Store.BindAttemptEndpoint(new(
|
|
attempt.MediationHandle,
|
|
AttemptPeerRole.Client,
|
|
clientFingerprint,
|
|
new(AddressFamilyKind.Ipv4, "198.51.100.40", 42_000),
|
|
null)).Succeeded);
|
|
StoreResult<IntroductionEndpoints> introduced = Sessions.Store.ConsumeIntroduction(
|
|
attempt.MediationHandle);
|
|
Assert.True(introduced.Succeeded);
|
|
return introduced.Value!;
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
Cursors.Dispose();
|
|
Sessions.Dispose();
|
|
}
|
|
}
|