Fixing an issue with output parameters that are of type IntPtr
[castle.git] / InversionOfControl / Castle.MicroKernel.Tests / KeySearchNamingSubSystemTestCase.cs
blobfd208eab3dcdca7a6c801e745b02d0a0ec3c0e67
1 // Copyright 2004-2008 Castle Project - http://www.castleproject.org/
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 namespace Castle.MicroKernel.Tests
17 using System;
18 using System.Collections;
19 using System.Threading;
20 using Castle.MicroKernel.SubSystems.Naming;
21 using Castle.MicroKernel.Tests.ClassComponents;
22 using NUnit.Framework;
24 [TestFixture]
25 public class KeySearchNamingSubSystemTestCase
27 [Test]
28 public void EmptyDelegateReturnsFirstTypeLoaded()
30 IKernel kernel = new DefaultKernel();
31 kernel.AddSubSystem(SubSystemConstants.NamingKey, new KeySearchNamingSubSystem());
33 kernel.AddComponent("1.common", typeof(ICommon), typeof(CommonImpl1));
34 kernel.AddComponent("2.common", typeof(ICommon), typeof(CommonImpl2));
36 ICommon common = kernel[typeof(ICommon)] as ICommon;
38 Assert.IsNotNull(common);
39 Assert.AreEqual(typeof(CommonImpl1), common.GetType());
42 [Test]
43 public void ReturnsCorrectType()
45 IKernel kernel = new DefaultKernel();
46 kernel.AddSubSystem(SubSystemConstants.NamingKey,
47 new KeySearchNamingSubSystem(
48 delegate(string key) { return key.StartsWith("castlestronghold.com"); }));
50 kernel.AddComponent("castleproject.org.common", typeof(ICommon), typeof(CommonImpl1));
51 kernel.AddComponent("castlestronghold.com.common", typeof(ICommon), typeof(CommonImpl2));
53 ICommon common = kernel[typeof(ICommon)] as ICommon;
55 Assert.IsNotNull(common);
56 Assert.AreEqual(typeof(CommonImpl2), common.GetType());
59 [Test]
60 public void ReturnsFirstTypeWhenNotFound()
62 IKernel kernel = new DefaultKernel();
63 kernel.AddSubSystem(SubSystemConstants.NamingKey,
64 new KeySearchNamingSubSystem(delegate(string key) { return key.StartsWith("3"); }));
66 kernel.AddComponent("1.common", typeof(ICommon), typeof(CommonImpl1));
67 kernel.AddComponent("2.common", typeof(ICommon), typeof(CommonImpl2));
69 ICommon common = kernel[typeof(ICommon)] as ICommon;
71 Assert.IsNotNull(common);
72 Assert.AreEqual(typeof(CommonImpl1), common.GetType());
75 [Test]
76 public void ReturnsFirstMatchingType()
78 IKernel kernel = new DefaultKernel();
79 kernel.AddSubSystem(SubSystemConstants.NamingKey,
80 new KeySearchNamingSubSystem(delegate(string key) { return key.StartsWith("1"); }));
82 kernel.AddComponent("1.common", typeof(ICommon), typeof(CommonImpl1));
83 kernel.AddComponent("11.common", typeof(ICommon), typeof(CommonImpl2));
85 ICommon common = kernel[typeof(ICommon)] as ICommon;
87 Assert.IsNotNull(common);
88 Assert.AreEqual(typeof(CommonImpl1), common.GetType());
91 [Test]
92 public void ComponentUnregistersProperly()
94 IKernel kernel = new DefaultKernel();
96 kernel.AddSubSystem(SubSystemConstants.NamingKey,
97 new KeySearchNamingSubSystem(delegate(string key) { return key.StartsWith("2"); }));
99 kernel.AddComponent("1.common", typeof(ICommon), typeof(CommonImpl1));
100 kernel.AddComponent("2.common", typeof(ICommon), typeof(CommonImpl2));
102 ICommon common = kernel[typeof(ICommon)] as ICommon;
104 Assert.IsNotNull(common);
105 Assert.AreEqual(typeof(CommonImpl2), common.GetType());
107 kernel.RemoveComponent("2.common");
109 common = kernel[typeof(ICommon)] as ICommon;
111 Assert.IsNotNull(common);
112 Assert.AreEqual(typeof(CommonImpl1), common.GetType());
114 kernel.RemoveComponent("1.common");
115 Assert.AreEqual(0, kernel.GetHandlers(typeof(ICommon)).Length);
118 [Test]
119 public void FirstLoadedComponentUnregistersProperly()
121 IKernel kernel = new DefaultKernel();
122 kernel.AddSubSystem(SubSystemConstants.NamingKey,
123 new KeySearchNamingSubSystem(delegate(string key) { return key.StartsWith("1"); }));
125 kernel.AddComponent("1.common", typeof(ICommon), typeof(CommonImpl1));
126 kernel.AddComponent("2.common", typeof(ICommon), typeof(CommonImpl2));
128 ICommon common = kernel[typeof(ICommon)] as ICommon;
130 Assert.IsNotNull(common);
131 Assert.AreEqual(typeof(CommonImpl1), common.GetType());
133 kernel.RemoveComponent("1.common");
135 common = kernel[typeof(ICommon)] as ICommon;
137 Assert.IsNotNull(common);
138 Assert.AreEqual(typeof(CommonImpl2), common.GetType());
141 [Test]
142 [ExpectedException(typeof(ComponentNotFoundException))]
143 public void SingleComponentUnregistersProperly()
145 IKernel kernel = new DefaultKernel();
146 kernel.AddSubSystem(SubSystemConstants.NamingKey,
147 new KeySearchNamingSubSystem(delegate(string key) { return key.StartsWith("1"); }));
149 kernel.AddComponent("1.common", typeof(ICommon), typeof(CommonImpl1));
151 ICommon common = kernel[typeof(ICommon)] as ICommon;
153 Assert.IsNotNull(common);
154 Assert.AreEqual(typeof(CommonImpl1), common.GetType());
156 kernel.RemoveComponent("1.common");
158 Assert.IsFalse(kernel.HasComponent("1.common"));
159 Assert.IsFalse(kernel.HasComponent(typeof(CommonImpl1)));
160 common = kernel[typeof(ICommon)] as ICommon;
163 [Test]
164 public void MultiThreadedAddResolve()
166 int threadCount = 100;
167 ArrayList list = ArrayList.Synchronized(new ArrayList());
168 Random rand = new Random();
169 ManualResetEvent waitEvent = new ManualResetEvent(false);
171 IKernel kernel = new DefaultKernel();
172 kernel.AddSubSystem(SubSystemConstants.NamingKey, new KeySearchNamingSubSystem());
173 kernel.AddComponent("common", typeof(ICommon), typeof(CommonImpl1));
175 WaitCallback resolveThread = delegate
177 waitEvent.WaitOne();
178 while(threadCount > 0 && list.Count == 0)
182 ICommon common = kernel[typeof(ICommon)] as ICommon;
184 catch(Exception e)
186 list.Add(e.ToString());
190 ThreadPool.QueueUserWorkItem(resolveThread);
192 WaitCallback addThread = delegate
194 waitEvent.WaitOne();
195 kernel.AddComponent(rand.Next() + ".common", typeof(ICommon), typeof(CommonImpl1));
196 Interlocked.Decrement(ref threadCount);
198 for(int i = 0; i < threadCount; i++)
200 ThreadPool.QueueUserWorkItem(addThread);
203 waitEvent.Set();
204 while(threadCount > 0 && list.Count == 0)
206 Thread.Sleep(15);
209 if (list.Count > 0)
211 Assert.Fail(list[0].ToString());
215 /// <summary>
216 /// What I consider an edge case (only consistently reproducable with 1000+ threads):
217 /// + Large number of components that implement the same service
218 /// + Thread 1 Requests component by service
219 /// + Thread n is simultaneously removing component
220 /// + Predicate does not match any keys for the requested service OR
221 /// + Matching component is removed before the Predicate can match it
222 /// </summary>
223 [Test]
224 [ExpectedException(typeof(ArgumentOutOfRangeException))]
225 [Ignore("This test needs to be reviewed")]
226 public void MultiThreaded_RemoveResolve_Throws_When_LargeRatio_Of_ComponentsToService()
228 int threadCount = 1000;
229 ArrayList list = ArrayList.Synchronized(new ArrayList());
230 Random rand = new Random();
231 ManualResetEvent waitEvent = new ManualResetEvent(false);
233 IKernel kernel = new DefaultKernel();
234 kernel.AddSubSystem(SubSystemConstants.NamingKey, new KeySearchNamingSubSystem(delegate { return false; }));
236 kernel.AddComponent("common", typeof(ICommon), typeof(CommonImpl1));
238 WaitCallback resolveThread = delegate
240 waitEvent.WaitOne();
241 while(threadCount > 0 && list.Count == 0)
245 ICommon common = kernel[typeof(ICommon)] as ICommon;
247 catch(Exception e)
249 list.Add(e);
253 ThreadPool.QueueUserWorkItem(resolveThread);
255 WaitCallback removeThread = delegate
257 waitEvent.WaitOne();
258 kernel.RemoveComponent(threadCount + ".common");
259 Interlocked.Decrement(ref threadCount);
261 for(int i = 0; i < threadCount; i++)
263 kernel.AddComponent(i + ".common", typeof(ICommon), typeof(CommonImpl1));
264 ThreadPool.QueueUserWorkItem(removeThread);
267 waitEvent.Set();
268 while(threadCount > 0 && list.Count == 0)
270 Thread.Sleep(15);
273 if (list.Count > 0)
275 throw (Exception) list[0];