Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions samples/OrdersApi/Consumer.Tests/OrderCreatedConsumerTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Text.Json;
using System;
using System.Text.Json;
using System.Threading.Tasks;
using Moq;
using PactNet;
Expand All @@ -9,7 +10,7 @@

namespace Consumer.Tests
{
public class OrderCreatedConsumerTests
public sealed class OrderCreatedConsumerTests : IDisposable
{
private readonly OrderCreatedConsumer consumer;
private readonly Mock<IFulfilmentService> mockService;
Expand Down Expand Up @@ -38,6 +39,9 @@ public OrderCreatedConsumerTests(ITestOutputHelper output)
this.pact = Pact.V4("Fulfilment API", "Orders API", config).WithMessageInteractions();
}

public void Dispose() => this.pact.Dispose();


[Fact]
public async Task OnMessageAsync_OrderCreated_HandlesMessage()
{
Expand Down
4 changes: 3 additions & 1 deletion samples/OrdersApi/Consumer.Tests/OrdersClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

namespace Consumer.Tests
{
public class OrdersClientTests
public sealed class OrdersClientTests : IDisposable
{
private readonly IPactBuilderV4 pact;
private readonly Mock<IHttpClientFactory> mockFactory;
Expand Down Expand Up @@ -44,6 +44,8 @@ public OrdersClientTests(ITestOutputHelper output)
this.pact = Pact.V4("Fulfilment API", "Orders API", config).WithHttpInteractions();
}

public void Dispose() => this.pact.Dispose();

[Fact]
public async Task GetOrderAsync_WhenCalled_ReturnsOrder()
{
Expand Down
13 changes: 11 additions & 2 deletions src/PactNet.Abstractions/IMessagePactBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
using System;

namespace PactNet
{
/// <summary>
/// Message Pact Builder
/// </summary>
public interface IMessagePactBuilder : IDisposable
{
}

/// <summary>
/// Message pact v3 Builder
/// </summary>
public interface IMessagePactBuilderV3
public interface IMessagePactBuilderV3 : IMessagePactBuilder
{
/// <summary>
/// Add a new message to the pact
Expand All @@ -25,7 +34,7 @@ public interface IMessagePactBuilderV3
/// <summary>
/// Message pact v4 Builder
/// </summary>
public interface IMessagePactBuilderV4
public interface IMessagePactBuilderV4 : IMessagePactBuilder
{
/// <summary>
/// Add a new message to the pact
Expand Down
2 changes: 1 addition & 1 deletion src/PactNet.Abstractions/IPactBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace PactNet
/// <summary>
/// Pact Builder
/// </summary>
public interface IPactBuilder
public interface IPactBuilder : IDisposable
{
/// <summary>
/// Verify the configured interactions
Expand Down
25 changes: 25 additions & 0 deletions src/PactNet/Drivers/HttpPactDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,5 +57,30 @@ public IMockServerDriver CreateMockServer(string host, int? port, bool tls)
_ => new InvalidOperationException($"Unknown mock server error: {result}")
};
}

/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
this.ReleaseUnmanagedResources();
GC.SuppressFinalize(this);
}

/// <summary>
/// Allows an object to try to free resources and perform other cleanup operations before it is reclaimed by garbage collection.
/// </summary>
~HttpPactDriver()
{
this.ReleaseUnmanagedResources();
}

/// <summary>
/// Release unmanaged resources
/// </summary>
private void ReleaseUnmanagedResources()
{
NativeInterop.FreePact(this.pact);
}
}
}
2 changes: 1 addition & 1 deletion src/PactNet/Drivers/IHttpPactDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace PactNet.Drivers
/// <summary>
/// Driver for synchronous HTTP pacts
/// </summary>
internal interface IHttpPactDriver : ICompletedPactDriver
internal interface IHttpPactDriver : ICompletedPactDriver, IDisposable
{
/// <summary>
/// Create a new interaction on the current pact
Expand Down
6 changes: 4 additions & 2 deletions src/PactNet/Drivers/IMessagePactDriver.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
namespace PactNet.Drivers
using System;

namespace PactNet.Drivers
{
/// <summary>
/// Driver for message pacts
/// </summary>
internal interface IMessagePactDriver
internal interface IMessagePactDriver : IDisposable
{
/// <summary>
/// Create a new message interaction on the current pact
Expand Down
28 changes: 27 additions & 1 deletion src/PactNet/Drivers/MessagePactDriver.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using PactNet.Interop;
using System;
using PactNet.Interop;

namespace PactNet.Drivers
{
Expand Down Expand Up @@ -37,5 +38,30 @@ public IMessageInteractionDriver NewMessageInteraction(string description)
/// <param name="value">the value of the parameter</param>
public void WithMessagePactMetadata(string @namespace, string name, string value)
=> NativeInterop.WithMessagePactMetadata(this.pact, @namespace, name, value);

/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
this.ReleaseUnmanagedResources();
GC.SuppressFinalize(this);
}

/// <summary>
/// Allows an object to try to free resources and perform other cleanup operations before it is reclaimed by garbage collection.
/// </summary>
~MessagePactDriver()
{
this.ReleaseUnmanagedResources();
}

/// <summary>
/// Release unmanaged resources
/// </summary>
private void ReleaseUnmanagedResources()
{
NativeInterop.FreeMessagePact(this.pact);
}
}
}
2 changes: 1 addition & 1 deletion src/PactNet/Drivers/PactDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public IHttpPactDriver NewHttpPact(string consumerName, string providerName, Pac
/// <returns>Message pact driver driver</returns>
public IMessagePactDriver NewMessagePact(string consumerName, string providerName, PactSpecification version)
{
PactHandle pact = NativeInterop.NewPact(consumerName, providerName);
PactHandle pact = NativeInterop.NewMessagePact(consumerName, providerName);
NativeInterop.WithSpecification(pact, version).CheckInteropSuccess();

return new MessagePactDriver(pact);
Expand Down
9 changes: 9 additions & 0 deletions src/PactNet/Interop/NativeInterop.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ internal static class NativeInterop
[DllImport(DllName, EntryPoint = "pactffi_new_pact")]
public static extern PactHandle NewPact(string consumerName, string providerName);

[DllImport(DllName, EntryPoint = "pactffi_free_pact_handle")]
public static extern uint FreePact(PactHandle pact);

[DllImport(DllName, EntryPoint = "pactffi_with_specification")]
public static extern bool WithSpecification(PactHandle pact, PactSpecification version);

Expand Down Expand Up @@ -73,6 +76,12 @@ internal static class NativeInterop

#region Messaging Interop Support

[DllImport(DllName, EntryPoint = "pactffi_new_message_pact")]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These FFI methods have been effectively deprecated if I remember correctly, especially from spec v4 onwards. The new model is that the single pact handle can have both sync and async interactions added to it, and that's the call that we make internally regardless of pact type (sync, async or both [in v4 onwards])

public static extern PactHandle NewMessagePact(string consumerName, string providerName);

[DllImport(DllName, EntryPoint = "pactffi_free_message_pact_handle")]
public static extern uint FreeMessagePact(PactHandle pact);

[DllImport(DllName, EntryPoint = "pactffi_with_message_pact_metadata")]
public static extern void WithMessagePactMetadata(PactHandle pact, string @namespace, string name, string value);

Expand Down
8 changes: 8 additions & 0 deletions src/PactNet/MessagePactBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,5 +73,13 @@ internal MessagePactBuilder WithPactMetadata(string @namespace, string name, str
this.driver.WithMessagePactMetadata(@namespace, name, value);
return this;
}

/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
this.driver.Dispose();
}
}
}
8 changes: 8 additions & 0 deletions src/PactNet/PactBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -172,5 +172,13 @@ private void PrintLogs(IMockServerDriver mockServer)
this.config.WriteLine(string.Empty);
this.config.WriteLine(logs);
}

/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
this.pact.Dispose();
}
}
}