PageRenderTime 59ms CodeModel.GetById 7ms app.highlight 44ms RepoModel.GetById 1ms app.codeStats 1ms

/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//===================================================================================
 17using System;
 18using System.Collections.Generic;
 19using System.IO;
 20using System.Linq;
 21using System.Reflection;
 22using System.Reflection.Emit;
 23using System.Security.Policy;
 24using System.Text;
 25using System.Threading;
 26using Microsoft.Practices.Composite.Modularity;
 27using Microsoft.VisualStudio.TestTools.UnitTesting;
 28
 29namespace Microsoft.Practices.Composite.Tests.Modularity
 30{
 31    [TestClass]
 32    public class DirectoryModuleCatalogFixture
 33    {
 34        private const string ModulesDirectory1 = @".\DynamicModules\MocksModules1";
 35        private const string ModulesDirectory2 = @".\DynamicModules\AttributedModules";
 36        private const string ModulesDirectory3 = @".\DynamicModules\DependantModules";
 37        private const string ModulesDirectory4 = @".\DynamicModules\MocksModules2";
 38        private const string ModulesDirectory5 = @".\DynamicModules\ModulesMainDomain\";
 39
 40        public DirectoryModuleCatalogFixture()
 41        {
 42        }
 43
 44        [TestInitialize]
 45        [TestCleanup]
 46        public void CleanUpDirectories()
 47        {
 48            CompilerHelper.CleanUpDirectory(ModulesDirectory1);
 49            CompilerHelper.CleanUpDirectory(ModulesDirectory2);
 50            CompilerHelper.CleanUpDirectory(ModulesDirectory3);
 51            CompilerHelper.CleanUpDirectory(ModulesDirectory4);
 52            CompilerHelper.CleanUpDirectory(ModulesDirectory5);
 53        }
 54
 55        [TestMethod]
 56        [ExpectedException(typeof(InvalidOperationException))]
 57        public void NullPathThrows()
 58        {
 59            DirectoryModuleCatalog catalog = new DirectoryModuleCatalog();
 60            catalog.Load();
 61        }
 62
 63        [TestMethod]
 64        [ExpectedException(typeof(InvalidOperationException))]
 65        public void EmptyPathThrows()
 66        {
 67            DirectoryModuleCatalog catalog = new DirectoryModuleCatalog();
 68            catalog.Load();
 69        }
 70
 71        [TestMethod]
 72        [ExpectedException(typeof(InvalidOperationException))]
 73        public void NonExistentPathThrows()
 74        {
 75            DirectoryModuleCatalog catalog = new DirectoryModuleCatalog();
 76            catalog.ModulePath = "NonExistentPath";
 77            catalog.Load();
 78        }
 79
 80        [TestMethod]
 81        public void ShouldReturnAListOfModuleInfo()
 82        {
 83            CompilerHelper.CompileFile(@"Microsoft.Practices.Composite.Tests.Mocks.Modules.MockModuleA.cs",
 84                                       ModulesDirectory1 + @"\MockModuleA.dll");
 85
 86
 87            DirectoryModuleCatalog catalog = new DirectoryModuleCatalog();
 88            catalog.ModulePath = ModulesDirectory1;
 89            catalog.Load();
 90
 91            ModuleInfo[] modules = catalog.Modules.ToArray();
 92
 93            Assert.IsNotNull(modules);
 94            Assert.AreEqual(1, modules.Length);
 95            Assert.IsNotNull(modules[0].Ref);
 96            StringAssert.StartsWith(modules[0].Ref, "file://");
 97            Assert.IsTrue(modules[0].Ref.Contains(@"MockModuleA.dll"));
 98            Assert.IsNotNull(modules[0].ModuleType);
 99            StringAssert.Contains(modules[0].ModuleType, "Microsoft.Practices.Composite.Tests.Mocks.Modules.MockModuleA");
100        }
101
102        [TestMethod]
103        public void ShouldNotThrowWithLoadFromByteAssemblies()
104        {
105            CompilerHelper.CleanUpDirectory(@".\CompileOutput\");
106            CompilerHelper.CleanUpDirectory(@".\IgnoreLoadFromByteAssembliesTestDir\");
107            var results = CompilerHelper.CompileFile(@"Microsoft.Practices.Composite.Tests.Mocks.Modules.MockModuleA.cs",
108                                                     @".\CompileOutput\MockModuleA.dll");
109
110            CompilerHelper.CompileFile(@"Microsoft.Practices.Composite.Tests.Mocks.Modules.MockAttributedModule.cs",
111                                       @".\IgnoreLoadFromByteAssembliesTestDir\MockAttributedModule.dll");
112
113            string path = @".\IgnoreLoadFromByteAssembliesTestDir";
114
115            AppDomain testDomain = null;
116            try
117            {
118                testDomain = CreateAppDomain();
119                RemoteDirectoryLookupCatalog remoteEnum = CreateRemoteDirectoryModuleCatalogInAppDomain(testDomain);
120
121                remoteEnum.LoadDynamicEmittedModule();
122
123                remoteEnum.LoadAssembliesByByte(@".\CompileOutput\MockModuleA.dll");
124
125                ModuleInfo[] infos = remoteEnum.DoEnumeration(path);
126
127
128                Assert.IsNotNull(
129                    infos.FirstOrDefault(x => x.ModuleType.IndexOf("Microsoft.Practices.Composite.Tests.Mocks.Modules.MockAttributedModule") >= 0)
130                    );
131            }
132            finally
133            {
134                if (testDomain != null)
135                    AppDomain.Unload(testDomain);
136            }
137        }
138
139        [TestMethod]
140        public void ShouldGetModuleNameFromAttribute()
141        {
142            CompilerHelper.CompileFile(@"Microsoft.Practices.Composite.Tests.Mocks.Modules.MockAttributedModule.cs",
143                                       ModulesDirectory2 + @"\MockAttributedModule.dll");
144
145
146            DirectoryModuleCatalog catalog = new DirectoryModuleCatalog();
147            catalog.ModulePath = ModulesDirectory2;
148            catalog.Load();
149
150            ModuleInfo[] modules = catalog.Modules.ToArray();
151
152            Assert.AreEqual(1, modules.Length);
153            Assert.AreEqual("TestModule", modules[0].ModuleName);
154        }
155
156        [TestMethod]
157        public void ShouldGetDependantModulesFromAttribute()
158        {
159            CompilerHelper.CompileFile(@"Microsoft.Practices.Composite.Tests.Mocks.Modules.MockDependencyModule.cs",
160                                       ModulesDirectory3 + @"\DependencyModule.dll");
161
162            CompilerHelper.CompileFile(@"Microsoft.Practices.Composite.Tests.Mocks.Modules.MockDependantModule.cs",
163                                       ModulesDirectory3 + @"\DependantModule.dll");
164
165            DirectoryModuleCatalog catalog = new DirectoryModuleCatalog();
166            catalog.ModulePath = ModulesDirectory3;
167            catalog.Load();
168
169            ModuleInfo[] modules = catalog.Modules.ToArray();
170
171            Assert.AreEqual(2, modules.Length);
172            var dependantModule = modules.First(module => module.ModuleName == "DependantModule");
173            var dependencyModule = modules.First(module => module.ModuleName == "DependencyModule");
174            Assert.IsNotNull(dependantModule);
175            Assert.IsNotNull(dependencyModule);
176            Assert.IsNotNull(dependantModule.DependsOn);
177            Assert.AreEqual(1, dependantModule.DependsOn.Count);
178            Assert.AreEqual(dependencyModule.ModuleName, dependantModule.DependsOn[0]);
179        }
180
181        [TestMethod]
182        public void UseClassNameAsModuleNameWhenNotSpecifiedInAttribute()
183        {
184            CompilerHelper.CompileFile(@"Microsoft.Practices.Composite.Tests.Mocks.Modules.MockModuleA.cs",
185                                       ModulesDirectory1 + @"\MockModuleA.dll");
186
187            DirectoryModuleCatalog catalog = new DirectoryModuleCatalog();
188            catalog.ModulePath = ModulesDirectory1;
189            catalog.Load();
190
191            ModuleInfo[] modules = catalog.Modules.ToArray();
192
193            Assert.IsNotNull(modules);
194            Assert.AreEqual("MockModuleA", modules[0].ModuleName);
195        }
196
197        [TestMethod]
198        public void ShouldDefaultInitializationModeToWhenAvailable()
199        {
200            CompilerHelper.CompileFile(@"Microsoft.Practices.Composite.Tests.Mocks.Modules.MockModuleA.cs",
201                                       ModulesDirectory1 + @"\MockModuleA.dll");
202
203            DirectoryModuleCatalog catalog = new DirectoryModuleCatalog();
204            catalog.ModulePath = ModulesDirectory1;
205            catalog.Load();
206
207            ModuleInfo[] modules = catalog.Modules.ToArray();
208
209            Assert.IsNotNull(modules);
210            Assert.AreEqual(InitializationMode.WhenAvailable, modules[0].InitializationMode);
211        }
212
213        [TestMethod]
214        public void ShouldGetOnDemandFromAttribute()
215        {
216            CompilerHelper.CompileFile(@"Microsoft.Practices.Composite.Tests.Mocks.Modules.MockAttributedModule.cs",
217                                       ModulesDirectory3 + @"\MockAttributedModule.dll");
218
219            DirectoryModuleCatalog catalog = new DirectoryModuleCatalog();
220            catalog.ModulePath = ModulesDirectory3;
221            catalog.Load();
222
223            ModuleInfo[] modules = catalog.Modules.ToArray();
224            
225            Assert.AreEqual(1, modules.Length);
226            Assert.AreEqual(InitializationMode.OnDemand, modules[0].InitializationMode);
227
228        }
229
230        [TestMethod]
231        public void ShouldHonorStartupLoadedAttribute()
232        {
233            CompilerHelper.CompileFile(@"Microsoft.Practices.Composite.Tests.Mocks.Modules.MockStartupLoadedAttributedModule.cs",
234                           ModulesDirectory3 + @"\MockStartupLoadedAttributedModule.dll");
235
236            DirectoryModuleCatalog catalog = new DirectoryModuleCatalog();
237            catalog.ModulePath = ModulesDirectory3;
238            catalog.Load();
239
240            ModuleInfo[] modules = catalog.Modules.ToArray();
241
242            Assert.AreEqual(1, modules.Length);
243            Assert.AreEqual(InitializationMode.OnDemand, modules[0].InitializationMode);
244        }
245
246        [TestMethod]
247        public void ShouldNotLoadAssembliesInCurrentAppDomain()
248        {
249            CompilerHelper.CompileFile(@"Microsoft.Practices.Composite.Tests.Mocks.Modules.MockModuleA.cs",
250                                       ModulesDirectory4 + @"\MockModuleA.dll");
251
252            DirectoryModuleCatalog catalog = new DirectoryModuleCatalog();
253            catalog.ModulePath = ModulesDirectory4;
254            catalog.Load();
255
256            ModuleInfo[] modules = catalog.Modules.ToArray();
257
258            Assembly loadedAssembly = Array.Find<Assembly>(AppDomain.CurrentDomain.GetAssemblies(), assembly => assembly.Location.Equals(modules[0].Ref, StringComparison.InvariantCultureIgnoreCase));
259            Assert.IsNull(loadedAssembly);
260        }
261
262        [TestMethod]
263        public void ShouldNotGetModuleInfoForAnAssemblyAlreadyLoadedInTheMainDomain()
264        {
265            var assemblyPath = Assembly.GetCallingAssembly().Location;
266            DirectoryModuleCatalog catalog = new DirectoryModuleCatalog();
267            catalog.ModulePath = ModulesDirectory5;
268            catalog.Load();
269
270            ModuleInfo[] modules = catalog.Modules.ToArray();
271
272            Assert.AreEqual(0, modules.Length);
273        }
274
275        [TestMethod]
276        public void ShouldLoadAssemblyEvenIfTheyAreReferencingEachOther()
277        {
278            CompilerHelper.CompileFile(@"Microsoft.Practices.Composite.Tests.Mocks.Modules.MockModuleA.cs",
279                                       ModulesDirectory4 + @"\MockModuleZZZ.dll");
280
281            CompilerHelper.CompileFile(@"Microsoft.Practices.Composite.Tests.Mocks.Modules.MockModuleReferencingOtherModule.cs",
282                                       ModulesDirectory4 + @"\MockModuleReferencingOtherModule.dll", ModulesDirectory4 + @"\MockModuleZZZ.dll");
283
284            DirectoryModuleCatalog catalog = new DirectoryModuleCatalog();
285            catalog.ModulePath = ModulesDirectory4;
286            catalog.Load();
287
288            ModuleInfo[] modules = catalog.Modules.ToArray();
289
290            Assert.AreEqual(2, modules.Count());
291        }
292
293        [TestMethod]
294        public void CreateChildAppDomainHasParentEvidenceAndSetup()
295        {
296            TestableDirectoryModuleCatalog catalog = new TestableDirectoryModuleCatalog();
297            catalog.ModulePath = ModulesDirectory4;
298            catalog.Load();
299            Evidence parentEvidence = new Evidence();
300            AppDomainSetup parentSetup = new AppDomainSetup();
301            parentSetup.ApplicationName = "Test Parent";
302            AppDomain parentAppDomain = AppDomain.CreateDomain("Parent", parentEvidence, parentSetup);
303            AppDomain childDomain = catalog.BuildChildDomain(parentAppDomain);
304            Assert.AreEqual(parentEvidence.Count, childDomain.Evidence.Count);
305            Assert.AreEqual("Test Parent", childDomain.SetupInformation.ApplicationName);
306            Assert.AreNotEqual(AppDomain.CurrentDomain.Evidence.Count, childDomain.Evidence.Count);
307            Assert.AreNotEqual(AppDomain.CurrentDomain.SetupInformation.ApplicationName, childDomain.SetupInformation.ApplicationName);
308        }
309
310
311        [TestMethod]
312        public void ShouldLoadFilesEvenIfDynamicAssemblyExists()
313        {
314            CompilerHelper.CleanUpDirectory(@".\CompileOutput\");
315            CompilerHelper.CleanUpDirectory(@".\IgnoreDynamicGeneratedFilesTestDir\");
316            CompilerHelper.CompileFile(@"Microsoft.Practices.Composite.Tests.Mocks.Modules.MockAttributedModule.cs",
317                                       @".\IgnoreDynamicGeneratedFilesTestDir\MockAttributedModule.dll");
318
319            string path = @".\IgnoreDynamicGeneratedFilesTestDir";
320
321            AppDomain testDomain = null;
322            try
323            {
324                testDomain = CreateAppDomain();
325                RemoteDirectoryLookupCatalog remoteEnum = CreateRemoteDirectoryModuleCatalogInAppDomain(testDomain);
326
327                remoteEnum.LoadDynamicEmittedModule();
328
329                ModuleInfo[] infos = remoteEnum.DoEnumeration(path);
330
331                Assert.IsNotNull(
332                    infos.FirstOrDefault(x => x.ModuleType.IndexOf("Microsoft.Practices.Composite.Tests.Mocks.Modules.MockAttributedModule") >= 0)
333                    );
334            }
335            finally
336            {
337                if (testDomain != null)
338                    AppDomain.Unload(testDomain);
339            }
340        }
341
342        [TestMethod]
343        public void ShouldLoadAssemblyEvenIfIsExposingTypesFromAnAssemblyInTheGac()
344        {
345            CompilerHelper.CompileFile(@"Microsoft.Practices.Composite.Tests.Mocks.Modules.MockExposingTypeFromGacAssemblyModule.cs",
346                                       ModulesDirectory4 + @"\MockExposingTypeFromGacAssemblyModule.dll", @"System.Transactions.dll");
347
348            DirectoryModuleCatalog catalog = new DirectoryModuleCatalog();
349            catalog.ModulePath = ModulesDirectory4;
350            catalog.Load();
351
352            ModuleInfo[] modules = catalog.Modules.ToArray();
353
354            Assert.AreEqual(1, modules.Count());
355        }
356
357        [TestMethod]
358        public void ShouldNotFailWhenAlreadyLoadedAssembliesAreAlsoFoundOnTargetDirectory()
359        {
360            CompilerHelper.CompileFile(@"Microsoft.Practices.Composite.Tests.Mocks.Modules.MockModuleA.cs",
361                                       ModulesDirectory1 + @"\MockModuleA.dll");
362
363            string filename = typeof(DirectoryModuleCatalog).Assembly.Location;
364            string destinationFileName = Path.Combine(ModulesDirectory1, Path.GetFileName(filename));
365            File.Copy(filename, destinationFileName);
366
367            DirectoryModuleCatalog catalog = new DirectoryModuleCatalog();
368            catalog.ModulePath = ModulesDirectory1;
369            catalog.Load();
370
371            ModuleInfo[] modules = catalog.Modules.ToArray();
372            Assert.AreEqual(1, modules.Length);
373        }
374
375        [TestMethod]
376        public void ShouldIgnoreAbstractClassesThatImplementIModule()
377        {
378            CompilerHelper.CleanUpDirectory(ModulesDirectory1);
379            CompilerHelper.CompileFile(@"Microsoft.Practices.Composite.Tests.Mocks.Modules.MockAbstractModule.cs",
380                                     ModulesDirectory1 + @"\MockAbstractModule.dll");
381
382            string filename = typeof(DirectoryModuleCatalog).Assembly.Location;
383            string destinationFileName = Path.Combine(ModulesDirectory1, Path.GetFileName(filename));
384            File.Copy(filename, destinationFileName);
385
386            DirectoryModuleCatalog catalog = new DirectoryModuleCatalog();
387            catalog.ModulePath = ModulesDirectory1;
388            catalog.Load();
389
390            ModuleInfo[] modules = catalog.Modules.ToArray();
391            Assert.AreEqual(1, modules.Length);
392            Assert.AreEqual("MockInheritingModule", modules[0].ModuleName);
393
394            CompilerHelper.CleanUpDirectory(ModulesDirectory1);
395        }
396
397        
398	
399
400        private AppDomain CreateAppDomain()
401        {
402            Evidence evidence = AppDomain.CurrentDomain.Evidence;
403            AppDomainSetup setup = AppDomain.CurrentDomain.SetupInformation;
404
405            return AppDomain.CreateDomain("TestDomain", evidence, setup);
406        }
407
408        private RemoteDirectoryLookupCatalog CreateRemoteDirectoryModuleCatalogInAppDomain(AppDomain testDomain)
409        {
410            RemoteDirectoryLookupCatalog remoteEnum;
411            Type remoteEnumType = typeof(RemoteDirectoryLookupCatalog);
412
413            remoteEnum = (RemoteDirectoryLookupCatalog)testDomain.CreateInstanceFrom(
414                                               remoteEnumType.Assembly.Location, remoteEnumType.FullName).Unwrap();
415            return remoteEnum;
416        }
417
418        private class TestableDirectoryModuleCatalog : DirectoryModuleCatalog
419        {
420            public new AppDomain BuildChildDomain(AppDomain currentDomain)
421            {
422                return base.BuildChildDomain(currentDomain);
423            }
424        }
425
426
427        private class RemoteDirectoryLookupCatalog : MarshalByRefObject
428        {
429
430            public void LoadAssembliesByByte(string assemblyPath)
431            {
432                byte[] assemblyBytes = File.ReadAllBytes(assemblyPath);
433                AppDomain.CurrentDomain.Load(assemblyBytes);
434            }
435
436            public ModuleInfo[] DoEnumeration(string path)
437            {
438                DirectoryModuleCatalog catalog = new DirectoryModuleCatalog();
439                catalog.ModulePath = path;
440                catalog.Load();
441                return catalog.Modules.ToArray();
442            }
443
444            public void LoadDynamicEmittedModule()
445            {
446                // create a dynamic assembly and module 
447                AssemblyName assemblyName = new AssemblyName();
448                assemblyName.Name = "DynamicBuiltAssembly";
449                AssemblyBuilder assemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
450                ModuleBuilder module = assemblyBuilder.DefineDynamicModule("DynamicBuiltAssembly.dll");
451
452                // create a new type
453                TypeBuilder typeBuilder = module.DefineType("DynamicBuiltType", TypeAttributes.Public | TypeAttributes.Class);
454
455                // Create the type
456                Type helloWorldType = typeBuilder.CreateType();
457
458            }
459        }
460    }
461}