/V2.2/trunk/CAL/Desktop/Composite.Tests/Modularity/DirectoryModuleCatalogFixture.Desktop.cs

# · C# · 461 lines · 346 code · 96 blank · 19 comment · 6 complexity · 6e9e9c20381b4aa3988ceb1f96d8c6bc MD5 · raw file

  1. //===================================================================================
  2. // Microsoft patterns & practices
  3. // Composite Application Guidance for Windows Presentation Foundation and Silverlight
  4. //===================================================================================
  5. // Copyright (c) Microsoft Corporation. All rights reserved.
  6. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
  7. // OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
  8. // LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  9. // FITNESS FOR A PARTICULAR PURPOSE.
  10. //===================================================================================
  11. // The example companies, organizations, products, domain names,
  12. // e-mail addresses, logos, people, places, and events depicted
  13. // herein are fictitious. No association with any real company,
  14. // organization, product, domain name, email address, logo, person,
  15. // places, or events is intended or should be inferred.
  16. //===================================================================================
  17. using System;
  18. using System.Collections.Generic;
  19. using System.IO;
  20. using System.Linq;
  21. using System.Reflection;
  22. using System.Reflection.Emit;
  23. using System.Security.Policy;
  24. using System.Text;
  25. using System.Threading;
  26. using Microsoft.Practices.Composite.Modularity;
  27. using Microsoft.VisualStudio.TestTools.UnitTesting;
  28. namespace Microsoft.Practices.Composite.Tests.Modularity
  29. {
  30. [TestClass]
  31. public class DirectoryModuleCatalogFixture
  32. {
  33. private const string ModulesDirectory1 = @".\DynamicModules\MocksModules1";
  34. private const string ModulesDirectory2 = @".\DynamicModules\AttributedModules";
  35. private const string ModulesDirectory3 = @".\DynamicModules\DependantModules";
  36. private const string ModulesDirectory4 = @".\DynamicModules\MocksModules2";
  37. private const string ModulesDirectory5 = @".\DynamicModules\ModulesMainDomain\";
  38. public DirectoryModuleCatalogFixture()
  39. {
  40. }
  41. [TestInitialize]
  42. [TestCleanup]
  43. public void CleanUpDirectories()
  44. {
  45. CompilerHelper.CleanUpDirectory(ModulesDirectory1);
  46. CompilerHelper.CleanUpDirectory(ModulesDirectory2);
  47. CompilerHelper.CleanUpDirectory(ModulesDirectory3);
  48. CompilerHelper.CleanUpDirectory(ModulesDirectory4);
  49. CompilerHelper.CleanUpDirectory(ModulesDirectory5);
  50. }
  51. [TestMethod]
  52. [ExpectedException(typeof(InvalidOperationException))]
  53. public void NullPathThrows()
  54. {
  55. DirectoryModuleCatalog catalog = new DirectoryModuleCatalog();
  56. catalog.Load();
  57. }
  58. [TestMethod]
  59. [ExpectedException(typeof(InvalidOperationException))]
  60. public void EmptyPathThrows()
  61. {
  62. DirectoryModuleCatalog catalog = new DirectoryModuleCatalog();
  63. catalog.Load();
  64. }
  65. [TestMethod]
  66. [ExpectedException(typeof(InvalidOperationException))]
  67. public void NonExistentPathThrows()
  68. {
  69. DirectoryModuleCatalog catalog = new DirectoryModuleCatalog();
  70. catalog.ModulePath = "NonExistentPath";
  71. catalog.Load();
  72. }
  73. [TestMethod]
  74. public void ShouldReturnAListOfModuleInfo()
  75. {
  76. CompilerHelper.CompileFile(@"Microsoft.Practices.Composite.Tests.Mocks.Modules.MockModuleA.cs",
  77. ModulesDirectory1 + @"\MockModuleA.dll");
  78. DirectoryModuleCatalog catalog = new DirectoryModuleCatalog();
  79. catalog.ModulePath = ModulesDirectory1;
  80. catalog.Load();
  81. ModuleInfo[] modules = catalog.Modules.ToArray();
  82. Assert.IsNotNull(modules);
  83. Assert.AreEqual(1, modules.Length);
  84. Assert.IsNotNull(modules[0].Ref);
  85. StringAssert.StartsWith(modules[0].Ref, "file://");
  86. Assert.IsTrue(modules[0].Ref.Contains(@"MockModuleA.dll"));
  87. Assert.IsNotNull(modules[0].ModuleType);
  88. StringAssert.Contains(modules[0].ModuleType, "Microsoft.Practices.Composite.Tests.Mocks.Modules.MockModuleA");
  89. }
  90. [TestMethod]
  91. public void ShouldNotThrowWithLoadFromByteAssemblies()
  92. {
  93. CompilerHelper.CleanUpDirectory(@".\CompileOutput\");
  94. CompilerHelper.CleanUpDirectory(@".\IgnoreLoadFromByteAssembliesTestDir\");
  95. var results = CompilerHelper.CompileFile(@"Microsoft.Practices.Composite.Tests.Mocks.Modules.MockModuleA.cs",
  96. @".\CompileOutput\MockModuleA.dll");
  97. CompilerHelper.CompileFile(@"Microsoft.Practices.Composite.Tests.Mocks.Modules.MockAttributedModule.cs",
  98. @".\IgnoreLoadFromByteAssembliesTestDir\MockAttributedModule.dll");
  99. string path = @".\IgnoreLoadFromByteAssembliesTestDir";
  100. AppDomain testDomain = null;
  101. try
  102. {
  103. testDomain = CreateAppDomain();
  104. RemoteDirectoryLookupCatalog remoteEnum = CreateRemoteDirectoryModuleCatalogInAppDomain(testDomain);
  105. remoteEnum.LoadDynamicEmittedModule();
  106. remoteEnum.LoadAssembliesByByte(@".\CompileOutput\MockModuleA.dll");
  107. ModuleInfo[] infos = remoteEnum.DoEnumeration(path);
  108. Assert.IsNotNull(
  109. infos.FirstOrDefault(x => x.ModuleType.IndexOf("Microsoft.Practices.Composite.Tests.Mocks.Modules.MockAttributedModule") >= 0)
  110. );
  111. }
  112. finally
  113. {
  114. if (testDomain != null)
  115. AppDomain.Unload(testDomain);
  116. }
  117. }
  118. [TestMethod]
  119. public void ShouldGetModuleNameFromAttribute()
  120. {
  121. CompilerHelper.CompileFile(@"Microsoft.Practices.Composite.Tests.Mocks.Modules.MockAttributedModule.cs",
  122. ModulesDirectory2 + @"\MockAttributedModule.dll");
  123. DirectoryModuleCatalog catalog = new DirectoryModuleCatalog();
  124. catalog.ModulePath = ModulesDirectory2;
  125. catalog.Load();
  126. ModuleInfo[] modules = catalog.Modules.ToArray();
  127. Assert.AreEqual(1, modules.Length);
  128. Assert.AreEqual("TestModule", modules[0].ModuleName);
  129. }
  130. [TestMethod]
  131. public void ShouldGetDependantModulesFromAttribute()
  132. {
  133. CompilerHelper.CompileFile(@"Microsoft.Practices.Composite.Tests.Mocks.Modules.MockDependencyModule.cs",
  134. ModulesDirectory3 + @"\DependencyModule.dll");
  135. CompilerHelper.CompileFile(@"Microsoft.Practices.Composite.Tests.Mocks.Modules.MockDependantModule.cs",
  136. ModulesDirectory3 + @"\DependantModule.dll");
  137. DirectoryModuleCatalog catalog = new DirectoryModuleCatalog();
  138. catalog.ModulePath = ModulesDirectory3;
  139. catalog.Load();
  140. ModuleInfo[] modules = catalog.Modules.ToArray();
  141. Assert.AreEqual(2, modules.Length);
  142. var dependantModule = modules.First(module => module.ModuleName == "DependantModule");
  143. var dependencyModule = modules.First(module => module.ModuleName == "DependencyModule");
  144. Assert.IsNotNull(dependantModule);
  145. Assert.IsNotNull(dependencyModule);
  146. Assert.IsNotNull(dependantModule.DependsOn);
  147. Assert.AreEqual(1, dependantModule.DependsOn.Count);
  148. Assert.AreEqual(dependencyModule.ModuleName, dependantModule.DependsOn[0]);
  149. }
  150. [TestMethod]
  151. public void UseClassNameAsModuleNameWhenNotSpecifiedInAttribute()
  152. {
  153. CompilerHelper.CompileFile(@"Microsoft.Practices.Composite.Tests.Mocks.Modules.MockModuleA.cs",
  154. ModulesDirectory1 + @"\MockModuleA.dll");
  155. DirectoryModuleCatalog catalog = new DirectoryModuleCatalog();
  156. catalog.ModulePath = ModulesDirectory1;
  157. catalog.Load();
  158. ModuleInfo[] modules = catalog.Modules.ToArray();
  159. Assert.IsNotNull(modules);
  160. Assert.AreEqual("MockModuleA", modules[0].ModuleName);
  161. }
  162. [TestMethod]
  163. public void ShouldDefaultInitializationModeToWhenAvailable()
  164. {
  165. CompilerHelper.CompileFile(@"Microsoft.Practices.Composite.Tests.Mocks.Modules.MockModuleA.cs",
  166. ModulesDirectory1 + @"\MockModuleA.dll");
  167. DirectoryModuleCatalog catalog = new DirectoryModuleCatalog();
  168. catalog.ModulePath = ModulesDirectory1;
  169. catalog.Load();
  170. ModuleInfo[] modules = catalog.Modules.ToArray();
  171. Assert.IsNotNull(modules);
  172. Assert.AreEqual(InitializationMode.WhenAvailable, modules[0].InitializationMode);
  173. }
  174. [TestMethod]
  175. public void ShouldGetOnDemandFromAttribute()
  176. {
  177. CompilerHelper.CompileFile(@"Microsoft.Practices.Composite.Tests.Mocks.Modules.MockAttributedModule.cs",
  178. ModulesDirectory3 + @"\MockAttributedModule.dll");
  179. DirectoryModuleCatalog catalog = new DirectoryModuleCatalog();
  180. catalog.ModulePath = ModulesDirectory3;
  181. catalog.Load();
  182. ModuleInfo[] modules = catalog.Modules.ToArray();
  183. Assert.AreEqual(1, modules.Length);
  184. Assert.AreEqual(InitializationMode.OnDemand, modules[0].InitializationMode);
  185. }
  186. [TestMethod]
  187. public void ShouldHonorStartupLoadedAttribute()
  188. {
  189. CompilerHelper.CompileFile(@"Microsoft.Practices.Composite.Tests.Mocks.Modules.MockStartupLoadedAttributedModule.cs",
  190. ModulesDirectory3 + @"\MockStartupLoadedAttributedModule.dll");
  191. DirectoryModuleCatalog catalog = new DirectoryModuleCatalog();
  192. catalog.ModulePath = ModulesDirectory3;
  193. catalog.Load();
  194. ModuleInfo[] modules = catalog.Modules.ToArray();
  195. Assert.AreEqual(1, modules.Length);
  196. Assert.AreEqual(InitializationMode.OnDemand, modules[0].InitializationMode);
  197. }
  198. [TestMethod]
  199. public void ShouldNotLoadAssembliesInCurrentAppDomain()
  200. {
  201. CompilerHelper.CompileFile(@"Microsoft.Practices.Composite.Tests.Mocks.Modules.MockModuleA.cs",
  202. ModulesDirectory4 + @"\MockModuleA.dll");
  203. DirectoryModuleCatalog catalog = new DirectoryModuleCatalog();
  204. catalog.ModulePath = ModulesDirectory4;
  205. catalog.Load();
  206. ModuleInfo[] modules = catalog.Modules.ToArray();
  207. Assembly loadedAssembly = Array.Find<Assembly>(AppDomain.CurrentDomain.GetAssemblies(), assembly => assembly.Location.Equals(modules[0].Ref, StringComparison.InvariantCultureIgnoreCase));
  208. Assert.IsNull(loadedAssembly);
  209. }
  210. [TestMethod]
  211. public void ShouldNotGetModuleInfoForAnAssemblyAlreadyLoadedInTheMainDomain()
  212. {
  213. var assemblyPath = Assembly.GetCallingAssembly().Location;
  214. DirectoryModuleCatalog catalog = new DirectoryModuleCatalog();
  215. catalog.ModulePath = ModulesDirectory5;
  216. catalog.Load();
  217. ModuleInfo[] modules = catalog.Modules.ToArray();
  218. Assert.AreEqual(0, modules.Length);
  219. }
  220. [TestMethod]
  221. public void ShouldLoadAssemblyEvenIfTheyAreReferencingEachOther()
  222. {
  223. CompilerHelper.CompileFile(@"Microsoft.Practices.Composite.Tests.Mocks.Modules.MockModuleA.cs",
  224. ModulesDirectory4 + @"\MockModuleZZZ.dll");
  225. CompilerHelper.CompileFile(@"Microsoft.Practices.Composite.Tests.Mocks.Modules.MockModuleReferencingOtherModule.cs",
  226. ModulesDirectory4 + @"\MockModuleReferencingOtherModule.dll", ModulesDirectory4 + @"\MockModuleZZZ.dll");
  227. DirectoryModuleCatalog catalog = new DirectoryModuleCatalog();
  228. catalog.ModulePath = ModulesDirectory4;
  229. catalog.Load();
  230. ModuleInfo[] modules = catalog.Modules.ToArray();
  231. Assert.AreEqual(2, modules.Count());
  232. }
  233. [TestMethod]
  234. public void CreateChildAppDomainHasParentEvidenceAndSetup()
  235. {
  236. TestableDirectoryModuleCatalog catalog = new TestableDirectoryModuleCatalog();
  237. catalog.ModulePath = ModulesDirectory4;
  238. catalog.Load();
  239. Evidence parentEvidence = new Evidence();
  240. AppDomainSetup parentSetup = new AppDomainSetup();
  241. parentSetup.ApplicationName = "Test Parent";
  242. AppDomain parentAppDomain = AppDomain.CreateDomain("Parent", parentEvidence, parentSetup);
  243. AppDomain childDomain = catalog.BuildChildDomain(parentAppDomain);
  244. Assert.AreEqual(parentEvidence.Count, childDomain.Evidence.Count);
  245. Assert.AreEqual("Test Parent", childDomain.SetupInformation.ApplicationName);
  246. Assert.AreNotEqual(AppDomain.CurrentDomain.Evidence.Count, childDomain.Evidence.Count);
  247. Assert.AreNotEqual(AppDomain.CurrentDomain.SetupInformation.ApplicationName, childDomain.SetupInformation.ApplicationName);
  248. }
  249. [TestMethod]
  250. public void ShouldLoadFilesEvenIfDynamicAssemblyExists()
  251. {
  252. CompilerHelper.CleanUpDirectory(@".\CompileOutput\");
  253. CompilerHelper.CleanUpDirectory(@".\IgnoreDynamicGeneratedFilesTestDir\");
  254. CompilerHelper.CompileFile(@"Microsoft.Practices.Composite.Tests.Mocks.Modules.MockAttributedModule.cs",
  255. @".\IgnoreDynamicGeneratedFilesTestDir\MockAttributedModule.dll");
  256. string path = @".\IgnoreDynamicGeneratedFilesTestDir";
  257. AppDomain testDomain = null;
  258. try
  259. {
  260. testDomain = CreateAppDomain();
  261. RemoteDirectoryLookupCatalog remoteEnum = CreateRemoteDirectoryModuleCatalogInAppDomain(testDomain);
  262. remoteEnum.LoadDynamicEmittedModule();
  263. ModuleInfo[] infos = remoteEnum.DoEnumeration(path);
  264. Assert.IsNotNull(
  265. infos.FirstOrDefault(x => x.ModuleType.IndexOf("Microsoft.Practices.Composite.Tests.Mocks.Modules.MockAttributedModule") >= 0)
  266. );
  267. }
  268. finally
  269. {
  270. if (testDomain != null)
  271. AppDomain.Unload(testDomain);
  272. }
  273. }
  274. [TestMethod]
  275. public void ShouldLoadAssemblyEvenIfIsExposingTypesFromAnAssemblyInTheGac()
  276. {
  277. CompilerHelper.CompileFile(@"Microsoft.Practices.Composite.Tests.Mocks.Modules.MockExposingTypeFromGacAssemblyModule.cs",
  278. ModulesDirectory4 + @"\MockExposingTypeFromGacAssemblyModule.dll", @"System.Transactions.dll");
  279. DirectoryModuleCatalog catalog = new DirectoryModuleCatalog();
  280. catalog.ModulePath = ModulesDirectory4;
  281. catalog.Load();
  282. ModuleInfo[] modules = catalog.Modules.ToArray();
  283. Assert.AreEqual(1, modules.Count());
  284. }
  285. [TestMethod]
  286. public void ShouldNotFailWhenAlreadyLoadedAssembliesAreAlsoFoundOnTargetDirectory()
  287. {
  288. CompilerHelper.CompileFile(@"Microsoft.Practices.Composite.Tests.Mocks.Modules.MockModuleA.cs",
  289. ModulesDirectory1 + @"\MockModuleA.dll");
  290. string filename = typeof(DirectoryModuleCatalog).Assembly.Location;
  291. string destinationFileName = Path.Combine(ModulesDirectory1, Path.GetFileName(filename));
  292. File.Copy(filename, destinationFileName);
  293. DirectoryModuleCatalog catalog = new DirectoryModuleCatalog();
  294. catalog.ModulePath = ModulesDirectory1;
  295. catalog.Load();
  296. ModuleInfo[] modules = catalog.Modules.ToArray();
  297. Assert.AreEqual(1, modules.Length);
  298. }
  299. [TestMethod]
  300. public void ShouldIgnoreAbstractClassesThatImplementIModule()
  301. {
  302. CompilerHelper.CleanUpDirectory(ModulesDirectory1);
  303. CompilerHelper.CompileFile(@"Microsoft.Practices.Composite.Tests.Mocks.Modules.MockAbstractModule.cs",
  304. ModulesDirectory1 + @"\MockAbstractModule.dll");
  305. string filename = typeof(DirectoryModuleCatalog).Assembly.Location;
  306. string destinationFileName = Path.Combine(ModulesDirectory1, Path.GetFileName(filename));
  307. File.Copy(filename, destinationFileName);
  308. DirectoryModuleCatalog catalog = new DirectoryModuleCatalog();
  309. catalog.ModulePath = ModulesDirectory1;
  310. catalog.Load();
  311. ModuleInfo[] modules = catalog.Modules.ToArray();
  312. Assert.AreEqual(1, modules.Length);
  313. Assert.AreEqual("MockInheritingModule", modules[0].ModuleName);
  314. CompilerHelper.CleanUpDirectory(ModulesDirectory1);
  315. }
  316. private AppDomain CreateAppDomain()
  317. {
  318. Evidence evidence = AppDomain.CurrentDomain.Evidence;
  319. AppDomainSetup setup = AppDomain.CurrentDomain.SetupInformation;
  320. return AppDomain.CreateDomain("TestDomain", evidence, setup);
  321. }
  322. private RemoteDirectoryLookupCatalog CreateRemoteDirectoryModuleCatalogInAppDomain(AppDomain testDomain)
  323. {
  324. RemoteDirectoryLookupCatalog remoteEnum;
  325. Type remoteEnumType = typeof(RemoteDirectoryLookupCatalog);
  326. remoteEnum = (RemoteDirectoryLookupCatalog)testDomain.CreateInstanceFrom(
  327. remoteEnumType.Assembly.Location, remoteEnumType.FullName).Unwrap();
  328. return remoteEnum;
  329. }
  330. private class TestableDirectoryModuleCatalog : DirectoryModuleCatalog
  331. {
  332. public new AppDomain BuildChildDomain(AppDomain currentDomain)
  333. {
  334. return base.BuildChildDomain(currentDomain);
  335. }
  336. }
  337. private class RemoteDirectoryLookupCatalog : MarshalByRefObject
  338. {
  339. public void LoadAssembliesByByte(string assemblyPath)
  340. {
  341. byte[] assemblyBytes = File.ReadAllBytes(assemblyPath);
  342. AppDomain.CurrentDomain.Load(assemblyBytes);
  343. }
  344. public ModuleInfo[] DoEnumeration(string path)
  345. {
  346. DirectoryModuleCatalog catalog = new DirectoryModuleCatalog();
  347. catalog.ModulePath = path;
  348. catalog.Load();
  349. return catalog.Modules.ToArray();
  350. }
  351. public void LoadDynamicEmittedModule()
  352. {
  353. // create a dynamic assembly and module
  354. AssemblyName assemblyName = new AssemblyName();
  355. assemblyName.Name = "DynamicBuiltAssembly";
  356. AssemblyBuilder assemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
  357. ModuleBuilder module = assemblyBuilder.DefineDynamicModule("DynamicBuiltAssembly.dll");
  358. // create a new type
  359. TypeBuilder typeBuilder = module.DefineType("DynamicBuiltType", TypeAttributes.Public | TypeAttributes.Class);
  360. // Create the type
  361. Type helloWorldType = typeBuilder.CreateType();
  362. }
  363. }
  364. }
  365. }