Skip to content

Commit a551f55

Browse files
committed
CSHARP-1347: implemented command monitoring specification.
1 parent 445713a commit a551f55

File tree

113 files changed

+6599
-358
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

113 files changed

+6599
-358
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ obj
88
*.vbproj.VisualState.xml
99
*.cache
1010
TestResults
11+
.vs
1112

1213
# CodeReview
1314
codereview.rc

src/MongoDB.Bson.TestHelpers/BsonDocumentAssertions.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,17 @@ public AndConstraint<BsonDocumentAssertions> Be(BsonDocument expected, string be
4242
return new AndConstraint<BsonDocumentAssertions>(this);
4343
}
4444

45+
public AndConstraint<BsonDocumentAssertions> BeEquivalentTo(BsonDocument expected, string because = "", params object[] reasonArgs)
46+
{
47+
Execute.Assertion
48+
.BecauseOf(because, reasonArgs)
49+
.ForCondition(BsonValueEquivalencyComparer.Compare(Subject, expected))
50+
.FailWith("Expected {context:object} to be {0}{reason}, but found {1}.", expected,
51+
Subject);
52+
53+
return new AndConstraint<BsonDocumentAssertions>(this);
54+
}
55+
4556
public AndConstraint<BsonDocumentAssertions> Be(string json, string because = "", params object[] reasonArgs)
4657
{
4758
var expected = json == null ? null : BsonDocument.Parse(json);
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/* Copyright 2015 MongoDB Inc.
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
using System;
17+
using System.Collections.Generic;
18+
using System.Linq;
19+
using System.Text;
20+
using System.Threading.Tasks;
21+
22+
namespace MongoDB.Bson.TestHelpers
23+
{
24+
public class BsonValueEquivalencyComparer
25+
{
26+
public static bool Compare(BsonValue a, BsonValue b)
27+
{
28+
if (a.BsonType == BsonType.Document && b.BsonType == BsonType.Document)
29+
{
30+
return CompareDocuments((BsonDocument)a, (BsonDocument)b);
31+
}
32+
else if (a.BsonType == BsonType.Array && b.BsonType == BsonType.Array)
33+
{
34+
return CompareArrays((BsonArray)a, (BsonArray)b);
35+
}
36+
else if (a.BsonType == b.BsonType)
37+
{
38+
return a.Equals(b);
39+
}
40+
else if (IsNumber(a) && IsNumber(b))
41+
{
42+
return a.ToDouble() == b.ToDouble();
43+
}
44+
else if (CouldBeBoolean(a) && CouldBeBoolean(b))
45+
{
46+
return a.ToBoolean() == b.ToBoolean();
47+
}
48+
else
49+
{
50+
return false;
51+
}
52+
}
53+
54+
private static bool CompareArrays(BsonArray a, BsonArray b)
55+
{
56+
if (a.Count != b.Count)
57+
{
58+
return false;
59+
}
60+
61+
for (var i = 0; i < a.Count; i++)
62+
{
63+
if (!Compare(a[i], b[i]))
64+
{
65+
return false;
66+
}
67+
}
68+
69+
return true;
70+
}
71+
72+
private static bool CompareDocuments(BsonDocument a, BsonDocument b)
73+
{
74+
if (a.ElementCount != b.ElementCount)
75+
{
76+
return false;
77+
}
78+
79+
foreach (var aElement in a)
80+
{
81+
BsonElement bElement;
82+
if (!b.TryGetElement(aElement.Name, out bElement))
83+
{
84+
return false;
85+
}
86+
87+
if (!Compare(aElement.Value, bElement.Value))
88+
{
89+
return false;
90+
}
91+
}
92+
93+
return true;
94+
}
95+
96+
private static bool CouldBeBoolean(BsonValue value)
97+
{
98+
switch (value.BsonType)
99+
{
100+
case BsonType.Boolean:
101+
return true;
102+
case BsonType.Double:
103+
case BsonType.Int32:
104+
case BsonType.Int64:
105+
var numericValue = value.ToDouble();
106+
return numericValue == 0.0 || numericValue == 1.0;
107+
default:
108+
return false;
109+
}
110+
}
111+
112+
private static bool IsNumber(BsonValue value)
113+
{
114+
switch (value.BsonType)
115+
{
116+
case BsonType.Double:
117+
case BsonType.Int32:
118+
case BsonType.Int64:
119+
return true;
120+
default:
121+
return false;
122+
}
123+
}
124+
}
125+
}

src/MongoDB.Bson.TestHelpers/MongoDB.Bson.TestHelpers.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
<Compile Include="BsonAssertionExtensions.cs" />
5555
<Compile Include="BsonDocumentAssertions.cs" />
5656
<Compile Include="BsonValueAssertions.cs" />
57+
<Compile Include="BsonValueEquivalencyComparer.cs" />
5758
<Compile Include="EqualityComparers\EnumerableEqualityComparer.cs" />
5859
<Compile Include="EqualityComparers\EnumerableEqualityComparerFactory.cs" />
5960
<Compile Include="EqualityComparers\EqualityComparerRegistry.cs" />
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
/* Copyright 2013-2015 MongoDB Inc.
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
using System;
17+
using System.Collections.Generic;
18+
using MongoDB.Bson;
19+
using MongoDB.Driver.Core.Events;
20+
21+
namespace MongoDB.Driver.Core
22+
{
23+
public class EventCapturer : IEventSubscriber
24+
{
25+
private readonly Queue<object> _capturedEvents;
26+
private readonly IEventSubscriber _subscriber;
27+
private readonly List<Type> _eventsToCapture;
28+
29+
public EventCapturer()
30+
{
31+
_capturedEvents = new Queue<object>();
32+
_subscriber = new ReflectionEventSubscriber(new CommandCapturer(this));
33+
_eventsToCapture = new List<Type>();
34+
}
35+
36+
public EventCapturer Capture<TEvent>()
37+
{
38+
_eventsToCapture.Add(typeof(TEvent));
39+
return this;
40+
}
41+
42+
public void Clear()
43+
{
44+
_capturedEvents.Clear();
45+
}
46+
47+
public object Next()
48+
{
49+
if (_capturedEvents.Count == 0)
50+
{
51+
throw new Exception("No captured events exist.");
52+
}
53+
54+
return _capturedEvents.Dequeue();
55+
}
56+
57+
public bool Any()
58+
{
59+
return _capturedEvents.Count > 0;
60+
}
61+
62+
public bool TryGetEventHandler<TEvent>(out Action<TEvent> handler)
63+
{
64+
if (_eventsToCapture.Count > 0 && !_eventsToCapture.Contains(typeof(TEvent)))
65+
{
66+
handler = null;
67+
return false;
68+
}
69+
70+
if (!_subscriber.TryGetEventHandler<TEvent>(out handler))
71+
{
72+
handler = e => Capture(e);
73+
}
74+
75+
return true;
76+
}
77+
78+
private void Capture(object @event)
79+
{
80+
_capturedEvents.Enqueue(@event);
81+
}
82+
83+
private class CommandCapturer
84+
{
85+
private readonly EventCapturer _parent;
86+
87+
public CommandCapturer(EventCapturer parent)
88+
{
89+
_parent = parent;
90+
}
91+
92+
public void Handle(CommandStartedEvent @event)
93+
{
94+
@event = new CommandStartedEvent(
95+
@event.CommandName,
96+
(BsonDocument)@event.Command.DeepClone(),
97+
@event.DatabaseNamespace,
98+
@event.OperationId,
99+
@event.RequestId,
100+
@event.ConnectionId);
101+
_parent.Capture(@event);
102+
}
103+
104+
public void Handle(CommandSucceededEvent @event)
105+
{
106+
@event = new CommandSucceededEvent(
107+
@event.CommandName,
108+
@event.Reply == null ? null : (BsonDocument)@event.Reply.DeepClone(),
109+
@event.OperationId,
110+
@event.RequestId,
111+
@event.ConnectionId,
112+
@event.Duration);
113+
_parent.Capture(@event);
114+
}
115+
116+
public void Handle(CommandFailedEvent @event)
117+
{
118+
_parent.Capture(@event);
119+
}
120+
}
121+
}
122+
}

src/MongoDB.Driver.Core.TestHelpers/MongoDB.Driver.Core.TestHelpers.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
<Reference Include="System.Xml" />
4343
</ItemGroup>
4444
<ItemGroup>
45+
<Compile Include="EventCapturer.cs" />
4546
<Compile Include="Properties\AssemblyInfo.cs" />
4647
<Compile Include="RequiresServerAttribute.cs" />
4748
<Compile Include="CoreTestConfiguration.cs" />

src/MongoDB.Driver.Core.Tests/Core/Authentication/MongoDBCRAuthenticatorTests.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright 2013-2014 MongoDB Inc.
1+
/* Copyright 2013-2015 MongoDB Inc.
22
*
33
* Licensed under the Apache License, Version 2.0 (the "License");
44
* you may not use this file except in compliance with the License.
@@ -66,9 +66,9 @@ public void AuthenticateAsync_should_not_throw_when_authentication_succeeds()
6666
{
6767
var subject = new MongoDBCRAuthenticator(__credential);
6868

69-
var getNonceReply = MessageHelper.BuildSuccessReply<RawBsonDocument>(
69+
var getNonceReply = MessageHelper.BuildReply<RawBsonDocument>(
7070
RawBsonDocumentHelper.FromJson("{nonce: \"2375531c32080ae8\", ok: 1}"));
71-
var authenticateReply = MessageHelper.BuildSuccessReply<RawBsonDocument>(
71+
var authenticateReply = MessageHelper.BuildReply<RawBsonDocument>(
7272
RawBsonDocumentHelper.FromJson("{ok: 1}"));
7373

7474
var connection = new MockConnection(__serverId);

src/MongoDB.Driver.Core.Tests/Core/Authentication/MongoDBX509AuthenticatorTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright 2013-2014 MongoDB Inc.
1+
/* Copyright 2013-2015 MongoDB Inc.
22
*
33
* Licensed under the Apache License, Version 2.0 (the "License");
44
* you may not use this file except in compliance with the License.
@@ -66,7 +66,7 @@ public void AuthenticateAsync_should_not_throw_when_authentication_succeeds()
6666
{
6767
var subject = new MongoDBX509Authenticator("CN=client,OU=kerneluser,O=10Gen,L=New York City,ST=New York,C=US");
6868

69-
var reply = MessageHelper.BuildSuccessReply<RawBsonDocument>(
69+
var reply = MessageHelper.BuildReply<RawBsonDocument>(
7070
RawBsonDocumentHelper.FromJson("{ok: 1}"));
7171

7272
var connection = new MockConnection(__serverId);

src/MongoDB.Driver.Core.Tests/Core/Authentication/PlainAuthenticatorTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright 2013-2014 MongoDB Inc.
1+
/* Copyright 2013-2015 MongoDB Inc.
22
*
33
* Licensed under the Apache License, Version 2.0 (the "License");
44
* you may not use this file except in compliance with the License.
@@ -66,7 +66,7 @@ public void AuthenticateAsync_should_not_throw_when_authentication_succeeds()
6666
{
6767
var subject = new PlainAuthenticator(__credential);
6868

69-
var saslStartReply = MessageHelper.BuildSuccessReply<RawBsonDocument>(
69+
var saslStartReply = MessageHelper.BuildReply<RawBsonDocument>(
7070
RawBsonDocumentHelper.FromJson("{conversationId: 0, payload: BinData(0,\"\"), done: true, ok: 1}"));
7171

7272
var connection = new MockConnection(__serverId);

src/MongoDB.Driver.Core.Tests/Core/Authentication/ScramSha1AuthenticatorTests.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright 2013-2014 MongoDB Inc.
1+
/* Copyright 2013-2015 MongoDB Inc.
22
*
33
* Licensed under the Apache License, Version 2.0 (the "License");
44
* you may not use this file except in compliance with the License.
@@ -68,7 +68,7 @@ public void AuthenticateAsync_should_throw_when_server_provides_invalid_r_value(
6868
var randomStringGenerator = new ConstantRandomStringGenerator("fyko+d2lbbFgONRv9qkxdawL");
6969
var subject = new ScramSha1Authenticator(__credential, randomStringGenerator);
7070

71-
var saslStartReply = MessageHelper.BuildSuccessReply<RawBsonDocument>(
71+
var saslStartReply = MessageHelper.BuildReply<RawBsonDocument>(
7272
RawBsonDocumentHelper.FromJson("{conversationId: 1, payload: BinData(0,\"cj1meWtvLWQybGJiRmdPTlJ2OXFreGRhd0xIbytWZ2s3cXZVT0tVd3VXTElXZzRsLzlTcmFHTUhFRSxzPXJROVpZM01udEJldVAzRTFURFZDNHc9PSxpPTEwMDAw\"), done: false, ok: 1}"));
7373

7474
var connection = new MockConnection(__serverId);
@@ -85,9 +85,9 @@ public void AuthenticateAsync_should_throw_when_server_provides_invalid_serverSi
8585
var randomStringGenerator = new ConstantRandomStringGenerator("fyko+d2lbbFgONRv9qkxdawL");
8686
var subject = new ScramSha1Authenticator(__credential, randomStringGenerator);
8787

88-
var saslStartReply = MessageHelper.BuildSuccessReply<RawBsonDocument>(
88+
var saslStartReply = MessageHelper.BuildReply<RawBsonDocument>(
8989
RawBsonDocumentHelper.FromJson("{conversationId: 1, payload: BinData(0,\"cj1meWtvK2QybGJiRmdPTlJ2OXFreGRhd0xIbytWZ2s3cXZVT0tVd3VXTElXZzRsLzlTcmFHTUhFRSxzPXJROVpZM01udEJldVAzRTFURFZDNHc9PSxpPTEwMDAw\"), done: false, ok: 1}"));
90-
var saslContinueReply = MessageHelper.BuildSuccessReply<RawBsonDocument>(
90+
var saslContinueReply = MessageHelper.BuildReply<RawBsonDocument>(
9191
RawBsonDocumentHelper.FromJson("{conversationId: 1, payload: BinData(0,\"dj1VTVdlSTI1SkQxeU5ZWlJNcFo0Vkh2aFo5ZTBh\"), done: true, ok: 1}"));
9292

9393
var connection = new MockConnection(__serverId);
@@ -105,9 +105,9 @@ public void AuthenticateAsync_should_not_throw_when_authentication_succeeds()
105105
var randomStringGenerator = new ConstantRandomStringGenerator("fyko+d2lbbFgONRv9qkxdawL");
106106
var subject = new ScramSha1Authenticator(__credential, randomStringGenerator);
107107

108-
var saslStartReply = MessageHelper.BuildSuccessReply<RawBsonDocument>(
108+
var saslStartReply = MessageHelper.BuildReply<RawBsonDocument>(
109109
RawBsonDocumentHelper.FromJson("{conversationId: 1, payload: BinData(0,\"cj1meWtvK2QybGJiRmdPTlJ2OXFreGRhd0xIbytWZ2s3cXZVT0tVd3VXTElXZzRsLzlTcmFHTUhFRSxzPXJROVpZM01udEJldVAzRTFURFZDNHc9PSxpPTEwMDAw\"), done: false, ok: 1}"));
110-
var saslContinueReply = MessageHelper.BuildSuccessReply<RawBsonDocument>(
110+
var saslContinueReply = MessageHelper.BuildReply<RawBsonDocument>(
111111
RawBsonDocumentHelper.FromJson("{conversationId: 1, payload: BinData(0,\"dj1VTVdlSTI1SkQxeU5ZWlJNcFo0Vkh2aFo5ZTA9\"), done: true, ok: 1}"));
112112

113113
var connection = new MockConnection(__serverId);

0 commit comments

Comments
 (0)