/Test/Mono.Cecil.Tests/ModuleTests.cs

http://github.com/jbevain/cecil · C# · 328 lines · 263 code · 63 blank · 2 comment · 3 complexity · 7724840c0dd889a8c74a498046ea78e8 MD5 · raw file

  1. using System;
  2. using System.Diagnostics;
  3. using System.IO;
  4. using System.Linq;
  5. using Mono.Cecil;
  6. using NUnit.Framework;
  7. namespace Mono.Cecil.Tests {
  8. [TestFixture]
  9. public class ModuleTests : BaseTestFixture {
  10. [Test]
  11. public void CreateModuleEscapesAssemblyName ()
  12. {
  13. var module = ModuleDefinition.CreateModule ("Test.dll", ModuleKind.Dll);
  14. Assert.AreEqual ("Test", module.Assembly.Name.Name);
  15. module = ModuleDefinition.CreateModule ("Test.exe", ModuleKind.Console);
  16. Assert.AreEqual ("Test", module.Assembly.Name.Name);
  17. }
  18. [Test]
  19. public void SingleModule ()
  20. {
  21. TestModule ("hello.exe", module => {
  22. var assembly = module.Assembly;
  23. Assert.AreEqual (1, assembly.Modules.Count);
  24. Assert.IsNotNull (assembly.MainModule);
  25. });
  26. }
  27. [Test]
  28. public void EntryPoint ()
  29. {
  30. TestModule ("hello.exe", module => {
  31. var entry_point = module.EntryPoint;
  32. Assert.IsNotNull (entry_point);
  33. Assert.AreEqual ("System.Void Program::Main()", entry_point.ToString ());
  34. });
  35. }
  36. [Test]
  37. public void MultiModules ()
  38. {
  39. IgnoreOnCoreClr ();
  40. TestModule("mma.exe", module => {
  41. var assembly = module.Assembly;
  42. Assert.AreEqual (3, assembly.Modules.Count);
  43. Assert.AreEqual ("mma.exe", assembly.Modules [0].Name);
  44. Assert.AreEqual (ModuleKind.Console, assembly.Modules [0].Kind);
  45. Assert.AreEqual ("moda.netmodule", assembly.Modules [1].Name);
  46. Assert.AreEqual ("eedb4721-6c3e-4d9a-be30-49021121dd92", assembly.Modules [1].Mvid.ToString ());
  47. Assert.AreEqual (ModuleKind.NetModule, assembly.Modules [1].Kind);
  48. Assert.AreEqual ("modb.netmodule", assembly.Modules [2].Name);
  49. Assert.AreEqual ("46c5c577-11b2-4ea0-bb3c-3c71f1331dd0", assembly.Modules [2].Mvid.ToString ());
  50. Assert.AreEqual (ModuleKind.NetModule, assembly.Modules [2].Kind);
  51. });
  52. }
  53. [Test]
  54. public void ModuleInformation ()
  55. {
  56. TestModule ("hello.exe", module => {
  57. Assert.IsNotNull (module);
  58. Assert.AreEqual ("hello.exe", module.Name);
  59. Assert.AreEqual (new Guid ("C3BC2BD3-2576-4D00-A80E-465B5632415F"), module.Mvid);
  60. });
  61. }
  62. [Test]
  63. public void AssemblyReferences ()
  64. {
  65. TestModule ("hello.exe", module => {
  66. Assert.AreEqual (1, module.AssemblyReferences.Count);
  67. var reference = module.AssemblyReferences [0];
  68. Assert.AreEqual ("mscorlib", reference.Name);
  69. Assert.AreEqual (new Version (2, 0, 0, 0), reference.Version);
  70. Assert.AreEqual (new byte [] { 0xB7, 0x7A, 0x5C, 0x56, 0x19, 0x34, 0xE0, 0x89 }, reference.PublicKeyToken);
  71. });
  72. }
  73. [Test]
  74. public void ModuleReferences ()
  75. {
  76. TestModule ("pinvoke.exe", module => {
  77. Assert.AreEqual (2, module.ModuleReferences.Count);
  78. Assert.AreEqual ("kernel32.dll", module.ModuleReferences [0].Name);
  79. Assert.AreEqual ("shell32.dll", module.ModuleReferences [1].Name);
  80. });
  81. }
  82. [Test]
  83. public void Types ()
  84. {
  85. TestModule ("hello.exe", module => {
  86. Assert.AreEqual (2, module.Types.Count);
  87. Assert.AreEqual ("<Module>", module.Types [0].FullName);
  88. Assert.AreEqual ("<Module>", module.GetType ("<Module>").FullName);
  89. Assert.AreEqual ("Program", module.Types [1].FullName);
  90. Assert.AreEqual ("Program", module.GetType ("Program").FullName);
  91. });
  92. }
  93. [Test]
  94. public void LinkedResource ()
  95. {
  96. TestModule ("libres.dll", module => {
  97. var resource = module.Resources.Where (res => res.Name == "linked.txt").First () as LinkedResource;
  98. Assert.IsNotNull (resource);
  99. Assert.AreEqual ("linked.txt", resource.Name);
  100. Assert.AreEqual ("linked.txt", resource.File);
  101. Assert.AreEqual (ResourceType.Linked, resource.ResourceType);
  102. Assert.IsTrue (resource.IsPublic);
  103. });
  104. }
  105. [Test]
  106. public void EmbeddedResource ()
  107. {
  108. TestModule ("libres.dll", module => {
  109. var resource = module.Resources.Where (res => res.Name == "embedded1.txt").First () as EmbeddedResource;
  110. Assert.IsNotNull (resource);
  111. Assert.AreEqual ("embedded1.txt", resource.Name);
  112. Assert.AreEqual (ResourceType.Embedded, resource.ResourceType);
  113. Assert.IsTrue (resource.IsPublic);
  114. using (var reader = new StreamReader (resource.GetResourceStream ()))
  115. Assert.AreEqual ("Hello", reader.ReadToEnd ());
  116. resource = module.Resources.Where (res => res.Name == "embedded2.txt").First () as EmbeddedResource;
  117. Assert.IsNotNull (resource);
  118. Assert.AreEqual ("embedded2.txt", resource.Name);
  119. Assert.AreEqual (ResourceType.Embedded, resource.ResourceType);
  120. Assert.IsTrue (resource.IsPublic);
  121. using (var reader = new StreamReader (resource.GetResourceStream ()))
  122. Assert.AreEqual ("World", reader.ReadToEnd ());
  123. });
  124. }
  125. [Test]
  126. public void ExportedTypeFromNetModule ()
  127. {
  128. IgnoreOnCoreClr ();
  129. TestModule ("mma.exe", module => {
  130. Assert.IsTrue (module.HasExportedTypes);
  131. Assert.AreEqual (2, module.ExportedTypes.Count);
  132. var exported_type = module.ExportedTypes [0];
  133. Assert.AreEqual ("Module.A.Foo", exported_type.FullName);
  134. Assert.AreEqual ("moda.netmodule", exported_type.Scope.Name);
  135. exported_type = module.ExportedTypes [1];
  136. Assert.AreEqual ("Module.B.Baz", exported_type.FullName);
  137. Assert.AreEqual ("modb.netmodule", exported_type.Scope.Name);
  138. });
  139. }
  140. [Test]
  141. public void NestedTypeForwarder ()
  142. {
  143. TestCSharp ("CustomAttributes.cs", module => {
  144. Assert.IsTrue (module.HasExportedTypes);
  145. Assert.AreEqual (2, module.ExportedTypes.Count);
  146. var exported_type = module.ExportedTypes [0];
  147. Assert.AreEqual ("System.Diagnostics.DebuggableAttribute", exported_type.FullName);
  148. Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib", exported_type.Scope.Name);
  149. Assert.IsTrue (exported_type.IsForwarder);
  150. var nested_exported_type = module.ExportedTypes [1];
  151. Assert.AreEqual ("System.Diagnostics.DebuggableAttribute/DebuggingModes", nested_exported_type.FullName);
  152. Assert.AreEqual (exported_type, nested_exported_type.DeclaringType);
  153. Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib", nested_exported_type.Scope.Name);
  154. });
  155. }
  156. [Test]
  157. public void HasTypeReference ()
  158. {
  159. TestCSharp ("CustomAttributes.cs", module => {
  160. Assert.IsTrue (module.HasTypeReference ("System.Attribute"));
  161. Assert.IsTrue (module.HasTypeReference (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib", "System.Attribute"));
  162. Assert.IsFalse (module.HasTypeReference ("System.Core", "System.Attribute"));
  163. Assert.IsFalse (module.HasTypeReference ("System.Linq.Enumerable"));
  164. });
  165. }
  166. [Test]
  167. public void Win32FileVersion ()
  168. {
  169. IgnoreOnCoreClr ();
  170. TestModule ("libhello.dll", module => {
  171. var version = FileVersionInfo.GetVersionInfo (module.FileName);
  172. Assert.AreEqual ("0.0.0.0", version.FileVersion);
  173. });
  174. }
  175. [Test]
  176. public void ModuleWithoutBlob ()
  177. {
  178. TestModule ("noblob.dll", module => {
  179. Assert.IsNull (module.Image.BlobHeap);
  180. });
  181. }
  182. [Test]
  183. public void MixedModeModule ()
  184. {
  185. using (var module = GetResourceModule ("cppcli.dll")) {
  186. Assert.AreEqual (1, module.ModuleReferences.Count);
  187. Assert.AreEqual (string.Empty, module.ModuleReferences [0].Name);
  188. }
  189. }
  190. [Test]
  191. public void OpenIrrelevantFile ()
  192. {
  193. Assert.Throws<BadImageFormatException> (() => GetResourceModule ("text_file.txt"));
  194. }
  195. [Test]
  196. public void GetTypeNamespacePlusName ()
  197. {
  198. using (var module = GetResourceModule ("moda.netmodule")) {
  199. var type = module.GetType ("Module.A", "Foo");
  200. Assert.IsNotNull (type);
  201. }
  202. }
  203. [Test]
  204. public void GetNonExistentTypeRuntimeName ()
  205. {
  206. using (var module = GetResourceModule ("libhello.dll")) {
  207. var type = module.GetType ("DoesNotExist", runtimeName: true);
  208. Assert.IsNull (type);
  209. }
  210. }
  211. [Test]
  212. public void OpenModuleImmediate ()
  213. {
  214. using (var module = GetResourceModule ("hello.exe", ReadingMode.Immediate)) {
  215. Assert.AreEqual (ReadingMode.Immediate, module.ReadingMode);
  216. }
  217. }
  218. [Test]
  219. public void OpenModuleDeferred ()
  220. {
  221. using (var module = GetResourceModule ("hello.exe", ReadingMode.Deferred)) {
  222. Assert.AreEqual (ReadingMode.Deferred, module.ReadingMode);
  223. }
  224. }
  225. [Test]
  226. public void OwnedStreamModuleFileName ()
  227. {
  228. var path = GetAssemblyResourcePath ("hello.exe");
  229. using (var file = File.Open (path, FileMode.Open))
  230. {
  231. using (var module = ModuleDefinition.ReadModule (file))
  232. {
  233. Assert.IsNotNull (module.FileName);
  234. Assert.IsNotEmpty (module.FileName);
  235. Assert.AreEqual (path, module.FileName);
  236. }
  237. }
  238. }
  239. [Test]
  240. public void ReadAndWriteFile ()
  241. {
  242. var path = Path.GetTempFileName ();
  243. var original = ModuleDefinition.CreateModule ("FooFoo", ModuleKind.Dll);
  244. var type = new TypeDefinition ("Foo", "Foo", TypeAttributes.Abstract | TypeAttributes.Sealed);
  245. original.Types.Add (type);
  246. original.Write (path);
  247. using (var module = ModuleDefinition.ReadModule (path, new ReaderParameters { ReadWrite = true })) {
  248. module.Write ();
  249. }
  250. using (var module = ModuleDefinition.ReadModule (path))
  251. Assert.AreEqual ("Foo.Foo", module.Types [1].FullName);
  252. }
  253. [Test]
  254. public void ExceptionInWriteDoesNotKeepLockOnFile ()
  255. {
  256. var path = Path.GetTempFileName ();
  257. var module = ModuleDefinition.CreateModule ("FooFoo", ModuleKind.Dll);
  258. // Mixed mode module that Cecil can not write
  259. module.Attributes = (ModuleAttributes) 0;
  260. Assert.Throws<NotSupportedException>(() => module.Write (path));
  261. // Ensure you can still delete the file
  262. File.Delete (path);
  263. }
  264. }
  265. }