Skip to content
This repository was archived by the owner on Sep 3, 2022. It is now read-only.

Commit aafe269

Browse files
committed
config toString bug and validating balanced strategy
1 parent 7a6c4f0 commit aafe269

File tree

7 files changed

+286
-18
lines changed

7 files changed

+286
-18
lines changed

CqlSharp/Config/ClusterConfig.cs

+7-14
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,14 @@ public class ClusterConfig
2929
private const DiscoveryScope DefaultDiscoveryScope = DiscoveryScope.None;
3030
private const ConnectionStrategy DefaultConnectionStrategy = ConnectionStrategy.Balanced;
3131
private const string DefaultCqlVersion = "3.0.0";
32-
private const int DefaultMaxDownTime = 60*60*1000; //max down for 1 hour
32+
private const int DefaultMaxDownTime = 60 * 60 * 1000; //max down for 1 hour
3333
private const int DefaultMinDownTime = 500; //min down time for .5 second
3434
private const int DefaultMaxConnectionsPerNode = 2;
3535
private const int DefaultMaxConnections = -1; //no total max
3636
private const int DefaultNewConnectionTreshold = 10; //new connection when 10 parallel queries on one connection
3737
private const int DefaultMaxConcurrentQueries = -1;
38-
private static readonly char[] PartSeperator = new[] {';'};
39-
private static readonly char[] ValueSeperator = new[] {'='};
38+
private static readonly char[] PartSeperator = new[] { ';' };
39+
private static readonly char[] ValueSeperator = new[] { '=' };
4040
private static readonly TimeSpan DefaultMaxConnectionIdleTime = TimeSpan.FromSeconds(10);
4141

4242
/// <summary>
@@ -178,8 +178,8 @@ private void Parse(string connectionstring)
178178
throw new CqlException(
179179
"Configuration error: Could not split the configuration element in a key and value: " + part);
180180

181-
string key = kv[0].Trim().Trim(new[] {'\'', '"'}).ToLower();
182-
string value = kv[1].Trim().Trim(new[] {'\'', '"'});
181+
string key = kv[0].Trim().Trim(new[] { '\'', '"' }).ToLower();
182+
string value = kv[1].Trim().Trim(new[] { '\'', '"' });
183183

184184
switch (key)
185185
{
@@ -194,11 +194,11 @@ private void Parse(string connectionstring)
194194
break;
195195
case "discovery scope":
196196
case "discoveryscope":
197-
DiscoveryScope = (DiscoveryScope) Enum.Parse(typeof (DiscoveryScope), value, true);
197+
DiscoveryScope = (DiscoveryScope)Enum.Parse(typeof(DiscoveryScope), value, true);
198198
break;
199199
case "connection strategy":
200200
case "connectionstrategy":
201-
ConnectionStrategy = (ConnectionStrategy) Enum.Parse(typeof (ConnectionStrategy), value, true);
201+
ConnectionStrategy = (ConnectionStrategy)Enum.Parse(typeof(ConnectionStrategy), value, true);
202202
break;
203203
case "cql":
204204
case "version":
@@ -353,13 +353,6 @@ public override string ToString()
353353
builder.Append(";");
354354
}
355355

356-
if (!NewConnectionTreshold.Equals(DefaultNewConnectionTreshold))
357-
{
358-
builder.Append("NewConnectionTreshold=");
359-
builder.Append(NewConnectionTreshold);
360-
builder.Append(";");
361-
}
362-
363356
if (MaxConcurrentQueries > 0)
364357
{
365358
builder.Append("MaxConcurrentQueries=");

CqlSharp/Network/Node.cs

+1
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ public Node(IPAddress address, ClusterConfig config)
8989
Address = address;
9090
_config = config;
9191
IsUp = true;
92+
Tokens = new HashSet<string>();
9293
}
9394

9495
/// <summary>

CqlSharp/Properties/AssemblyInfo.cs

+1-4
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,5 @@
5454
[assembly: AssemblyVersion("0.10.0.0")]
5555
[assembly: AssemblyFileVersion("0.10.0.0")]
5656

57-
#if DEBUG
58-
57+
[assembly: InternalsVisibleTo("CqlSharp.Fakes")]
5958
[assembly: InternalsVisibleTo("CqlSharpTest")]
60-
61-
#endif
+268
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
using CqlSharp.Config;
2+
using CqlSharp.Network;
3+
using CqlSharp.Network.Fakes;
4+
using CqlSharp.Network.Partition;
5+
using CqlSharp.Protocol;
6+
using CqlSharp.Protocol.Frames;
7+
using Microsoft.QualityTools.Testing.Fakes;
8+
using Microsoft.VisualStudio.TestTools.UnitTesting;
9+
using System;
10+
using System.Collections.Generic;
11+
using System.Linq;
12+
using System.Net;
13+
using System.Threading.Tasks;
14+
15+
namespace CqlSharpTest
16+
{
17+
[TestClass]
18+
public class ConnectionStrategyTest
19+
{
20+
[TestMethod]
21+
public async Task BalancedStrategyLowTreshold()
22+
{
23+
using (ShimsContext.Create())
24+
{
25+
//create config
26+
var config = new ClusterConfig();
27+
config.NewConnectionTreshold = 5;
28+
29+
//create nodes
30+
Node n = new Node(IPAddress.Parse("127.0.0.1"), config);
31+
Node n2 = new Node(IPAddress.Parse("127.0.0.2"), config);
32+
Node n3 = new Node(IPAddress.Parse("127.0.0.3"), config);
33+
Node n4 = new Node(IPAddress.Parse("127.0.0.4"), config);
34+
var nodes = new Ring(new List<Node>() { n, n2, n3, n4 }, "RandomPartitioner");
35+
36+
ShimAllConnections();
37+
38+
IConnectionStrategy strategy = new BalancedConnectionStrategy(nodes, config);
39+
40+
int nr = 8;
41+
42+
for (int i = 0; i < nr; i++)
43+
{
44+
var connection = await strategy.GetOrCreateConnectionAsync(PartitionKey.None);
45+
await connection.SendRequestAsync(new QueryFrame("", CqlSharp.CqlConsistency.Any), 10);
46+
47+
}
48+
49+
Assert.AreEqual(nodes.Sum(nd => nd.ConnectionCount), nr);
50+
Assert.IsTrue(nodes.All(nd => nd.ConnectionCount == nr / 4));
51+
52+
}
53+
}
54+
55+
[TestMethod]
56+
public async Task BalancedStrategyTestMedTreshold()
57+
{
58+
using (ShimsContext.Create())
59+
{
60+
//create config
61+
var config = new ClusterConfig();
62+
config.NewConnectionTreshold = 20;
63+
64+
//create nodes
65+
Node n = new Node(IPAddress.Parse("127.0.0.1"), config);
66+
Node n2 = new Node(IPAddress.Parse("127.0.0.2"), config);
67+
Node n3 = new Node(IPAddress.Parse("127.0.0.3"), config);
68+
Node n4 = new Node(IPAddress.Parse("127.0.0.4"), config);
69+
var nodes = new Ring(new List<Node>() { n, n2, n3, n4 }, "RandomPartitioner");
70+
71+
ShimAllConnections();
72+
73+
74+
IConnectionStrategy strategy = new BalancedConnectionStrategy(nodes, config);
75+
76+
int nr = 8;
77+
78+
for (int i = 0; i < nr; i++)
79+
{
80+
var connection = await strategy.GetOrCreateConnectionAsync(PartitionKey.None);
81+
await connection.SendRequestAsync(new QueryFrame("", CqlSharp.CqlConsistency.Any), 10);
82+
}
83+
84+
Assert.AreEqual(4, nodes.Sum(nd => nd.ConnectionCount));
85+
Assert.IsTrue(nodes.SelectMany(nd => nd).All(c => c.Load == 20));
86+
87+
}
88+
}
89+
90+
[TestMethod]
91+
public async Task BalancedStrategyTestHighTreshold()
92+
{
93+
using (ShimsContext.Create())
94+
{
95+
//create config
96+
var config = new ClusterConfig();
97+
config.NewConnectionTreshold = 200;
98+
99+
//create nodes
100+
Node n = new Node(IPAddress.Parse("127.0.0.1"), config);
101+
Node n2 = new Node(IPAddress.Parse("127.0.0.2"), config);
102+
Node n3 = new Node(IPAddress.Parse("127.0.0.3"), config);
103+
Node n4 = new Node(IPAddress.Parse("127.0.0.4"), config);
104+
var nodes = new Ring(new List<Node>() { n, n2, n3, n4 }, "RandomPartitioner");
105+
106+
ShimAllConnections();
107+
108+
109+
IConnectionStrategy strategy = new BalancedConnectionStrategy(nodes, config);
110+
111+
int nr = 8;
112+
113+
for (int i = 0; i < nr; i++)
114+
{
115+
var connection = await strategy.GetOrCreateConnectionAsync(PartitionKey.None);
116+
await connection.SendRequestAsync(new QueryFrame("", CqlSharp.CqlConsistency.Any), 10);
117+
}
118+
119+
Assert.AreEqual(1, nodes.Sum(nd => nd.ConnectionCount));
120+
//Assert.IsTrue(nodes.SelectMany(nd => nd).All(c => c.Load == 20));
121+
122+
}
123+
}
124+
125+
[TestMethod]
126+
public async Task BalancedStrategyTestMaxConnections()
127+
{
128+
using (ShimsContext.Create())
129+
{
130+
//create config
131+
var config = new ClusterConfig();
132+
config.NewConnectionTreshold = 5;
133+
config.MaxConnections = 6;
134+
135+
//create nodes
136+
Node n = new Node(IPAddress.Parse("127.0.0.1"), config);
137+
Node n2 = new Node(IPAddress.Parse("127.0.0.2"), config);
138+
Node n3 = new Node(IPAddress.Parse("127.0.0.3"), config);
139+
Node n4 = new Node(IPAddress.Parse("127.0.0.4"), config);
140+
var nodes = new Ring(new List<Node>() { n, n2, n3, n4 }, "RandomPartitioner");
141+
142+
ShimAllConnections();
143+
144+
IConnectionStrategy strategy = new BalancedConnectionStrategy(nodes, config);
145+
146+
int nr = 8;
147+
148+
for (int i = 0; i < nr; i++)
149+
{
150+
var connection = await strategy.GetOrCreateConnectionAsync(PartitionKey.None);
151+
await connection.SendRequestAsync(new QueryFrame("", CqlSharp.CqlConsistency.Any), 10);
152+
}
153+
154+
Assert.AreEqual(nodes.Sum(nd => nd.ConnectionCount), 6);
155+
Assert.IsTrue(nodes.All(nd => nd.ConnectionCount == 1 || nd.ConnectionCount == 2));
156+
157+
}
158+
}
159+
160+
161+
162+
[TestMethod]
163+
public async Task BalancedStrategyFewRequests()
164+
{
165+
using (ShimsContext.Create())
166+
{
167+
//create config
168+
var config = new ClusterConfig();
169+
config.NewConnectionTreshold = 20;
170+
171+
//create nodes
172+
Node n = new Node(IPAddress.Parse("127.0.0.1"), config);
173+
Node n2 = new Node(IPAddress.Parse("127.0.0.2"), config);
174+
Node n3 = new Node(IPAddress.Parse("127.0.0.3"), config);
175+
Node n4 = new Node(IPAddress.Parse("127.0.0.4"), config);
176+
var nodes = new Ring(new List<Node>() { n, n2, n3, n4 }, "RandomPartitioner");
177+
178+
ShimAllConnections();
179+
180+
IConnectionStrategy strategy = new BalancedConnectionStrategy(nodes, config);
181+
182+
int nr = 8;
183+
184+
for (int i = 0; i < nr; i++)
185+
{
186+
Connection c = await strategy.GetOrCreateConnectionAsync(PartitionKey.None);
187+
await c.SendRequestAsync(new QueryFrame("select null", CqlSharp.CqlConsistency.Any), 10);
188+
}
189+
190+
Assert.AreEqual(nodes.Sum(nd => nd.ConnectionCount), 4);
191+
Assert.IsTrue(nodes.All(nd => nd.ConnectionCount == 1));
192+
Assert.IsTrue(nodes.SelectMany(nd => nd).All(c => c.Load == 20));
193+
194+
}
195+
}
196+
197+
[TestMethod]
198+
public async Task BalancedStrategyManyRequests()
199+
{
200+
using (ShimsContext.Create())
201+
{
202+
//create config
203+
var config = new ClusterConfig();
204+
config.NewConnectionTreshold = 20;
205+
206+
//create nodes
207+
Node n = new Node(IPAddress.Parse("127.0.0.1"), config);
208+
Node n2 = new Node(IPAddress.Parse("127.0.0.2"), config);
209+
Node n3 = new Node(IPAddress.Parse("127.0.0.3"), config);
210+
Node n4 = new Node(IPAddress.Parse("127.0.0.4"), config);
211+
var nodes = new Ring(new List<Node>() { n, n2, n3, n4 }, "RandomPartitioner");
212+
213+
ShimAllConnections();
214+
215+
216+
IConnectionStrategy strategy = new BalancedConnectionStrategy(nodes, config);
217+
218+
int nr = 80;
219+
220+
for (int i = 0; i < nr; i++)
221+
{
222+
Connection c = await strategy.GetOrCreateConnectionAsync(PartitionKey.None);
223+
await c.SendRequestAsync(new QueryFrame("select null", CqlSharp.CqlConsistency.Any), 10);
224+
}
225+
226+
Assert.AreEqual(nodes.Sum(nd => nd.ConnectionCount), 8);
227+
Assert.IsTrue(nodes.All(nd => nd.ConnectionCount == 2));
228+
Assert.IsTrue(nodes.SelectMany(nd => nd).All(c => c.Load == (80 * 10) / 4 / 2));
229+
230+
}
231+
}
232+
233+
private static void ShimAllConnections()
234+
{
235+
//shim connections to avoid network connections...
236+
ShimConnection.ConstructorIPAddressClusterConfig = (conn, address, conf) =>
237+
{
238+
//wrap the new connection in a shim
239+
var connection = new ShimConnection(conn);
240+
int connLoad = 0;
241+
EventHandler<LoadChangeEvent> nodeHandler = null;
242+
243+
//replace any IO inducing methods
244+
connection.ConnectAsync = () => { return Task.FromResult(true); };
245+
connection.SendRequestAsyncFrameInt32 = (frame, load) =>
246+
{
247+
//update connection load
248+
connLoad += load;
249+
//call load change event handler
250+
nodeHandler(connection, new LoadChangeEvent() { LoadDelta = load });
251+
//done
252+
return Task.FromResult((Frame)new ResultFrame() { Stream = frame.Stream });
253+
};
254+
255+
//intercept load changed handlers
256+
connection.OnLoadChangeAddEventHandlerOfLoadChangeEvent = (handler) => { nodeHandler += handler; };
257+
258+
//return proper load values
259+
connection.LoadGet = () => connLoad;
260+
261+
//set some default properties
262+
connection.IsConnectedGet = () => true;
263+
connection.IsIdleGet = () => false;
264+
265+
};
266+
}
267+
}
268+
}

CqlSharpTest/CqlSharpTest.csproj

+8
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@
3939
<WarningLevel>4</WarningLevel>
4040
</PropertyGroup>
4141
<ItemGroup>
42+
<Reference Include="CqlSharp.Fakes">
43+
<HintPath>FakesAssemblies\CqlSharp.Fakes.dll</HintPath>
44+
</Reference>
45+
<Reference Include="Microsoft.QualityTools.Testing.Fakes, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
4246
<Reference Include="System" />
4347
<Reference Include="System.Numerics" />
4448
</ItemGroup>
@@ -55,6 +59,7 @@
5559
</Otherwise>
5660
</Choose>
5761
<ItemGroup>
62+
<Compile Include="ConnectionStrategyTest.cs" />
5863
<Compile Include="QueryTests.cs" />
5964
<Compile Include="Properties\AssemblyInfo.cs" />
6065
<Compile Include="SerializationTest.cs" />
@@ -65,6 +70,9 @@
6570
<Name>CqlSharp</Name>
6671
</ProjectReference>
6772
</ItemGroup>
73+
<ItemGroup>
74+
<Fakes Include="Fakes\CqlSharp.fakes" />
75+
</ItemGroup>
6876
<Choose>
6977
<When Condition="'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'">
7078
<ItemGroup>

CqlSharpTest/Fakes/CqlSharp.fakes

232 Bytes
Binary file not shown.

CqlSharpTest/non-Cassandra.playlist

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<Playlist Version="1.0"><Add Test="CqlSharpTest.ConnectionStrategyTest.BalancedStrategyTestHighTreshold" /><Add Test="CqlSharpTest.ConnectionStrategyTest.BalancedStrategyFewRequests" /><Add Test="CqlSharpTest.ConnectionStrategyTest.BalancedStrategyLowTreshold" /><Add Test="CqlSharpTest.ConnectionStrategyTest.BalancedStrategyTestMaxConnections" /><Add Test="CqlSharpTest.ConnectionStrategyTest.BalancedStrategyManyRequests" /><Add Test="CqlSharpTest.ConnectionStrategyTest.BalancedStrategyTestMedTreshold" /></Playlist>

0 commit comments

Comments
 (0)