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 monitor = mc.CreateCacheEntryChangeMonitor (new string [] { "key1", "doesnotexist" });
309 Assert.IsNotNull (monitor, "#A3-1");
310 Assert.AreEqual ("System.Runtime.Caching.MemoryCacheEntryChangeMonitor", monitor.GetType ().ToString (), "#A3-2");
311 Assert.AreEqual (1, monitor.CacheKeys.Count, "#A3-3");
312 Assert.AreEqual ("key1", monitor.CacheKeys [0], "#A3-3-1");
313 Assert.IsNull (monitor.RegionName, "#A3-4");
314 Assert.IsTrue (monitor.HasChanged, "#A3-5");
319 public void AddOrGetExisting_String_Object_DateTimeOffset_String ()
321 var mc = new PokerMemoryCache ("MyCache");
323 AssertExtensions.Throws<ArgumentNullException> (() => {
324 mc.AddOrGetExisting (null, "value", DateTimeOffset.Now);
327 AssertExtensions.Throws<ArgumentNullException> (() => {
328 mc.AddOrGetExisting ("key", null, DateTimeOffset.Now);
331 AssertExtensions.Throws<NotSupportedException> (() => {
332 mc.AddOrGetExisting ("key", "value", DateTimeOffset.Now, "region");
335 object value = mc.AddOrGetExisting ("key3_A2-1", "value", DateTimeOffset.Now.AddMinutes (1));
336 Assert.IsTrue (mc.Contains ("key3_A2-1"), "#A2-1");
337 Assert.IsNull (value, "#A2-2");
340 value = mc.AddOrGetExisting ("key3_A2-1", "value2", DateTimeOffset.Now.AddMinutes (1));
341 Assert.IsTrue (mc.Contains ("key3_A2-1"), "#A3-1");
342 Assert.IsNotNull (value, "#A3-2");
343 Assert.AreEqual ("value", value, "#A3-3");
344 Assert.AreEqual (2, mc.Calls.Count, "#A3-4");
345 Assert.AreEqual ("AddOrGetExisting (string key, object value, DateTimeOffset absoluteExpiration, string regionName = null)", mc.Calls [0], "#A3-5");
347 value = mc.AddOrGetExisting ("key_expired", "value", DateTimeOffset.MinValue);
348 Assert.IsFalse (mc.Contains ("key_expired"), "#A4-1");
349 Assert.IsNull (value, "#A4-1");
353 public void AddOrGetExisting_String_Object_CacheItemPolicy_String ()
355 var mc = new PokerMemoryCache ("MyCache");
357 AssertExtensions.Throws<ArgumentNullException> (() => {
358 mc.AddOrGetExisting (null, "value", null);
361 AssertExtensions.Throws<ArgumentNullException> (() => {
362 mc.AddOrGetExisting ("key", null, null);
365 var cip = new CacheItemPolicy ();
366 cip.AbsoluteExpiration = DateTime.Now.AddMinutes (1);
367 cip.SlidingExpiration = TimeSpan.FromMinutes (1);
369 AssertExtensions.Throws<ArgumentException> (() => {
370 mc.AddOrGetExisting ("key", "value", cip);
373 cip = new CacheItemPolicy ();
374 cip.SlidingExpiration = TimeSpan.MinValue;
375 AssertExtensions.Throws<ArgumentOutOfRangeException> (() => {
376 mc.AddOrGetExisting ("key3", "value", cip);
379 AssertExtensions.Throws<NotSupportedException> (() => {
380 mc.AddOrGetExisting ("key", "value", null, "region");
383 cip = new CacheItemPolicy ();
384 cip.SlidingExpiration = TimeSpan.FromDays (500);
385 AssertExtensions.Throws<ArgumentOutOfRangeException> (() => {
386 mc.AddOrGetExisting ("key3", "value", cip);
389 cip = new CacheItemPolicy ();
390 cip.Priority = (CacheItemPriority) 20;
391 AssertExtensions.Throws<ArgumentOutOfRangeException> (() => {
392 mc.AddOrGetExisting ("key3", "value", cip);
395 cip = new CacheItemPolicy ();
396 cip.SlidingExpiration = TimeSpan.FromTicks (0L);
397 mc.AddOrGetExisting ("key3_A2-1", "value", cip);
398 Assert.IsTrue (mc.Contains ("key3_A2-1"), "#A2-1");
400 cip = new CacheItemPolicy ();
401 cip.SlidingExpiration = TimeSpan.FromDays (365);
402 mc.AddOrGetExisting ("key3_A2-2", "value", cip);
403 Assert.IsTrue (mc.Contains ("key3_A2-2"), "#A2-2");
405 cip = new CacheItemPolicy ();
406 cip.RemovedCallback = (CacheEntryRemovedArguments arguments) => { };
407 object value = mc.AddOrGetExisting ("key3_A2-3", "value", cip);
408 Assert.IsTrue (mc.Contains ("key3_A2-3"), "#A2-3");
409 Assert.IsNull (value, "#A2-4");
412 value = mc.AddOrGetExisting ("key3_A2-3", "value2", null);
413 Assert.IsTrue (mc.Contains ("key3_A2-3"), "#A3-1");
414 Assert.IsNotNull (value, "#A3-2");
415 Assert.AreEqual ("value", value, "#A3-3");
416 Assert.AreEqual (2, mc.Calls.Count, "#A3-4");
417 Assert.AreEqual ("AddOrGetExisting (string key, object value, CacheItemPolicy policy, string regionName = null)", mc.Calls [0], "#A3-5");
419 cip = new CacheItemPolicy ();
420 cip.AbsoluteExpiration = DateTimeOffset.MinValue;
421 value = mc.AddOrGetExisting ("key_expired", "value", cip);
422 Assert.IsFalse (mc.Contains ("key_expired"), "#A4-1");
423 Assert.IsNull (value, "#A4-1");
427 public void AddOrGetExisting_CacheItem_CacheItemPolicy ()
429 var mc = new PokerMemoryCache ("MyCache");
432 AssertExtensions.Throws<ArgumentNullException> (() => {
433 ci = mc.AddOrGetExisting (null, new CacheItemPolicy ());
436 ci = new CacheItem ("key", "value");
437 ci2 = mc.AddOrGetExisting (ci, null);
439 // LAMESPEC: MSDN says it should return null if the entry does not exist yet.
441 Assert.IsNotNull (ci2, "#A2-1");
442 Assert.AreNotEqual (ci, ci2, "#A2-2");
443 Assert.IsNull (ci2.Value, "#A2-3");
444 Assert.IsTrue (mc.Contains (ci.Key), "#A2-4");
445 Assert.AreEqual (ci.Key, ci2.Key, "#A2-5");
447 ci = new CacheItem ("key", "value");
448 ci2 = mc.AddOrGetExisting (ci, null);
449 Assert.IsNotNull (ci2, "#A3-1");
450 Assert.AreNotEqual (ci, ci2, "#A3-2");
451 Assert.IsNotNull (ci2.Value, "#A3-3");
452 Assert.AreEqual (ci.Value, ci2.Value, "#A3-4");
453 Assert.AreEqual (ci.Key, ci2.Key, "#A3-5");
455 AssertExtensions.Throws<ArgumentNullException> (() => {
456 ci = new CacheItem (null, "value");
457 ci2 = mc.AddOrGetExisting (ci, null);
460 ci = new CacheItem (String.Empty, "value");
461 ci2 = mc.AddOrGetExisting (ci, null);
462 Assert.IsNotNull (ci2, "#A5-1");
463 Assert.AreNotEqual (ci, ci2, "#A5-2");
464 Assert.IsNull (ci2.Value, "#A5-3");
465 Assert.IsTrue (mc.Contains (ci.Key), "#A5-4");
466 Assert.AreEqual (ci.Key, ci2.Key, "#A5-5");
468 ci = new CacheItem ("key2", null);
471 // at System.Runtime.Caching.MemoryCacheEntry..ctor(String key, Object value, DateTimeOffset absExp, TimeSpan slidingExp, CacheItemPriority priority, Collection`1 dependencies, CacheEntryRemovedCallback removedCallback, MemoryCache cache)
472 // at System.Runtime.Caching.MemoryCache.AddOrGetExistingInternal(String key, Object value, CacheItemPolicy policy)
473 // at System.Runtime.Caching.MemoryCache.AddOrGetExisting(CacheItem item, CacheItemPolicy policy)
474 // 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
475 AssertExtensions.Throws<ArgumentNullException> (() => {
476 ci2 = mc.AddOrGetExisting (ci, null);
479 ci = new CacheItem ("key3", "value");
480 var cip = new CacheItemPolicy ();
481 cip.UpdateCallback = (CacheEntryUpdateArguments arguments) => { };
482 AssertExtensions.Throws<ArgumentException> (() => {
483 ci2 = mc.AddOrGetExisting (ci, cip);
486 ci = new CacheItem ("key3", "value");
487 cip = new CacheItemPolicy ();
488 cip.AbsoluteExpiration = DateTimeOffset.Now;
489 cip.SlidingExpiration = TimeSpan.FromTicks (DateTime.Now.Ticks);
490 AssertExtensions.Throws<ArgumentException> (() => {
491 mc.AddOrGetExisting (ci, cip);
494 ci = new CacheItem ("key3", "value");
495 cip = new CacheItemPolicy ();
496 cip.SlidingExpiration = TimeSpan.MinValue;
497 AssertExtensions.Throws<ArgumentOutOfRangeException> (() => {
498 mc.AddOrGetExisting (ci, cip);
501 ci = new CacheItem ("key4_#B4-2", "value");
502 cip = new CacheItemPolicy ();
503 cip.SlidingExpiration = TimeSpan.FromTicks (0L);
504 mc.AddOrGetExisting (ci, cip);
505 Assert.IsTrue (mc.Contains ("key4_#B4-2"), "#B4-2");
507 ci = new CacheItem ("key3", "value");
508 cip = new CacheItemPolicy ();
509 cip.SlidingExpiration = TimeSpan.FromDays (500);
510 AssertExtensions.Throws<ArgumentOutOfRangeException> (() => {
511 mc.AddOrGetExisting (ci, cip);
514 ci = new CacheItem ("key5_#B5-2", "value");
515 cip = new CacheItemPolicy ();
516 cip.SlidingExpiration = TimeSpan.FromDays (365);
517 mc.AddOrGetExisting (ci, cip);
518 Assert.IsTrue (mc.Contains ("key5_#B5-2"), "#B5-2");
520 ci = new CacheItem ("key3", "value");
521 cip = new CacheItemPolicy ();
522 cip.Priority = (CacheItemPriority)20;
523 AssertExtensions.Throws<ArgumentOutOfRangeException> (() => {
524 mc.AddOrGetExisting (ci, cip);
527 ci = new CacheItem ("key3_B7", "value");
528 cip = new CacheItemPolicy ();
529 cip.RemovedCallback = (CacheEntryRemovedArguments arguments) => { };
530 ci2 = mc.AddOrGetExisting (ci, cip);
531 Assert.IsTrue (mc.Contains ("key3_B7"), "#B7");
533 // LAMESPEC: MSDN says it should return null if the entry does not exist yet.
535 Assert.IsNotNull (ci2, "#C1-1");
536 Assert.AreNotEqual (ci, ci2, "#C1-2");
537 Assert.IsNull (ci2.Value, "#C1-3");
538 Assert.IsTrue (mc.Contains (ci.Key), "#C1-4");
539 Assert.AreEqual (ci.Key, ci2.Key, "#C1-5");
541 // The entry is never inserted as its expiration date is before now
542 ci = new CacheItem ("key_D1", "value_D1");
543 cip = new CacheItemPolicy ();
544 cip.AbsoluteExpiration = DateTimeOffset.MinValue;
545 ci2 = mc.AddOrGetExisting (ci, cip);
546 Assert.IsFalse (mc.Contains ("key_D1"), "#D1-1");
547 Assert.IsNotNull (ci2, "#D1-2");
548 Assert.IsNull (ci2.Value, "#D1-3");
549 Assert.AreEqual ("key_D1", ci2.Key, "#D1-4");
552 ci = new CacheItem ("key_D2", "value_D2");
553 cip = new CacheItemPolicy ();
554 cip.AbsoluteExpiration = DateTimeOffset.MaxValue;
555 mc.AddOrGetExisting (ci, cip);
556 Assert.IsTrue (mc.Contains ("key_D2"), "#D2-1");
557 Assert.AreEqual (2, mc.Calls.Count, "#D2-2");
558 Assert.AreEqual ("AddOrGetExisting (CacheItem item, CacheItemPolicy policy)", mc.Calls [0], "#D2-3");
562 public void Set_String_Object_CacheItemPolicy_String ()
564 var mc = new PokerMemoryCache ("MyCache");
566 AssertExtensions.Throws<NotSupportedException> (() => {
567 mc.Set ("key", "value", new CacheItemPolicy (), "region");
570 AssertExtensions.Throws<ArgumentNullException> (() => {
571 mc.Set (null, "value", new CacheItemPolicy ());
574 AssertExtensions.Throws<ArgumentNullException> (() => {
575 mc.Set ("key", null, new CacheItemPolicy ());
578 var cip = new CacheItemPolicy ();
579 cip.UpdateCallback = (CacheEntryUpdateArguments arguments) => { };
580 cip.RemovedCallback = (CacheEntryRemovedArguments arguments) => { };
581 AssertExtensions.Throws<ArgumentException> (() => {
582 mc.Set ("key", "value", cip);
585 cip = new CacheItemPolicy ();
586 cip.SlidingExpiration = TimeSpan.MinValue;
587 AssertExtensions.Throws<ArgumentOutOfRangeException> (() => {
588 mc.Set ("key", "value", cip);
591 cip = new CacheItemPolicy ();
592 cip.SlidingExpiration = TimeSpan.FromTicks (0L);
593 mc.Set ("key_A1-6", "value", cip);
594 Assert.IsTrue (mc.Contains ("key_A1-6"), "#A1-6");
596 cip = new CacheItemPolicy ();
597 cip.SlidingExpiration = TimeSpan.FromDays (500);
598 AssertExtensions.Throws<ArgumentOutOfRangeException> (() => {
599 mc.Set ("key", "value", cip);
602 cip = new CacheItemPolicy ();
603 cip.SlidingExpiration = TimeSpan.FromDays (365);
604 mc.Set ("key_A1-8", "value", cip);
605 Assert.IsTrue (mc.Contains ("key_A1-8"), "#A1-8");
607 cip = new CacheItemPolicy ();
608 cip.Priority = (CacheItemPriority) 20;
609 AssertExtensions.Throws<ArgumentOutOfRangeException> (() => {
610 mc.Set ("key", "value", cip);
613 cip = new CacheItemPolicy ();
614 cip.RemovedCallback = (CacheEntryRemovedArguments arguments) => { };
615 mc.Set ("key_A2", "value_A2", cip);
616 Assert.IsTrue (mc.Contains ("key_A2"), "#A2");
618 mc.Set ("key_A3", "value_A3", new CacheItemPolicy ());
619 Assert.IsTrue (mc.Contains ("key_A3"), "#A3-1");
620 Assert.AreEqual ("value_A3", mc.Get ("key_A3"), "#A3-2");
622 // The entry is never inserted as its expiration date is before now
623 cip = new CacheItemPolicy ();
624 cip.AbsoluteExpiration = DateTimeOffset.MinValue;
625 mc.Set ("key_A4", "value_A4", cip);
626 Assert.IsFalse (mc.Contains ("key_A4"), "#A4");
629 cip = new CacheItemPolicy ();
630 cip.AbsoluteExpiration = DateTimeOffset.MaxValue;
631 mc.Set ("key_A5", "value_A5", cip);
632 Assert.IsTrue (mc.Contains ("key_A5"), "#A5-1");
633 Assert.AreEqual (2, mc.Calls.Count, "#A5-2");
634 Assert.AreEqual ("Set (string key, object value, CacheItemPolicy policy, string regionName = null)", mc.Calls [0], "#A5-3");
638 public void Set_String_Object_DateTimeOffset_String ()
640 var mc = new PokerMemoryCache ("MyCache");
642 AssertExtensions.Throws<NotSupportedException> (() => {
643 mc.Set ("key", "value", DateTimeOffset.MaxValue, "region");
646 AssertExtensions.Throws<ArgumentNullException> (() => {
647 mc.Set (null, "value", DateTimeOffset.MaxValue);
650 AssertExtensions.Throws<ArgumentNullException> (() => {
651 mc.Set ("key", null, DateTimeOffset.MaxValue);
654 // The entry is never inserted as its expiration date is before now
655 mc.Set ("key_A2", "value_A2", DateTimeOffset.MinValue);
656 Assert.IsFalse (mc.Contains ("key_A2"), "#A2");
659 mc.Set ("key", "value", DateTimeOffset.MaxValue);
661 Assert.AreEqual (2, mc.Calls.Count, "#A2-1");
662 Assert.AreEqual ("Set (string key, object value, DateTimeOffset absoluteExpiration, string regionName = null)", mc.Calls [0], "#A2-2");
663 Assert.AreEqual ("Set (string key, object value, CacheItemPolicy policy, string regionName = null)", mc.Calls [1], "#A2-3");
667 public void Set_CacheItem_CacheItemPolicy ()
669 var mc = new PokerMemoryCache ("MyCache");
671 AssertExtensions.Throws<ArgumentNullException> (() => {
672 mc.Set (null, new CacheItemPolicy ());
675 // Actually thrown from the Set (string, object, CacheItemPolicy, string) overload
676 var ci = new CacheItem (null, "value");
677 AssertExtensions.Throws<ArgumentNullException> (() => {
678 mc.Set (ci, new CacheItemPolicy ());
681 ci = new CacheItem ("key", null);
682 AssertExtensions.Throws<ArgumentNullException> (() => {
683 mc.Set (ci, new CacheItemPolicy ());
686 ci = new CacheItem ("key", "value");
687 var cip = new CacheItemPolicy ();
688 cip.UpdateCallback = (CacheEntryUpdateArguments arguments) => { };
689 cip.RemovedCallback = (CacheEntryRemovedArguments arguments) => { };
690 AssertExtensions.Throws<ArgumentException> (() => {
694 ci = new CacheItem ("key", "value");
695 cip = new CacheItemPolicy ();
696 cip.SlidingExpiration = TimeSpan.MinValue;
697 AssertExtensions.Throws<ArgumentOutOfRangeException> (() => {
701 ci = new CacheItem ("key_A1-6", "value");
702 cip = new CacheItemPolicy ();
703 cip.SlidingExpiration = TimeSpan.FromTicks (0L);
705 Assert.IsTrue (mc.Contains ("key_A1-6"), "#A1-6");
707 ci = new CacheItem ("key", "value");
708 cip = new CacheItemPolicy ();
709 cip.SlidingExpiration = TimeSpan.FromDays (500);
710 AssertExtensions.Throws<ArgumentOutOfRangeException> (() => {
714 ci = new CacheItem ("key_A1-8", "value");
715 cip = new CacheItemPolicy ();
716 cip.SlidingExpiration = TimeSpan.FromDays (365);
718 Assert.IsTrue (mc.Contains ("key_A1-8"), "#A1-8");
720 ci = new CacheItem ("key", "value");
721 cip = new CacheItemPolicy ();
722 cip.Priority = (CacheItemPriority) 20;
723 AssertExtensions.Throws<ArgumentOutOfRangeException> (() => {
727 ci = new CacheItem ("key_A2", "value_A2");
728 cip = new CacheItemPolicy ();
729 cip.RemovedCallback = (CacheEntryRemovedArguments arguments) => { };
731 Assert.IsTrue (mc.Contains ("key_A2"), "#A2");
733 ci = new CacheItem ("key_A3", "value_A3");
734 mc.Set (ci, new CacheItemPolicy ());
735 Assert.IsTrue (mc.Contains ("key_A3"), "#A3-1");
736 Assert.AreEqual ("value_A3", mc.Get ("key_A3"), "#A3-2");
738 // The entry is never inserted as its expiration date is before now
739 ci = new CacheItem ("key_A4", "value");
740 cip = new CacheItemPolicy ();
741 cip.AbsoluteExpiration = DateTimeOffset.MinValue;
743 Assert.IsFalse (mc.Contains ("key_A4"), "#A4");
745 ci = new CacheItem ("key_A5", "value");
747 mc.Set (ci, new CacheItemPolicy ());
749 Assert.AreEqual (2, mc.Calls.Count, "#A5-1");
750 Assert.AreEqual ("Set (CacheItem item, CacheItemPolicy policy)", mc.Calls [0], "#A5-2");
751 Assert.AreEqual ("Set (string key, object value, CacheItemPolicy policy, string regionName = null)", mc.Calls [1], "#A5-3");
755 public void Remove ()
757 var mc = new PokerMemoryCache ("MyCache");
759 AssertExtensions.Throws<NotSupportedException> (() => {
760 mc.Remove ("key", "region");
763 AssertExtensions.Throws<ArgumentNullException> (() => {
767 bool callbackInvoked;
768 CacheEntryRemovedReason reason = (CacheEntryRemovedReason) 1000;
769 var cip = new CacheItemPolicy ();
770 cip.Priority = CacheItemPriority.NotRemovable;
771 mc.Set ("key2", "value1", cip);
772 object value = mc.Remove ("key2");
774 Assert.IsNotNull (value, "#B1-1");
775 Assert.IsFalse (mc.Contains ("key2"), "#B1-2");
777 cip = new CacheItemPolicy ();
778 cip.RemovedCallback = (CacheEntryRemovedArguments args) => {
779 callbackInvoked = true;
780 reason = args.RemovedReason;
783 mc.Set ("key", "value", cip);
784 callbackInvoked = false;
785 reason = (CacheEntryRemovedReason) 1000;
786 value = mc.Remove ("key");
787 Assert.IsNotNull (value, "#C1-1");
788 Assert.IsTrue (callbackInvoked, "#C1-2");
789 Assert.AreEqual (CacheEntryRemovedReason.Removed, reason, "#C1-3");
791 cip = new CacheItemPolicy ();
792 cip.RemovedCallback = (CacheEntryRemovedArguments args) => {
793 callbackInvoked = true;
794 reason = args.RemovedReason;
795 throw new ApplicationException ("test");
798 mc.Set ("key", "value", cip);
799 callbackInvoked = false;
800 reason = (CacheEntryRemovedReason) 1000;
801 value = mc.Remove ("key");
802 Assert.IsNotNull (value, "#C2-1");
803 Assert.IsTrue (callbackInvoked, "#C2-2");
804 Assert.AreEqual (CacheEntryRemovedReason.Removed, reason, "#C2-3");
806 // LAMESPEC: UpdateCallback is not called on remove
807 cip = new CacheItemPolicy ();
808 cip.UpdateCallback = (CacheEntryUpdateArguments args) => {
809 callbackInvoked = true;
810 reason = args.RemovedReason;
813 mc.Set ("key", "value", cip);
814 callbackInvoked = false;
815 reason = (CacheEntryRemovedReason) 1000;
816 value = mc.Remove ("key");
817 Assert.IsNotNull (value, "#D1-1");
818 Assert.IsFalse (callbackInvoked, "#D1-2");
820 cip = new CacheItemPolicy ();
821 cip.UpdateCallback = (CacheEntryUpdateArguments args) => {
822 callbackInvoked = true;
823 reason = args.RemovedReason;
824 throw new ApplicationException ("test");
827 mc.Set ("key", "value", cip);
828 callbackInvoked = false;
829 reason = (CacheEntryRemovedReason) 1000;
830 value = mc.Remove ("key");
831 Assert.IsNotNull (value, "#D2-1");
832 Assert.IsFalse (callbackInvoked, "#D2-2");
836 public void TimedExpiration ()
838 bool expired = false;
839 CacheEntryRemovedReason reason = CacheEntryRemovedReason.CacheSpecificEviction;
840 NameValueCollection config;
843 config = new NameValueCollection ();
844 config.Add ("__MonoTimerPeriod", "1");
848 sleepPeriod = 20100; // 20s is the .NET period - discovered by experimentation
850 var mc = new PokerMemoryCache ("MyCache", config);
851 var cip = new CacheItemPolicy ();
853 cip.RemovedCallback = (CacheEntryRemovedArguments args) => {
855 reason = args.RemovedReason;
857 cip.AbsoluteExpiration = DateTimeOffset.Now.AddMilliseconds (50);
858 mc.Set ("key", "value", cip);
861 Assert.IsFalse (expired, "#A1");
862 object value = mc.Get ("key");
864 Assert.IsNull (value, "#A2-1");
865 Assert.IsTrue (expired, "#A2-2");
866 Assert.AreEqual (CacheEntryRemovedReason.Expired, reason, "A2-3");
869 cip = new CacheItemPolicy ();
870 cip.RemovedCallback = (CacheEntryRemovedArguments args) => {
872 reason = args.RemovedReason;
874 cip.AbsoluteExpiration = DateTimeOffset.Now.AddMilliseconds (50);
875 mc.Set ("key", "value", cip);
876 Thread.Sleep (sleepPeriod);
878 Assert.IsTrue (expired, "#A3-1");
879 Assert.AreEqual (CacheEntryRemovedReason.Expired, reason, "#A3-2");
881 int expiredCount = 0;
882 object expiredCountLock = new object ();
883 CacheEntryRemovedCallback removedCb = (CacheEntryRemovedArguments args) => {
884 lock (expiredCountLock) {
889 cip = new CacheItemPolicy ();
890 cip.RemovedCallback = removedCb;
891 cip.AbsoluteExpiration = DateTimeOffset.Now.AddMilliseconds (20);
892 mc.Set ("key1", "value1", cip);
894 cip = new CacheItemPolicy ();
895 cip.RemovedCallback = removedCb;
896 cip.AbsoluteExpiration = DateTimeOffset.Now.AddMilliseconds (200);
897 mc.Set ("key2", "value2", cip);
899 cip = new CacheItemPolicy ();
900 cip.RemovedCallback = removedCb;
901 cip.AbsoluteExpiration = DateTimeOffset.Now.AddMilliseconds (600);
902 mc.Set ("key3", "value3", cip);
904 cip = new CacheItemPolicy ();
905 cip.RemovedCallback = removedCb;
906 cip.AbsoluteExpiration = DateTimeOffset.Now.AddMilliseconds (sleepPeriod + 100);
907 mc.Set ("key4", "value4", cip);
909 Thread.Sleep (sleepPeriod);
910 Assert.AreEqual (3, expiredCount, "#A4");
914 public void GetEnumerator ()
916 var mc = new PokerMemoryCache ("MyCache");
918 // This one is a Hashtable enumerator
919 IEnumerator enumerator = ((IEnumerable) mc).GetEnumerator ();
921 // This one is a Dictionary <string, object> enumerator
922 IEnumerator enumerator2 = mc.DoGetEnumerator ();
924 Assert.IsNotNull (enumerator, "#A1-1");
925 Assert.IsNotNull (enumerator2, "#A1-2");
926 Assert.IsTrue (enumerator.GetType () != enumerator2.GetType (), "#A1-3");
928 mc.Set ("key1", "value1", null);
929 mc.Set ("key2", "value2", null);
930 mc.Set ("key3", "value3", null);
932 bool expired = false;
933 var cip = new CacheItemPolicy ();
934 cip.AbsoluteExpiration = DateTime.Now.AddMilliseconds (50);
935 cip.RemovedCallback = (CacheEntryRemovedArguments args) => {
939 mc.Set ("key4", "value4", cip);
942 enumerator = ((IEnumerable) mc).GetEnumerator ();
944 while (enumerator.MoveNext ()) {
948 Assert.IsFalse (expired, "#A2-1");
949 Assert.AreEqual (3, count, "#A2-2");
952 cip = new CacheItemPolicy ();
953 cip.AbsoluteExpiration = DateTime.Now.AddMilliseconds (50);
954 cip.RemovedCallback = (CacheEntryRemovedArguments args) => {
958 mc.Set ("key5", "value5", cip);
961 enumerator2 = mc.DoGetEnumerator ();
963 while (enumerator2.MoveNext ()) {
967 Assert.IsFalse (expired, "#A3-1");
968 Assert.AreEqual (3, count, "#A3-2");
972 public void GetValues ()
974 var mc = new PokerMemoryCache ("MyCache");
976 AssertExtensions.Throws<ArgumentNullException> (() => {
980 AssertExtensions.Throws<NotSupportedException> (() => {
981 mc.GetValues (new string[] {}, "region");
984 AssertExtensions.Throws<ArgumentException> (() => {
985 mc.GetValues (new string [] { "key", null });
988 IDictionary<string, object> value = mc.GetValues (new string[] {});
989 Assert.IsNull (value, "#A2");
991 mc.Set ("key1", "value1", null);
992 mc.Set ("key2", "value2", null);
993 mc.Set ("key3", "value3", null);
995 Assert.IsTrue (mc.Contains ("key1"), "#A3-1");
996 Assert.IsTrue (mc.Contains ("key2"), "#A3-2");
997 Assert.IsTrue (mc.Contains ("key3"), "#A3-2");
999 value = mc.GetValues (new string [] { "key1", "key3" });
1000 Assert.IsNotNull (value, "#A4-1");
1001 Assert.AreEqual (2, value.Count, "#A4-2");
1002 Assert.AreEqual ("value1", value ["key1"], "#A4-3");
1003 Assert.AreEqual ("value3", value ["key3"], "#A4-4");
1004 Assert.AreEqual (typeof (Dictionary<string, object>), value.GetType (), "#A4-5");
1006 // LAMESPEC: MSDN says the number of items in the returned dictionary should be the same as in the
1007 // 'keys' collection - this is not the case. The returned dictionary contains only entries for keys
1008 // that exist in the cache.
1009 value = mc.GetValues (new string [] { "key1", "key3", "nosuchkey" });
1010 Assert.IsNotNull (value, "#A5-1");
1011 Assert.AreEqual (2, value.Count, "#A5-2");
1012 Assert.AreEqual ("value1", value ["key1"], "#A5-3");
1013 Assert.AreEqual ("value3", value ["key3"], "#A5-4");
1014 Assert.IsFalse (value.ContainsKey ("Key1"), "#A5-5");
1020 var mc = new PokerMemoryCache ("MyCache");
1022 AssertExtensions.Throws<NotSupportedException> (() => {
1023 mc.Get ("key", "region");
1026 AssertExtensions.Throws<ArgumentNullException> (() => {
1031 mc.Set ("key", "value", null);
1032 value = mc.Get ("key");
1033 Assert.IsNotNull (value, "#A2-1");
1034 Assert.AreEqual ("value", value, "#A2-2");
1036 value = mc.Get ("nosuchkey");
1037 Assert.IsNull (value, "#A3");
1039 var cip = new CacheItemPolicy ();
1040 bool callbackInvoked;
1041 CacheEntryRemovedReason reason = (CacheEntryRemovedReason)1000;
1043 cip.AbsoluteExpiration = DateTimeOffset.Now.AddMilliseconds (50);
1044 cip.RemovedCallback = (CacheEntryRemovedArguments args) => {
1045 callbackInvoked = true;
1046 reason = args.RemovedReason;
1048 mc.Set ("key", "value", cip);
1051 callbackInvoked = false;
1052 reason = (CacheEntryRemovedReason) 1000;
1053 value = mc.Get ("key");
1054 Assert.IsNull (value, "#B1-1");
1055 Assert.IsTrue (callbackInvoked, "#B1-2");
1056 Assert.AreEqual (CacheEntryRemovedReason.Expired, reason, "#B1-3");
1058 cip = new CacheItemPolicy ();
1059 cip.AbsoluteExpiration = DateTimeOffset.Now.AddMilliseconds (50);
1060 cip.RemovedCallback = (CacheEntryRemovedArguments args) => {
1061 callbackInvoked = true;
1062 reason = args.RemovedReason;
1063 throw new ApplicationException ("test");
1066 mc.Set ("key", "value", cip);
1069 callbackInvoked = false;
1070 reason = (CacheEntryRemovedReason) 1000;
1071 value = mc.Get ("key");
1072 Assert.IsNull (value, "#B2-1");
1073 Assert.IsTrue (callbackInvoked, "#B2-2");
1074 Assert.AreEqual (CacheEntryRemovedReason.Expired, reason, "#B2-3");
1078 public void GetCacheItem ()
1080 var mc = new PokerMemoryCache ("MyCache");
1082 AssertExtensions.Throws<NotSupportedException> (() => {
1083 mc.GetCacheItem ("key", "region");
1086 AssertExtensions.Throws<ArgumentNullException> (() => {
1087 mc.GetCacheItem (null);
1091 mc.Set ("key", "value", null);
1092 value = mc.GetCacheItem ("key");
1093 Assert.IsNotNull (value, "#A2-1");
1094 Assert.AreEqual ("value", value.Value, "#A2-2");
1095 Assert.AreEqual ("key", value.Key, "#A2-3");
1097 value = mc.GetCacheItem ("doesnotexist");
1098 Assert.IsNull (value, "#A3");
1100 var cip = new CacheItemPolicy ();
1101 bool callbackInvoked;
1102 CacheEntryRemovedReason reason = (CacheEntryRemovedReason) 1000;
1104 cip.AbsoluteExpiration = DateTimeOffset.Now.AddMilliseconds (50);
1105 cip.RemovedCallback = (CacheEntryRemovedArguments args) => {
1106 callbackInvoked = true;
1107 reason = args.RemovedReason;
1109 mc.Set ("key", "value", cip);
1112 callbackInvoked = false;
1113 reason = (CacheEntryRemovedReason) 1000;
1114 value = mc.GetCacheItem ("key");
1115 Assert.IsNull (value, "#B1-1");
1116 Assert.IsTrue (callbackInvoked, "#B1-2");
1117 Assert.AreEqual (CacheEntryRemovedReason.Expired, reason, "#B1-3");
1119 cip = new CacheItemPolicy ();
1120 cip.AbsoluteExpiration = DateTimeOffset.Now.AddMilliseconds (50);
1121 cip.RemovedCallback = (CacheEntryRemovedArguments args) => {
1122 callbackInvoked = true;
1123 reason = args.RemovedReason;
1124 throw new ApplicationException ("test");
1127 mc.Set ("key", "value", cip);
1130 callbackInvoked = false;
1131 reason = (CacheEntryRemovedReason) 1000;
1132 value = mc.GetCacheItem ("key");
1133 Assert.IsNull (value, "#B2-1");
1134 Assert.IsTrue (callbackInvoked, "#B2-2");
1135 Assert.AreEqual (CacheEntryRemovedReason.Expired, reason, "#B2-3");
1139 public void ChangeMonitors ()
1141 bool removed = false;
1142 var mc = new PokerMemoryCache ("MyCache");
1143 var cip = new CacheItemPolicy ();
1144 var monitor = new PokerChangeMonitor ();
1145 cip.ChangeMonitors.Add (monitor);
1146 cip.RemovedCallback = (CacheEntryRemovedArguments args) => {
1150 mc.Set ("key", "value", cip);
1151 Assert.AreEqual (0, monitor.Calls.Count, "#A1");
1153 monitor.SignalChange ();
1154 Assert.IsTrue (removed, "#A2");
1156 bool onChangedCalled = false;
1157 monitor = new PokerChangeMonitor ();
1158 monitor.NotifyOnChanged ((object state) => {
1159 onChangedCalled = true;
1162 cip = new CacheItemPolicy ();
1163 cip.ChangeMonitors.Add (monitor);
1165 // Thrown by ChangeMonitor.NotifyOnChanged
1166 AssertExtensions.Throws<InvalidOperationException> (() => {
1167 mc.Set ("key1", "value1", cip);
1171 // NOTE: on Windows with 2 or more CPUs this test will most probably fail.
1175 var config = new NameValueCollection ();
1176 config ["__MonoEmulateOneCPU"] = "true";
1177 var mc = new MemoryCache ("MyCache", config);
1179 for (int i = 0; i < 10; i++)
1180 mc.Set ("key" + i.ToString (), "value" + i.ToString (), null);
1182 // .NET doesn't touch the freshest 10 entries
1183 Assert.AreEqual (10, mc.GetCount (), "#A1-1");
1184 long trimmed = mc.Trim (50);
1185 Assert.AreEqual (0, trimmed, "#A1-2");
1186 Assert.AreEqual (10, mc.GetCount (), "#A1-3");
1188 mc = new MemoryCache ("MyCache", config);
1189 // Only entries 11- are considered for removal
1190 for (int i = 0; i < 11; i++)
1191 mc.Set ("key" + i.ToString (), "value" + i.ToString (), null);
1193 Assert.AreEqual (11, mc.GetCount (), "#A2-1");
1194 trimmed = mc.Trim (50);
1195 Assert.AreEqual (1, trimmed, "#A2-2");
1196 Assert.AreEqual (10, mc.GetCount (), "#A2-3");
1198 mc = new MemoryCache ("MyCache", config);
1199 // Only entries 11- are considered for removal
1200 for (int i = 0; i < 125; i++)
1201 mc.Set ("key" + i.ToString (), "value" + i.ToString (), null);
1203 Assert.AreEqual (125, mc.GetCount (), "#A3-1");
1204 trimmed = mc.Trim (50);
1205 Assert.AreEqual (62, trimmed, "#A3-2");
1206 Assert.AreEqual (63, mc.GetCount (), "#A3-3");
1208 // Testing the removal order
1209 mc = new MemoryCache ("MyCache", config);
1210 var removed = new List <string> ();
1211 var cip = new CacheItemPolicy ();
1212 cip.RemovedCallback = (CacheEntryRemovedArguments args) => {
1213 removed.Add (args.CacheItem.Key);
1216 for (int i = 0; i < 50; i++)
1217 mc.Set ("key" + i.ToString (), "value" + i.ToString (), cip);
1220 for (int i = 0; i < 50; i++)
1221 value = mc.Get ("key" + i.ToString ());
1223 trimmed = mc.Trim (50);
1224 Assert.AreEqual (25, mc.GetCount (), "#A4-1");
1225 Assert.AreEqual (25, trimmed, "#A4-2");
1226 Assert.AreEqual (25, removed.Count, "#A4-3");
1228 // OK, this is odd... The list is correct in terms of entries removed but the entries
1229 // are removed in the _MOST_ frequently used order, within the group selected for removal.
1230 for (int i = 24; i >= 0; i--) {
1232 Assert.AreEqual ("key" + i.ToString (), removed [idx], "#A5-" + idx.ToString ());