Fixing an issue with output parameters that are of type IntPtr
[castle.git] / Tools / Castle.DynamicProxy2 / Castle.DynamicProxy.Tests / ModuleScopeTestCase.cs
blob958971d34ea9e0fe15f9322343635ae61c783ed1
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 using System.Collections;
16 using System.Collections.Generic;
17 using Castle.DynamicProxy.Generators;
18 using Castle.DynamicProxy.Tests.InterClasses;
20 namespace Castle.DynamicProxy.Tests
22 using System;
23 using NUnit.Framework;
24 using System.Reflection.Emit;
25 using System.IO;
26 using System.Reflection;
28 [TestFixture]
29 public class ModuleScopeTestCase
31 [Test]
32 public void ModuleScopeStoresModuleBuilder ()
34 ModuleScope scope = new ModuleScope ();
35 ModuleBuilder one = scope.ObtainDynamicModuleWithStrongName ();
36 ModuleBuilder two = scope.ObtainDynamicModuleWithStrongName ();
38 Assert.AreSame (one, two);
39 Assert.AreSame (one.Assembly, two.Assembly);
42 [Test]
43 public void ModuleScopeCanHandleSignedAndUnsignedInParallel ()
45 ModuleScope scope = new ModuleScope ();
46 Assert.IsNull (scope.StrongNamedModule);
47 Assert.IsNull (scope.WeakNamedModule);
49 ModuleBuilder one = scope.ObtainDynamicModuleWithStrongName ();
50 Assert.IsNotNull (scope.StrongNamedModule);
51 Assert.IsNull (scope.WeakNamedModule);
52 Assert.AreSame (one, scope.StrongNamedModule);
54 ModuleBuilder two = scope.ObtainDynamicModuleWithWeakName ();
55 Assert.IsNotNull (scope.StrongNamedModule);
56 Assert.IsNotNull (scope.WeakNamedModule);
57 Assert.AreSame (two, scope.WeakNamedModule);
59 Assert.AreNotSame (one, two);
60 Assert.AreNotSame (one.Assembly, two.Assembly);
62 ModuleBuilder three = scope.ObtainDynamicModuleWithStrongName ();
63 ModuleBuilder four = scope.ObtainDynamicModuleWithWeakName ();
65 Assert.AreSame (one, three);
66 Assert.AreSame (two, four);
69 #if !MONO
71 [Test]
72 public void ImplicitModulePaths ()
74 ModuleScope scope = new ModuleScope (true);
75 Assert.AreEqual (ModuleScope.DEFAULT_FILE_NAME, scope.StrongNamedModuleName);
76 Assert.AreEqual (Path.Combine (Environment.CurrentDirectory, ModuleScope.DEFAULT_FILE_NAME),
77 scope.ObtainDynamicModuleWithStrongName ().FullyQualifiedName);
78 Assert.IsNull (scope.StrongNamedModuleDirectory);
80 Assert.AreEqual (ModuleScope.DEFAULT_FILE_NAME, scope.WeakNamedModuleName);
81 Assert.AreEqual (Path.Combine (Environment.CurrentDirectory, ModuleScope.DEFAULT_FILE_NAME),
82 scope.ObtainDynamicModuleWithWeakName ().FullyQualifiedName);
83 Assert.IsNull (scope.WeakNamedModuleDirectory);
86 [Test]
87 public void ExplicitModulePaths ()
89 ModuleScope scope = new ModuleScope (true, "Strong", "StrongModule.dll", "Weak", "WeakModule.dll");
90 Assert.AreEqual ("StrongModule.dll", scope.StrongNamedModuleName);
91 Assert.AreEqual (Path.Combine (Environment.CurrentDirectory, "StrongModule.dll"), scope.ObtainDynamicModuleWithStrongName ().FullyQualifiedName);
92 Assert.IsNull (scope.StrongNamedModuleDirectory);
94 Assert.AreEqual ("WeakModule.dll", scope.WeakNamedModuleName);
95 Assert.AreEqual (Path.Combine (Environment.CurrentDirectory, "WeakModule.dll"), scope.ObtainDynamicModuleWithWeakName ().FullyQualifiedName);
96 Assert.IsNull (scope.WeakNamedModuleDirectory);
98 scope = new ModuleScope (true, "Strong", @"c:\Foo\StrongModule.dll", "Weak", @"d:\Bar\WeakModule.dll");
99 Assert.AreEqual ("StrongModule.dll", scope.StrongNamedModuleName);
100 Assert.AreEqual (@"c:\Foo\StrongModule.dll", scope.ObtainDynamicModuleWithStrongName ().FullyQualifiedName);
101 Assert.AreEqual (@"c:\Foo", scope.StrongNamedModuleDirectory);
103 Assert.AreEqual ("WeakModule.dll", scope.WeakNamedModuleName);
104 Assert.AreEqual (@"d:\Bar\WeakModule.dll", scope.ObtainDynamicModuleWithWeakName ().FullyQualifiedName);
105 Assert.AreEqual (@"d:\Bar", scope.WeakNamedModuleDirectory);
108 #endif
110 private static void CheckSignedSavedAssembly (string path)
112 Assert.IsTrue (File.Exists (path));
114 AssemblyName assemblyName = AssemblyName.GetAssemblyName (path);
115 Assert.AreEqual (ModuleScope.DEFAULT_ASSEMBLY_NAME, assemblyName.Name);
117 byte[] keyPairBytes = ModuleScope.GetKeyPair ();
118 StrongNameKeyPair keyPair = new StrongNameKeyPair (keyPairBytes);
119 byte[] loadedPublicKey = assemblyName.GetPublicKey ();
121 Assert.AreEqual (keyPair.PublicKey.Length, loadedPublicKey.Length);
122 for (int i = 0; i < keyPair.PublicKey.Length; ++i)
123 Assert.AreEqual (keyPair.PublicKey[i], loadedPublicKey[i]);
126 [Test]
127 public void SaveSigned ()
129 ModuleScope scope = new ModuleScope (true);
130 scope.ObtainDynamicModuleWithStrongName ();
132 string path = ModuleScope.DEFAULT_FILE_NAME;
133 if (File.Exists (path))
134 File.Delete (path);
136 Assert.IsFalse (File.Exists (path));
137 string savedPath = scope.SaveAssembly ();
139 Assert.AreEqual (savedPath, Path.GetFullPath (path));
141 CheckSignedSavedAssembly(path);
142 File.Delete (path);
145 [Test]
146 public void SaveUnsigned ()
148 ModuleScope scope = new ModuleScope (true);
149 scope.ObtainDynamicModuleWithWeakName ();
151 string path = ModuleScope.DEFAULT_FILE_NAME;
152 if (File.Exists (path))
153 File.Delete (path);
155 Assert.IsFalse (File.Exists (path));
156 string savedPath = scope.SaveAssembly ();
158 Assert.AreEqual (savedPath, Path.GetFullPath (path));
160 CheckUnsignedSavedAssembly(path);
161 File.Delete (path);
164 [Test]
165 public void SaveWithPath ()
167 string strongModulePath = Path.GetTempFileName ();
168 string weakModulePath = Path.GetTempFileName ();
170 File.Delete (strongModulePath);
171 File.Delete (weakModulePath);
173 Assert.IsFalse (File.Exists (strongModulePath));
174 Assert.IsFalse (File.Exists (weakModulePath));
176 ModuleScope scope = new ModuleScope (true, "Strong", strongModulePath, "Weak", weakModulePath);
177 scope.ObtainDynamicModuleWithStrongName ();
178 scope.ObtainDynamicModuleWithWeakName ();
180 scope.SaveAssembly (true);
181 scope.SaveAssembly (false);
183 Assert.IsTrue (File.Exists (strongModulePath));
184 Assert.IsTrue (File.Exists (weakModulePath));
186 File.Delete (strongModulePath);
187 File.Delete (weakModulePath);
190 private static void CheckUnsignedSavedAssembly (string path)
192 Assert.IsTrue (File.Exists (path));
194 AssemblyName assemblyName = AssemblyName.GetAssemblyName (path);
195 Assert.AreEqual (ModuleScope.DEFAULT_ASSEMBLY_NAME, assemblyName.Name);
197 byte[] loadedPublicKey = assemblyName.GetPublicKey ();
198 Assert.IsNull (loadedPublicKey);
201 [Test]
202 public void SaveReturnsNullWhenNoModuleObtained ()
204 ModuleScope scope = new ModuleScope (true);
205 Assert.IsNull (scope.SaveAssembly ());
208 [Test]
209 [ExpectedException (typeof (InvalidOperationException))]
210 public void SaveThrowsWhenMultipleAssembliesGenerated ()
212 ModuleScope scope = new ModuleScope (true);
213 scope.ObtainDynamicModuleWithStrongName ();
214 scope.ObtainDynamicModuleWithWeakName ();
216 scope.SaveAssembly ();
219 [Test]
220 public void SaveWithFlagFalseDoesntThrowsWhenMultipleAssembliesGenerated ()
222 ModuleScope scope = new ModuleScope (false);
223 scope.ObtainDynamicModuleWithStrongName ();
224 scope.ObtainDynamicModuleWithWeakName ();
226 scope.SaveAssembly ();
229 [Test]
230 public void ExplicitSaveWorksEvenWhenMultipleAssembliesGenerated ()
232 ModuleScope scope = new ModuleScope (true);
233 scope.ObtainDynamicModuleWithStrongName ();
234 scope.ObtainDynamicModuleWithWeakName ();
236 scope.SaveAssembly (true);
237 CheckSignedSavedAssembly (ModuleScope.DEFAULT_FILE_NAME);
239 scope.SaveAssembly (false);
240 CheckUnsignedSavedAssembly (ModuleScope.DEFAULT_FILE_NAME);
242 File.Delete (ModuleScope.DEFAULT_FILE_NAME);
245 [Test]
246 [ExpectedException (typeof (InvalidOperationException))]
247 public void ExplicitSaveThrowsWhenSpecifiedAssemblyNotGeneratedWeakName ()
249 ModuleScope scope = new ModuleScope (true);
250 scope.ObtainDynamicModuleWithStrongName ();
252 scope.SaveAssembly (false);
255 [Test]
256 [ExpectedException (typeof (InvalidOperationException))]
257 public void ExplicitSaveThrowsWhenSpecifiedAssemblyNotGeneratedStrongName ()
259 ModuleScope scope = new ModuleScope (true);
260 scope.ObtainDynamicModuleWithWeakName ();
262 scope.SaveAssembly (true);
265 [Test]
266 public void SavedAssemblyHasCacheMappings ()
268 ModuleScope scope = new ModuleScope (true);
269 scope.ObtainDynamicModuleWithWeakName ();
271 string savedPath = scope.SaveAssembly ();
273 CrossAppDomainCaller.RunInOtherAppDomain (delegate (object[] args)
275 Assembly assembly = Assembly.LoadFrom ((string)args[0]);
276 Assert.IsTrue (assembly.IsDefined (typeof (CacheMappingsAttribute), false));
278 savedPath);
280 File.Delete (savedPath);
283 [Test]
284 public void CacheMappingsHoldTypes ()
286 ModuleScope scope = new ModuleScope (true);
287 DefaultProxyBuilder builder = new DefaultProxyBuilder (scope);
288 Type cp = builder.CreateClassProxy (typeof (object), ProxyGenerationOptions.Default);
290 string savedPath = scope.SaveAssembly ();
292 CrossAppDomainCaller.RunInOtherAppDomain (delegate (object[] args)
294 Assembly assembly = Assembly.LoadFrom ((string) args[0]);
295 CacheMappingsAttribute attribute = (CacheMappingsAttribute) assembly.GetCustomAttributes (typeof (CacheMappingsAttribute), false)[0];
296 Dictionary<CacheKey, string> entries = attribute.GetDeserializedMappings();
297 Assert.AreEqual (1, entries.Count);
299 CacheKey key = new CacheKey (typeof (object), new Type[0], ProxyGenerationOptions.Default);
300 Assert.IsTrue (entries.ContainsKey (key));
301 Assert.AreEqual (args[1], entries[key]);
303 savedPath, cp.FullName);
305 File.Delete (savedPath);
308 [Test]
309 public void GeneratedAssembliesDefaultName ()
311 ModuleScope scope = new ModuleScope ();
312 ModuleBuilder strong = scope.ObtainDynamicModuleWithStrongName ();
313 ModuleBuilder weak = scope.ObtainDynamicModuleWithWeakName ();
315 Assert.AreEqual (ModuleScope.DEFAULT_ASSEMBLY_NAME, strong.Assembly.GetName ().Name);
316 Assert.AreEqual (ModuleScope.DEFAULT_ASSEMBLY_NAME, weak.Assembly.GetName ().Name);
319 [Test]
320 public void GeneratedAssembliesWithCustomName ()
322 ModuleScope scope = new ModuleScope (false, "Strong", "Module1.dll", "Weak", "Module2,dll");
323 ModuleBuilder strong = scope.ObtainDynamicModuleWithStrongName ();
324 ModuleBuilder weak = scope.ObtainDynamicModuleWithWeakName ();
326 Assert.AreEqual ("Strong", strong.Assembly.GetName ().Name);
327 Assert.AreEqual ("Weak", weak.Assembly.GetName ().Name);
330 [Test]
331 public void ModuleScopeDoesntTryToDeleteFromCurrentDirectory ()
333 string moduleDirectory = Path.Combine (Environment.CurrentDirectory, "GeneratedDlls");
334 if (Directory.Exists (moduleDirectory))
335 Directory.Delete (moduleDirectory, true);
337 string strongModulePath = Path.Combine (moduleDirectory, "Strong.dll");
338 string weakModulePath = Path.Combine (moduleDirectory, "Weak.dll");
340 Directory.CreateDirectory(moduleDirectory);
341 ModuleScope scope = new ModuleScope (true, "Strong", strongModulePath, "Weak", weakModulePath);
343 using (File.Create (Path.Combine (Environment.CurrentDirectory, "Strong.dll")))
345 scope.ObtainDynamicModuleWithStrongName ();
346 scope.SaveAssembly (true); // this will throw if SaveAssembly tries to delete from the current directory
349 using (File.Create (Path.Combine (Environment.CurrentDirectory, "Weak.dll")))
351 scope.ObtainDynamicModuleWithWeakName ();
352 scope.SaveAssembly (false); // this will throw if SaveAssembly tries to delete from the current directory
356 [Test]
357 public void DefaultProxyBuilderWithSpecificScope ()
359 ModuleScope scope = new ModuleScope (false);
360 DefaultProxyBuilder builder = new DefaultProxyBuilder (scope);
361 Assert.AreSame (scope, builder.ModuleScope);
364 [Test]
365 [ExpectedException (typeof (ArgumentException))]
366 public void LoadAssemblyIntoCache_InvalidAssembly ()
368 ModuleScope newScope = new ModuleScope (false);
369 newScope.LoadAssemblyIntoCache (Assembly.GetExecutingAssembly());
372 [Test]
373 public void LoadAssemblyIntoCache_CreateClassProxy ()
375 CheckLoadAssemblyIntoCache (delegate (IProxyBuilder builder)
377 return builder.CreateClassProxy (typeof (object), ProxyGenerationOptions.Default);
381 [Test]
382 public void LoadAssemblyIntoCache_CreateInterfaceProxyTypeWithoutTarget ()
384 CheckLoadAssemblyIntoCache (delegate (IProxyBuilder builder)
386 return builder.CreateInterfaceProxyTypeWithoutTarget (typeof (IServiceProvider), new Type[0], ProxyGenerationOptions.Default);
390 [Test]
391 public void LoadAssemblyIntoCache_CreateInterfaceProxyTypeWithTarget ()
393 CheckLoadAssemblyIntoCache (delegate (IProxyBuilder builder)
395 return builder.CreateInterfaceProxyTypeWithTarget (typeof (IMyInterface2), new Type[0], typeof (MyInterfaceImpl), ProxyGenerationOptions.Default);
399 [Test]
400 public void LoadAssemblyIntoCache_CreateInterfaceProxyTypeWithTargetInterface ()
402 CheckLoadAssemblyIntoCache (delegate (IProxyBuilder builder)
404 return builder.CreateInterfaceProxyTypeWithTargetInterface (typeof (IMyInterface2), ProxyGenerationOptions.Default);
408 [Test]
409 public void LoadAssemblyIntoCache_DifferentGenerationOptions ()
411 ModuleScope savedScope = new ModuleScope (true);
412 DefaultProxyBuilder builder = new DefaultProxyBuilder (savedScope);
414 ProxyGenerationOptions options1 = new ProxyGenerationOptions();
415 options1.AddMixinInstance (new DateTime ());
416 ProxyGenerationOptions options2 = ProxyGenerationOptions.Default;
418 Type cp1 = builder.CreateClassProxy (typeof (object), options1);
419 Type cp2 = builder.CreateClassProxy (typeof (object), options2);
420 Assert.AreNotSame (cp1, cp2);
421 Assert.AreSame (cp1, builder.CreateClassProxy (typeof (object), options1));
422 Assert.AreSame (cp2, builder.CreateClassProxy (typeof (object), options2));
424 string path = savedScope.SaveAssembly ();
426 CrossAppDomainCaller.RunInOtherAppDomain (delegate (object[] args)
428 ModuleScope newScope = new ModuleScope (false);
429 DefaultProxyBuilder newBuilder = new DefaultProxyBuilder (newScope);
431 Assembly assembly = Assembly.LoadFrom ((string) args[0]);
432 newScope.LoadAssemblyIntoCache (assembly);
434 ProxyGenerationOptions newOptions1 = new ProxyGenerationOptions ();
435 newOptions1.AddMixinInstance (new DateTime ());
436 ProxyGenerationOptions newOptions2 = ProxyGenerationOptions.Default;
438 Type loadedCP1 = newBuilder.CreateClassProxy (typeof (object), newOptions1);
439 Type loadedCP2 = newBuilder.CreateClassProxy (typeof (object), newOptions2);
440 Assert.AreNotSame (loadedCP1, loadedCP2);
441 Assert.AreEqual (assembly, loadedCP1.Assembly);
442 Assert.AreEqual (assembly, loadedCP2.Assembly);
443 }, path);
445 File.Delete (path);
448 private delegate Type ProxyCreator (IProxyBuilder proxyBuilder);
450 private void CheckLoadAssemblyIntoCache (ProxyCreator creator)
452 ModuleScope savedScope = new ModuleScope (true);
453 DefaultProxyBuilder builder = new DefaultProxyBuilder (savedScope);
455 Type cp = creator (builder);
456 Assert.AreSame (cp, creator (builder));
458 string path = savedScope.SaveAssembly ();
460 CrossAppDomainCaller.RunInOtherAppDomain (delegate (object[] args)
462 ModuleScope newScope = new ModuleScope (false);
463 DefaultProxyBuilder newBuilder = new DefaultProxyBuilder (newScope);
465 Assembly assembly = Assembly.LoadFrom ((string) args[0]);
466 newScope.LoadAssemblyIntoCache (assembly);
468 Type loadedCP = assembly.GetType ((string) args[1]);
469 Assert.AreSame (loadedCP, ((ProxyCreator) args[2])(newBuilder));
470 Assert.AreEqual (assembly, ((ProxyCreator) args[2]) (newBuilder).Assembly);
471 }, path, cp.FullName, creator);
473 File.Delete (path);