5 // Marek Habersack <mhabersack@novell.com>
7 // Copyright (C) 2010 Novell, Inc. (http://novell.com/)
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 using System.Collections;
30 using System.Collections.Generic;
31 using System.Collections.ObjectModel;
32 using System.Collections.Specialized;
33 using System.Runtime.Caching;
34 using System.Threading;
36 using NUnit.Framework;
37 using MonoTests.Common;
39 namespace MonoTests.System.Runtime.Caching
42 public class MemoryCacheTest
45 public void ConstructorParameters ()
48 AssertExtensions.Throws<ArgumentNullException> (() => {
49 mc = new MemoryCache (null);
52 AssertExtensions.Throws<ArgumentException> (() => {
53 mc = new MemoryCache (String.Empty);
56 AssertExtensions.Throws<ArgumentException> (() => {
57 mc = new MemoryCache ("default");
60 var config = new NameValueCollection ();
61 config.Add ("CacheMemoryLimitMegabytes", "invalid");
62 AssertExtensions.Throws<ArgumentException> (() => {
63 mc = new MemoryCache ("MyCache", config);
67 config.Add ("PhysicalMemoryLimitPercentage", "invalid");
68 AssertExtensions.Throws<ArgumentException> (() => {
69 mc = new MemoryCache ("MyCache", config);
73 config.Add ("PollingInterval", "invalid");
74 AssertExtensions.Throws<ArgumentException> (() => {
75 mc = new MemoryCache ("MyCache", config);
79 config.Add ("CacheMemoryLimitMegabytes", "-1");
80 AssertExtensions.Throws<ArgumentException> (() => {
81 mc = new MemoryCache ("MyCache", config);
85 config.Add ("CacheMemoryLimitMegabytes", UInt64.MaxValue.ToString ());
86 AssertExtensions.Throws<ArgumentException> (() => {
87 mc = new MemoryCache ("MyCache", config);
91 config.Add ("PhysicalMemoryLimitPercentage", "-1");
92 AssertExtensions.Throws<ArgumentException> (() => {
93 mc = new MemoryCache ("MyCache", config);
97 config.Add ("PhysicalMemoryLimitPercentage", UInt64.MaxValue.ToString ());
98 AssertExtensions.Throws<ArgumentException> (() => {
99 mc = new MemoryCache ("MyCache", config);
103 config.Add ("PhysicalMemoryLimitPercentage", UInt32.MaxValue.ToString ());
104 AssertExtensions.Throws<ArgumentException> (() => {
105 mc = new MemoryCache ("MyCache", config);
109 config.Add ("PhysicalMemoryLimitPercentage", "-10");
110 AssertExtensions.Throws<ArgumentException> (() => {
111 mc = new MemoryCache ("MyCache", config);
115 config.Add ("PhysicalMemoryLimitPercentage", "0");
116 // Just make sure it doesn't throw any exception
117 mc = new MemoryCache ("MyCache", config);
120 config.Add ("PhysicalMemoryLimitPercentage", "101");
121 AssertExtensions.Throws<ArgumentException> (() => {
122 mc = new MemoryCache ("MyCache", config);
125 // Just make sure it doesn't throw any exception
127 config.Add ("UnsupportedSetting", "123");
128 mc = new MemoryCache ("MyCache", config);
132 public void Defaults ()
134 var mc = new MemoryCache ("MyCache");
135 Assert.AreEqual ("MyCache", mc.Name, "#A1");
136 Assert.AreEqual (98, mc.PhysicalMemoryLimit, "#A2");
137 // Value of this property is different from system to system
138 //Assert.AreEqual (0, mc.CacheMemoryLimit, "#A3");
139 Assert.AreEqual (TimeSpan.FromMinutes (2), mc.PollingInterval, "#A4");
141 DefaultCacheCapabilities.InMemoryProvider |
142 DefaultCacheCapabilities.CacheEntryChangeMonitors |
143 DefaultCacheCapabilities.AbsoluteExpirations |
144 DefaultCacheCapabilities.SlidingExpirations |
145 DefaultCacheCapabilities.CacheEntryRemovedCallback |
146 DefaultCacheCapabilities.CacheEntryUpdateCallback,
147 mc.DefaultCacheCapabilities, "#A1");
151 public void DefaultInstanceDefaults ()
153 var mc = MemoryCache.Default;
154 Assert.AreEqual ("Default", mc.Name, "#A1");
155 Assert.AreEqual (98, mc.PhysicalMemoryLimit, "#A2");
156 // Value of this property is different from system to system
157 //Assert.AreEqual (0, mc.CacheMemoryLimit, "#A3");
158 Assert.AreEqual (TimeSpan.FromMinutes (2), mc.PollingInterval, "#A4");
160 DefaultCacheCapabilities.InMemoryProvider |
161 DefaultCacheCapabilities.CacheEntryChangeMonitors |
162 DefaultCacheCapabilities.AbsoluteExpirations |
163 DefaultCacheCapabilities.SlidingExpirations |
164 DefaultCacheCapabilities.CacheEntryRemovedCallback |
165 DefaultCacheCapabilities.CacheEntryUpdateCallback,
166 mc.DefaultCacheCapabilities, "#A1");
170 public void ConstructorValues ()
172 var config = new NameValueCollection ();
173 config.Add ("PhysicalMemoryLimitPercentage", "0");
174 config.Add ("CacheMemoryLimitMegabytes", "1");
175 config.Add ("pollingInterval", "00:10:00");
177 var mc = new MemoryCache ("MyCache", config);
178 Assert.AreEqual (98, mc.PhysicalMemoryLimit, "#A1");
179 Assert.AreEqual (1048576, mc.CacheMemoryLimit, "#A2");
180 Assert.AreEqual (TimeSpan.FromMinutes (10), mc.PollingInterval, "#A3");
183 config.Add ("PhysicalMemoryLimitPercentage", "10");
184 config.Add ("CacheMemoryLimitMegabytes", "5");
185 config.Add ("PollingInterval", "01:10:00");
187 mc = new MemoryCache ("MyCache", config);
188 Assert.AreEqual (10, mc.PhysicalMemoryLimit, "#B1");
189 Assert.AreEqual (5242880, mc.CacheMemoryLimit, "#B2");
190 Assert.AreEqual (TimeSpan.FromMinutes (70), mc.PollingInterval, "#B3");
194 public void Indexer ()
196 var mc = new PokerMemoryCache ("MyCache");
198 AssertExtensions.Throws<ArgumentNullException> (() => {
202 AssertExtensions.Throws<ArgumentNullException> (() => {
203 object v = mc [null];
206 AssertExtensions.Throws<ArgumentNullException> (() => {
211 mc ["key"] = "value";
212 Assert.AreEqual (3, mc.Calls.Count, "#A2-1");
213 Assert.AreEqual ("set_this [string key]", mc.Calls [0], "#A2-2");
214 Assert.AreEqual ("Set (string key, object value, DateTimeOffset absoluteExpiration, string regionName = null)", mc.Calls [1], "#A2-3");
215 Assert.AreEqual ("Set (string key, object value, CacheItemPolicy policy, string regionName = null)", mc.Calls [2], "#A2-4");
216 Assert.IsTrue (mc.Contains ("key"), "#A2-5");
219 object value = mc ["key"];
220 Assert.AreEqual (1, mc.Calls.Count, "#A3-1");
221 Assert.AreEqual ("get_this [string key]", mc.Calls [0], "#A3-2");
222 Assert.AreEqual ("value", value, "#A3-3");
226 public void Contains ()
228 var mc = new PokerMemoryCache ("MyCache");
230 AssertExtensions.Throws<ArgumentNullException> (() => {
234 AssertExtensions.Throws<NotSupportedException> (() => {
235 mc.Contains ("key", "region");
238 mc.Set ("key", "value", ObjectCache.InfiniteAbsoluteExpiration);
239 Assert.IsTrue (mc.Contains ("key"), "#A2");
241 var cip = new CacheItemPolicy ();
242 cip.Priority = CacheItemPriority.NotRemovable;
243 cip.AbsoluteExpiration = DateTimeOffset.Now.AddMilliseconds (500);
244 mc.Set ("key", "value", cip);
245 Assert.IsTrue (mc.Contains ("key"), "#B1-1");
247 // The call below removes the expired entry and returns false
248 Assert.IsFalse (mc.Contains ("key"), "#B1-2");
252 public void CreateCacheEntryChangeMonitor ()
254 var mc = new PokerMemoryCache ("MyCache");
256 AssertExtensions.Throws<NotSupportedException> (() => {
257 mc.CreateCacheEntryChangeMonitor (new string [] { "key" }, "region");
260 AssertExtensions.Throws<ArgumentNullException> (() => {
261 mc.CreateCacheEntryChangeMonitor (null);
264 AssertExtensions.Throws<ArgumentException> (() => {
265 mc.CreateCacheEntryChangeMonitor (new string [] {});
268 AssertExtensions.Throws<ArgumentException> (() => {
269 mc.CreateCacheEntryChangeMonitor (new string [] { "key", null });
272 mc.Set ("key1", "value1", ObjectCache.InfiniteAbsoluteExpiration);
273 mc.Set ("key2", "value2", ObjectCache.InfiniteAbsoluteExpiration);
274 mc.Set ("key3", "value3", ObjectCache.InfiniteAbsoluteExpiration);
276 CacheEntryChangeMonitor monitor = mc.CreateCacheEntryChangeMonitor (new string [] { "key1", "key2" });
277 Assert.IsNotNull (monitor, "#A2-1");
278 Assert.AreEqual ("System.Runtime.Caching.MemoryCacheEntryChangeMonitor", monitor.GetType ().ToString (), "#A2-2");
279 Assert.AreEqual (2, monitor.CacheKeys.Count, "#A2-3");
280 Assert.AreEqual ("key1", monitor.CacheKeys [0], "#A2-3-1");
281 Assert.AreEqual ("key2", monitor.CacheKeys [1], "#A2-3-2");
282 Assert.IsNull (monitor.RegionName, "#A2-4");
283 // Since this comparison can fail from time to time, leaving it commented out
284 //Assert.AreEqual (DateTimeOffset.UtcNow.ToString (), monitor.LastModified.ToString (), "#A2-5");
285 Assert.IsFalse (monitor.HasChanged, "#A2-5");
287 // The actual unique id is constructed from key names followed by the hex value of ticks of their last modifed time
288 Assert.IsFalse (String.IsNullOrEmpty (monitor.UniqueId), "#A2-6");
290 // There seems to be a bug in .NET 4.0 regarding the code below. MSDN says that non-existing keys will cause the
291 // returned monitor instance to be marked as changed, but instead this exception is thrown:
293 // MonoTests.System.Runtime.Caching.MemoryCacheTest.CreateCacheEntryChangeMonitor:
294 // System.ArgumentOutOfRangeException : The UTC time represented when the offset is applied must be between year 0 and 10,000.
295 // Parameter name: offset
297 // at System.DateTimeOffset.ValidateDate(DateTime dateTime, TimeSpan offset)
298 // at System.DateTimeOffset..ctor(DateTime dateTime)
299 // at System.Runtime.Caching.MemoryCacheEntryChangeMonitor.InitDisposableMembers(MemoryCache cache)
300 // at System.Runtime.Caching.MemoryCache.CreateCacheEntryChangeMonitor(IEnumerable`1 keys, String regionName)
301 // at MonoTests.Common.PokerMemoryCache.CreateCacheEntryChangeMonitor(IEnumerable`1 keys, String regionName) in C:\Users\grendel\documents\visual studio 2010\Projects\System.Runtime.Caching.Test\System.Runtime.Caching.Test\Common\PokerMemoryCache.cs:line 113
302 // at MonoTests.System.Runtime.Caching.MemoryCacheTest.CreateCacheEntryChangeMonitor() in C:\Users\grendel\documents\visual studio 2010\Projects\System.Runtime.Caching.Test\System.Runtime.Caching.Test\System.Runtime.Caching\MemoryCacheTest.cs:line 275
304 // It's probably caused by the code passing a DateTime.MinValue to DateTimeOffset constructor for non-existing entries.
305 // Until this (apparent) bug is fixed, Mono is going to implement the buggy behavior.
308 AssertExtensions.Throws<ArgumentOutOfRangeException> (() => {
309 monitor = mc.CreateCacheEntryChangeMonitor (new string [] { "key1", "doesnotexist" });
312 monitor = mc.CreateCacheEntryChangeMonitor (new string [] { "key1", "doesnotexist" });
313 Assert.IsNotNull (monitor, "#A3-1");
314 Assert.AreEqual ("System.Runtime.Caching.MemoryCacheEntryChangeMonitor", monitor.GetType ().ToString (), "#A3-2");
315 Assert.AreEqual (1, monitor.CacheKeys.Count, "#A3-3");
316 Assert.AreEqual ("key1", monitor.CacheKeys [0], "#A3-3-1");
317 Assert.IsNull (monitor.RegionName, "#A3-4");
318 Assert.IsTrue (monitor.HasChanged, "#A3-5");
323 public void AddOrGetExisting_String_Object_DateTimeOffset_String ()
325 var mc = new PokerMemoryCache ("MyCache");
327 AssertExtensions.Throws<ArgumentNullException> (() => {
328 mc.AddOrGetExisting (null, "value", DateTimeOffset.Now);
331 AssertExtensions.Throws<ArgumentNullException> (() => {
332 mc.AddOrGetExisting ("key", null, DateTimeOffset.Now);
335 AssertExtensions.Throws<NotSupportedException> (() => {
336 mc.AddOrGetExisting ("key", "value", DateTimeOffset.Now, "region");
339 object value = mc.AddOrGetExisting ("key3_A2-1", "value", DateTimeOffset.Now.AddMinutes (1));
340 Assert.IsTrue (mc.Contains ("key3_A2-1"), "#A2-1");
341 Assert.IsNull (value, "#A2-2");
344 value = mc.AddOrGetExisting ("key3_A2-1", "value2", DateTimeOffset.Now.AddMinutes (1));
345 Assert.IsTrue (mc.Contains ("key3_A2-1"), "#A3-1");
346 Assert.IsNotNull (value, "#A3-2");
347 Assert.AreEqual ("value", value, "#A3-3");
348 Assert.AreEqual (2, mc.Calls.Count, "#A3-4");
349 Assert.AreEqual ("AddOrGetExisting (string key, object value, DateTimeOffset absoluteExpiration, string regionName = null)", mc.Calls [0], "#A3-5");
351 value = mc.AddOrGetExisting ("key_expired", "value", DateTimeOffset.MinValue);
352 Assert.IsFalse (mc.Contains ("key_expired"), "#A4-1");
353 Assert.IsNull (value, "#A4-1");
357 public void AddOrGetExisting_String_Object_CacheItemPolicy_String ()
359 var mc = new PokerMemoryCache ("MyCache");
361 AssertExtensions.Throws<ArgumentNullException> (() => {
362 mc.AddOrGetExisting (null, "value", null);
365 AssertExtensions.Throws<ArgumentNullException> (() => {
366 mc.AddOrGetExisting ("key", null, null);
369 var cip = new CacheItemPolicy ();
370 cip.AbsoluteExpiration = DateTime.Now.AddMinutes (1);
371 cip.SlidingExpiration = TimeSpan.FromMinutes (1);
373 AssertExtensions.Throws<ArgumentException> (() => {
374 mc.AddOrGetExisting ("key", "value", cip);
377 cip = new CacheItemPolicy ();
378 cip.SlidingExpiration = TimeSpan.MinValue;
379 AssertExtensions.Throws<ArgumentOutOfRangeException> (() => {
380 mc.AddOrGetExisting ("key3", "value", cip);
383 AssertExtensions.Throws<NotSupportedException> (() => {
384 mc.AddOrGetExisting ("key", "value", null, "region");
387 cip = new CacheItemPolicy ();
388 cip.SlidingExpiration = TimeSpan.FromDays (500);
389 AssertExtensions.Throws<ArgumentOutOfRangeException> (() => {
390 mc.AddOrGetExisting ("key3", "value", cip);
393 cip = new CacheItemPolicy ();
394 cip.Priority = (CacheItemPriority) 20;
395 AssertExtensions.Throws<ArgumentOutOfRangeException> (() => {
396 mc.AddOrGetExisting ("key3", "value", cip);
399 cip = new CacheItemPolicy ();
400 cip.SlidingExpiration = TimeSpan.FromTicks (0L);
401 mc.AddOrGetExisting ("key3_A2-1", "value", cip);
402 Assert.IsTrue (mc.Contains ("key3_A2-1"), "#A2-1");
404 cip = new CacheItemPolicy ();
405 cip.SlidingExpiration = TimeSpan.FromDays (365);
406 mc.AddOrGetExisting ("key3_A2-2", "value", cip);
407 Assert.IsTrue (mc.Contains ("key3_A2-2"), "#A2-2");
409 cip = new CacheItemPolicy ();
410 cip.RemovedCallback = (CacheEntryRemovedArguments arguments) => { };
411 object value = mc.AddOrGetExisting ("key3_A2-3", "value", cip);
412 Assert.IsTrue (mc.Contains ("key3_A2-3"), "#A2-3");
413 Assert.IsNull (value, "#A2-4");
416 value = mc.AddOrGetExisting ("key3_A2-3", "value2", null);
417 Assert.IsTrue (mc.Contains ("key3_A2-3"), "#A3-1");
418 Assert.IsNotNull (value, "#A3-2");
419 Assert.AreEqual ("value", value, "#A3-3");
420 Assert.AreEqual (2, mc.Calls.Count, "#A3-4");
421 Assert.AreEqual ("AddOrGetExisting (string key, object value, CacheItemPolicy policy, string regionName = null)", mc.Calls [0], "#A3-5");
423 cip = new CacheItemPolicy ();
424 cip.AbsoluteExpiration = DateTimeOffset.MinValue;
425 value = mc.AddOrGetExisting ("key_expired", "value", cip);
426 Assert.IsFalse (mc.Contains ("key_expired"), "#A4-1");
427 Assert.IsNull (value, "#A4-1");
431 public void AddOrGetExisting_CacheItem_CacheItemPolicy ()
433 var mc = new PokerMemoryCache ("MyCache");
436 AssertExtensions.Throws<ArgumentNullException> (() => {
437 ci = mc.AddOrGetExisting (null, new CacheItemPolicy ());
440 ci = new CacheItem ("key", "value");
441 ci2 = mc.AddOrGetExisting (ci, null);
443 // LAMESPEC: MSDN says it should return null if the entry does not exist yet.
445 Assert.IsNotNull (ci2, "#A2-1");
446 Assert.AreNotEqual (ci, ci2, "#A2-2");
447 Assert.IsNull (ci2.Value, "#A2-3");
448 Assert.IsTrue (mc.Contains (ci.Key), "#A2-4");
449 Assert.AreEqual (ci.Key, ci2.Key, "#A2-5");
451 ci = new CacheItem ("key", "value");
452 ci2 = mc.AddOrGetExisting (ci, null);
453 Assert.IsNotNull (ci2, "#A3-1");
454 Assert.AreNotEqual (ci, ci2, "#A3-2");
455 Assert.IsNotNull (ci2.Value, "#A3-3");
456 Assert.AreEqual (ci.Value, ci2.Value, "#A3-4");
457 Assert.AreEqual (ci.Key, ci2.Key, "#A3-5");
459 AssertExtensions.Throws<ArgumentNullException> (() => {
460 ci = new CacheItem (null, "value");
461 ci2 = mc.AddOrGetExisting (ci, null);
464 ci = new CacheItem (String.Empty, "value");
465 ci2 = mc.AddOrGetExisting (ci, null);
466 Assert.IsNotNull (ci2, "#A5-1");
467 Assert.AreNotEqual (ci, ci2, "#A5-2");
468 Assert.IsNull (ci2.Value, "#A5-3");
469 Assert.IsTrue (mc.Contains (ci.Key), "#A5-4");
470 Assert.AreEqual (ci.Key, ci2.Key, "#A5-5");
472 ci = new CacheItem ("key2", null);
475 // at System.Runtime.Caching.MemoryCacheEntry..ctor(String key, Object value, DateTimeOffset absExp, TimeSpan slidingExp, CacheItemPriority priority, Collection`1 dependencies, CacheEntryRemovedCallback removedCallback, MemoryCache cache)
476 // at System.Runtime.Caching.MemoryCache.AddOrGetExistingInternal(String key, Object value, CacheItemPolicy policy)
477 // at System.Runtime.Caching.MemoryCache.AddOrGetExisting(CacheItem item, CacheItemPolicy policy)
478 // at MonoTests.System.Runtime.Caching.MemoryCacheTest.AddOrGetExisting_CacheItem_CacheItemPolicy() in C:\Users\grendel\documents\visual studio 2010\Projects\System.Runtime.Caching.Test\System.Runtime.Caching.Test\System.Runtime.Caching\MemoryCacheTest.cs:line 211
479 AssertExtensions.Throws<ArgumentNullException> (() => {
480 ci2 = mc.AddOrGetExisting (ci, null);
483 ci = new CacheItem ("key3", "value");
484 var cip = new CacheItemPolicy ();
485 cip.UpdateCallback = (CacheEntryUpdateArguments arguments) => { };
486 AssertExtensions.Throws<ArgumentException> (() => {
487 ci2 = mc.AddOrGetExisting (ci, cip);
490 ci = new CacheItem ("key3", "value");
491 cip = new CacheItemPolicy ();
492 cip.AbsoluteExpiration = DateTimeOffset.Now;
493 cip.SlidingExpiration = TimeSpan.FromTicks (DateTime.Now.Ticks);
494 AssertExtensions.Throws<ArgumentException> (() => {
495 mc.AddOrGetExisting (ci, cip);
498 ci = new CacheItem ("key3", "value");
499 cip = new CacheItemPolicy ();
500 cip.SlidingExpiration = TimeSpan.MinValue;
501 AssertExtensions.Throws<ArgumentOutOfRangeException> (() => {
502 mc.AddOrGetExisting (ci, cip);
505 ci = new CacheItem ("key4_#B4-2", "value");
506 cip = new CacheItemPolicy ();
507 cip.SlidingExpiration = TimeSpan.FromTicks (0L);
508 mc.AddOrGetExisting (ci, cip);
509 Assert.IsTrue (mc.Contains ("key4_#B4-2"), "#B4-2");
511 ci = new CacheItem ("key3", "value");
512 cip = new CacheItemPolicy ();
513 cip.SlidingExpiration = TimeSpan.FromDays (500);
514 AssertExtensions.Throws<ArgumentOutOfRangeException> (() => {
515 mc.AddOrGetExisting (ci, cip);
518 ci = new CacheItem ("key5_#B5-2", "value");
519 cip = new CacheItemPolicy ();
520 cip.SlidingExpiration = TimeSpan.FromDays (365);
521 mc.AddOrGetExisting (ci, cip);
522 Assert.IsTrue (mc.Contains ("key5_#B5-2"), "#B5-2");
524 ci = new CacheItem ("key3", "value");
525 cip = new CacheItemPolicy ();
526 cip.Priority = (CacheItemPriority)20;
527 AssertExtensions.Throws<ArgumentOutOfRangeException> (() => {
528 mc.AddOrGetExisting (ci, cip);
531 ci = new CacheItem ("key3_B7", "value");
532 cip = new CacheItemPolicy ();
533 cip.RemovedCallback = (CacheEntryRemovedArguments arguments) => { };
534 ci2 = mc.AddOrGetExisting (ci, cip);
535 Assert.IsTrue (mc.Contains ("key3_B7"), "#B7");
537 // LAMESPEC: MSDN says it should return null if the entry does not exist yet.
539 Assert.IsNotNull (ci2, "#C1-1");
540 Assert.AreNotEqual (ci, ci2, "#C1-2");
541 Assert.IsNull (ci2.Value, "#C1-3");
542 Assert.IsTrue (mc.Contains (ci.Key), "#C1-4");
543 Assert.AreEqual (ci.Key, ci2.Key, "#C1-5");
545 // The entry is never inserted as its expiration date is before now
546 ci = new CacheItem ("key_D1", "value_D1");
547 cip = new CacheItemPolicy ();
548 cip.AbsoluteExpiration = DateTimeOffset.MinValue;
549 ci2 = mc.AddOrGetExisting (ci, cip);
550 Assert.IsFalse (mc.Contains ("key_D1"), "#D1-1");
551 Assert.IsNotNull (ci2, "#D1-2");
552 Assert.IsNull (ci2.Value, "#D1-3");
553 Assert.AreEqual ("key_D1", ci2.Key, "#D1-4");
556 ci = new CacheItem ("key_D2", "value_D2");
557 cip = new CacheItemPolicy ();
558 cip.AbsoluteExpiration = DateTimeOffset.MaxValue;
559 mc.AddOrGetExisting (ci, cip);
560 Assert.IsTrue (mc.Contains ("key_D2"), "#D2-1");
561 Assert.AreEqual (2, mc.Calls.Count, "#D2-2");
562 Assert.AreEqual ("AddOrGetExisting (CacheItem item, CacheItemPolicy policy)", mc.Calls [0], "#D2-3");
566 public void Set_String_Object_CacheItemPolicy_String ()
568 var mc = new PokerMemoryCache ("MyCache");
570 AssertExtensions.Throws<NotSupportedException> (() => {
571 mc.Set ("key", "value", new CacheItemPolicy (), "region");
574 AssertExtensions.Throws<ArgumentNullException> (() => {
575 mc.Set (null, "value", new CacheItemPolicy ());
578 AssertExtensions.Throws<ArgumentNullException> (() => {
579 mc.Set ("key", null, new CacheItemPolicy ());
582 var cip = new CacheItemPolicy ();
583 cip.UpdateCallback = (CacheEntryUpdateArguments arguments) => { };
584 cip.RemovedCallback = (CacheEntryRemovedArguments arguments) => { };
585 AssertExtensions.Throws<ArgumentException> (() => {
586 mc.Set ("key", "value", cip);
589 cip = new CacheItemPolicy ();
590 cip.SlidingExpiration = TimeSpan.MinValue;
591 AssertExtensions.Throws<ArgumentOutOfRangeException> (() => {
592 mc.Set ("key", "value", cip);
595 cip = new CacheItemPolicy ();
596 cip.SlidingExpiration = TimeSpan.FromTicks (0L);
597 mc.Set ("key_A1-6", "value", cip);
598 Assert.IsTrue (mc.Contains ("key_A1-6"), "#A1-6");
600 cip = new CacheItemPolicy ();
601 cip.SlidingExpiration = TimeSpan.FromDays (500);
602 AssertExtensions.Throws<ArgumentOutOfRangeException> (() => {
603 mc.Set ("key", "value", cip);
606 cip = new CacheItemPolicy ();
607 cip.SlidingExpiration = TimeSpan.FromDays (365);
608 mc.Set ("key_A1-8", "value", cip);
609 Assert.IsTrue (mc.Contains ("key_A1-8"), "#A1-8");
611 cip = new CacheItemPolicy ();
612 cip.Priority = (CacheItemPriority) 20;
613 AssertExtensions.Throws<ArgumentOutOfRangeException> (() => {
614 mc.Set ("key", "value", cip);
617 cip = new CacheItemPolicy ();
618 cip.RemovedCallback = (CacheEntryRemovedArguments arguments) => { };
619 mc.Set ("key_A2", "value_A2", cip);
620 Assert.IsTrue (mc.Contains ("key_A2"), "#A2");
622 mc.Set ("key_A3", "value_A3", new CacheItemPolicy ());
623 Assert.IsTrue (mc.Contains ("key_A3"), "#A3-1");
624 Assert.AreEqual ("value_A3", mc.Get ("key_A3"), "#A3-2");
626 // The entry is never inserted as its expiration date is before now
627 cip = new CacheItemPolicy ();
628 cip.AbsoluteExpiration = DateTimeOffset.MinValue;
629 mc.Set ("key_A4", "value_A4", cip);
630 Assert.IsFalse (mc.Contains ("key_A4"), "#A4");
633 cip = new CacheItemPolicy ();
634 cip.AbsoluteExpiration = DateTimeOffset.MaxValue;
635 mc.Set ("key_A5", "value_A5", cip);
636 Assert.IsTrue (mc.Contains ("key_A5"), "#A5-1");
637 Assert.AreEqual (2, mc.Calls.Count, "#A5-2");
638 Assert.AreEqual ("Set (string key, object value, CacheItemPolicy policy, string regionName = null)", mc.Calls [0], "#A5-3");
642 public void Set_String_Object_DateTimeOffset_String ()
644 var mc = new PokerMemoryCache ("MyCache");
646 AssertExtensions.Throws<NotSupportedException> (() => {
647 mc.Set ("key", "value", DateTimeOffset.MaxValue, "region");
650 AssertExtensions.Throws<ArgumentNullException> (() => {
651 mc.Set (null, "value", DateTimeOffset.MaxValue);
654 AssertExtensions.Throws<ArgumentNullException> (() => {
655 mc.Set ("key", null, DateTimeOffset.MaxValue);
658 // The entry is never inserted as its expiration date is before now
659 mc.Set ("key_A2", "value_A2", DateTimeOffset.MinValue);
660 Assert.IsFalse (mc.Contains ("key_A2"), "#A2");
663 mc.Set ("key", "value", DateTimeOffset.MaxValue);
665 Assert.AreEqual (2, mc.Calls.Count, "#A2-1");
666 Assert.AreEqual ("Set (string key, object value, DateTimeOffset absoluteExpiration, string regionName = null)", mc.Calls [0], "#A2-2");
667 Assert.AreEqual ("Set (string key, object value, CacheItemPolicy policy, string regionName = null)", mc.Calls [1], "#A2-3");
671 public void Set_CacheItem_CacheItemPolicy ()
673 var mc = new PokerMemoryCache ("MyCache");
675 AssertExtensions.Throws<ArgumentNullException> (() => {
676 mc.Set (null, new CacheItemPolicy ());
679 // Actually thrown from the Set (string, object, CacheItemPolicy, string) overload
680 var ci = new CacheItem (null, "value");
681 AssertExtensions.Throws<ArgumentNullException> (() => {
682 mc.Set (ci, new CacheItemPolicy ());
685 ci = new CacheItem ("key", null);
686 AssertExtensions.Throws<ArgumentNullException> (() => {
687 mc.Set (ci, new CacheItemPolicy ());
690 ci = new CacheItem ("key", "value");
691 var cip = new CacheItemPolicy ();
692 cip.UpdateCallback = (CacheEntryUpdateArguments arguments) => { };
693 cip.RemovedCallback = (CacheEntryRemovedArguments arguments) => { };
694 AssertExtensions.Throws<ArgumentException> (() => {
698 ci = new CacheItem ("key", "value");
699 cip = new CacheItemPolicy ();
700 cip.SlidingExpiration = TimeSpan.MinValue;
701 AssertExtensions.Throws<ArgumentOutOfRangeException> (() => {
705 ci = new CacheItem ("key_A1-6", "value");
706 cip = new CacheItemPolicy ();
707 cip.SlidingExpiration = TimeSpan.FromTicks (0L);
709 Assert.IsTrue (mc.Contains ("key_A1-6"), "#A1-6");
711 ci = new CacheItem ("key", "value");
712 cip = new CacheItemPolicy ();
713 cip.SlidingExpiration = TimeSpan.FromDays (500);
714 AssertExtensions.Throws<ArgumentOutOfRangeException> (() => {
718 ci = new CacheItem ("key_A1-8", "value");
719 cip = new CacheItemPolicy ();
720 cip.SlidingExpiration = TimeSpan.FromDays (365);
722 Assert.IsTrue (mc.Contains ("key_A1-8"), "#A1-8");
724 ci = new CacheItem ("key", "value");
725 cip = new CacheItemPolicy ();
726 cip.Priority = (CacheItemPriority) 20;
727 AssertExtensions.Throws<ArgumentOutOfRangeException> (() => {
731 ci = new CacheItem ("key_A2", "value_A2");
732 cip = new CacheItemPolicy ();
733 cip.RemovedCallback = (CacheEntryRemovedArguments arguments) => { };
735 Assert.IsTrue (mc.Contains ("key_A2"), "#A2");
737 ci = new CacheItem ("key_A3", "value_A3");
738 mc.Set (ci, new CacheItemPolicy ());
739 Assert.IsTrue (mc.Contains ("key_A3"), "#A3-1");
740 Assert.AreEqual ("value_A3", mc.Get ("key_A3"), "#A3-2");
742 // The entry is never inserted as its expiration date is before now
743 ci = new CacheItem ("key_A4", "value");
744 cip = new CacheItemPolicy ();
745 cip.AbsoluteExpiration = DateTimeOffset.MinValue;
747 Assert.IsFalse (mc.Contains ("key_A4"), "#A4");
749 ci = new CacheItem ("key_A5", "value");
751 mc.Set (ci, new CacheItemPolicy ());
753 Assert.AreEqual (2, mc.Calls.Count, "#A5-1");
754 Assert.AreEqual ("Set (CacheItem item, CacheItemPolicy policy)", mc.Calls [0], "#A5-2");
755 Assert.AreEqual ("Set (string key, object value, CacheItemPolicy policy, string regionName = null)", mc.Calls [1], "#A5-3");
759 public void Remove ()
761 var mc = new PokerMemoryCache ("MyCache");
763 AssertExtensions.Throws<NotSupportedException> (() => {
764 mc.Remove ("key", "region");
767 AssertExtensions.Throws<ArgumentNullException> (() => {
771 bool callbackInvoked;
772 CacheEntryRemovedReason reason = (CacheEntryRemovedReason) 1000;
773 var cip = new CacheItemPolicy ();
774 cip.Priority = CacheItemPriority.NotRemovable;
775 mc.Set ("key2", "value1", cip);
776 object value = mc.Remove ("key2");
778 Assert.IsNotNull (value, "#B1-1");
779 Assert.IsFalse (mc.Contains ("key2"), "#B1-2");
781 cip = new CacheItemPolicy ();
782 cip.RemovedCallback = (CacheEntryRemovedArguments args) => {
783 callbackInvoked = true;
784 reason = args.RemovedReason;
787 mc.Set ("key", "value", cip);
788 callbackInvoked = false;
789 reason = (CacheEntryRemovedReason) 1000;
790 value = mc.Remove ("key");
791 Assert.IsNotNull (value, "#C1-1");
792 Assert.IsTrue (callbackInvoked, "#C1-2");
793 Assert.AreEqual (CacheEntryRemovedReason.Removed, reason, "#C1-3");
795 cip = new CacheItemPolicy ();
796 cip.RemovedCallback = (CacheEntryRemovedArguments args) => {
797 callbackInvoked = true;
798 reason = args.RemovedReason;
799 throw new ApplicationException ("test");
802 mc.Set ("key", "value", cip);
803 callbackInvoked = false;
804 reason = (CacheEntryRemovedReason) 1000;
805 value = mc.Remove ("key");
806 Assert.IsNotNull (value, "#C2-1");
807 Assert.IsTrue (callbackInvoked, "#C2-2");
808 Assert.AreEqual (CacheEntryRemovedReason.Removed, reason, "#C2-3");
810 // LAMESPEC: UpdateCallback is not called on remove
811 cip = new CacheItemPolicy ();
812 cip.UpdateCallback = (CacheEntryUpdateArguments args) => {
813 callbackInvoked = true;
814 reason = args.RemovedReason;
817 mc.Set ("key", "value", cip);
818 callbackInvoked = false;
819 reason = (CacheEntryRemovedReason) 1000;
820 value = mc.Remove ("key");
821 Assert.IsNotNull (value, "#D1-1");
822 Assert.IsFalse (callbackInvoked, "#D1-2");
824 cip = new CacheItemPolicy ();
825 cip.UpdateCallback = (CacheEntryUpdateArguments args) => {
826 callbackInvoked = true;
827 reason = args.RemovedReason;
828 throw new ApplicationException ("test");
831 mc.Set ("key", "value", cip);
832 callbackInvoked = false;
833 reason = (CacheEntryRemovedReason) 1000;
834 value = mc.Remove ("key");
835 Assert.IsNotNull (value, "#D2-1");
836 Assert.IsFalse (callbackInvoked, "#D2-2");
840 public void TimedExpiration ()
842 bool expired = false;
843 CacheEntryRemovedReason reason = CacheEntryRemovedReason.CacheSpecificEviction;
844 NameValueCollection config;
847 config = new NameValueCollection ();
848 config.Add ("__MonoTimerPeriod", "1");
852 sleepPeriod = 20100; // 20s is the .NET period - discovered by experimentation
854 var mc = new PokerMemoryCache ("MyCache", config);
855 var cip = new CacheItemPolicy ();
857 cip.RemovedCallback = (CacheEntryRemovedArguments args) => {
859 reason = args.RemovedReason;
861 cip.AbsoluteExpiration = DateTimeOffset.Now.AddMilliseconds (50);
862 mc.Set ("key", "value", cip);
865 Assert.IsFalse (expired, "#A1");
866 object value = mc.Get ("key");
868 Assert.IsNull (value, "#A2-1");
869 Assert.IsTrue (expired, "#A2-2");
870 Assert.AreEqual (CacheEntryRemovedReason.Expired, reason, "A2-3");
873 cip = new CacheItemPolicy ();
874 cip.RemovedCallback = (CacheEntryRemovedArguments args) => {
876 reason = args.RemovedReason;
878 cip.AbsoluteExpiration = DateTimeOffset.Now.AddMilliseconds (50);
879 mc.Set ("key", "value", cip);
880 Thread.Sleep (sleepPeriod);
882 Assert.IsTrue (expired, "#A3-1");
883 Assert.AreEqual (CacheEntryRemovedReason.Expired, reason, "#A3-2");
885 int expiredCount = 0;
886 object expiredCountLock = new object ();
887 CacheEntryRemovedCallback removedCb = (CacheEntryRemovedArguments args) => {
888 lock (expiredCountLock) {
893 cip = new CacheItemPolicy ();
894 cip.RemovedCallback = removedCb;
895 cip.AbsoluteExpiration = DateTimeOffset.Now.AddMilliseconds (20);
896 mc.Set ("key1", "value1", cip);
898 cip = new CacheItemPolicy ();
899 cip.RemovedCallback = removedCb;
900 cip.AbsoluteExpiration = DateTimeOffset.Now.AddMilliseconds (200);
901 mc.Set ("key2", "value2", cip);
903 cip = new CacheItemPolicy ();
904 cip.RemovedCallback = removedCb;
905 cip.AbsoluteExpiration = DateTimeOffset.Now.AddMilliseconds (600);
906 mc.Set ("key3", "value3", cip);
908 cip = new CacheItemPolicy ();
909 cip.RemovedCallback = removedCb;
910 cip.AbsoluteExpiration = DateTimeOffset.Now.AddMilliseconds (sleepPeriod + 100);
911 mc.Set ("key4", "value4", cip);
913 Thread.Sleep (sleepPeriod);
914 Assert.AreEqual (3, expiredCount, "#A4");
918 public void GetEnumerator ()
920 var mc = new PokerMemoryCache ("MyCache");
922 // This one is a Hashtable enumerator
923 IEnumerator enumerator = ((IEnumerable) mc).GetEnumerator ();
925 // This one is a Dictionary <string, object> enumerator
926 IEnumerator enumerator2 = mc.DoGetEnumerator ();
928 Assert.IsNotNull (enumerator, "#A1-1");
929 Assert.IsNotNull (enumerator2, "#A1-2");
930 Assert.IsTrue (enumerator.GetType () != enumerator2.GetType (), "#A1-3");
932 mc.Set ("key1", "value1", null);
933 mc.Set ("key2", "value2", null);
934 mc.Set ("key3", "value3", null);
936 bool expired = false;
937 var cip = new CacheItemPolicy ();
938 cip.AbsoluteExpiration = DateTime.Now.AddMilliseconds (50);
939 cip.RemovedCallback = (CacheEntryRemovedArguments args) => {
943 mc.Set ("key4", "value4", cip);
946 enumerator = ((IEnumerable) mc).GetEnumerator ();
948 while (enumerator.MoveNext ()) {
952 Assert.IsFalse (expired, "#A2-1");
953 Assert.AreEqual (3, count, "#A2-2");
956 cip = new CacheItemPolicy ();
957 cip.AbsoluteExpiration = DateTime.Now.AddMilliseconds (50);
958 cip.RemovedCallback = (CacheEntryRemovedArguments args) => {
962 mc.Set ("key5", "value5", cip);
965 enumerator2 = mc.DoGetEnumerator ();
967 while (enumerator2.MoveNext ()) {
971 Assert.IsFalse (expired, "#A3-1");
972 Assert.AreEqual (3, count, "#A3-2");
976 public void GetValues ()
978 var mc = new PokerMemoryCache ("MyCache");
980 AssertExtensions.Throws<ArgumentNullException> (() => {
984 AssertExtensions.Throws<NotSupportedException> (() => {
985 mc.GetValues (new string[] {}, "region");
988 AssertExtensions.Throws<ArgumentException> (() => {
989 mc.GetValues (new string [] { "key", null });
992 IDictionary<string, object> value = mc.GetValues (new string[] {});
993 Assert.IsNull (value, "#A2");
995 mc.Set ("key1", "value1", null);
996 mc.Set ("key2", "value2", null);
997 mc.Set ("key3", "value3", null);
999 Assert.IsTrue (mc.Contains ("key1"), "#A3-1");
1000 Assert.IsTrue (mc.Contains ("key2"), "#A3-2");
1001 Assert.IsTrue (mc.Contains ("key3"), "#A3-2");
1003 value = mc.GetValues (new string [] { "key1", "key3" });
1004 Assert.IsNotNull (value, "#A4-1");
1005 Assert.AreEqual (2, value.Count, "#A4-2");
1006 Assert.AreEqual ("value1", value ["key1"], "#A4-3");
1007 Assert.AreEqual ("value3", value ["key3"], "#A4-4");
1008 Assert.AreEqual (typeof (Dictionary<string, object>), value.GetType (), "#A4-5");
1010 // LAMESPEC: MSDN says the number of items in the returned dictionary should be the same as in the
1011 // 'keys' collection - this is not the case. The returned dictionary contains only entries for keys
1012 // that exist in the cache.
1013 value = mc.GetValues (new string [] { "key1", "key3", "nosuchkey" });
1014 Assert.IsNotNull (value, "#A5-1");
1015 Assert.AreEqual (2, value.Count, "#A5-2");
1016 Assert.AreEqual ("value1", value ["key1"], "#A5-3");
1017 Assert.AreEqual ("value3", value ["key3"], "#A5-4");
1018 Assert.IsFalse (value.ContainsKey ("Key1"), "#A5-5");
1024 var mc = new PokerMemoryCache ("MyCache");
1026 AssertExtensions.Throws<NotSupportedException> (() => {
1027 mc.Get ("key", "region");
1030 AssertExtensions.Throws<ArgumentNullException> (() => {
1035 mc.Set ("key", "value", null);
1036 value = mc.Get ("key");
1037 Assert.IsNotNull (value, "#A2-1");
1038 Assert.AreEqual ("value", value, "#A2-2");
1040 value = mc.Get ("nosuchkey");
1041 Assert.IsNull (value, "#A3");
1043 var cip = new CacheItemPolicy ();
1044 bool callbackInvoked;
1045 CacheEntryRemovedReason reason = (CacheEntryRemovedReason)1000;
1047 cip.AbsoluteExpiration = DateTimeOffset.Now.AddMilliseconds (50);
1048 cip.RemovedCallback = (CacheEntryRemovedArguments args) => {
1049 callbackInvoked = true;
1050 reason = args.RemovedReason;
1052 mc.Set ("key", "value", cip);
1055 callbackInvoked = false;
1056 reason = (CacheEntryRemovedReason) 1000;
1057 value = mc.Get ("key");
1058 Assert.IsNull (value, "#B1-1");
1059 Assert.IsTrue (callbackInvoked, "#B1-2");
1060 Assert.AreEqual (CacheEntryRemovedReason.Expired, reason, "#B1-3");
1062 cip = new CacheItemPolicy ();
1063 cip.AbsoluteExpiration = DateTimeOffset.Now.AddMilliseconds (50);
1064 cip.RemovedCallback = (CacheEntryRemovedArguments args) => {
1065 callbackInvoked = true;
1066 reason = args.RemovedReason;
1067 throw new ApplicationException ("test");
1070 mc.Set ("key", "value", cip);
1073 callbackInvoked = false;
1074 reason = (CacheEntryRemovedReason) 1000;
1075 value = mc.Get ("key");
1076 Assert.IsNull (value, "#B2-1");
1077 Assert.IsTrue (callbackInvoked, "#B2-2");
1078 Assert.AreEqual (CacheEntryRemovedReason.Expired, reason, "#B2-3");
1082 public void GetCacheItem ()
1084 var mc = new PokerMemoryCache ("MyCache");
1086 AssertExtensions.Throws<NotSupportedException> (() => {
1087 mc.GetCacheItem ("key", "region");
1090 AssertExtensions.Throws<ArgumentNullException> (() => {
1091 mc.GetCacheItem (null);
1095 mc.Set ("key", "value", null);
1096 value = mc.GetCacheItem ("key");
1097 Assert.IsNotNull (value, "#A2-1");
1098 Assert.AreEqual ("value", value.Value, "#A2-2");
1099 Assert.AreEqual ("key", value.Key, "#A2-3");
1101 value = mc.GetCacheItem ("doesnotexist");
1102 Assert.IsNull (value, "#A3");
1104 var cip = new CacheItemPolicy ();
1105 bool callbackInvoked;
1106 CacheEntryRemovedReason reason = (CacheEntryRemovedReason) 1000;
1108 cip.AbsoluteExpiration = DateTimeOffset.Now.AddMilliseconds (50);
1109 cip.RemovedCallback = (CacheEntryRemovedArguments args) => {
1110 callbackInvoked = true;
1111 reason = args.RemovedReason;
1113 mc.Set ("key", "value", cip);
1116 callbackInvoked = false;
1117 reason = (CacheEntryRemovedReason) 1000;
1118 value = mc.GetCacheItem ("key");
1119 Assert.IsNull (value, "#B1-1");
1120 Assert.IsTrue (callbackInvoked, "#B1-2");
1121 Assert.AreEqual (CacheEntryRemovedReason.Expired, reason, "#B1-3");
1123 cip = new CacheItemPolicy ();
1124 cip.AbsoluteExpiration = DateTimeOffset.Now.AddMilliseconds (50);
1125 cip.RemovedCallback = (CacheEntryRemovedArguments args) => {
1126 callbackInvoked = true;
1127 reason = args.RemovedReason;
1128 throw new ApplicationException ("test");
1131 mc.Set ("key", "value", cip);
1134 callbackInvoked = false;
1135 reason = (CacheEntryRemovedReason) 1000;
1136 value = mc.GetCacheItem ("key");
1137 Assert.IsNull (value, "#B2-1");
1138 Assert.IsTrue (callbackInvoked, "#B2-2");
1139 Assert.AreEqual (CacheEntryRemovedReason.Expired, reason, "#B2-3");
1143 public void ChangeMonitors ()
1145 bool removed = false;
1146 var mc = new PokerMemoryCache ("MyCache");
1147 var cip = new CacheItemPolicy ();
1148 var monitor = new PokerChangeMonitor ();
1149 cip.ChangeMonitors.Add (monitor);
1150 cip.RemovedCallback = (CacheEntryRemovedArguments args) => {
1154 mc.Set ("key", "value", cip);
1155 Assert.AreEqual (0, monitor.Calls.Count, "#A1");
1157 monitor.SignalChange ();
1158 Assert.IsTrue (removed, "#A2");
1160 bool onChangedCalled = false;
1161 monitor = new PokerChangeMonitor ();
1162 monitor.NotifyOnChanged ((object state) => {
1163 onChangedCalled = true;
1166 cip = new CacheItemPolicy ();
1167 cip.ChangeMonitors.Add (monitor);
1169 // Thrown by ChangeMonitor.NotifyOnChanged
1170 AssertExtensions.Throws<InvalidOperationException> (() => {
1171 mc.Set ("key1", "value1", cip);
1175 // NOTE: on Windows with 2 or more CPUs this test will most probably fail.
1179 var config = new NameValueCollection ();
1180 config ["__MonoEmulateOneCPU"] = "true";
1181 var mc = new MemoryCache ("MyCache", config);
1183 for (int i = 0; i < 10; i++)
1184 mc.Set ("key" + i.ToString (), "value" + i.ToString (), null);
1186 // .NET doesn't touch the freshest 10 entries
1187 Assert.AreEqual (10, mc.GetCount (), "#A1-1");
1188 long trimmed = mc.Trim (50);
1189 Assert.AreEqual (0, trimmed, "#A1-2");
1190 Assert.AreEqual (10, mc.GetCount (), "#A1-3");
1192 mc = new MemoryCache ("MyCache", config);
1193 // Only entries 11- are considered for removal
1194 for (int i = 0; i < 11; i++)
1195 mc.Set ("key" + i.ToString (), "value" + i.ToString (), null);
1197 Assert.AreEqual (11, mc.GetCount (), "#A2-1");
1198 trimmed = mc.Trim (50);
1199 Assert.AreEqual (1, trimmed, "#A2-2");
1200 Assert.AreEqual (10, mc.GetCount (), "#A2-3");
1202 mc = new MemoryCache ("MyCache", config);
1203 // Only entries 11- are considered for removal
1204 for (int i = 0; i < 125; i++)
1205 mc.Set ("key" + i.ToString (), "value" + i.ToString (), null);
1207 Assert.AreEqual (125, mc.GetCount (), "#A3-1");
1208 trimmed = mc.Trim (50);
1209 Assert.AreEqual (62, trimmed, "#A3-2");
1210 Assert.AreEqual (63, mc.GetCount (), "#A3-3");
1212 // Testing the removal order
1213 mc = new MemoryCache ("MyCache", config);
1214 var removed = new List <string> ();
1215 var cip = new CacheItemPolicy ();
1216 cip.RemovedCallback = (CacheEntryRemovedArguments args) => {
1217 removed.Add (args.CacheItem.Key);
1220 for (int i = 0; i < 50; i++)
1221 mc.Set ("key" + i.ToString (), "value" + i.ToString (), cip);
1224 for (int i = 0; i < 50; i++)
1225 value = mc.Get ("key" + i.ToString ());
1227 trimmed = mc.Trim (50);
1228 Assert.AreEqual (25, mc.GetCount (), "#A4-1");
1229 Assert.AreEqual (25, trimmed, "#A4-2");
1230 Assert.AreEqual (25, removed.Count, "#A4-3");
1232 // OK, this is odd... The list is correct in terms of entries removed but the entries
1233 // are removed in the _MOST_ frequently used order, within the group selected for removal.
1234 for (int i = 24; i >= 0; i--) {
1236 Assert.AreEqual ("key" + i.ToString (), removed [idx], "#A5-" + idx.ToString ());