Skip to content

Commit 11fbf3b

Browse files
authored
Merge pull request #1587 from rabbitmq/rabbitmq-dotnet-client-1573
Add test demonstrating that #1573 is fixed
2 parents 1a8d0cb + 4457c17 commit 11fbf3b

File tree

2 files changed

+128
-1
lines changed

2 files changed

+128
-1
lines changed

projects/Test/SequentialIntegration/SequentialIntegration.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
<AssemblyOriginatorKeyFile>../../rabbit.snk</AssemblyOriginatorKeyFile>
1717
<SignAssembly>true</SignAssembly>
1818
<IsTestProject>true</IsTestProject>
19-
<LangVersion>7.3</LangVersion>
19+
<LangVersion>8.0</LangVersion>
2020
</PropertyGroup>
2121

2222
<ItemGroup>
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
// This source code is dual-licensed under the Apache License, version
2+
// 2.0, and the Mozilla Public License, version 2.0.
3+
//
4+
// The APL v2.0:
5+
//
6+
//---------------------------------------------------------------------------
7+
// Copyright (c) 2007-2020 VMware, Inc.
8+
//
9+
// Licensed under the Apache License, Version 2.0 (the "License");
10+
// you may not use this file except in compliance with the License.
11+
// You may obtain a copy of the License at
12+
//
13+
// https://www.apache.org/licenses/LICENSE-2.0
14+
//
15+
// Unless required by applicable law or agreed to in writing, software
16+
// distributed under the License is distributed on an "AS IS" BASIS,
17+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18+
// See the License for the specific language governing permissions and
19+
// limitations under the License.
20+
//---------------------------------------------------------------------------
21+
//
22+
// The MPL v2.0:
23+
//
24+
//---------------------------------------------------------------------------
25+
// This Source Code Form is subject to the terms of the Mozilla Public
26+
// License, v. 2.0. If a copy of the MPL was not distributed with this
27+
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
28+
//
29+
// Copyright (c) 2007-2020 VMware, Inc. All rights reserved.
30+
//---------------------------------------------------------------------------
31+
32+
using System;
33+
using System.Collections.Generic;
34+
using System.Threading;
35+
using System.Threading.Tasks;
36+
using RabbitMQ.Client;
37+
using RabbitMQ.Client.Events;
38+
using Xunit;
39+
using Xunit.Abstractions;
40+
41+
namespace Test.SequentialIntegration
42+
{
43+
public class TestConnectionBlockedChannelLeak : SequentialIntegrationFixture
44+
{
45+
public TestConnectionBlockedChannelLeak(ITestOutputHelper output) : base(output)
46+
{
47+
}
48+
49+
public override async Task InitializeAsync()
50+
{
51+
await UnblockAsync();
52+
_connFactory = new ConnectionFactory
53+
{
54+
AutomaticRecoveryEnabled = true,
55+
ClientProvidedName = _testDisplayName,
56+
ContinuationTimeout = TimeSpan.FromSeconds(2)
57+
};
58+
_conn = await _connFactory.CreateConnectionAsync();
59+
_channel = await _conn.CreateChannelAsync();
60+
}
61+
62+
public override async Task DisposeAsync()
63+
{
64+
await UnblockAsync();
65+
await base.DisposeAsync();
66+
}
67+
68+
[Fact]
69+
public async Task TestConnectionBlockedChannelLeak_GH1573()
70+
{
71+
string exchangeName = GenerateExchangeName();
72+
73+
var tcs = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
74+
75+
using var cts = new CancellationTokenSource(WaitSpan);
76+
using CancellationTokenRegistration ctr = cts.Token.Register(() =>
77+
{
78+
tcs.TrySetCanceled();
79+
});
80+
81+
_conn.ConnectionBlocked += (object sender, ConnectionBlockedEventArgs args) =>
82+
{
83+
UnblockAsync();
84+
};
85+
86+
_conn.ConnectionUnblocked += (object sender, EventArgs ea) =>
87+
{
88+
tcs.SetResult(true);
89+
};
90+
91+
await BlockAsync(_channel);
92+
93+
using (IChannel publishChannel = await _conn.CreateChannelAsync())
94+
{
95+
await publishChannel.ExchangeDeclareAsync(exchangeName, ExchangeType.Direct, autoDelete: true);
96+
await publishChannel.BasicPublishAsync(exchangeName, exchangeName, GetRandomBody(), mandatory: true);
97+
await publishChannel.CloseAsync();
98+
}
99+
100+
var channels = new List<IChannel>();
101+
for (int i = 1; i <= 5; i++)
102+
{
103+
IChannel c = await _conn.CreateChannelAsync();
104+
channels.Add(c);
105+
}
106+
107+
/*
108+
* Note:
109+
* This wait probably isn't necessary, if the above CreateChannelAsync
110+
* calls were to timeout, we'd get exceptions on the await
111+
*/
112+
await Task.Delay(TimeSpan.FromSeconds(5));
113+
114+
// Note: debugging
115+
// var rmq = new RabbitMQCtl(_output);
116+
// string output = await rmq.ExecRabbitMQCtlAsync("list_channels");
117+
// _output.WriteLine("CHANNELS 0: {0}", output);
118+
119+
await UnblockAsync();
120+
121+
// output = await rmq.ExecRabbitMQCtlAsync("list_channels");
122+
// _output.WriteLine("CHANNELS 1: {0}", output);
123+
124+
Assert.True(await tcs.Task, "Unblock notification not received.");
125+
}
126+
}
127+
}

0 commit comments

Comments
 (0)