1 // -----------------------------------------------------------------------
\r
2 // Copyright (c) Microsoft Corporation. All rights reserved.
\r
3 // -----------------------------------------------------------------------
\r
5 using System.Collections;
\r
6 using System.Collections.Generic;
\r
7 using System.Runtime.CompilerServices;
\r
9 using System.UnitTesting;
\r
10 using Microsoft.VisualStudio.TestTools.UnitTesting;
\r
12 namespace Microsoft.Internal.Collections
\r
15 public class ConditionalWeakTableTests
\r
18 public void Add_KeyShouldBeCollected()
\r
20 var obj = new object();
\r
21 var cwt = new ConditionalWeakTable<object, object>();
\r
23 cwt.Add(obj, new object());
\r
25 var wr = new WeakReference(obj);
\r
30 GC.WaitForPendingFinalizers();
\r
32 Assert.IsNull(wr.Target, "Key should be collected now!");
\r
38 public void Add_KeyHeld_ValueShouldNotBeCollected()
\r
40 var obj = new object();
\r
41 var str = new StringBuilder();
\r
42 var cwt = new ConditionalWeakTable<object, StringBuilder>();
\r
44 var wrKey = new WeakReference(obj);
\r
45 var wrValue = new WeakReference(str);
\r
52 GC.WaitForPendingFinalizers();
\r
54 // Should still have both references
\r
55 Assert.IsNotNull(wrKey.Target, "Key should NOT be collected yet!");
\r
56 Assert.IsNotNull(wrValue.Target, "Value should NOT be collected yet!");
\r
64 public void Add_KeyCollected_ValueShouldBeCollected()
\r
66 var obj = new object();
\r
67 var str = new StringBuilder();
\r
68 var cwt = new ConditionalWeakTable<object, StringBuilder>();
\r
72 var wrKey = new WeakReference(obj);
\r
73 var wrValue = new WeakReference(str);
\r
78 GC.WaitForPendingFinalizers();
\r
80 Assert.IsNull(wrKey.Target, "Key should be collected now!");
\r
81 Assert.IsNull(wrValue.Target, "Value should be collected now!");
\r
88 public void Remove_ValidKey_ShouldReturnTrue()
\r
90 var obj = new object();
\r
91 var obj2 = new object();
\r
92 var cwt = new ConditionalWeakTable<object, object>();
\r
96 Assert.IsTrue(cwt.Remove(obj));
\r
100 public void Remove_InvalidKey_ShouldReturnTrue()
\r
102 var obj = new object();
\r
103 var obj2 = new object();
\r
104 var cwt = new ConditionalWeakTable<object, object>();
\r
106 cwt.Add(obj, obj2);
\r
108 Assert.IsFalse(cwt.Remove(obj2));
\r
112 public void TryGetValue_ValidKey_ShouldReturnTrueAndValue()
\r
114 var obj = new object();
\r
115 var obj2 = new object();
\r
116 var cwt = new ConditionalWeakTable<object, object>();
\r
118 cwt.Add(obj, obj2);
\r
121 Assert.IsTrue(cwt.TryGetValue(obj, out obj3), "Should find a value with the key!");
\r
122 Assert.AreEqual(obj2, obj3);
\r
126 public void TryGetValue_InvalidKey_ShouldReturnFalseAndNull()
\r
128 var obj = new object();
\r
129 var obj2 = new object();
\r
130 var cwt = new ConditionalWeakTable<object, object>();
\r
132 cwt.Add(obj, obj2);
\r
135 Assert.IsFalse(cwt.TryGetValue(obj2, out obj3), "Should NOT find a value with the key!");
\r
136 Assert.IsNull(obj3);
\r
141 public void Add_KeyValueSame_KeyShouldNotBeCollected()
\r
143 // Dev10:556089 - This test demonstrations a bug in our implementation
\r
144 // of ConditionalWeakTable which needs CLR 4 support to fix so once
\r
145 // we switch to the CLR 4 version of ConditionalWeakTable this should go away.
\r
147 var obj = new object();
\r
148 var cwt = new ConditionalWeakTable<object, object>();
\r
152 var wrKey = new WeakReference(obj);
\r
156 GC.WaitForPendingFinalizers();
\r
158 Assert.IsNotNull(wrKey.Target, "Key should NOT be collected yet!");
\r
160 // Apply pressure to ensure they still don't go away.
\r
161 ApplyMemoryPressureOnConditionalWeakTable(cwt);
\r
163 Assert.IsNotNull(wrKey.Target, "Key should NOT be collected yet!");
\r
168 public class ObjectHolder
\r
170 public object Obj { get; set; }
\r
171 public ObjectHolder() { }
\r
172 public ObjectHolder(object obj)
\r
179 public void Add_ValueReferencesKey_KeyAndValueShouldNotBeCollected()
\r
181 // Dev10:556089 - This test demonstrations a bug in our implementation
\r
182 // of ConditionalWeakTable which needs CLR 4 support to fix so once
\r
183 // we switch to the CLR 4 version of ConditionalWeakTable this should go away.
\r
185 var obj = new object();
\r
186 var holder = new ObjectHolder(obj);
\r
187 var cwt = new ConditionalWeakTable<object, ObjectHolder>();
\r
189 cwt.Add(obj, holder);
\r
191 var wrKey = new WeakReference(obj);
\r
192 var wrValue = new WeakReference(holder);
\r
197 GC.WaitForPendingFinalizers();
\r
199 Assert.IsNotNull(wrKey.Target, "Key should NOT be collected yet!");
\r
200 Assert.IsNotNull(wrValue.Target, "Value should NOT be collected now!");
\r
202 // Apply pressure to ensure they still don't go away.
\r
203 ApplyMemoryPressureOnConditionalWeakTable(cwt);
\r
205 Assert.IsNotNull(wrKey.Target, "Key should NOT be collected yet!");
\r
206 Assert.IsNotNull(wrValue.Target, "Value should NOT be collected now!");
\r
211 private void ApplyMemoryPressureOnConditionalWeakTable<T,V>(ConditionalWeakTable<T,V> table)
\r
212 where T : class, new()
\r
213 where V : class, new()
\r
215 // Adding 100 items should do it.
\r
216 for (int i = 0; i < 100; i++)
\r
218 table.Add(new T(), new V());
\r
222 GC.WaitForPendingFinalizers();
\r