diff --git a/Enyim.Caching.Tests/MemcachedClientTestsBase.cs b/Enyim.Caching.Tests/MemcachedClientTestsBase.cs index 437a1571..5437bb7c 100644 --- a/Enyim.Caching.Tests/MemcachedClientTestsBase.cs +++ b/Enyim.Caching.Tests/MemcachedClientTestsBase.cs @@ -9,6 +9,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; +using System.Threading.Tasks; namespace Enyim.Caching.Tests { @@ -16,10 +17,18 @@ public abstract class MemcachedClientTestsBase { protected MemcachedClient _client; - public MemcachedClientTestsBase() + public MemcachedClientTestsBase(Action onAddEnyimMemcached = null) { IServiceCollection services = new ServiceCollection(); - services.AddEnyimMemcached(options => options.AddServer("memcached", 11211)); + services.AddEnyimMemcached(options => + { + options.AddServer("memcached", 11211); + if (onAddEnyimMemcached != null) + { + onAddEnyimMemcached(options); + } + }); + services.AddLogging(builder => builder.SetMinimumLevel(LogLevel.Debug).AddConsole()); IServiceProvider serviceProvider = services.BuildServiceProvider(); _client = serviceProvider.GetService() as MemcachedClient; @@ -63,6 +72,20 @@ protected IStoreOperationResult Store(StoreMode mode = StoreMode.Set, string key return _client.ExecuteStore(mode, key, value); } + protected Task StoreAsync(StoreMode mode = StoreMode.Set, string key = null, object value = null) + { + if (string.IsNullOrEmpty(key)) + { + key = GetUniqueKey("store"); + } + + if (value == null) + { + value = GetRandomString(); + } + return _client.StoreAsync(mode, key, value, TimeSpan.MaxValue); + } + protected void StoreAssertPass(IStoreOperationResult result) { Assert.True(result.Success, "Success was false"); @@ -95,6 +118,15 @@ protected void GetAssertFail(IGetOperationResult result) Assert.Null(result.Value); } + protected void GetAssertFail(IGetOperationResult result) + { + Assert.False(result.Success, "Success was true"); + Assert.Equal((ulong)0, result.Cas); + Assert.True(result.StatusCode > 0, "StatusCode not greater than 0"); + Assert.False(result.HasValue, "HasValue was true"); + Assert.Null(result.Value); + } + protected void MutateAssertPass(IMutateOperationResult result, ulong expectedValue) { Assert.True(result.Success, "Success was false"); diff --git a/Enyim.Caching.Tests/MemcachedClientWithKeyTransformerTests.cs b/Enyim.Caching.Tests/MemcachedClientWithKeyTransformerTests.cs new file mode 100644 index 00000000..2bbb623c --- /dev/null +++ b/Enyim.Caching.Tests/MemcachedClientWithKeyTransformerTests.cs @@ -0,0 +1,81 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Enyim.Caching.Configuration; +using Enyim.Caching.Memcached; +using Xunit; + +namespace Enyim.Caching.Tests +{ + public class MemcachedClientWithKeyTransformerTests : MemcachedClientTestsBase + { + public MemcachedClientWithKeyTransformerTests(Action onAddEnyimMemcached = null) + : base(options => + { + options.KeyTransformer = "Enyim.Caching.Memcached.TigerHashKeyTransformer"; + if (onAddEnyimMemcached != null) + { + onAddEnyimMemcached(options); + } + }) + { + } + + [Fact] + public void When_Removing_A_Valid_Transformed_Key_Is_Successful() + { + var key = GetUniqueKey("remove"); + var storeResult = Store(key: key); + StoreAssertPass(storeResult); + + var removeResult = _client.ExecuteRemove(key); + Assert.True(removeResult.Success, "Success was false"); + Assert.True((removeResult.StatusCode ?? 0) == 0, "StatusCode was neither null nor 0"); + + var getResult = _client.ExecuteGet(key); + GetAssertFail(getResult); + } + + + [Fact] + public async Task When_Removing_A_Valid_Transformed_Key_Is_Successful_Async() + { + var key = GetUniqueKey("remove"); + var storeResult = await StoreAsync(key: key); + Assert.True(storeResult, "Success was false"); + + var removeResult = await _client.RemoveAsync(key); + + Assert.True(removeResult, "Success was false"); + + var getResult = await _client.GetAsync(key); + GetAssertFail(getResult); + } + + [Fact] + public void When_Getting_Existing_Item_Value_With_Transformed_Key_Is_Not_Null_And_Result_Is_Successful() + { + var key = GetUniqueKey("get"); + var value = GetRandomString(); + var storeResult = Store(key: key, value: value); + StoreAssertPass(storeResult); + + var getResult = _client.ExecuteGet(key); + GetAssertPass(getResult, value); + } + + [Fact] + public void When_Storing_Item_With_With_Transformed_Key_And_Valid_Cas_Result_Is_Successful() + { + var key = GetUniqueKey("cas"); + var value = GetRandomString(); + var storeResult = Store(StoreMode.Add, key, value); + StoreAssertPass(storeResult); + + var casResult = _client.ExecuteCas(StoreMode.Set, key, value, storeResult.Cas); + StoreAssertPass(casResult); + } + } +} diff --git a/Enyim.Caching/MemcachedClient.Results.cs b/Enyim.Caching/MemcachedClient.Results.cs index 954da280..9e58764b 100644 --- a/Enyim.Caching/MemcachedClient.Results.cs +++ b/Enyim.Caching/MemcachedClient.Results.cs @@ -444,13 +444,13 @@ public IConcatOperationResult ExecutePrepend(string key, ulong cas, ArraySegment /// true if the item was successfully removed from the cache; false otherwise. public IRemoveOperationResult ExecuteRemove(string key) { - //var hashedKey = this.keyTransformer.Transform(key); - var node = this.pool.Locate(key); + var hashedKey = this.keyTransformer.Transform(key); + var node = this.pool.Locate(hashedKey); var result = RemoveOperationResultFactory.Create(); if (node != null) { - var command = this.pool.OperationFactory.Delete(key, 0); + var command = this.pool.OperationFactory.Delete(hashedKey, 0); var commandResult = node.Execute(command); if (commandResult.Success) @@ -472,12 +472,13 @@ public IRemoveOperationResult ExecuteRemove(string key) public async Task ExecuteRemoveAsync(string key) { - var node = this.pool.Locate(key); + var hashedKey = this.keyTransformer.Transform(key); + var node = this.pool.Locate(hashedKey); var result = RemoveOperationResultFactory.Create(); if (node != null) { - var command = this.pool.OperationFactory.Delete(key, 0); + var command = this.pool.OperationFactory.Delete(hashedKey, 0); var commandResult = await node.ExecuteAsync(command); if (commandResult.Success) diff --git a/Enyim.Caching/MemcachedClient.cs b/Enyim.Caching/MemcachedClient.cs index e92b4705..8ccd3077 100755 --- a/Enyim.Caching/MemcachedClient.cs +++ b/Enyim.Caching/MemcachedClient.cs @@ -196,6 +196,12 @@ public async Task> GetAsync(string key) result.Value = transcoder.Deserialize(command.Result); return result; } + else + { + commandResult.Combine(result); + + return result; + } } catch (Exception ex) { @@ -208,8 +214,7 @@ public async Task> GetAsync(string key) _logger.LogError($"Unable to locate memcached node"); } - result.Success = false; - result.Value = default(T); + result.Fail("Unable to locate node"); return result; }