Skip to content
Merged
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
30 changes: 28 additions & 2 deletions test/StreamJsonRpc.Tests/MarshalableProxyTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,31 @@ public async Task IMarshalable_MarshaledBackAndForth()
Assert.True(IsExceptionOrInnerOfType<NotSupportedException>(ex));
}

[Fact]
public async Task OneObjectMarshalledTwiceHasIndependentLifetimes()
{
// The method we call twice returns the same object each time,
// but JsonRpc doesn't recognize this and assigns a unique token and proxy each time.
IMarshalable proxy1 = (await this.client.GetMarshalableAsync().WithCancellation(this.TimeoutToken))!;
IMarshalable proxy2 = (await this.client.GetMarshalableAsync().WithCancellation(this.TimeoutToken))!;

// Verify that although the original object is the same, the proxies are different.
Assert.NotSame(proxy1, proxy2);

// Verify that the proxies both work.
await proxy1.DoSomethingAsync();
await proxy2.DoSomethingAsync();

// Verify that disposing one proxy doesn't break the connection the other proxy has with the original object.
// For our purposes, the original object's Dispose isn't so self-destructive that it would break proxy2's
// ability to call methods on it.
// In doing so, wait for the dispose to propagate to the remote party.
proxy1.Dispose();
await this.server.ReturnedMarshalableDisposed.WaitAsync(this.TimeoutToken);
await proxy2.DoSomethingAsync();
proxy2.Dispose();
}

[Fact]
public async Task DisposeOnDisconnect()
{
Expand Down Expand Up @@ -892,9 +917,10 @@ public class Server : IServer

public Task<IMarshalable?> GetMarshalableAsync(bool returnNull)
{
var marshalable = returnNull ? null : new Data(() => this.ReturnedMarshalableDisposed.Set());
// The OneObjectMarshalledTwiceHasIndependentLifetimes test depends on us returning the same instance each time.
var marshalable = returnNull ? null : (this.ReturnedMarshalable ?? new Data(() => this.ReturnedMarshalableDisposed.Set()));
this.ReturnedMarshalable = marshalable;
return Task.FromResult<IMarshalable?>(marshalable);
return Task.FromResult(marshalable);
}

public Task<IMarshalableWithOptionalInterfaces?> GetMarshalableWithOptionalInterfacesAsync()
Expand Down