Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for generic services #510

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion build/Build.cs
Original file line number Diff line number Diff line change
Expand Up @@ -146,9 +146,10 @@ ITargetDefinition TestDefinition(ITargetDefinition targetDefinition, Target depe
.SetVerbosity(DotNetVerbosity.Normal));
});

[PublicAPI]
Target CopyToLocalPackages => _ => _
.OnlyWhenStatic(() => IsLocalBuild)
.TriggeredBy(Pack)
.DependsOn(Pack)
.Executes(() =>
{
EnsureExistingDirectory(LocalPackagesDirectory);
Expand Down
16 changes: 16 additions & 0 deletions source/Halibut.TestUtils.Contracts/IGenericService`.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;
using System.Threading;
using System.Threading.Tasks;

namespace Halibut.TestUtils.Contracts
{
public interface IGenericService<in T>
{
string GetInfo(T value);
}

public interface IAsyncGenericService<in T>
{
Task<string> GetInfoAsync(T value, CancellationToken cancellationToken);
}
}
31 changes: 31 additions & 0 deletions source/Halibut.Tests/GenericServiceFixture.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System.Threading.Tasks;
using FluentAssertions;
using Halibut.Logging;
using Halibut.Tests.Support.TestAttributes;
using Halibut.Tests.Support.TestCases;
using Halibut.Tests.TestServices.Async;
using Halibut.TestUtils.Contracts;
using NUnit.Framework;

namespace Halibut.Tests
{
public class GenericServiceFixture : BaseTest
{
[Test]
[LatestClientAndLatestServiceTestCases(testNetworkConditions: false)]
public async Task GenericServiceNamesAreCorrectlyCalled(ClientAndServiceTestCase clientAndServiceTestCase)
{
await using var clientAndService = await clientAndServiceTestCase.CreateTestCaseBuilder()
.WithGenericService<string>()
.WithGenericService<double>()
.WithHalibutLoggingLevel(LogLevel.Info)
.Build(CancellationToken);

var stringClient = clientAndService.CreateClient<IGenericService<string>, IAsyncClientGenericService<string>>();
(await stringClient.GetInfoAsync("Cool string")).Should().Be("String => Cool string");

var doubleClient = clientAndService.CreateClient<IGenericService<double>, IAsyncClientGenericService<double>>();
(await doubleClient.GetInfoAsync(6.54321)).Should().Be("Double => 6.54321");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -109,13 +109,21 @@ public LatestClientAndPreviousServiceVersionBuilder WithTentacleServices()
}

IClientAndServiceBuilder IClientAndServiceBuilder.WithCachingService() => WithCachingService();



public IClientAndServiceBuilder WithCachingService()
{
availableServices.HasCachingService = true;
return this;
}

IClientAndServiceBuilder IClientAndServiceBuilder.WithGenericService<T>() => WithGenericService<T>();
public IClientAndServiceBuilder WithGenericService<T>()
{
availableServices.HasGenericService = true;
return this;
}

IClientAndServiceBuilder IClientAndServiceBuilder.WithProxy()
{
return WithProxy();
Expand Down Expand Up @@ -156,7 +164,7 @@ IClientAndServiceBuilder IClientAndServiceBuilder.NoService()
{
return NoService();
}

IClientAndServiceBuilder IClientAndServiceBuilder.WithForcingClientProxyType(ForceClientProxyType forceClientProxyType)
{
return WithForcingClientProxyType(forceClientProxyType);
Expand All @@ -177,7 +185,7 @@ async Task<IClientAndService> IClientAndServiceBuilder.Build(CancellationToken c
{
return await Build(cancellationToken);
}

public async Task<ClientAndService> Build(CancellationToken cancellationToken)
{
var logger = new SerilogLoggerBuilder().Build().ForContext<LatestClientAndPreviousServiceVersionBuilder>();
Expand Down Expand Up @@ -368,12 +376,12 @@ public TService CreateClient<TService>(Action<ServiceEndPoint> modifyServiceEndp
modifyServiceEndpoint(serviceEndpoint);
return new AdaptToSyncOrAsyncTestCase().Adapt<TService, TClientService>(forceClientProxyType, Client, serviceEndpoint);
}

public TAsyncClientWithOptions CreateClientWithOptions<TService, TSyncClientWithOptions, TAsyncClientWithOptions>()
{
return CreateClientWithOptions<TService, TSyncClientWithOptions, TAsyncClientWithOptions>(_ => { });
}

public TAsyncClientWithOptions CreateClientWithOptions<TService, TSyncClientWithOptions, TAsyncClientWithOptions>(Action<ServiceEndPoint> modifyServiceEndpoint)
{
var serviceEndpoint = ServiceEndPoint;
Expand All @@ -389,7 +397,7 @@ public TService CreateClient<TService>(Action<ServiceEndPoint> modifyServiceEndp
public async ValueTask DisposeAsync()
{
var logger = new SerilogLoggerBuilder().Build().ForContext<ClientAndService>();

logger.Information("****** ****** ****** ****** ****** ****** ******");
logger.Information("****** CLIENT AND SERVICE DISPOSE CALLED ******");
logger.Information("* Subsequent errors should be ignored *");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ public OldServiceAvailableServices(bool hasStandardServices, bool hasCachingServ
public bool HasStandardServices { get; set; }
public bool HasCachingService { get; set; }
public bool HasTentacleServices { get; set; }
public bool HasGenericService { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,11 @@ IClientAndServiceBuilder IClientAndServiceBuilder.WithCachingService()
throw new Exception("Caching service is not supported, when testing on the old Client. Since the old client is on external CLR which does not have the new caching attributes which this service is used to test.");
}

public IClientAndServiceBuilder WithGenericService<T>()
{
throw new NotSupportedException("Generic services are not supported when testing the old client");
}

public PreviousClientVersionAndLatestServiceBuilder WithMultipleParametersTestService(IMultipleParametersTestService multipleParametersTestService)
{
this.multipleParametersTestService = multipleParametersTestService;
Expand All @@ -128,13 +133,13 @@ public PreviousClientVersionAndLatestServiceBuilder WithComplexObjectService(ICo
this.complexObjectService = complexObjectService;
return this;
}

public PreviousClientVersionAndLatestServiceBuilder WithLockService(ILockService lockService)
{
this.lockService = lockService;
return this;
}

public PreviousClientVersionAndLatestServiceBuilder WithCountingService(ICountingService countingService)
{
this.countingService = countingService;
Expand Down Expand Up @@ -185,7 +190,7 @@ public PreviousClientVersionAndLatestServiceBuilder WithProxy()

return this;
}

IClientAndServiceBuilder IClientAndServiceBuilder.WithHalibutLoggingLevel(LogLevel halibutLogLevel)
{
return WithHalibutLoggingLevel(halibutLogLevel);
Expand All @@ -202,7 +207,7 @@ async Task<IClientAndService> IClientAndServiceBuilder.Build(CancellationToken c
{
return await Build(cancellationToken);
}

public PreviousClientVersionAndLatestServiceBuilder NoService()
{
throw new NotImplementedException();
Expand All @@ -212,7 +217,7 @@ IClientAndServiceBuilder IClientAndServiceBuilder.NoService()
{
return NoService();
}

IClientAndServiceBuilder IClientAndServiceBuilder.WithForcingClientProxyType(ForceClientProxyType forceClientProxyType)
{
throw new Exception("Not supported");
Expand Down Expand Up @@ -240,7 +245,7 @@ public async Task<ClientAndService> Build(CancellationToken cancellationToken)
.WithLogFactory(new TestContextLogCreator("ProxyClient", halibutLogLevel).ToCachingLogFactory())
.WithAsyncHalibutFeatureEnabled()
.Build();

proxyClient.Trust(serviceCertAndThumbprint.Thumbprint);

var serviceFactory = new DelegateServiceFactory()
Expand Down Expand Up @@ -464,9 +469,9 @@ public TService CreateClient<TService>(Action<ServiceEndPoint> modifyServiceEndp
{
throw new Exception($"Unsupported, since types within {typeof(TClientService)} would not actually be passed on to the remote process which holds the actual client under test.", e);
}

var serviceEndpoint = new ServiceEndPoint(serviceUri, serviceCertAndThumbprint.Thumbprint, Client.TimeoutsAndLimits);

return ProxyClient.CreateAsyncClient<TService, TClientService>(serviceEndpoint);
}

Expand All @@ -479,12 +484,12 @@ public TService CreateClient<TService>(Action<ServiceEndPoint> modifyServiceEndp
{
return CreateClientWithOptions<TService, TSyncClientWithOptions, TAsyncClientWithOptions>(_ => { });
}

public TAsyncClientWithOptions CreateClientWithOptions<TService, TSyncClientWithOptions, TAsyncClientWithOptions>(Action<ServiceEndPoint> modifyServiceEndpoint)
{
throw new NotSupportedException("Not supported since the options can not be passed to the external binary.");
}

public TAsyncClientService CreateAsyncClient<TService, TAsyncClientService>()
{
return Client.CreateAsyncClient<TService, TAsyncClientService>(ServiceEndPoint);
Expand Down
1 change: 1 addition & 0 deletions source/Halibut.Tests/Support/IClientAndServiceBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public interface IClientAndServiceBuilder
IClientAndServiceBuilder WithTentacleServices();
IClientAndServiceBuilder WithHalibutLoggingLevel(LogLevel info);
IClientAndServiceBuilder WithCachingService();
IClientAndServiceBuilder WithGenericService<T>();
IClientAndServiceBuilder NoService();
IClientAndServiceBuilder WithForcingClientProxyType(ForceClientProxyType forceClientProxyType);
IClientAndServiceBuilder WithServiceAsyncHalibutFeatureEnabled();
Expand Down