[Redis] Add functional test support (#1051)
This commit is contained in:
parent
9789e09cfb
commit
ff43390ed2
|
|
@ -1,4 +1,4 @@
|
||||||
image: Visual Studio 2015
|
image: Visual Studio 2017
|
||||||
init:
|
init:
|
||||||
- git config --global core.autocrlf true
|
- git config --global core.autocrlf true
|
||||||
branches:
|
branches:
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
language: csharp
|
language: csharp
|
||||||
sudo: false
|
sudo: required
|
||||||
dist: trusty
|
dist: trusty
|
||||||
|
services:
|
||||||
|
- docker
|
||||||
env:
|
env:
|
||||||
global:
|
global:
|
||||||
- DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
|
- DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
|
||||||
|
|
@ -24,6 +26,7 @@ branches:
|
||||||
- /^(.*\/)?ci-.*$/
|
- /^(.*\/)?ci-.*$/
|
||||||
- /^rel\/.*/
|
- /^rel\/.*/
|
||||||
before_install:
|
before_install:
|
||||||
- if test "$TRAVIS_OS_NAME" == "linux"; then nvm install $TRAVIS_NODE_VERSION; fi
|
# Pull redis docker image so when test creates container it doesn't time out
|
||||||
|
- if test "$TRAVIS_OS_NAME" == "linux"; then nvm install $TRAVIS_NODE_VERSION; docker pull redis; fi
|
||||||
script:
|
script:
|
||||||
- ./build.sh
|
- ./build.sh
|
||||||
|
|
|
||||||
|
|
@ -17,33 +17,33 @@ namespace Microsoft.AspNetCore.SignalR.Tests.Common
|
||||||
public class ServerFixture<TStartup> : IDisposable
|
public class ServerFixture<TStartup> : IDisposable
|
||||||
where TStartup : class
|
where TStartup : class
|
||||||
{
|
{
|
||||||
private ILoggerFactory _loggerFactory;
|
private readonly ILoggerFactory _loggerFactory;
|
||||||
private ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
private IWebHost _host;
|
private IWebHost _host;
|
||||||
private IApplicationLifetime _lifetime;
|
private IApplicationLifetime _lifetime;
|
||||||
private readonly IDisposable _logToken;
|
private readonly IDisposable _logToken;
|
||||||
|
|
||||||
public string BaseUrl { get; private set; }
|
public string WebSocketsUrl => Url.Replace("http", "ws");
|
||||||
|
|
||||||
public string WebSocketsUrl => BaseUrl.Replace("http", "ws");
|
public string Url { get; private set; }
|
||||||
|
|
||||||
public ServerFixture()
|
public ServerFixture()
|
||||||
{
|
{
|
||||||
var testLog = AssemblyTestLog.ForAssembly(typeof(ServerFixture<TStartup>).Assembly);
|
var testLog = AssemblyTestLog.ForAssembly(typeof(ServerFixture<TStartup>).Assembly);
|
||||||
_logToken = testLog.StartTestLog(null, $"{nameof(ServerFixture<TStartup>)}_{typeof(TStartup).Name}" , out _loggerFactory, "ServerFixture");
|
_logToken = testLog.StartTestLog(null, $"{nameof(ServerFixture<TStartup>)}_{typeof(TStartup).Name}", out _loggerFactory, "ServerFixture");
|
||||||
_logger = _loggerFactory.CreateLogger<ServerFixture<TStartup>>();
|
_logger = _loggerFactory.CreateLogger<ServerFixture<TStartup>>();
|
||||||
BaseUrl = "http://localhost:" + GetNextPort();
|
Url = "http://localhost:" + GetNextPort();
|
||||||
|
|
||||||
StartServer();
|
StartServer(Url);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StartServer()
|
private void StartServer(string url)
|
||||||
{
|
{
|
||||||
_host = new WebHostBuilder()
|
_host = new WebHostBuilder()
|
||||||
.ConfigureLogging(builder => builder.AddProvider(new ForwardingLoggerProvider(_loggerFactory)))
|
.ConfigureLogging(builder => builder.AddProvider(new ForwardingLoggerProvider(_loggerFactory)))
|
||||||
.UseStartup(typeof(TStartup))
|
.UseStartup(typeof(TStartup))
|
||||||
.UseKestrel()
|
.UseKestrel()
|
||||||
.UseUrls(BaseUrl)
|
.UseUrls(url)
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.FunctionalTests
|
||||||
using (StartLog(out var loggerFactory))
|
using (StartLog(out var loggerFactory))
|
||||||
{
|
{
|
||||||
var connection = new HubConnectionBuilder()
|
var connection = new HubConnectionBuilder()
|
||||||
.WithUrl(_serverFixture.BaseUrl + path)
|
.WithUrl(_serverFixture.Url + path)
|
||||||
.WithTransport(transportType)
|
.WithTransport(transportType)
|
||||||
.WithLoggerFactory(loggerFactory)
|
.WithLoggerFactory(loggerFactory)
|
||||||
.WithHubProtocol(protocol)
|
.WithHubProtocol(protocol)
|
||||||
|
|
@ -78,7 +78,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.FunctionalTests
|
||||||
using (StartLog(out var loggerFactory))
|
using (StartLog(out var loggerFactory))
|
||||||
{
|
{
|
||||||
const string originalMessage = "SignalR";
|
const string originalMessage = "SignalR";
|
||||||
var httpConnection = new HttpConnection(new Uri(_serverFixture.BaseUrl + path), transportType, loggerFactory);
|
var httpConnection = new HttpConnection(new Uri(_serverFixture.Url + path), transportType, loggerFactory);
|
||||||
var connection = new HubConnection(httpConnection, protocol, loggerFactory);
|
var connection = new HubConnection(httpConnection, protocol, loggerFactory);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -108,7 +108,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.FunctionalTests
|
||||||
{
|
{
|
||||||
const string originalMessage = "SignalR";
|
const string originalMessage = "SignalR";
|
||||||
var uriString = "http://test/" + path;
|
var uriString = "http://test/" + path;
|
||||||
var httpConnection = new HttpConnection(new Uri(_serverFixture.BaseUrl + path), transportType, loggerFactory);
|
var httpConnection = new HttpConnection(new Uri(_serverFixture.Url + path), transportType, loggerFactory);
|
||||||
var connection = new HubConnection(httpConnection, protocol, loggerFactory);
|
var connection = new HubConnection(httpConnection, protocol, loggerFactory);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -138,7 +138,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.FunctionalTests
|
||||||
{
|
{
|
||||||
const string originalMessage = "SignalR";
|
const string originalMessage = "SignalR";
|
||||||
|
|
||||||
var httpConnection = new HttpConnection(new Uri(_serverFixture.BaseUrl + path), transportType, loggerFactory);
|
var httpConnection = new HttpConnection(new Uri(_serverFixture.Url + path), transportType, loggerFactory);
|
||||||
var connection = new HubConnection(httpConnection, protocol, loggerFactory);
|
var connection = new HubConnection(httpConnection, protocol, loggerFactory);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -169,7 +169,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.FunctionalTests
|
||||||
{
|
{
|
||||||
using (StartLog(out var loggerFactory))
|
using (StartLog(out var loggerFactory))
|
||||||
{
|
{
|
||||||
var httpConnection = new HttpConnection(new Uri(_serverFixture.BaseUrl + path), transportType, loggerFactory);
|
var httpConnection = new HttpConnection(new Uri(_serverFixture.Url + path), transportType, loggerFactory);
|
||||||
var connection = new HubConnection(httpConnection, protocol, loggerFactory);
|
var connection = new HubConnection(httpConnection, protocol, loggerFactory);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -191,7 +191,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.FunctionalTests
|
||||||
{
|
{
|
||||||
using (StartLog(out var loggerFactory))
|
using (StartLog(out var loggerFactory))
|
||||||
{
|
{
|
||||||
var httpConnection = new HttpConnection(new Uri(_serverFixture.BaseUrl + path), transportType, loggerFactory);
|
var httpConnection = new HttpConnection(new Uri(_serverFixture.Url + path), transportType, loggerFactory);
|
||||||
var connection = new HubConnection(httpConnection, protocol, loggerFactory);
|
var connection = new HubConnection(httpConnection, protocol, loggerFactory);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -220,7 +220,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.FunctionalTests
|
||||||
{
|
{
|
||||||
using (StartLog(out var loggerFactory))
|
using (StartLog(out var loggerFactory))
|
||||||
{
|
{
|
||||||
var httpConnection = new HttpConnection(new Uri(_serverFixture.BaseUrl + path), transportType, loggerFactory);
|
var httpConnection = new HttpConnection(new Uri(_serverFixture.Url + path), transportType, loggerFactory);
|
||||||
var connection = new HubConnection(httpConnection, protocol, loggerFactory);
|
var connection = new HubConnection(httpConnection, protocol, loggerFactory);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -255,7 +255,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.FunctionalTests
|
||||||
{
|
{
|
||||||
using (StartLog(out var loggerFactory))
|
using (StartLog(out var loggerFactory))
|
||||||
{
|
{
|
||||||
var httpConnection = new HttpConnection(new Uri(_serverFixture.BaseUrl + path), transportType, loggerFactory);
|
var httpConnection = new HttpConnection(new Uri(_serverFixture.Url + path), transportType, loggerFactory);
|
||||||
var connection = new HubConnection(httpConnection, protocol, loggerFactory);
|
var connection = new HubConnection(httpConnection, protocol, loggerFactory);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -286,7 +286,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.FunctionalTests
|
||||||
{
|
{
|
||||||
using (StartLog(out var loggerFactory))
|
using (StartLog(out var loggerFactory))
|
||||||
{
|
{
|
||||||
var httpConnection = new HttpConnection(new Uri(_serverFixture.BaseUrl + path), transportType, loggerFactory);
|
var httpConnection = new HttpConnection(new Uri(_serverFixture.Url + path), transportType, loggerFactory);
|
||||||
var connection = new HubConnection(httpConnection, protocol, loggerFactory);
|
var connection = new HubConnection(httpConnection, protocol, loggerFactory);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -314,7 +314,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.FunctionalTests
|
||||||
{
|
{
|
||||||
using (StartLog(out var loggerFactory))
|
using (StartLog(out var loggerFactory))
|
||||||
{
|
{
|
||||||
var httpConnection = new HttpConnection(new Uri(_serverFixture.BaseUrl + hubPath), transportType, loggerFactory);
|
var httpConnection = new HttpConnection(new Uri(_serverFixture.Url + hubPath), transportType, loggerFactory);
|
||||||
var connection = new HubConnection(httpConnection, hubProtocol, loggerFactory);
|
var connection = new HubConnection(httpConnection, hubProtocol, loggerFactory);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -341,7 +341,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.FunctionalTests
|
||||||
{
|
{
|
||||||
using (StartLog(out var loggerFactory))
|
using (StartLog(out var loggerFactory))
|
||||||
{
|
{
|
||||||
var httpConnection = new HttpConnection(new Uri(_serverFixture.BaseUrl + hubPath), transportType, loggerFactory);
|
var httpConnection = new HttpConnection(new Uri(_serverFixture.Url + hubPath), transportType, loggerFactory);
|
||||||
var connection = new HubConnection(httpConnection, hubProtocol, loggerFactory);
|
var connection = new HubConnection(httpConnection, hubProtocol, loggerFactory);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -368,7 +368,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.FunctionalTests
|
||||||
{
|
{
|
||||||
using (StartLog(out var loggerFactory))
|
using (StartLog(out var loggerFactory))
|
||||||
{
|
{
|
||||||
var httpConnection = new HttpConnection(new Uri(_serverFixture.BaseUrl + hubPath), transportType, loggerFactory);
|
var httpConnection = new HttpConnection(new Uri(_serverFixture.Url + hubPath), transportType, loggerFactory);
|
||||||
var connection = new HubConnection(httpConnection, hubProtocol, loggerFactory);
|
var connection = new HubConnection(httpConnection, hubProtocol, loggerFactory);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -395,7 +395,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.FunctionalTests
|
||||||
{
|
{
|
||||||
using (StartLog(out var loggerFactory))
|
using (StartLog(out var loggerFactory))
|
||||||
{
|
{
|
||||||
var httpConnection = new HttpConnection(new Uri(_serverFixture.BaseUrl + hubPath), transportType, loggerFactory);
|
var httpConnection = new HttpConnection(new Uri(_serverFixture.Url + hubPath), transportType, loggerFactory);
|
||||||
var connection = new HubConnection(httpConnection, hubProtocol, loggerFactory);
|
var connection = new HubConnection(httpConnection, hubProtocol, loggerFactory);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -424,7 +424,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.FunctionalTests
|
||||||
using (StartLog(out var loggerFactory))
|
using (StartLog(out var loggerFactory))
|
||||||
{
|
{
|
||||||
loggerFactory.AddConsole(LogLevel.Trace);
|
loggerFactory.AddConsole(LogLevel.Trace);
|
||||||
var httpConnection = new HttpConnection(new Uri(_serverFixture.BaseUrl + hubPath), transportType, loggerFactory);
|
var httpConnection = new HttpConnection(new Uri(_serverFixture.Url + hubPath), transportType, loggerFactory);
|
||||||
var connection = new HubConnection(httpConnection, hubProtocol, loggerFactory);
|
var connection = new HubConnection(httpConnection, hubProtocol, loggerFactory);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -452,7 +452,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.FunctionalTests
|
||||||
{
|
{
|
||||||
using (StartLog(out var loggerFactory))
|
using (StartLog(out var loggerFactory))
|
||||||
{
|
{
|
||||||
var httpConnection = new HttpConnection(new Uri(_serverFixture.BaseUrl + hubPath), transportType, loggerFactory);
|
var httpConnection = new HttpConnection(new Uri(_serverFixture.Url + hubPath), transportType, loggerFactory);
|
||||||
var connection = new HubConnection(httpConnection, hubProtocol, loggerFactory);
|
var connection = new HubConnection(httpConnection, hubProtocol, loggerFactory);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -480,7 +480,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.FunctionalTests
|
||||||
{
|
{
|
||||||
using (StartLog(out var loggerFactory))
|
using (StartLog(out var loggerFactory))
|
||||||
{
|
{
|
||||||
var httpConnection = new HttpConnection(new Uri(_serverFixture.BaseUrl + hubPath), transportType, loggerFactory);
|
var httpConnection = new HttpConnection(new Uri(_serverFixture.Url + hubPath), transportType, loggerFactory);
|
||||||
var connection = new HubConnection(httpConnection, hubProtocol, loggerFactory);
|
var connection = new HubConnection(httpConnection, hubProtocol, loggerFactory);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -507,7 +507,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.FunctionalTests
|
||||||
{
|
{
|
||||||
using (StartLog(out var loggerFactory))
|
using (StartLog(out var loggerFactory))
|
||||||
{
|
{
|
||||||
var httpConnection = new HttpConnection(new Uri(_serverFixture.BaseUrl + hubPath), transportType, loggerFactory);
|
var httpConnection = new HttpConnection(new Uri(_serverFixture.Url + hubPath), transportType, loggerFactory);
|
||||||
var connection = new HubConnection(httpConnection, hubProtocol, loggerFactory);
|
var connection = new HubConnection(httpConnection, hubProtocol, loggerFactory);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -534,7 +534,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.FunctionalTests
|
||||||
{
|
{
|
||||||
using (StartLog(out var loggerFactory))
|
using (StartLog(out var loggerFactory))
|
||||||
{
|
{
|
||||||
var httpConnection = new HttpConnection(new Uri(_serverFixture.BaseUrl + hubPath), transportType, loggerFactory);
|
var httpConnection = new HttpConnection(new Uri(_serverFixture.Url + hubPath), transportType, loggerFactory);
|
||||||
var connection = new HubConnection(httpConnection, hubProtocol, loggerFactory);
|
var connection = new HubConnection(httpConnection, hubProtocol, loggerFactory);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,108 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.SignalR.Redis.Tests
|
||||||
|
{
|
||||||
|
public class Docker
|
||||||
|
{
|
||||||
|
private static readonly string _exeSuffix = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".exe" : string.Empty;
|
||||||
|
|
||||||
|
private static readonly string _dockerContainerName = "redisTestContainer";
|
||||||
|
private static Lazy<Docker> _instance = new Lazy<Docker>(Create);
|
||||||
|
|
||||||
|
public static Docker Default => _instance.Value;
|
||||||
|
|
||||||
|
private readonly string _path;
|
||||||
|
|
||||||
|
public Docker(string path)
|
||||||
|
{
|
||||||
|
_path = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Docker Create()
|
||||||
|
{
|
||||||
|
// Currently Windows Server 2016 doesn't support linux containers which redis is.
|
||||||
|
if (string.Equals("True", Environment.GetEnvironmentVariable("APPVEYOR"), StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var location = GetDockerLocation();
|
||||||
|
return location == null ? null : new Docker(location);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetDockerLocation()
|
||||||
|
{
|
||||||
|
foreach (var dir in Environment.GetEnvironmentVariable("PATH").Split(Path.PathSeparator))
|
||||||
|
{
|
||||||
|
var candidate = Path.Combine(dir, "docker" + _exeSuffix);
|
||||||
|
if (File.Exists(candidate))
|
||||||
|
{
|
||||||
|
return candidate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Start(ILogger logger)
|
||||||
|
{
|
||||||
|
logger.LogInformation("Starting docker container");
|
||||||
|
|
||||||
|
// create and run docker container, remove automatically when stopped, map 6379 from the container to 6379 localhost
|
||||||
|
// use static name 'redisTestContainer' so if the container doesn't get removed we don't keep adding more
|
||||||
|
// use redis base docker image
|
||||||
|
return RunProcess(_path, $"run --rm -p 6379:6379 --name {_dockerContainerName} -d redis", logger);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Stop(ILogger logger)
|
||||||
|
{
|
||||||
|
logger.LogInformation("Stopping docker container");
|
||||||
|
return RunProcess(_path, $"stop {_dockerContainerName}", logger);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int RunProcess(string fileName, string arugments, ILogger logger)
|
||||||
|
{
|
||||||
|
var process = new Process
|
||||||
|
{
|
||||||
|
StartInfo = new ProcessStartInfo
|
||||||
|
{
|
||||||
|
FileName = fileName,
|
||||||
|
Arguments = arugments,
|
||||||
|
UseShellExecute = false,
|
||||||
|
RedirectStandardError = true,
|
||||||
|
RedirectStandardOutput = true
|
||||||
|
},
|
||||||
|
EnableRaisingEvents = true
|
||||||
|
};
|
||||||
|
|
||||||
|
var exitCode = 0;
|
||||||
|
process.Exited += (_, __) => exitCode = process.ExitCode;
|
||||||
|
process.OutputDataReceived += (_, a) => LogIfNotNull(logger.LogInformation, "stdout: {0}", a.Data);
|
||||||
|
process.ErrorDataReceived += (_, a) => LogIfNotNull(logger.LogError, "stderr: {0}", a.Data);
|
||||||
|
|
||||||
|
process.Start();
|
||||||
|
|
||||||
|
process.BeginErrorReadLine();
|
||||||
|
process.BeginOutputReadLine();
|
||||||
|
|
||||||
|
process.WaitForExit(5000);
|
||||||
|
|
||||||
|
return exitCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void LogIfNotNull(Action<string, object[]> logger, string message, string data)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(data))
|
||||||
|
{
|
||||||
|
logger(message, new[] { data });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.SignalR.Redis.Tests
|
||||||
|
{
|
||||||
|
public class EchoHub : Hub
|
||||||
|
{
|
||||||
|
public string Echo(string message)
|
||||||
|
{
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task EchoGroup(string group, string message)
|
||||||
|
{
|
||||||
|
return Clients.Group(group).InvokeAsync("Echo", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task AddSelfToGroup(string group)
|
||||||
|
{
|
||||||
|
return Groups.AddAsync(Context.ConnectionId, group);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -6,17 +6,25 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="..\Common\ServerFixture.cs" Link="ServerFixture.cs" />
|
||||||
<Compile Include="..\Common\TestClient.cs" Link="TestClient.cs" />
|
<Compile Include="..\Common\TestClient.cs" Link="TestClient.cs" />
|
||||||
|
<Compile Include="..\Common\TestHelpers.cs" Link="TestHelpers.cs" />
|
||||||
<Compile Include="..\Common\TaskExtensions.cs" Link="TaskExtensions.cs" />
|
<Compile Include="..\Common\TaskExtensions.cs" Link="TaskExtensions.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.SignalR.Redis\Microsoft.AspNetCore.SignalR.Redis.csproj" />
|
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.SignalR.Redis\Microsoft.AspNetCore.SignalR.Redis.csproj" />
|
||||||
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Sockets\Microsoft.AspNetCore.Sockets.csproj" />
|
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Sockets\Microsoft.AspNetCore.Sockets.csproj" />
|
||||||
|
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.SignalR\Microsoft.AspNetCore.SignalR.csproj" />
|
||||||
|
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.SignalR.Client\Microsoft.AspNetCore.SignalR.Client.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="$(MicrosoftAspNetCoreHostingPackageVersion)" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="$(MicrosoftAspNetCoreServerKestrelPackageVersion)" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="$(MicrosoftExtensionsDependencyInjectionPackageVersion)" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="$(MicrosoftExtensionsLoggingPackageVersion)" />
|
<PackageReference Include="Microsoft.Extensions.Logging" Version="$(MicrosoftExtensionsLoggingPackageVersion)" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Logging.Testing" Version="$(MicrosoftExtensionsLoggingTestingPackageVersion)" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,120 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.SignalR.Client;
|
||||||
|
using Microsoft.AspNetCore.SignalR.Internal.Protocol;
|
||||||
|
using Microsoft.AspNetCore.SignalR.Tests.Common;
|
||||||
|
using Microsoft.AspNetCore.Sockets;
|
||||||
|
using Microsoft.AspNetCore.Testing.xunit;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Microsoft.Extensions.Logging.Testing;
|
||||||
|
using Xunit;
|
||||||
|
using Xunit.Abstractions;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.SignalR.Redis.Tests
|
||||||
|
{
|
||||||
|
[CollectionDefinition(Name)]
|
||||||
|
public class EndToEndTestsCollection : ICollectionFixture<RedisServerFixture<Startup>>
|
||||||
|
{
|
||||||
|
public const string Name = "RedisEndToEndTests";
|
||||||
|
}
|
||||||
|
|
||||||
|
[Collection(EndToEndTestsCollection.Name)]
|
||||||
|
public class RedisEndToEndTests : LoggedTest
|
||||||
|
{
|
||||||
|
private readonly RedisServerFixture<Startup> _serverFixture;
|
||||||
|
|
||||||
|
public RedisEndToEndTests(RedisServerFixture<Startup> serverFixture, ITestOutputHelper output) : base(output)
|
||||||
|
{
|
||||||
|
if (serverFixture == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(serverFixture));
|
||||||
|
}
|
||||||
|
|
||||||
|
_serverFixture = serverFixture;
|
||||||
|
}
|
||||||
|
|
||||||
|
[ConditionalTheory]
|
||||||
|
[SkipIfDockerNotPresent]
|
||||||
|
[MemberData(nameof(TransportTypesAndProtocolTypes))]
|
||||||
|
public async Task HubConnectionCanSendAndReceiveMessages(TransportType transportType, IHubProtocol protocol)
|
||||||
|
{
|
||||||
|
using (StartLog(out var loggerFactory, testName:
|
||||||
|
$"{nameof(HubConnectionCanSendAndReceiveMessages)}_{transportType.ToString()}_{protocol.Name}"))
|
||||||
|
{
|
||||||
|
var connection = CreateConnection(_serverFixture.FirstServer.Url + "/echo", transportType, protocol, loggerFactory);
|
||||||
|
|
||||||
|
await connection.StartAsync().OrTimeout();
|
||||||
|
var str = await connection.InvokeAsync<string>("Echo", "Hello, World!").OrTimeout();
|
||||||
|
|
||||||
|
Assert.Equal("Hello, World!", str);
|
||||||
|
|
||||||
|
await connection.DisposeAsync().OrTimeout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[ConditionalTheory]
|
||||||
|
[SkipIfDockerNotPresent]
|
||||||
|
[MemberData(nameof(TransportTypesAndProtocolTypes))]
|
||||||
|
public async Task HubConnectionCanSendAndReceiveGroupMessages(TransportType transportType, IHubProtocol protocol)
|
||||||
|
{
|
||||||
|
using (StartLog(out var loggerFactory, testName:
|
||||||
|
$"{nameof(HubConnectionCanSendAndReceiveGroupMessages)}_{transportType.ToString()}_{protocol.Name}"))
|
||||||
|
{
|
||||||
|
var connection = CreateConnection(_serverFixture.FirstServer.Url + "/echo", transportType, protocol, loggerFactory);
|
||||||
|
var secondConnection = CreateConnection(_serverFixture.SecondServer.Url + "/echo", transportType, protocol, loggerFactory);
|
||||||
|
|
||||||
|
var tcs = new TaskCompletionSource<string>();
|
||||||
|
connection.On<string>("Echo", message => tcs.TrySetResult(message));
|
||||||
|
var tcs2 = new TaskCompletionSource<string>();
|
||||||
|
secondConnection.On<string>("Echo", message => tcs2.TrySetResult(message));
|
||||||
|
|
||||||
|
await secondConnection.StartAsync().OrTimeout();
|
||||||
|
await connection.StartAsync().OrTimeout();
|
||||||
|
await connection.InvokeAsync("AddSelfToGroup", "Test").OrTimeout();
|
||||||
|
await secondConnection.InvokeAsync("AddSelfToGroup", "Test").OrTimeout();
|
||||||
|
await connection.InvokeAsync("EchoGroup", "Test", "Hello, World!").OrTimeout();
|
||||||
|
|
||||||
|
Assert.Equal("Hello, World!", await tcs.Task.OrTimeout());
|
||||||
|
Assert.Equal("Hello, World!", await tcs2.Task.OrTimeout());
|
||||||
|
|
||||||
|
await connection.DisposeAsync().OrTimeout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static HubConnection CreateConnection(string url, TransportType transportType, IHubProtocol protocol, ILoggerFactory loggerFactory)
|
||||||
|
{
|
||||||
|
return new HubConnectionBuilder()
|
||||||
|
.WithUrl(url)
|
||||||
|
.WithTransport(transportType)
|
||||||
|
.WithHubProtocol(protocol)
|
||||||
|
.WithLoggerFactory(loggerFactory)
|
||||||
|
.Build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IEnumerable<TransportType> TransportTypes()
|
||||||
|
{
|
||||||
|
if (TestHelpers.IsWebSocketsSupported())
|
||||||
|
{
|
||||||
|
yield return TransportType.WebSockets;
|
||||||
|
}
|
||||||
|
yield return TransportType.ServerSentEvents;
|
||||||
|
yield return TransportType.LongPolling;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<object[]> TransportTypesAndProtocolTypes
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
foreach (var transport in TransportTypes())
|
||||||
|
{
|
||||||
|
yield return new object[] { transport, new JsonHubProtocol() };
|
||||||
|
yield return new object[] { transport, new MessagePackHubProtocol() };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,64 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using Microsoft.AspNetCore.SignalR.Tests.Common;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Microsoft.Extensions.Logging.Testing;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.SignalR.Redis.Tests
|
||||||
|
{
|
||||||
|
public class RedisServerFixture<TStartup> : IDisposable
|
||||||
|
where TStartup : class
|
||||||
|
{
|
||||||
|
public ServerFixture<TStartup> FirstServer { get; private set; }
|
||||||
|
public ServerFixture<TStartup> SecondServer { get; private set; }
|
||||||
|
|
||||||
|
private readonly ILogger _logger;
|
||||||
|
private readonly ILoggerFactory _loggerFactory;
|
||||||
|
private readonly IDisposable _logToken;
|
||||||
|
|
||||||
|
public RedisServerFixture()
|
||||||
|
{
|
||||||
|
// Docker is not available on the machine, tests using this fixture
|
||||||
|
// should be using SkipIfDockerNotPresentAttribute and will be skipped.
|
||||||
|
if (Docker.Default == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var testLog = AssemblyTestLog.ForAssembly(typeof(RedisServerFixture<TStartup>).Assembly);
|
||||||
|
_logToken = testLog.StartTestLog(null, $"{nameof(RedisServerFixture<TStartup>)}_{typeof(TStartup).Name}", out _loggerFactory, "RedisServerFixture");
|
||||||
|
_logger = _loggerFactory.CreateLogger<RedisServerFixture<TStartup>>();
|
||||||
|
|
||||||
|
FirstServer = StartServer();
|
||||||
|
SecondServer = StartServer();
|
||||||
|
|
||||||
|
Docker.Default.Start(_logger);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ServerFixture<TStartup> StartServer()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return new ServerFixture<TStartup>();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Server failed to start.");
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if (Docker.Default != null)
|
||||||
|
{
|
||||||
|
FirstServer.Dispose();
|
||||||
|
SecondServer.Dispose();
|
||||||
|
Docker.Default.Stop(_logger);
|
||||||
|
_logToken.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using Microsoft.AspNetCore.Testing.xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.SignalR.Redis.Tests
|
||||||
|
{
|
||||||
|
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
|
||||||
|
public class SkipIfDockerNotPresentAttribute : Attribute, ITestCondition
|
||||||
|
{
|
||||||
|
public bool IsMet => Docker.Default != null;
|
||||||
|
public string SkipReason => "Docker is not installed on the host machine.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.SignalR.Redis.Tests
|
||||||
|
{
|
||||||
|
public class Startup
|
||||||
|
{
|
||||||
|
public void ConfigureServices(IServiceCollection services)
|
||||||
|
{
|
||||||
|
services.AddSignalR()
|
||||||
|
.AddRedis();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
|
||||||
|
{
|
||||||
|
app.UseSignalR(options => options.MapHub<EchoHub>("echo"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -47,7 +47,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task CanStartAndStopConnectionUsingDefaultTransport()
|
public async Task CanStartAndStopConnectionUsingDefaultTransport()
|
||||||
{
|
{
|
||||||
var url = _serverFixture.BaseUrl + "/echo";
|
var url = _serverFixture.Url + "/echo";
|
||||||
// The test should connect to the server using WebSockets transport on Windows 8 and newer.
|
// The test should connect to the server using WebSockets transport on Windows 8 and newer.
|
||||||
// On Windows 7/2008R2 it should use ServerSentEvents transport to connect to the server.
|
// On Windows 7/2008R2 it should use ServerSentEvents transport to connect to the server.
|
||||||
var connection = new HttpConnection(new Uri(url));
|
var connection = new HttpConnection(new Uri(url));
|
||||||
|
|
@ -59,7 +59,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests
|
||||||
[MemberData(nameof(TransportTypes))]
|
[MemberData(nameof(TransportTypes))]
|
||||||
public async Task CanStartAndStopConnectionUsingGivenTransport(TransportType transportType)
|
public async Task CanStartAndStopConnectionUsingGivenTransport(TransportType transportType)
|
||||||
{
|
{
|
||||||
var url = _serverFixture.BaseUrl + "/echo";
|
var url = _serverFixture.Url + "/echo";
|
||||||
var connection = new HttpConnection(new Uri(url), transportType);
|
var connection = new HttpConnection(new Uri(url), transportType);
|
||||||
await connection.StartAsync().OrTimeout();
|
await connection.StartAsync().OrTimeout();
|
||||||
await connection.DisposeAsync().OrTimeout();
|
await connection.DisposeAsync().OrTimeout();
|
||||||
|
|
@ -106,7 +106,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests
|
||||||
using (StartLog(out var loggerFactory))
|
using (StartLog(out var loggerFactory))
|
||||||
{
|
{
|
||||||
var logger = loggerFactory.CreateLogger<EndToEndTests>();
|
var logger = loggerFactory.CreateLogger<EndToEndTests>();
|
||||||
var url = _serverFixture.BaseUrl + "/echo";
|
var url = _serverFixture.Url + "/echo";
|
||||||
|
|
||||||
var mockHttpHandler = new Mock<HttpMessageHandler>();
|
var mockHttpHandler = new Mock<HttpMessageHandler>();
|
||||||
mockHttpHandler.Protected()
|
mockHttpHandler.Protected()
|
||||||
|
|
@ -157,7 +157,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests
|
||||||
|
|
||||||
const string message = "Major Key";
|
const string message = "Major Key";
|
||||||
|
|
||||||
var url = _serverFixture.BaseUrl + "/echo";
|
var url = _serverFixture.Url + "/echo";
|
||||||
var connection = new HttpConnection(new Uri(url), transportType, loggerFactory);
|
var connection = new HttpConnection(new Uri(url), transportType, loggerFactory);
|
||||||
|
|
||||||
connection.Features.Set<ITransferModeFeature>(
|
connection.Features.Set<ITransferModeFeature>(
|
||||||
|
|
@ -248,7 +248,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests
|
||||||
{
|
{
|
||||||
var logger = loggerFactory.CreateLogger<EndToEndTests>();
|
var logger = loggerFactory.CreateLogger<EndToEndTests>();
|
||||||
|
|
||||||
var url = _serverFixture.BaseUrl + "/echo";
|
var url = _serverFixture.Url + "/echo";
|
||||||
var connection = new HttpConnection(new Uri(url), TransportType.WebSockets, loggerFactory);
|
var connection = new HttpConnection(new Uri(url), TransportType.WebSockets, loggerFactory);
|
||||||
connection.Features.Set<ITransferModeFeature>(
|
connection.Features.Set<ITransferModeFeature>(
|
||||||
new TransferModeFeature { TransferMode = TransferMode.Binary });
|
new TransferModeFeature { TransferMode = TransferMode.Binary });
|
||||||
|
|
@ -315,7 +315,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests
|
||||||
{
|
{
|
||||||
var logger = loggerFactory.CreateLogger<EndToEndTests>();
|
var logger = loggerFactory.CreateLogger<EndToEndTests>();
|
||||||
|
|
||||||
var url = _serverFixture.BaseUrl + "/uncreatable";
|
var url = _serverFixture.Url + "/uncreatable";
|
||||||
|
|
||||||
var connection = new HubConnectionBuilder()
|
var connection = new HubConnectionBuilder()
|
||||||
.WithUrl(new Uri(url))
|
.WithUrl(new Uri(url))
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue