Commit 5f53d028 authored by Jeremy Meng's avatar Jeremy Meng

Fix whitespace issues for better viewing on github PR.

parent 1b6d7a36
...@@ -234,7 +234,9 @@ public void MassiveBulkOpsAsync(bool preserveOrder, bool withContinuation) ...@@ -234,7 +234,9 @@ public void MassiveBulkOpsAsync(bool preserveOrder, bool withContinuation)
var conn = muxer.GetDatabase(); var conn = muxer.GetDatabase();
muxer.Wait(conn.PingAsync()); muxer.Wait(conn.PingAsync());
#if DNXCORE50
int number = 0; int number = 0;
#endif
Action<Task> nonTrivial = delegate Action<Task> nonTrivial = delegate
{ {
#if !DNXCORE50 #if !DNXCORE50
...@@ -485,17 +487,14 @@ public void MassiveBulkOpsSyncOldStyle(ResultCompletionMode completionMode, int ...@@ -485,17 +487,14 @@ public void MassiveBulkOpsSyncOldStyle(ResultCompletionMode completionMode, int
} }
#endif #endif
//TODO: Ignore("dnxcore crash")
#if !DNXCORE50
[Test] [Test]
[TestCase(true, 1)] [TestCase(true, 1)]
[TestCase(false, 1)] [TestCase(false, 1)]
[TestCase(true, 5)] [TestCase(true, 5)]
[TestCase(false, 5)] [TestCase(false, 5)]
#endif
public void MassiveBulkOpsFireAndForget(bool preserveOrder, int threads) public void MassiveBulkOpsFireAndForget(bool preserveOrder, int threads)
{ {
using (var muxer = Create(syncTimeout:20000)) using (var muxer = Create())
{ {
muxer.PreserveAsyncOrder = preserveOrder; muxer.PreserveAsyncOrder = preserveOrder;
#if DEBUG #if DEBUG
......
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using NUnit.Framework; using NUnit.Framework;
namespace StackExchange.Redis.Tests namespace StackExchange.Redis.Tests
{ {
[TestFixture] [TestFixture]
public class Cluster : TestBase public class Cluster : TestBase
{ {
//private const string ClusterIp = "192.168.0.15"; // marc //private const string ClusterIp = "192.168.0.15"; // marc
private const string ClusterIp = "10.110.11.102"; // kmontrose private const string ClusterIp = "10.110.11.102"; // kmontrose
private const int ServerCount = 6, FirstPort = 7000; private const int ServerCount = 6, FirstPort = 7000;
protected override string GetConfiguration() protected override string GetConfiguration()
{ {
var server = ClusterIp; var server = ClusterIp;
#if !DNXCORE50 #if !DNXCORE50
if (string.Equals(Environment.MachineName, "MARC-LAPTOP", StringComparison.InvariantCultureIgnoreCase)) if (string.Equals(Environment.MachineName, "MARC-LAPTOP", StringComparison.InvariantCultureIgnoreCase))
#else #else
if (string.Equals(Environment.GetEnvironmentVariable("COMPUTERNAME"), "MARC-LAPTOP", StringComparison.OrdinalIgnoreCase)) if (string.Equals(Environment.GetEnvironmentVariable("COMPUTERNAME"), "MARC-LAPTOP", StringComparison.OrdinalIgnoreCase))
#endif #endif
{ {
server = "192.168.56.101"; server = "192.168.56.101";
} }
return string.Join(",", return string.Join(",",
from port in Enumerable.Range(FirstPort, ServerCount) from port in Enumerable.Range(FirstPort, ServerCount)
select server + ":" + port) + ",connectTimeout=10000"; select server + ":" + port) + ",connectTimeout=10000";
} }
[Test] [Test]
public void ExportConfiguration() public void ExportConfiguration()
{ {
if (File.Exists("cluster.zip")) File.Delete("cluster.zip"); if (File.Exists("cluster.zip")) File.Delete("cluster.zip");
Assert.IsFalse(File.Exists("cluster.zip")); Assert.IsFalse(File.Exists("cluster.zip"));
using (var muxer = Create(allowAdmin: true)) using (var muxer = Create(allowAdmin: true))
using(var file = File.Create("cluster.zip")) using(var file = File.Create("cluster.zip"))
{ {
muxer.ExportConfiguration(file); muxer.ExportConfiguration(file);
} }
Assert.IsTrue(File.Exists("cluster.zip")); Assert.IsTrue(File.Exists("cluster.zip"));
} }
[Test] [Test]
public void ConnectUsesSingleSocket() public void ConnectUsesSingleSocket()
{ {
for(int i = 0; i<10;i++) for(int i = 0; i<10;i++)
{ {
using (var muxer = Create(failMessage: i + ": ")) using (var muxer = Create(failMessage: i + ": "))
{ {
var eps = muxer.GetEndPoints(); var eps = muxer.GetEndPoints();
foreach (var ep in eps) foreach (var ep in eps)
{ {
var srv = muxer.GetServer(ep); var srv = muxer.GetServer(ep);
var counters = srv.GetCounters(); var counters = srv.GetCounters();
Assert.AreEqual(1, counters.Interactive.SocketCount, i + "; interactive, " + ep.ToString()); Assert.AreEqual(1, counters.Interactive.SocketCount, i + "; interactive, " + ep.ToString());
Assert.AreEqual(1, counters.Subscription.SocketCount, i + "; subscription, " + ep.ToString()); Assert.AreEqual(1, counters.Subscription.SocketCount, i + "; subscription, " + ep.ToString());
} }
} }
} }
} }
[Test] [Test]
public void CanGetTotalStats() public void CanGetTotalStats()
{ {
using(var muxer = Create()) using(var muxer = Create())
{ {
var counters = muxer.GetCounters(); var counters = muxer.GetCounters();
Console.WriteLine(counters); Console.WriteLine(counters);
} }
} }
[Test] [Test]
public void Connect() public void Connect()
{ {
using (var muxer = Create()) using (var muxer = Create())
{ {
var endpoints = muxer.GetEndPoints(); var endpoints = muxer.GetEndPoints();
Assert.AreEqual(ServerCount, endpoints.Length); Assert.AreEqual(ServerCount, endpoints.Length);
var expectedPorts = new HashSet<int>(Enumerable.Range(FirstPort, ServerCount)); var expectedPorts = new HashSet<int>(Enumerable.Range(FirstPort, ServerCount));
int masters = 0, slaves = 0; int masters = 0, slaves = 0;
var failed = new List<EndPoint>(); var failed = new List<EndPoint>();
foreach (var endpoint in endpoints) foreach (var endpoint in endpoints)
{ {
var server = muxer.GetServer(endpoint); var server = muxer.GetServer(endpoint);
if (!server.IsConnected) if (!server.IsConnected)
{ {
failed.Add(endpoint); failed.Add(endpoint);
} }
Assert.AreEqual(endpoint, server.EndPoint, "endpoint:" + endpoint); Assert.AreEqual(endpoint, server.EndPoint, "endpoint:" + endpoint);
Assert.IsInstanceOf<IPEndPoint>(endpoint, "endpoint-type:" + endpoint); Assert.IsInstanceOf<IPEndPoint>(endpoint, "endpoint-type:" + endpoint);
Assert.IsTrue(expectedPorts.Remove(((IPEndPoint)endpoint).Port), "port:" + endpoint); Assert.IsTrue(expectedPorts.Remove(((IPEndPoint)endpoint).Port), "port:" + endpoint);
Assert.AreEqual(ServerType.Cluster, server.ServerType, "server-type:" + endpoint); Assert.AreEqual(ServerType.Cluster, server.ServerType, "server-type:" + endpoint);
if (server.IsSlave) slaves++; if (server.IsSlave) slaves++;
else masters++; else masters++;
} }
if (failed.Count != 0) if (failed.Count != 0)
{ {
Console.WriteLine("{0} failues", failed.Count); Console.WriteLine("{0} failues", failed.Count);
foreach (var fail in failed) foreach (var fail in failed)
{ {
Console.WriteLine(fail); Console.WriteLine(fail);
} }
Assert.Fail("not all servers connected"); Assert.Fail("not all servers connected");
} }
Assert.AreEqual(ServerCount / 2, slaves, "slaves"); Assert.AreEqual(ServerCount / 2, slaves, "slaves");
Assert.AreEqual(ServerCount / 2, masters, "masters"); Assert.AreEqual(ServerCount / 2, masters, "masters");
} }
} }
[Test] [Test]
public void TestIdentity() public void TestIdentity()
{ {
using(var conn = Create()) using(var conn = Create())
{ {
RedisKey key = Guid.NewGuid().ToByteArray(); RedisKey key = Guid.NewGuid().ToByteArray();
var ep = conn.GetDatabase().IdentifyEndpoint(key); var ep = conn.GetDatabase().IdentifyEndpoint(key);
Assert.AreEqual(ep, conn.GetServer(ep).ClusterConfiguration.GetBySlot(key).EndPoint); Assert.AreEqual(ep, conn.GetServer(ep).ClusterConfiguration.GetBySlot(key).EndPoint);
} }
} }
[Test] [Test]
public void IntentionalWrongServer() public void IntentionalWrongServer()
{ {
using (var conn = Create()) using (var conn = Create())
{ {
var endpoints = conn.GetEndPoints(); var endpoints = conn.GetEndPoints();
var servers = endpoints.Select(e => conn.GetServer(e)); var servers = endpoints.Select(e => conn.GetServer(e));
var key = Me(); var key = Me();
const string value = "abc"; const string value = "abc";
var db = conn.GetDatabase(); var db = conn.GetDatabase();
db.KeyDelete(key); db.KeyDelete(key);
db.StringSet(key, value); db.StringSet(key, value);
servers.First().Ping(); servers.First().Ping();
var config = servers.First().ClusterConfiguration; var config = servers.First().ClusterConfiguration;
Assert.IsNotNull(config); Assert.IsNotNull(config);
int slot = conn.HashSlot(key); int slot = conn.HashSlot(key);
var rightMasterNode = config.GetBySlot(key); var rightMasterNode = config.GetBySlot(key);
Assert.IsNotNull(rightMasterNode); Assert.IsNotNull(rightMasterNode);
#if DEBUG #if DEBUG
string a = conn.GetServer(rightMasterNode.EndPoint).StringGet(db.Database, key); string a = conn.GetServer(rightMasterNode.EndPoint).StringGet(db.Database, key);
Assert.AreEqual(value, a, "right master"); Assert.AreEqual(value, a, "right master");
var node = config.Nodes.FirstOrDefault(x => !x.IsSlave && x.NodeId != rightMasterNode.NodeId); var node = config.Nodes.FirstOrDefault(x => !x.IsSlave && x.NodeId != rightMasterNode.NodeId);
Assert.IsNotNull(node); Assert.IsNotNull(node);
if (node != null) if (node != null)
{ {
string b = conn.GetServer(node.EndPoint).StringGet(db.Database, key); string b = conn.GetServer(node.EndPoint).StringGet(db.Database, key);
Assert.AreEqual(value, b, "wrong master, allow redirect"); Assert.AreEqual(value, b, "wrong master, allow redirect");
try try
{ {
string c = conn.GetServer(node.EndPoint).StringGet(db.Database, key, CommandFlags.NoRedirect); string c = conn.GetServer(node.EndPoint).StringGet(db.Database, key, CommandFlags.NoRedirect);
Assert.Fail("wrong master, no redirect"); Assert.Fail("wrong master, no redirect");
} catch (RedisServerException ex) } catch (RedisServerException ex)
{ {
Assert.AreEqual("MOVED " + slot + " " + rightMasterNode.EndPoint.ToString(), ex.Message, "wrong master, no redirect"); Assert.AreEqual("MOVED " + slot + " " + rightMasterNode.EndPoint.ToString(), ex.Message, "wrong master, no redirect");
} }
} }
node = config.Nodes.FirstOrDefault(x => x.IsSlave && x.ParentNodeId == rightMasterNode.NodeId); node = config.Nodes.FirstOrDefault(x => x.IsSlave && x.ParentNodeId == rightMasterNode.NodeId);
Assert.IsNotNull(node); Assert.IsNotNull(node);
if (node != null) if (node != null)
{ {
string d = conn.GetServer(node.EndPoint).StringGet(db.Database, key); string d = conn.GetServer(node.EndPoint).StringGet(db.Database, key);
Assert.AreEqual(value, d, "right slave"); Assert.AreEqual(value, d, "right slave");
} }
node = config.Nodes.FirstOrDefault(x => x.IsSlave && x.ParentNodeId != rightMasterNode.NodeId); node = config.Nodes.FirstOrDefault(x => x.IsSlave && x.ParentNodeId != rightMasterNode.NodeId);
Assert.IsNotNull(node); Assert.IsNotNull(node);
if (node != null) if (node != null)
{ {
string e = conn.GetServer(node.EndPoint).StringGet(db.Database, key); string e = conn.GetServer(node.EndPoint).StringGet(db.Database, key);
Assert.AreEqual(value, e, "wrong slave, allow redirect"); Assert.AreEqual(value, e, "wrong slave, allow redirect");
try try
{ {
string f = conn.GetServer(node.EndPoint).StringGet(db.Database, key, CommandFlags.NoRedirect); string f = conn.GetServer(node.EndPoint).StringGet(db.Database, key, CommandFlags.NoRedirect);
Assert.Fail("wrong slave, no redirect"); Assert.Fail("wrong slave, no redirect");
} }
catch (RedisServerException ex) catch (RedisServerException ex)
{ {
Assert.AreEqual("MOVED " + slot + " " + rightMasterNode.EndPoint.ToString(), ex.Message, "wrong slave, no redirect"); Assert.AreEqual("MOVED " + slot + " " + rightMasterNode.EndPoint.ToString(), ex.Message, "wrong slave, no redirect");
} }
} }
#endif #endif
} }
} }
[Test] [Test]
public void TransactionWithMultiServerKeys() public void TransactionWithMultiServerKeys()
{ {
Assert.Throws<RedisCommandException>(() => Assert.Throws<RedisCommandException>(() =>
{ {
using (var muxer = Create()) using (var muxer = Create())
{ {
// connect // connect
var cluster = muxer.GetDatabase(); var cluster = muxer.GetDatabase();
var anyServer = muxer.GetServer(muxer.GetEndPoints()[0]); var anyServer = muxer.GetServer(muxer.GetEndPoints()[0]);
anyServer.Ping(); anyServer.Ping();
Assert.AreEqual(ServerType.Cluster, anyServer.ServerType); Assert.AreEqual(ServerType.Cluster, anyServer.ServerType);
var config = anyServer.ClusterConfiguration; var config = anyServer.ClusterConfiguration;
Assert.IsNotNull(config); Assert.IsNotNull(config);
// invent 2 keys that we believe are served by different nodes // invent 2 keys that we believe are served by different nodes
string x = Guid.NewGuid().ToString(), y; string x = Guid.NewGuid().ToString(), y;
var xNode = config.GetBySlot(x); var xNode = config.GetBySlot(x);
int abort = 1000; int abort = 1000;
do do
{ {
y = Guid.NewGuid().ToString(); y = Guid.NewGuid().ToString();
} while (--abort > 0 && config.GetBySlot(y) == xNode); } while (--abort > 0 && config.GetBySlot(y) == xNode);
if (abort == 0) Assert.Inconclusive("failed to find a different node to use"); if (abort == 0) Assert.Inconclusive("failed to find a different node to use");
var yNode = config.GetBySlot(y); var yNode = config.GetBySlot(y);
Console.WriteLine("x={0}, served by {1}", x, xNode.NodeId); Console.WriteLine("x={0}, served by {1}", x, xNode.NodeId);
Console.WriteLine("y={0}, served by {1}", y, yNode.NodeId); Console.WriteLine("y={0}, served by {1}", y, yNode.NodeId);
Assert.AreNotEqual(xNode.NodeId, yNode.NodeId, "same node"); Assert.AreNotEqual(xNode.NodeId, yNode.NodeId, "same node");
// wipe those keys // wipe those keys
cluster.KeyDelete(x, CommandFlags.FireAndForget); cluster.KeyDelete(x, CommandFlags.FireAndForget);
cluster.KeyDelete(y, CommandFlags.FireAndForget); cluster.KeyDelete(y, CommandFlags.FireAndForget);
// create a transaction that attempts to assign both keys // create a transaction that attempts to assign both keys
var tran = cluster.CreateTransaction(); var tran = cluster.CreateTransaction();
tran.AddCondition(Condition.KeyNotExists(x)); tran.AddCondition(Condition.KeyNotExists(x));
tran.AddCondition(Condition.KeyNotExists(y)); tran.AddCondition(Condition.KeyNotExists(y));
var setX = tran.StringSetAsync(x, "x-val"); var setX = tran.StringSetAsync(x, "x-val");
var setY = tran.StringSetAsync(y, "y-val"); var setY = tran.StringSetAsync(y, "y-val");
bool success = tran.Execute(); bool success = tran.Execute();
Assert.Fail("Expected single-slot rules to apply"); Assert.Fail("Expected single-slot rules to apply");
// the rest no longer applies while we are following single-slot rules // the rest no longer applies while we are following single-slot rules
//// check that everything was aborted //// check that everything was aborted
//Assert.IsFalse(success, "tran aborted"); //Assert.IsFalse(success, "tran aborted");
//Assert.IsTrue(setX.IsCanceled, "set x cancelled"); //Assert.IsTrue(setX.IsCanceled, "set x cancelled");
//Assert.IsTrue(setY.IsCanceled, "set y cancelled"); //Assert.IsTrue(setY.IsCanceled, "set y cancelled");
//var existsX = cluster.KeyExistsAsync(x); //var existsX = cluster.KeyExistsAsync(x);
//var existsY = cluster.KeyExistsAsync(y); //var existsY = cluster.KeyExistsAsync(y);
//Assert.IsFalse(cluster.Wait(existsX), "x exists"); //Assert.IsFalse(cluster.Wait(existsX), "x exists");
//Assert.IsFalse(cluster.Wait(existsY), "y exists"); //Assert.IsFalse(cluster.Wait(existsY), "y exists");
} }
}, },
"Multi-key operations must involve a single slot; keys can use 'hash tags' to help this, i.e. '{/users/12345}/account' and '{/users/12345}/contacts' will always be in the same slot"); "Multi-key operations must involve a single slot; keys can use 'hash tags' to help this, i.e. '{/users/12345}/account' and '{/users/12345}/contacts' will always be in the same slot");
} }
[Test] [Test]
public void TransactionWithSameServerKeys() public void TransactionWithSameServerKeys()
{ {
Assert.Throws<RedisCommandException>(() => Assert.Throws<RedisCommandException>(() =>
{ {
using (var muxer = Create()) using (var muxer = Create())
{ {
// connect // connect
var cluster = muxer.GetDatabase(); var cluster = muxer.GetDatabase();
var anyServer = muxer.GetServer(muxer.GetEndPoints()[0]); var anyServer = muxer.GetServer(muxer.GetEndPoints()[0]);
anyServer.Ping(); anyServer.Ping();
var config = anyServer.ClusterConfiguration; var config = anyServer.ClusterConfiguration;
Assert.IsNotNull(config); Assert.IsNotNull(config);
// invent 2 keys that we believe are served by different nodes // invent 2 keys that we believe are served by different nodes
string x = Guid.NewGuid().ToString(), y; string x = Guid.NewGuid().ToString(), y;
var xNode = config.GetBySlot(x); var xNode = config.GetBySlot(x);
int abort = 1000; int abort = 1000;
do do
{ {
y = Guid.NewGuid().ToString(); y = Guid.NewGuid().ToString();
} while (--abort > 0 && config.GetBySlot(y) != xNode); } while (--abort > 0 && config.GetBySlot(y) != xNode);
if (abort == 0) Assert.Inconclusive("failed to find a key with the same node to use"); if (abort == 0) Assert.Inconclusive("failed to find a key with the same node to use");
var yNode = config.GetBySlot(y); var yNode = config.GetBySlot(y);
Console.WriteLine("x={0}, served by {1}", x, xNode.NodeId); Console.WriteLine("x={0}, served by {1}", x, xNode.NodeId);
Console.WriteLine("y={0}, served by {1}", y, yNode.NodeId); Console.WriteLine("y={0}, served by {1}", y, yNode.NodeId);
Assert.AreEqual(xNode.NodeId, yNode.NodeId, "same node"); Assert.AreEqual(xNode.NodeId, yNode.NodeId, "same node");
// wipe those keys // wipe those keys
cluster.KeyDelete(x, CommandFlags.FireAndForget); cluster.KeyDelete(x, CommandFlags.FireAndForget);
cluster.KeyDelete(y, CommandFlags.FireAndForget); cluster.KeyDelete(y, CommandFlags.FireAndForget);
// create a transaction that attempts to assign both keys // create a transaction that attempts to assign both keys
var tran = cluster.CreateTransaction(); var tran = cluster.CreateTransaction();
tran.AddCondition(Condition.KeyNotExists(x)); tran.AddCondition(Condition.KeyNotExists(x));
tran.AddCondition(Condition.KeyNotExists(y)); tran.AddCondition(Condition.KeyNotExists(y));
var setX = tran.StringSetAsync(x, "x-val"); var setX = tran.StringSetAsync(x, "x-val");
var setY = tran.StringSetAsync(y, "y-val"); var setY = tran.StringSetAsync(y, "y-val");
bool success = tran.Execute(); bool success = tran.Execute();
Assert.Fail("Expected single-slot rules to apply"); Assert.Fail("Expected single-slot rules to apply");
// the rest no longer applies while we are following single-slot rules // the rest no longer applies while we are following single-slot rules
//// check that everything was aborted //// check that everything was aborted
//Assert.IsTrue(success, "tran aborted"); //Assert.IsTrue(success, "tran aborted");
//Assert.IsFalse(setX.IsCanceled, "set x cancelled"); //Assert.IsFalse(setX.IsCanceled, "set x cancelled");
//Assert.IsFalse(setY.IsCanceled, "set y cancelled"); //Assert.IsFalse(setY.IsCanceled, "set y cancelled");
//var existsX = cluster.KeyExistsAsync(x); //var existsX = cluster.KeyExistsAsync(x);
//var existsY = cluster.KeyExistsAsync(y); //var existsY = cluster.KeyExistsAsync(y);
//Assert.IsTrue(cluster.Wait(existsX), "x exists"); //Assert.IsTrue(cluster.Wait(existsX), "x exists");
//Assert.IsTrue(cluster.Wait(existsY), "y exists"); //Assert.IsTrue(cluster.Wait(existsY), "y exists");
} }
}, },
"Multi-key operations must involve a single slot; keys can use 'hash tags' to help this, i.e. '{/users/12345}/account' and '{/users/12345}/contacts' will always be in the same slot"); "Multi-key operations must involve a single slot; keys can use 'hash tags' to help this, i.e. '{/users/12345}/account' and '{/users/12345}/contacts' will always be in the same slot");
} }
[Test] [Test]
public void TransactionWithSameSlotKeys() public void TransactionWithSameSlotKeys()
{ {
using (var muxer = Create()) using (var muxer = Create())
{ {
// connect // connect
var cluster = muxer.GetDatabase(); var cluster = muxer.GetDatabase();
var anyServer = muxer.GetServer(muxer.GetEndPoints()[0]); var anyServer = muxer.GetServer(muxer.GetEndPoints()[0]);
anyServer.Ping(); anyServer.Ping();
var config = anyServer.ClusterConfiguration; var config = anyServer.ClusterConfiguration;
Assert.IsNotNull(config); Assert.IsNotNull(config);
// invent 2 keys that we believe are in the same slot // invent 2 keys that we believe are in the same slot
var guid = Guid.NewGuid().ToString(); var guid = Guid.NewGuid().ToString();
string x = "/{" + guid + "}/foo", y = "/{" + guid + "}/bar"; string x = "/{" + guid + "}/foo", y = "/{" + guid + "}/bar";
Assert.AreEqual(muxer.HashSlot(x), muxer.HashSlot(y)); Assert.AreEqual(muxer.HashSlot(x), muxer.HashSlot(y));
var xNode = config.GetBySlot(x); var xNode = config.GetBySlot(x);
var yNode = config.GetBySlot(y); var yNode = config.GetBySlot(y);
Console.WriteLine("x={0}, served by {1}", x, xNode.NodeId); Console.WriteLine("x={0}, served by {1}", x, xNode.NodeId);
Console.WriteLine("y={0}, served by {1}", y, yNode.NodeId); Console.WriteLine("y={0}, served by {1}", y, yNode.NodeId);
Assert.AreEqual(xNode.NodeId, yNode.NodeId, "same node"); Assert.AreEqual(xNode.NodeId, yNode.NodeId, "same node");
// wipe those keys // wipe those keys
cluster.KeyDelete(x, CommandFlags.FireAndForget); cluster.KeyDelete(x, CommandFlags.FireAndForget);
cluster.KeyDelete(y, CommandFlags.FireAndForget); cluster.KeyDelete(y, CommandFlags.FireAndForget);
// create a transaction that attempts to assign both keys // create a transaction that attempts to assign both keys
var tran = cluster.CreateTransaction(); var tran = cluster.CreateTransaction();
tran.AddCondition(Condition.KeyNotExists(x)); tran.AddCondition(Condition.KeyNotExists(x));
tran.AddCondition(Condition.KeyNotExists(y)); tran.AddCondition(Condition.KeyNotExists(y));
var setX = tran.StringSetAsync(x, "x-val"); var setX = tran.StringSetAsync(x, "x-val");
var setY = tran.StringSetAsync(y, "y-val"); var setY = tran.StringSetAsync(y, "y-val");
bool success = tran.Execute(); bool success = tran.Execute();
// check that everything was aborted // check that everything was aborted
Assert.IsTrue(success, "tran aborted"); Assert.IsTrue(success, "tran aborted");
Assert.IsFalse(setX.IsCanceled, "set x cancelled"); Assert.IsFalse(setX.IsCanceled, "set x cancelled");
Assert.IsFalse(setY.IsCanceled, "set y cancelled"); Assert.IsFalse(setY.IsCanceled, "set y cancelled");
var existsX = cluster.KeyExistsAsync(x); var existsX = cluster.KeyExistsAsync(x);
var existsY = cluster.KeyExistsAsync(y); var existsY = cluster.KeyExistsAsync(y);
Assert.IsTrue(cluster.Wait(existsX), "x exists"); Assert.IsTrue(cluster.Wait(existsX), "x exists");
Assert.IsTrue(cluster.Wait(existsY), "y exists"); Assert.IsTrue(cluster.Wait(existsY), "y exists");
} }
} }
[Test] [Test]
[TestCase(null, 10)] [TestCase(null, 10)]
[TestCase(null, 100)] [TestCase(null, 100)]
[TestCase("abc", 10)] [TestCase("abc", 10)]
[TestCase("abc", 100)] [TestCase("abc", 100)]
public void Keys(string pattern, int pageSize) public void Keys(string pattern, int pageSize)
{ {
using (var conn = Create(allowAdmin: true)) using (var conn = Create(allowAdmin: true))
{ {
var cluster = conn.GetDatabase(); var cluster = conn.GetDatabase();
var server = conn.GetEndPoints().Select(x => conn.GetServer(x)).First(x => !x.IsSlave); var server = conn.GetEndPoints().Select(x => conn.GetServer(x)).First(x => !x.IsSlave);
server.FlushAllDatabases(); server.FlushAllDatabases();
try try
{ {
Assert.IsFalse(server.Keys(pattern: pattern, pageSize: pageSize).Any()); Assert.IsFalse(server.Keys(pattern: pattern, pageSize: pageSize).Any());
Console.WriteLine("Complete: '{0}' / {1}", pattern, pageSize); Console.WriteLine("Complete: '{0}' / {1}", pattern, pageSize);
} catch } catch
{ {
Console.WriteLine("Failed: '{0}' / {1}", pattern, pageSize); Console.WriteLine("Failed: '{0}' / {1}", pattern, pageSize);
throw; throw;
} }
} }
} }
[Test] [Test]
[TestCase("", 0)] [TestCase("", 0)]
[TestCase("abc", 7638)] [TestCase("abc", 7638)]
[TestCase("{abc}", 7638)] [TestCase("{abc}", 7638)]
[TestCase("abcdef", 15101)] [TestCase("abcdef", 15101)]
[TestCase("abc{abc}def", 7638)] [TestCase("abc{abc}def", 7638)]
[TestCase("c", 7365)] [TestCase("c", 7365)]
[TestCase("g", 7233)] [TestCase("g", 7233)]
[TestCase("d", 11298)] [TestCase("d", 11298)]
[TestCase("user1000", 3443)] [TestCase("user1000", 3443)]
[TestCase("{user1000}", 3443)] [TestCase("{user1000}", 3443)]
[TestCase("abc{user1000}", 3443)] [TestCase("abc{user1000}", 3443)]
[TestCase("abc{user1000}def", 3443)] [TestCase("abc{user1000}def", 3443)]
[TestCase("{user1000}.following", 3443)] [TestCase("{user1000}.following", 3443)]
[TestCase("{user1000}.followers", 3443)] [TestCase("{user1000}.followers", 3443)]
[TestCase("foo{}{bar}", 8363)] [TestCase("foo{}{bar}", 8363)]
[TestCase("foo{{bar}}zap", 4015)] [TestCase("foo{{bar}}zap", 4015)]
[TestCase("{bar", 4015)] [TestCase("{bar", 4015)]
[TestCase("foo{bar}{zap}", 5061)] [TestCase("foo{bar}{zap}", 5061)]
[TestCase("bar", 5061)] [TestCase("bar", 5061)]
public void HashSlots(string key, int slot) public void HashSlots(string key, int slot)
{ {
using(var muxer = Create(connectTimeout: 500, pause: false)) using(var muxer = Create(connectTimeout: 500, pause: false))
{ {
Assert.AreEqual(slot, muxer.HashSlot(key)); Assert.AreEqual(slot, muxer.HashSlot(key));
} }
} }
[Test] [Test]
public void SScan() public void SScan()
{ {
using (var conn = Create()) using (var conn = Create())
{ {
RedisKey key = "a"; RedisKey key = "a";
var db = conn.GetDatabase(); var db = conn.GetDatabase();
db.KeyDelete(key); db.KeyDelete(key);
int totalUnfiltered = 0, totalFiltered = 0; int totalUnfiltered = 0, totalFiltered = 0;
for (int i = 0; i < 1000; i++) for (int i = 0; i < 1000; i++)
{ {
db.SetAdd(key, i); db.SetAdd(key, i);
totalUnfiltered += i; totalUnfiltered += i;
if (i.ToString().Contains("3")) totalFiltered += i; if (i.ToString().Contains("3")) totalFiltered += i;
} }
var unfilteredActual = db.SetScan(key).Select(x => (int)x).Sum(); var unfilteredActual = db.SetScan(key).Select(x => (int)x).Sum();
var filteredActual = db.SetScan(key, "*3*").Select(x => (int)x).Sum(); var filteredActual = db.SetScan(key, "*3*").Select(x => (int)x).Sum();
Assert.AreEqual(totalUnfiltered, unfilteredActual); Assert.AreEqual(totalUnfiltered, unfilteredActual);
Assert.AreEqual(totalFiltered, filteredActual); Assert.AreEqual(totalFiltered, filteredActual);
} }
} }
[Test] [Test]
public void GetConfig() public void GetConfig()
{ {
using(var muxer = Create(allowAdmin: true)) using(var muxer = Create(allowAdmin: true))
{ {
var endpoints = muxer.GetEndPoints(); var endpoints = muxer.GetEndPoints();
var server = muxer.GetServer(endpoints.First()); var server = muxer.GetServer(endpoints.First());
var nodes = server.ClusterNodes(); var nodes = server.ClusterNodes();
Assert.AreEqual(endpoints.Length, nodes.Nodes.Count); Assert.AreEqual(endpoints.Length, nodes.Nodes.Count);
foreach(var node in nodes.Nodes.OrderBy(x => x)) foreach(var node in nodes.Nodes.OrderBy(x => x))
{ {
Console.WriteLine(node); Console.WriteLine(node);
} }
} }
} }
[Test] [Test]
public void AccessRandomKeys() public void AccessRandomKeys()
{ {
using(var conn = Create(allowAdmin: true)) using(var conn = Create(allowAdmin: true))
{ {
var cluster = conn.GetDatabase(); var cluster = conn.GetDatabase();
int slotMovedCount = 0; int slotMovedCount = 0;
conn.HashSlotMoved += (s, a) => conn.HashSlotMoved += (s, a) =>
{ {
Console.WriteLine("{0} moved from {1} to {2}", a.HashSlot, Describe(a.OldEndPoint), Describe(a.NewEndPoint)); Console.WriteLine("{0} moved from {1} to {2}", a.HashSlot, Describe(a.OldEndPoint), Describe(a.NewEndPoint));
Interlocked.Increment(ref slotMovedCount); Interlocked.Increment(ref slotMovedCount);
}; };
var pairs = new Dictionary<string, string>(); var pairs = new Dictionary<string, string>();
const int COUNT = 500; const int COUNT = 500;
Task[] send = new Task[COUNT]; Task[] send = new Task[COUNT];
int index = 0; int index = 0;
var servers = conn.GetEndPoints().Select(x => conn.GetServer(x)); var servers = conn.GetEndPoints().Select(x => conn.GetServer(x));
foreach (var server in servers) foreach (var server in servers)
{ {
if (!server.IsSlave) if (!server.IsSlave)
{ {
server.Ping(); server.Ping();
server.FlushAllDatabases(); server.FlushAllDatabases();
} }
} }
for(int i = 0; i < COUNT; i++) for(int i = 0; i < COUNT; i++)
{ {
var key = Guid.NewGuid().ToString(); var key = Guid.NewGuid().ToString();
var value = Guid.NewGuid().ToString(); var value = Guid.NewGuid().ToString();
pairs.Add(key, value); pairs.Add(key, value);
send[index++] = cluster.StringSetAsync(key, value); send[index++] = cluster.StringSetAsync(key, value);
} }
conn.WaitAll(send); conn.WaitAll(send);
var expected = new string[COUNT]; var expected = new string[COUNT];
var actual = new Task<RedisValue>[COUNT]; var actual = new Task<RedisValue>[COUNT];
index = 0; index = 0;
foreach (var pair in pairs) foreach (var pair in pairs)
{ {
expected[index] = pair.Value; expected[index] = pair.Value;
actual[index] = cluster.StringGetAsync(pair.Key); actual[index] = cluster.StringGetAsync(pair.Key);
index++; index++;
} }
cluster.WaitAll(actual); cluster.WaitAll(actual);
for(int i = 0; i < COUNT; i++) for(int i = 0; i < COUNT; i++)
{ {
Assert.AreEqual(expected[i], (string)actual[i].Result); Assert.AreEqual(expected[i], (string)actual[i].Result);
} }
int total = 0; int total = 0;
Parallel.ForEach(servers, server => Parallel.ForEach(servers, server =>
{ {
if (!server.IsSlave) if (!server.IsSlave)
{ {
int count = server.Keys(pageSize: 100).Count(); int count = server.Keys(pageSize: 100).Count();
Console.WriteLine("{0} has {1} keys", server.EndPoint, count); Console.WriteLine("{0} has {1} keys", server.EndPoint, count);
Interlocked.Add(ref total, count); Interlocked.Add(ref total, count);
} }
}); });
foreach (var server in servers) foreach (var server in servers)
{ {
var counters = server.GetCounters(); var counters = server.GetCounters();
Console.WriteLine(counters); Console.WriteLine(counters);
} }
int final = Interlocked.CompareExchange(ref total, 0, 0); int final = Interlocked.CompareExchange(ref total, 0, 0);
Assert.AreEqual(COUNT, final); Assert.AreEqual(COUNT, final);
Assert.AreEqual(0, Interlocked.CompareExchange(ref slotMovedCount, 0, 0), "slot moved count"); Assert.AreEqual(0, Interlocked.CompareExchange(ref slotMovedCount, 0, 0), "slot moved count");
} }
} }
[Test] [Test]
[TestCase(CommandFlags.DemandMaster, false)] [TestCase(CommandFlags.DemandMaster, false)]
[TestCase(CommandFlags.DemandSlave, true)] [TestCase(CommandFlags.DemandSlave, true)]
[TestCase(CommandFlags.PreferMaster, false)] [TestCase(CommandFlags.PreferMaster, false)]
[TestCase(CommandFlags.PreferSlave, true)] [TestCase(CommandFlags.PreferSlave, true)]
public void GetFromRightNodeBasedOnFlags(CommandFlags flags, bool isSlave) public void GetFromRightNodeBasedOnFlags(CommandFlags flags, bool isSlave)
{ {
using(var muxer = Create(allowAdmin: true)) using(var muxer = Create(allowAdmin: true))
{ {
var db = muxer.GetDatabase(); var db = muxer.GetDatabase();
for(int i = 0; i < 1000; i++) for(int i = 0; i < 1000; i++)
{ {
var key = Guid.NewGuid().ToString(); var key = Guid.NewGuid().ToString();
var endpoint = db.IdentifyEndpoint(key, flags); var endpoint = db.IdentifyEndpoint(key, flags);
var server = muxer.GetServer(endpoint); var server = muxer.GetServer(endpoint);
Assert.AreEqual(isSlave, server.IsSlave, key); Assert.AreEqual(isSlave, server.IsSlave, key);
} }
} }
} }
private static string Describe(EndPoint endpoint) private static string Describe(EndPoint endpoint)
{ {
return endpoint == null ? "(unknown)" : endpoint.ToString(); return endpoint == null ? "(unknown)" : endpoint.ToString();
} }
class TestProfiler : IProfiler class TestProfiler : IProfiler
...@@ -566,8 +566,8 @@ public object GetContext() ...@@ -566,8 +566,8 @@ public object GetContext()
{ {
return MyContext; return MyContext;
} }
} }
[Test] [Test]
public void SimpleProfiling() public void SimpleProfiling()
{ {
...@@ -587,10 +587,10 @@ public void SimpleProfiling() ...@@ -587,10 +587,10 @@ public void SimpleProfiling()
Assert.IsTrue(msgs.Any(m => m.Command == "GET")); Assert.IsTrue(msgs.Any(m => m.Command == "GET"));
Assert.IsTrue(msgs.Any(m => m.Command == "SET")); Assert.IsTrue(msgs.Any(m => m.Command == "SET"));
} }
} }
#if DEBUG #if DEBUG
[Test] [Test]
public void MovedProfiling() public void MovedProfiling()
{ {
const string Key = "redirected-key"; const string Key = "redirected-key";
...@@ -671,7 +671,7 @@ public void MovedProfiling() ...@@ -671,7 +671,7 @@ public void MovedProfiling()
} }
} }
} }
} }
#endif #endif
} }
} }
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
namespace StackExchange.Redis.Tests namespace StackExchange.Redis.Tests
{ {
[TestFixture] [TestFixture]
public class Scripting : TestBase public class Scripting : TestBase
{ {
[Test] [Test]
public void TestBasicScripting() public void TestBasicScripting()
{ {
using (var conn = Create()) using (var conn = Create())
{ {
RedisValue newId = Guid.NewGuid().ToString(); RedisValue newId = Guid.NewGuid().ToString();
RedisKey custKey = Me(); RedisKey custKey = Me();
var db = conn.GetDatabase(); var db = conn.GetDatabase();
db.KeyDelete(custKey); db.KeyDelete(custKey);
db.HashSet(custKey, "id", 123); db.HashSet(custKey, "id", 123);
var wasSet = (bool) db.ScriptEvaluate(@"if redis.call('hexists', KEYS[1], 'UniqueId') then return redis.call('hset', KEYS[1], 'UniqueId', ARGV[1]) else return 0 end", var wasSet = (bool) db.ScriptEvaluate(@"if redis.call('hexists', KEYS[1], 'UniqueId') then return redis.call('hset', KEYS[1], 'UniqueId', ARGV[1]) else return 0 end",
new RedisKey[] { custKey }, new RedisValue[] { newId }); new RedisKey[] { custKey }, new RedisValue[] { newId });
Assert.IsTrue(wasSet); Assert.IsTrue(wasSet);
wasSet = (bool)db.ScriptEvaluate(@"if redis.call('hexists', KEYS[1], 'UniqueId') then return redis.call('hset', KEYS[1], 'UniqueId', ARGV[1]) else return 0 end", wasSet = (bool)db.ScriptEvaluate(@"if redis.call('hexists', KEYS[1], 'UniqueId') then return redis.call('hset', KEYS[1], 'UniqueId', ARGV[1]) else return 0 end",
new RedisKey[] { custKey }, new RedisValue[] { newId }); new RedisKey[] { custKey }, new RedisValue[] { newId });
Assert.IsFalse(wasSet); Assert.IsFalse(wasSet);
} }
} }
[Test] [Test]
[TestCase(true)] [TestCase(true)]
[TestCase(false)] [TestCase(false)]
public void CheckLoads(bool async) public void CheckLoads(bool async)
{ {
using (var conn0 = Create(allowAdmin: true)) using (var conn0 = Create(allowAdmin: true))
using (var conn1 = Create(allowAdmin: true)) using (var conn1 = Create(allowAdmin: true))
{ {
// note that these are on different connections (so we wouldn't expect // note that these are on different connections (so we wouldn't expect
// the flush to drop the local cache - assume it is a surprise!) // the flush to drop the local cache - assume it is a surprise!)
var server = conn0.GetServer(PrimaryServer, PrimaryPort); var server = conn0.GetServer(PrimaryServer, PrimaryPort);
var db = conn1.GetDatabase(); var db = conn1.GetDatabase();
const string script = "return 1;"; const string script = "return 1;";
// start empty // start empty
server.ScriptFlush(); server.ScriptFlush();
Assert.IsFalse(server.ScriptExists(script)); Assert.IsFalse(server.ScriptExists(script));
// run once, causes to be cached // run once, causes to be cached
Assert.IsTrue((bool)db.ScriptEvaluate(script)); Assert.IsTrue((bool)db.ScriptEvaluate(script));
Assert.IsTrue(server.ScriptExists(script)); Assert.IsTrue(server.ScriptExists(script));
// can run again // can run again
Assert.IsTrue((bool)db.ScriptEvaluate(script)); Assert.IsTrue((bool)db.ScriptEvaluate(script));
// ditch the scripts; should no longer exist // ditch the scripts; should no longer exist
db.Ping(); db.Ping();
server.ScriptFlush(); server.ScriptFlush();
Assert.IsFalse(server.ScriptExists(script)); Assert.IsFalse(server.ScriptExists(script));
db.Ping(); db.Ping();
if (async) if (async)
{ {
// now: fails the first time // now: fails the first time
try try
{ {
db.Wait(db.ScriptEvaluateAsync(script)); db.Wait(db.ScriptEvaluateAsync(script));
Assert.Fail(); Assert.Fail();
} }
catch(AggregateException ex) catch(AggregateException ex)
{ {
Assert.AreEqual(1, ex.InnerExceptions.Count); Assert.AreEqual(1, ex.InnerExceptions.Count);
Assert.IsInstanceOf<RedisServerException>(ex.InnerExceptions[0]); Assert.IsInstanceOf<RedisServerException>(ex.InnerExceptions[0]);
Assert.AreEqual("NOSCRIPT No matching script. Please use EVAL.", ex.InnerExceptions[0].Message); Assert.AreEqual("NOSCRIPT No matching script. Please use EVAL.", ex.InnerExceptions[0].Message);
} }
} else } else
{ {
// just works; magic // just works; magic
Assert.IsTrue((bool)db.ScriptEvaluate(script)); Assert.IsTrue((bool)db.ScriptEvaluate(script));
} }
// but gets marked as unloaded, so we can use it again... // but gets marked as unloaded, so we can use it again...
Assert.IsTrue((bool)db.ScriptEvaluate(script)); Assert.IsTrue((bool)db.ScriptEvaluate(script));
// which will cause it to be cached // which will cause it to be cached
Assert.IsTrue(server.ScriptExists(script)); Assert.IsTrue(server.ScriptExists(script));
} }
} }
[Test] [Test]
public void CompareScriptToDirect() public void CompareScriptToDirect()
{ {
const string Script = "return redis.call('incr', KEYS[1])"; const string Script = "return redis.call('incr', KEYS[1])";
using (var conn = Create(allowAdmin: true)) using (var conn = Create(allowAdmin: true))
{ {
var server = conn.GetServer(PrimaryServer, PrimaryPort); var server = conn.GetServer(PrimaryServer, PrimaryPort);
server.FlushAllDatabases(); server.FlushAllDatabases();
server.ScriptFlush(); server.ScriptFlush();
server.ScriptLoad(Script); server.ScriptLoad(Script);
var db = conn.GetDatabase(); var db = conn.GetDatabase();
db.Ping(); // k, we're all up to date now; clean db, minimal script cache db.Ping(); // k, we're all up to date now; clean db, minimal script cache
// we're using a pipeline here, so send 1000 messages, but for timing: only care about the last // we're using a pipeline here, so send 1000 messages, but for timing: only care about the last
const int LOOP = 5000; const int LOOP = 5000;
RedisKey key = "foo"; RedisKey key = "foo";
RedisKey[] keys = new[] { key }; // script takes an array RedisKey[] keys = new[] { key }; // script takes an array
// run via script // run via script
db.KeyDelete(key); db.KeyDelete(key);
CollectGarbage(); CollectGarbage();
var watch = Stopwatch.StartNew(); var watch = Stopwatch.StartNew();
for(int i = 1; i < LOOP; i++) // the i=1 is to do all-but-one for(int i = 1; i < LOOP; i++) // the i=1 is to do all-but-one
{ {
db.ScriptEvaluate(Script, keys, flags: CommandFlags.FireAndForget); db.ScriptEvaluate(Script, keys, flags: CommandFlags.FireAndForget);
} }
var scriptResult = db.ScriptEvaluate(Script, keys); // last one we wait for (no F+F) var scriptResult = db.ScriptEvaluate(Script, keys); // last one we wait for (no F+F)
watch.Stop(); watch.Stop();
TimeSpan scriptTime = watch.Elapsed; TimeSpan scriptTime = watch.Elapsed;
// run via raw op // run via raw op
db.KeyDelete(key); db.KeyDelete(key);
CollectGarbage(); CollectGarbage();
watch = Stopwatch.StartNew(); watch = Stopwatch.StartNew();
for (int i = 1; i < LOOP; i++) // the i=1 is to do all-but-one for (int i = 1; i < LOOP; i++) // the i=1 is to do all-but-one
{ {
db.StringIncrement(key, flags: CommandFlags.FireAndForget); db.StringIncrement(key, flags: CommandFlags.FireAndForget);
} }
var directResult = db.StringIncrement(key); // last one we wait for (no F+F) var directResult = db.StringIncrement(key); // last one we wait for (no F+F)
watch.Stop(); watch.Stop();
TimeSpan directTime = watch.Elapsed; TimeSpan directTime = watch.Elapsed;
Assert.AreEqual(LOOP, (long)scriptResult, "script result"); Assert.AreEqual(LOOP, (long)scriptResult, "script result");
Assert.AreEqual(LOOP, (long)directResult, "direct result"); Assert.AreEqual(LOOP, (long)directResult, "direct result");
Console.WriteLine("script: {0}ms; direct: {1}ms", Console.WriteLine("script: {0}ms; direct: {1}ms",
scriptTime.TotalMilliseconds, scriptTime.TotalMilliseconds,
directTime.TotalMilliseconds); directTime.TotalMilliseconds);
} }
} }
[Test] [Test]
public void TestCallByHash() public void TestCallByHash()
{ {
const string Script = "return redis.call('incr', KEYS[1])"; const string Script = "return redis.call('incr', KEYS[1])";
using (var conn = Create(allowAdmin: true)) using (var conn = Create(allowAdmin: true))
{ {
var server = conn.GetServer(PrimaryServer, PrimaryPort); var server = conn.GetServer(PrimaryServer, PrimaryPort);
server.FlushAllDatabases(); server.FlushAllDatabases();
server.ScriptFlush(); server.ScriptFlush();
byte[] hash = server.ScriptLoad(Script); byte[] hash = server.ScriptLoad(Script);
var db = conn.GetDatabase(); var db = conn.GetDatabase();
RedisKey[] keys = { Me() }; RedisKey[] keys = { Me() };
string hexHash = string.Concat(hash.Select(x => x.ToString("X2"))); string hexHash = string.Concat(hash.Select(x => x.ToString("X2")));
Assert.AreEqual("2BAB3B661081DB58BD2341920E0BA7CF5DC77B25", hexHash); Assert.AreEqual("2BAB3B661081DB58BD2341920E0BA7CF5DC77B25", hexHash);
db.ScriptEvaluate(hexHash, keys); db.ScriptEvaluate(hexHash, keys);
db.ScriptEvaluate(hash, keys); db.ScriptEvaluate(hash, keys);
var count = (int)db.StringGet(keys)[0]; var count = (int)db.StringGet(keys)[0];
Assert.AreEqual(2, count); Assert.AreEqual(2, count);
} }
} }
[Test] [Test]
public void SimpleLuaScript() public void SimpleLuaScript()
{ {
...@@ -359,8 +359,8 @@ public void LoadedLuaScriptWithKeys() ...@@ -359,8 +359,8 @@ public void LoadedLuaScriptWithKeys()
Assert.AreEqual(1, keys.Length); Assert.AreEqual(1, keys.Length);
Assert.AreEqual("testkey", (string)keys[0]); Assert.AreEqual("testkey", (string)keys[0]);
} }
} }
[Test] [Test]
public void PurgeLuaScriptCache() public void PurgeLuaScriptCache()
{ {
...@@ -402,8 +402,8 @@ public void PurgeLuaScriptOnFinalize() ...@@ -402,8 +402,8 @@ public void PurgeLuaScriptOnFinalize()
var shouldBeNew = LuaScript.Prepare(Script); var shouldBeNew = LuaScript.Prepare(Script);
Assert.AreEqual(1, LuaScript.GetCachedScriptCount()); Assert.AreEqual(1, LuaScript.GetCachedScriptCount());
} }
[Test] [Test]
public void IDatabaseLuaScriptConvenienceMethods() public void IDatabaseLuaScriptConvenienceMethods()
{ {
...@@ -442,8 +442,8 @@ public void IServerLuaScriptConvenienceMethods() ...@@ -442,8 +442,8 @@ public void IServerLuaScriptConvenienceMethods()
var val = db.StringGet("key3"); var val = db.StringGet("key3");
Assert.AreEqual("value3", (string)val); Assert.AreEqual("value3", (string)val);
} }
} }
[Test] [Test]
public void LuaScriptPrefixedKeys() public void LuaScriptPrefixedKeys()
{ {
...@@ -461,8 +461,8 @@ public void LuaScriptPrefixedKeys() ...@@ -461,8 +461,8 @@ public void LuaScriptPrefixedKeys()
Assert.AreEqual(2, args.Length); Assert.AreEqual(2, args.Length);
Assert.AreEqual("prefix-key", (string)args[0]); Assert.AreEqual("prefix-key", (string)args[0]);
Assert.AreEqual("hello", (string)args[1]); Assert.AreEqual("hello", (string)args[1]);
} }
[Test] [Test]
public void LuaScriptWithWrappedDatabase() public void LuaScriptWithWrappedDatabase()
{ {
...@@ -508,6 +508,6 @@ public void LoadedLuaScriptWithWrappedDatabase() ...@@ -508,6 +508,6 @@ public void LoadedLuaScriptWithWrappedDatabase()
var val3 = db.StringGet("mykey"); var val3 = db.StringGet("mykey");
Assert.IsTrue(val3.IsNull); Assert.IsTrue(val3.IsNull);
} }
} }
} }
} }
...@@ -12,7 +12,6 @@ public sealed class TransactionWrapperTests ...@@ -12,7 +12,6 @@ public sealed class TransactionWrapperTests
private Mock<ITransaction> mock; private Mock<ITransaction> mock;
private TransactionWrapper wrapper; private TransactionWrapper wrapper;
//[TestFixtureSetUp]
[OneTimeSetUp] [OneTimeSetUp]
public void Initialize() public void Initialize()
{ {
......
...@@ -39,6 +39,7 @@ public void NullPrefixIsError_Bytes() ...@@ -39,6 +39,7 @@ public void NullPrefixIsError_Bytes()
} }
}); });
} }
[Test] [Test]
public void NullPrefixIsError_String() public void NullPrefixIsError_String()
{ {
...@@ -62,6 +63,7 @@ public void NullDatabaseIsError(string prefix) ...@@ -62,6 +63,7 @@ public void NullDatabaseIsError(string prefix)
var prefixed = raw.WithKeyPrefix(prefix); var prefixed = raw.WithKeyPrefix(prefix);
}); });
} }
[Test] [Test]
public void BasicSmokeTest() public void BasicSmokeTest()
{ {
......
...@@ -31,11 +31,10 @@ public HashEntry(RedisValue name, RedisValue value) ...@@ -31,11 +31,10 @@ public HashEntry(RedisValue name, RedisValue value)
/// <summary> /// <summary>
/// The name of the hash field /// The name of the hash field
/// </summary> /// </summary>
[
#if !DNXCORE50 #if !DNXCORE50
Browsable(false), [Browsable(false)]
#endif #endif
EditorBrowsable(EditorBrowsableState.Never), Obsolete("Please use Name", false)] [EditorBrowsable(EditorBrowsableState.Never), Obsolete("Please use Name", false)]
public RedisValue Key { get { return name; } } public RedisValue Key { get { return name; } }
/// <summary> /// <summary>
......
...@@ -32,21 +32,19 @@ public SortedSetEntry(RedisValue element, double score) ...@@ -32,21 +32,19 @@ public SortedSetEntry(RedisValue element, double score)
/// <summary> /// <summary>
/// The score against the element /// The score against the element
/// </summary> /// </summary>
[
#if !DNXCORE50 #if !DNXCORE50
Browsable(false), [Browsable(false)]
#endif #endif
EditorBrowsable(EditorBrowsableState.Never), Obsolete("Please use Score", false)] [EditorBrowsable(EditorBrowsableState.Never), Obsolete("Please use Score", false)]
public double Value { get { return score; } } public double Value { get { return score; } }
/// <summary> /// <summary>
/// The unique element stored in the sorted set /// The unique element stored in the sorted set
/// </summary> /// </summary>
[
#if !DNXCORE50 #if !DNXCORE50
Browsable(false), [Browsable(false)]
#endif #endif
EditorBrowsable(EditorBrowsableState.Never), Obsolete("Please use Element", false)] [EditorBrowsable(EditorBrowsableState.Never), Obsolete("Please use Element", false)]
public RedisValue Key { get { return element; } } public RedisValue Key { get { return element; } }
/// <summary> /// <summary>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment