Add integration tests for the API clients
This commit is contained in:
parent
2fb3546b76
commit
3a3b6f840e
10 changed files with 188 additions and 4 deletions
|
@ -4,9 +4,20 @@ stages:
|
||||||
- test
|
- test
|
||||||
- release
|
- release
|
||||||
|
|
||||||
|
variables:
|
||||||
|
DOCKER_TLS_CERTDIR: "/certs"
|
||||||
|
DOCKER_CERT_PATH: "/certs/client"
|
||||||
|
DOCKER_TLS_VERIFY: 0
|
||||||
|
DOCKER_HOST: 'tcp://docker:2375'
|
||||||
|
|
||||||
test:
|
test:
|
||||||
stage: test
|
stage: test
|
||||||
|
services:
|
||||||
|
- docker:dind
|
||||||
|
variables:
|
||||||
|
PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/docker
|
||||||
script:
|
script:
|
||||||
|
- curl https://download.docker.com/linux/static/stable/x86_64/docker-20.10.4.tgz | tar -xzv -C /usr/local/
|
||||||
- dotnet tool restore
|
- dotnet tool restore
|
||||||
- dotnet nuke Test
|
- dotnet nuke Test
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "INetMock.Client.Test", "tes
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "_build", "build\_build.csproj", "{37738E95-E68E-4242-B7D7-9591605D8E33}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "_build", "build\_build.csproj", "{37738E95-E68E-4242-B7D7-9591605D8E33}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "INetMock.Client.IntegrationTest", "tests\INetMock.Client.IntegrationTest\INetMock.Client.IntegrationTest.csproj", "{D12E0C79-2E27-4FDB-94E7-402EBA267F72}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
@ -39,9 +41,14 @@ Global
|
||||||
{66DAC329-57DE-4218-9880-84E65E91E623}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{66DAC329-57DE-4218-9880-84E65E91E623}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{66DAC329-57DE-4218-9880-84E65E91E623}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{66DAC329-57DE-4218-9880-84E65E91E623}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{66DAC329-57DE-4218-9880-84E65E91E623}.Release|Any CPU.Build.0 = Release|Any CPU
|
{66DAC329-57DE-4218-9880-84E65E91E623}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{D12E0C79-2E27-4FDB-94E7-402EBA267F72}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{D12E0C79-2E27-4FDB-94E7-402EBA267F72}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{D12E0C79-2E27-4FDB-94E7-402EBA267F72}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{D12E0C79-2E27-4FDB-94E7-402EBA267F72}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(NestedProjects) = preSolution
|
GlobalSection(NestedProjects) = preSolution
|
||||||
{4B1CFFB0-23B5-4238-BFCC-4155F459FF8E} = {07100561-E3C0-4B95-92E1-D2D3BA12C3A6}
|
{4B1CFFB0-23B5-4238-BFCC-4155F459FF8E} = {07100561-E3C0-4B95-92E1-D2D3BA12C3A6}
|
||||||
{66DAC329-57DE-4218-9880-84E65E91E623} = {4FF6267B-A7EC-4277-98EA-39155A82C886}
|
{66DAC329-57DE-4218-9880-84E65E91E623} = {4FF6267B-A7EC-4277-98EA-39155A82C886}
|
||||||
|
{D12E0C79-2E27-4FDB-94E7-402EBA267F72} = {4FF6267B-A7EC-4277-98EA-39155A82C886}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|
3
assets/integration-tests.dockerfile
Normal file
3
assets/integration-tests.dockerfile
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
FROM registry.gitlab.com/inetmock/inetmock:latest
|
||||||
|
|
||||||
|
USER root
|
|
@ -1,3 +1,4 @@
|
||||||
|
using System.IO;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Nuke.Common;
|
using Nuke.Common;
|
||||||
using Nuke.Common.CI;
|
using Nuke.Common.CI;
|
||||||
|
@ -7,6 +8,7 @@ using Nuke.Common.Git;
|
||||||
using Nuke.Common.IO;
|
using Nuke.Common.IO;
|
||||||
using Nuke.Common.ProjectModel;
|
using Nuke.Common.ProjectModel;
|
||||||
using Nuke.Common.Tooling;
|
using Nuke.Common.Tooling;
|
||||||
|
using Nuke.Common.Tools.Docker;
|
||||||
using Nuke.Common.Tools.DotNet;
|
using Nuke.Common.Tools.DotNet;
|
||||||
using Nuke.Common.Tools.GitVersion;
|
using Nuke.Common.Tools.GitVersion;
|
||||||
using Nuke.Common.Utilities.Collections;
|
using Nuke.Common.Utilities.Collections;
|
||||||
|
@ -79,8 +81,14 @@ class Build : NukeBuild
|
||||||
.EnableNoRestore());
|
.EnableNoRestore());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Target IntegrationTestImage => _ => _
|
||||||
|
.Executes(() => DockerTasks.DockerBuild(s => s
|
||||||
|
.SetFile(Path.Join("assets", "integration-tests.dockerfile"))
|
||||||
|
.SetTag("inetmock-root")
|
||||||
|
.SetPath(".")));
|
||||||
|
|
||||||
Target Test => _ => _
|
Target Test => _ => _
|
||||||
.DependsOn(Compile)
|
.DependsOn(Compile, IntegrationTestImage)
|
||||||
.Executes(() => DotNetTest(s => s
|
.Executes(() => DotNetTest(s => s
|
||||||
.SetProjectFile(Solution)
|
.SetProjectFile(Solution)
|
||||||
.SetConfiguration(Configuration)
|
.SetConfiguration(Configuration)
|
||||||
|
|
|
@ -5,6 +5,7 @@ using System.Threading.Tasks;
|
||||||
using Grpc.Core;
|
using Grpc.Core;
|
||||||
using Grpc.Net.Client;
|
using Grpc.Net.Client;
|
||||||
using INetMock.Client.Audit.Serialization;
|
using INetMock.Client.Audit.Serialization;
|
||||||
|
using INetMock.Client.Grpc;
|
||||||
using INetMock.Client.Rpc;
|
using INetMock.Client.Rpc;
|
||||||
|
|
||||||
namespace INetMock.Client.Audit.Client
|
namespace INetMock.Client.Audit.Client
|
||||||
|
@ -18,7 +19,7 @@ namespace INetMock.Client.Audit.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
public AuditApiClient(Uri address, GrpcChannelOptions? options = null) : this(
|
public AuditApiClient(Uri address, GrpcChannelOptions? options = null) : this(
|
||||||
GrpcChannel.ForAddress(address, options ?? new GrpcChannelOptions()))
|
ChannelFactory.ForAddress(address, options ?? new GrpcChannelOptions()))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
40
src/INetMock.Client/Grpc/ChannelFactory.cs
Normal file
40
src/INetMock.Client/Grpc/ChannelFactory.cs
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
using System;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using Grpc.Net.Client;
|
||||||
|
|
||||||
|
namespace INetMock.Client.Grpc
|
||||||
|
{
|
||||||
|
internal static class ChannelFactory
|
||||||
|
{
|
||||||
|
internal static GrpcChannel ForAddress(Uri uri, GrpcChannelOptions options) =>
|
||||||
|
uri.Scheme.ToLowerInvariant() switch
|
||||||
|
{
|
||||||
|
"unix" => ForUnixSocket(uri.AbsolutePath, options),
|
||||||
|
_ => GrpcChannel.ForAddress(uri, options)
|
||||||
|
};
|
||||||
|
|
||||||
|
private static GrpcChannel ForUnixSocket(string path, GrpcChannelOptions options)
|
||||||
|
{
|
||||||
|
var endpoint = new UnixDomainSocketEndPoint(path);
|
||||||
|
options.HttpHandler = new SocketsHttpHandler
|
||||||
|
{
|
||||||
|
ConnectCallback = async (_, cancellationToken) =>
|
||||||
|
{
|
||||||
|
var socket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.Unspecified);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await socket.ConnectAsync(endpoint, cancellationToken).ConfigureAwait(false);
|
||||||
|
return new NetworkStream(socket, true);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
socket.Dispose();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return GrpcChannel.ForAddress("http://localhost", options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ using System.Threading.Tasks;
|
||||||
using Google.Protobuf.WellKnownTypes;
|
using Google.Protobuf.WellKnownTypes;
|
||||||
using Grpc.Core;
|
using Grpc.Core;
|
||||||
using Grpc.Net.Client;
|
using Grpc.Net.Client;
|
||||||
|
using INetMock.Client.Grpc;
|
||||||
using INetMock.Client.Rpc;
|
using INetMock.Client.Rpc;
|
||||||
|
|
||||||
namespace INetMock.Client.PCAP.Client
|
namespace INetMock.Client.PCAP.Client
|
||||||
|
@ -21,7 +22,7 @@ namespace INetMock.Client.PCAP.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
public PcapApiClient(Uri address, GrpcChannelOptions? options = null)
|
public PcapApiClient(Uri address, GrpcChannelOptions? options = null)
|
||||||
: this(GrpcChannel.ForAddress(address, options ?? new GrpcChannelOptions()))
|
: this(ChannelFactory.ForAddress(address, options ?? new GrpcChannelOptions()))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +91,7 @@ namespace INetMock.Client.PCAP.Client
|
||||||
throw new ArgumentOutOfRangeException();
|
throw new ArgumentOutOfRangeException();
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Subscription(key.Substring(0, splitIndex), key.Substring(splitIndex), key);
|
return new Subscription(key.Substring(splitIndex+1), key.Substring(0, splitIndex), key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
|
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="DotNet.Testcontainers" Version="1.4.0" />
|
||||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />
|
||||||
|
<PackageReference Include="xunit" Version="2.4.1" />
|
||||||
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="coverlet.collector" Version="1.3.0">
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\src\INetMock.Client\INetMock.Client.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
|
@ -0,0 +1,41 @@
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using DotNet.Testcontainers.Containers.Builders;
|
||||||
|
using DotNet.Testcontainers.Containers.Modules;
|
||||||
|
using DotNet.Testcontainers.Containers.WaitStrategies;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace INetMock.Client.IntegrationTest
|
||||||
|
{
|
||||||
|
public class INetMockServerFixture : IAsyncLifetime
|
||||||
|
{
|
||||||
|
private readonly TestcontainersContainer _inetmockContainer;
|
||||||
|
|
||||||
|
public INetMockServerFixture()
|
||||||
|
{
|
||||||
|
_inetmockContainer = new TestcontainersBuilder<TestcontainersContainer>()
|
||||||
|
.WithImage("inetmock-root:latest")
|
||||||
|
.WithCommand("serve")
|
||||||
|
.WithPortBinding(80, true)
|
||||||
|
.WithWaitStrategy(Wait.ForUnixContainer().UntilPortIsAvailable(80))
|
||||||
|
.WithDockerEndpoint(Environment.GetEnvironmentVariable("DOCKER_HOST") ?? "unix:///var/run/docker.sock")
|
||||||
|
.WithMount(Path.GetTempPath(), "/var/run/inetmock")
|
||||||
|
.WithCleanUp(true)
|
||||||
|
.Build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Uri SocketPath => new ($"unix://{Path.Join(Path.GetTempPath(), "inetmock.sock")}", UriKind.Absolute);
|
||||||
|
|
||||||
|
public async Task InitializeAsync()
|
||||||
|
{
|
||||||
|
await _inetmockContainer.StartAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task DisposeAsync()
|
||||||
|
{
|
||||||
|
await _inetmockContainer.StopAsync();
|
||||||
|
await _inetmockContainer.DisposeAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
using INetMock.Client.PCAP;
|
||||||
|
using INetMock.Client.PCAP.Client;
|
||||||
|
using Xunit;
|
||||||
|
using Xunit.Abstractions;
|
||||||
|
|
||||||
|
namespace INetMock.Client.IntegrationTest.PCAP.Client
|
||||||
|
{
|
||||||
|
public class PcapApiClientTests : IClassFixture<INetMockServerFixture>
|
||||||
|
{
|
||||||
|
private readonly ITestOutputHelper _outputHelper;
|
||||||
|
private readonly IPcapApiClient _apiClient;
|
||||||
|
|
||||||
|
public PcapApiClientTests(ITestOutputHelper testOutputHelper, INetMockServerFixture inetmockFixture)
|
||||||
|
{
|
||||||
|
_outputHelper = testOutputHelper;
|
||||||
|
_apiClient = new PcapApiClient(inetmockFixture.SocketPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async void ListAvailableDevicesAsync_RunningContainer_AtLeastLoopbackDevice()
|
||||||
|
{
|
||||||
|
var devs = await _apiClient.ListAvailableDevicesAsync();
|
||||||
|
|
||||||
|
Assert.Contains(devs, device => device.Name.Equals("lo"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async void ListActiveRecordingsAsync_NoRecordingsRunning_EmptyResult()
|
||||||
|
{
|
||||||
|
var recordings = await _apiClient.ListActiveRecordingsAsync();
|
||||||
|
|
||||||
|
Assert.Empty(recordings);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async void StartPcapFileRecordingAsync_RecordLoopbackInterface_RunningRecording()
|
||||||
|
{
|
||||||
|
const string targetPath = "/tmp/lo_record.pcap";
|
||||||
|
await _apiClient.StartPcapFileRecordingAsync(new("lo", targetPath));
|
||||||
|
|
||||||
|
var subscriptions = await _apiClient.ListActiveRecordingsAsync();
|
||||||
|
Assert.Contains(subscriptions, subscription => subscription.Device.Equals("lo") && subscription.ConsumerName.Equals(targetPath));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue