Skip to content

Commit e703ee9

Browse files
committed
加上连接管理的单元测试
1 parent e05f45b commit e703ee9

File tree

2 files changed

+296
-0
lines changed

2 files changed

+296
-0
lines changed

src/dotnetCampus.Ipc/Pipes/IpcProvider.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,9 @@ private void NotifyPeerConnected(PeerProxy peer)
301301
/// <summary>
302302
/// 本机作为服务端,有对方连接过来时触发
303303
/// </summary>
304+
/// <remarks>
305+
/// 仅被动连接(被对方连接过来)时触发。主动去连接对方时,不会触发此事件。如需要获取无论是主动还是被动连接过来的事件,请使用 <see cref="IPeerManager.PeerConnected"/> 事件
306+
/// </remarks>
304307
public event EventHandler<PeerConnectedArgs>? PeerConnected;
305308

306309
/// <summary>
Lines changed: 293 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,293 @@
1+
using dotnetCampus.Ipc.Pipes;
2+
3+
using Microsoft.VisualStudio.TestTools.UnitTesting;
4+
5+
namespace dotnetCampus.Ipc.Tests;
6+
7+
[TestClass]
8+
public class PeerManagerTest
9+
{
10+
[TestMethod("无论是主动连接还是被动连接,都能触发 PeerManager.PeerConnected 事件")]
11+
public async Task TestPeerManager1()
12+
{
13+
var nameA = "PeerManagerTest_1";
14+
var nameB = "PeerManagerTest_2";
15+
16+
var a = new IpcProvider(nameA);
17+
var b = new IpcProvider(nameB);
18+
19+
var aPeerManagerConnectedCount = 0;
20+
var bPeerManagerConnectedCount = 0;
21+
22+
a.PeerManager.PeerConnected += (sender, args) =>
23+
{
24+
aPeerManagerConnectedCount++;
25+
};
26+
27+
b.PeerManager.PeerConnected += (sender, args) =>
28+
{
29+
bPeerManagerConnectedCount++;
30+
};
31+
32+
var aIpcProviderConnectedCount = 0;
33+
var bIpcProviderConnectedCount = 0;
34+
35+
a.PeerConnected += (sender, args) =>
36+
{
37+
aIpcProviderConnectedCount++;
38+
};
39+
var bConnectedTaskCompletionSource = new TaskCompletionSource();
40+
b.PeerConnected += (sender, args) =>
41+
{
42+
bIpcProviderConnectedCount++;
43+
bConnectedTaskCompletionSource.SetResult();
44+
};
45+
46+
a.StartServer();
47+
48+
Task<PeerProxy> connectTask = a.GetAndConnectToPeerAsync(nameB);
49+
50+
Assert.IsFalse(connectTask.IsCompleted, "由于此时 B 服务还没启动,必定现在还没连接完成");
51+
// 这里有一个小争议点,那就是事件名为 PeerConnected 但实际上可能没有完全完成连接的建立
52+
Assert.AreEqual(1, aPeerManagerConnectedCount, "已经主动在 a 发起连接,此时有一个记录");
53+
Assert.AreEqual(0, bPeerManagerConnectedCount, "还没有完成建立连接,必定现在是 0 的值");
54+
55+
Assert.AreEqual(0, aIpcProviderConnectedCount, "还没有完成建立连接,必定现在是 0 的值");
56+
Assert.AreEqual(0, bIpcProviderConnectedCount, "还没有完成建立连接,必定现在是 0 的值");
57+
58+
// 开启 B 服务了,预期现在能够完成连接
59+
b.StartServer();
60+
61+
// 等待连接
62+
await connectTask;
63+
64+
// 由于 b 是在另一个线程\进程跑的,不是在当前单元测试所在的线程跑的。需要等待一下,避免多线程执行顺序,导致单元测试概率不通过
65+
await Task.WhenAny(bConnectedTaskCompletionSource.Task, Task.Delay(TimeSpan.FromSeconds(3)));
66+
67+
// 连接完成之后,预期现在无论是 a 还是 b 的 PeerManager 都有一次连接触发。但 IpcProvider 的 PeerConnected 只有 b 被动连接的一次触发
68+
Assert.AreEqual(1, aPeerManagerConnectedCount, "连接完成之后,无论主动连接,都能让 PeerManager.PeerConnected 事件触发");
69+
Assert.AreEqual(1, bPeerManagerConnectedCount, "连接完成之后,无论主动连接,都能让 PeerManager.PeerConnected 事件触发");
70+
71+
Assert.AreEqual(0, aIpcProviderConnectedCount, "连接完成之后,只有被动连接才能让 IpcProvider.PeerConnected 事件触发。由于是 a 主动连接 b 的,因此 a 的 IpcProvider.PeerConnected 事件没有触发");
72+
Assert.AreEqual(1, bIpcProviderConnectedCount, "连接完成之后,只有被动连接才能让 IpcProvider.PeerConnected 事件触发。由于是 a 主动连接 b 的,因此 b 的 IpcProvider.PeerConnected 事件触发");
73+
74+
// 当前连接只有一项
75+
Assert.AreEqual(1, a.PeerManager.CurrentConnectedPeerProxyCount);
76+
Assert.AreEqual(1, b.PeerManager.CurrentConnectedPeerProxyCount);
77+
78+
Assert.AreEqual(1, a.PeerManager.GetCurrentConnectedPeerProxyList().Count);
79+
Assert.AreEqual(1, b.PeerManager.GetCurrentConnectedPeerProxyList().Count);
80+
81+
// 现在 a 所连接的就是 b 的
82+
Assert.AreEqual(nameB, a.PeerManager.GetCurrentConnectedPeerProxyList()[0].PeerName);
83+
// 现在 b 所连接的就是 a 的
84+
Assert.AreEqual(nameA, b.PeerManager.GetCurrentConnectedPeerProxyList()[0].PeerName);
85+
}
86+
87+
[TestMethod("a 主动连接 b 和 c,测试三端的 PeerManager.PeerConnected 事件和连接数量")]
88+
public async Task TestPeerManager2()
89+
{
90+
var nameA = "PeerManagerTest2_A";
91+
var nameB = "PeerManagerTest2_B";
92+
var nameC = "PeerManagerTest2_C";
93+
94+
var a = new IpcProvider(nameA);
95+
var b = new IpcProvider(nameB);
96+
var c = new IpcProvider(nameC);
97+
98+
var aPeerManagerConnectedCount = 0;
99+
var bPeerManagerConnectedCount = 0;
100+
var cPeerManagerConnectedCount = 0;
101+
102+
a.PeerManager.PeerConnected += (sender, args) =>
103+
{
104+
aPeerManagerConnectedCount++;
105+
};
106+
107+
b.PeerManager.PeerConnected += (sender, args) =>
108+
{
109+
bPeerManagerConnectedCount++;
110+
};
111+
112+
c.PeerManager.PeerConnected += (sender, args) =>
113+
{
114+
cPeerManagerConnectedCount++;
115+
};
116+
117+
var aIpcProviderConnectedCount = 0;
118+
var bIpcProviderConnectedCount = 0;
119+
var cIpcProviderConnectedCount = 0;
120+
121+
a.PeerConnected += (sender, args) =>
122+
{
123+
aIpcProviderConnectedCount++;
124+
};
125+
126+
var bConnectedTaskCompletionSource = new TaskCompletionSource();
127+
b.PeerConnected += (sender, args) =>
128+
{
129+
bIpcProviderConnectedCount++;
130+
bConnectedTaskCompletionSource.SetResult();
131+
};
132+
133+
var cConnectedTaskCompletionSource = new TaskCompletionSource();
134+
c.PeerConnected += (sender, args) =>
135+
{
136+
cIpcProviderConnectedCount++;
137+
cConnectedTaskCompletionSource.SetResult();
138+
};
139+
140+
a.StartServer();
141+
142+
Task<PeerProxy> connectToBTask = a.GetAndConnectToPeerAsync(nameB);
143+
Task<PeerProxy> connectToCTask = a.GetAndConnectToPeerAsync(nameC);
144+
145+
Assert.IsFalse(connectToBTask.IsCompleted, "由于此时 B 服务还没启动,必定现在还没连接完成");
146+
Assert.IsFalse(connectToCTask.IsCompleted, "由于此时 C 服务还没启动,必定现在还没连接完成");
147+
// 这里有一个小争议点,那就是事件名为 PeerConnected 但实际上可能没有完全完成连接的建立
148+
Assert.AreEqual(2, aPeerManagerConnectedCount, "a 主动发起连接 b 和 c,此时已有两个记录");
149+
Assert.AreEqual(0, bPeerManagerConnectedCount, "还没有完成建立连接,必定现在是 0 的值");
150+
Assert.AreEqual(0, cPeerManagerConnectedCount, "还没有完成建立连接,必定现在是 0 的值");
151+
152+
Assert.AreEqual(0, aIpcProviderConnectedCount, "还没有完成建立连接,必定现在是 0 的值");
153+
Assert.AreEqual(0, bIpcProviderConnectedCount, "还没有完成建立连接,必定现在是 0 的值");
154+
Assert.AreEqual(0, cIpcProviderConnectedCount, "还没有完成建立连接,必定现在是 0 的值");
155+
156+
// 开启 B 和 C 服务了,预期现在能够完成连接
157+
b.StartServer();
158+
c.StartServer();
159+
160+
// 等待连接
161+
await Task.WhenAll(connectToBTask, connectToCTask);
162+
163+
// 由于 b 和 c 是在另一个线程跑的,需要等待一下,避免多线程执行顺序,导致单元测试概率不通过
164+
await Task.WhenAny(
165+
Task.WhenAll(bConnectedTaskCompletionSource.Task, cConnectedTaskCompletionSource.Task),
166+
Task.Delay(TimeSpan.FromSeconds(3)));
167+
168+
Assert.AreEqual(2, aPeerManagerConnectedCount, "连接完成之后,a 主动连接 b 和 c,PeerManager.PeerConnected 触发两次");
169+
Assert.AreEqual(1, bPeerManagerConnectedCount, "连接完成之后,b 被 a 连接,PeerManager.PeerConnected 触发一次");
170+
Assert.AreEqual(1, cPeerManagerConnectedCount, "连接完成之后,c 被 a 连接,PeerManager.PeerConnected 触发一次");
171+
172+
Assert.AreEqual(0, aIpcProviderConnectedCount, "a 是主动连接方,IpcProvider.PeerConnected 事件不触发");
173+
Assert.AreEqual(1, bIpcProviderConnectedCount, "b 是被动连接方,IpcProvider.PeerConnected 事件触发一次");
174+
Assert.AreEqual(1, cIpcProviderConnectedCount, "c 是被动连接方,IpcProvider.PeerConnected 事件触发一次");
175+
176+
Assert.AreEqual(2, a.PeerManager.CurrentConnectedPeerProxyCount);
177+
Assert.AreEqual(1, b.PeerManager.CurrentConnectedPeerProxyCount);
178+
Assert.AreEqual(1, c.PeerManager.CurrentConnectedPeerProxyCount);
179+
180+
Assert.AreEqual(2, a.PeerManager.GetCurrentConnectedPeerProxyList().Count);
181+
Assert.AreEqual(1, b.PeerManager.GetCurrentConnectedPeerProxyList().Count);
182+
Assert.AreEqual(1, c.PeerManager.GetCurrentConnectedPeerProxyList().Count);
183+
184+
// a 连接了 b 和 c,顺序不保证,用名称集合验证
185+
var aConnectedPeerNames = a.PeerManager.GetCurrentConnectedPeerProxyList().Select(p => p.PeerName).ToHashSet();
186+
Assert.IsTrue(aConnectedPeerNames.Contains(nameB), "a 连接的列表中应包含 b");
187+
Assert.IsTrue(aConnectedPeerNames.Contains(nameC), "a 连接的列表中应包含 c");
188+
189+
// b 和 c 各自只连了 a
190+
Assert.AreEqual(nameA, b.PeerManager.GetCurrentConnectedPeerProxyList()[0].PeerName);
191+
Assert.AreEqual(nameA, c.PeerManager.GetCurrentConnectedPeerProxyList()[0].PeerName);
192+
}
193+
194+
[TestMethod("b 和 c 主动连接 a,测试三端的 PeerManager.PeerConnected 事件和连接数量")]
195+
public async Task TestPeerManager3()
196+
{
197+
var nameA = "PeerManagerTest3_A";
198+
var nameB = "PeerManagerTest3_B";
199+
var nameC = "PeerManagerTest3_C";
200+
201+
var a = new IpcProvider(nameA);
202+
var b = new IpcProvider(nameB);
203+
var c = new IpcProvider(nameC);
204+
205+
var aPeerManagerConnectedCount = 0;
206+
var bPeerManagerConnectedCount = 0;
207+
var cPeerManagerConnectedCount = 0;
208+
209+
a.PeerManager.PeerConnected += (sender, args) =>
210+
{
211+
aPeerManagerConnectedCount++;
212+
};
213+
214+
b.PeerManager.PeerConnected += (sender, args) =>
215+
{
216+
bPeerManagerConnectedCount++;
217+
};
218+
219+
c.PeerManager.PeerConnected += (sender, args) =>
220+
{
221+
cPeerManagerConnectedCount++;
222+
};
223+
224+
var aIpcProviderConnectedCount = 0;
225+
var bIpcProviderConnectedCount = 0;
226+
var cIpcProviderConnectedCount = 0;
227+
228+
var aAllConnectedTaskCompletionSource = new TaskCompletionSource();
229+
a.PeerConnected += (sender, args) =>
230+
{
231+
aIpcProviderConnectedCount++;
232+
if (aIpcProviderConnectedCount >= 2)
233+
{
234+
aAllConnectedTaskCompletionSource.TrySetResult();
235+
}
236+
};
237+
238+
b.PeerConnected += (sender, args) =>
239+
{
240+
bIpcProviderConnectedCount++;
241+
};
242+
243+
c.PeerConnected += (sender, args) =>
244+
{
245+
cIpcProviderConnectedCount++;
246+
};
247+
248+
a.StartServer();
249+
b.StartServer();
250+
c.StartServer();
251+
252+
Task<PeerProxy> bConnectToATask = b.GetAndConnectToPeerAsync(nameA);
253+
Task<PeerProxy> cConnectToATask = c.GetAndConnectToPeerAsync(nameA);
254+
255+
// 这里有一个小争议点,那就是事件名为 PeerConnected 但实际上可能没有完全完成连接的建立
256+
Assert.AreEqual(1, bPeerManagerConnectedCount, "b 主动发起连接 a,此时 b 有一个记录");
257+
Assert.AreEqual(1, cPeerManagerConnectedCount, "c 主动发起连接 a,此时 c 有一个记录");
258+
259+
Assert.AreEqual(0, bIpcProviderConnectedCount, "b 是主动连接方,IpcProvider.PeerConnected 事件不触发");
260+
Assert.AreEqual(0, cIpcProviderConnectedCount, "c 是主动连接方,IpcProvider.PeerConnected 事件不触发");
261+
262+
// 等待连接
263+
await Task.WhenAll(bConnectToATask, cConnectToATask);
264+
265+
// 由于 a 是在另一个线程跑的,需要等待一下,避免多线程执行顺序,导致单元测试概率不通过
266+
await Task.WhenAny(aAllConnectedTaskCompletionSource.Task, Task.Delay(TimeSpan.FromSeconds(3)));
267+
268+
Assert.AreEqual(2, aPeerManagerConnectedCount, "连接完成之后,a 被 b 和 c 连接,PeerManager.PeerConnected 触发两次");
269+
Assert.AreEqual(1, bPeerManagerConnectedCount, "b 主动连接 a,PeerManager.PeerConnected 触发一次");
270+
Assert.AreEqual(1, cPeerManagerConnectedCount, "c 主动连接 a,PeerManager.PeerConnected 触发一次");
271+
272+
Assert.AreEqual(2, aIpcProviderConnectedCount, "a 是被动连接方,IpcProvider.PeerConnected 事件触发两次");
273+
Assert.AreEqual(0, bIpcProviderConnectedCount, "b 是主动连接方,IpcProvider.PeerConnected 事件不触发");
274+
Assert.AreEqual(0, cIpcProviderConnectedCount, "c 是主动连接方,IpcProvider.PeerConnected 事件不触发");
275+
276+
Assert.AreEqual(2, a.PeerManager.CurrentConnectedPeerProxyCount);
277+
Assert.AreEqual(1, b.PeerManager.CurrentConnectedPeerProxyCount);
278+
Assert.AreEqual(1, c.PeerManager.CurrentConnectedPeerProxyCount);
279+
280+
Assert.AreEqual(2, a.PeerManager.GetCurrentConnectedPeerProxyList().Count);
281+
Assert.AreEqual(1, b.PeerManager.GetCurrentConnectedPeerProxyList().Count);
282+
Assert.AreEqual(1, c.PeerManager.GetCurrentConnectedPeerProxyList().Count);
283+
284+
// a 被 b 和 c 连接,顺序不保证,用名称集合验证
285+
var aConnectedPeerNames = a.PeerManager.GetCurrentConnectedPeerProxyList().Select(p => p.PeerName).ToHashSet();
286+
Assert.IsTrue(aConnectedPeerNames.Contains(nameB), "a 连接的列表中应包含 b");
287+
Assert.IsTrue(aConnectedPeerNames.Contains(nameC), "a 连接的列表中应包含 c");
288+
289+
// b 和 c 各自只连了 a
290+
Assert.AreEqual(nameA, b.PeerManager.GetCurrentConnectedPeerProxyList()[0].PeerName);
291+
Assert.AreEqual(nameA, c.PeerManager.GetCurrentConnectedPeerProxyList()[0].PeerName);
292+
}
293+
}

0 commit comments

Comments
 (0)