1 //
2 // ModuleTest - NUnit Test Cases for the Module class
3 //
4 // Zoltan Varga (vargaz@freemail.hu)
5 //
6 // (C) Ximian, Inc.  http://www.ximian.com
7 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
8 //
9 
10 using System;
11 using System.Threading;
12 using System.Reflection;
13 #if !MONOTOUCH && !FULL_AOT_RUNTIME
14 using System.Reflection.Emit;
15 #endif
16 using System.Runtime.Serialization;
17 using System.IO;
18 using System.Collections;
19 
20 using NUnit.Framework;
21 
22 namespace MonoTests.System.Reflection
23 {
24 [TestFixture]
25 public class ModuleTest
26 {
27 	static string BaseTempFolder = Path.Combine (Path.GetTempPath (), "MonoTests.System.Reflection.ModuleTest");
28 	static string TempFolder;
29 
30 	[TestFixtureSetUp]
FixtureSetUp()31 	public void FixtureSetUp ()
32 	{
33 		try {
34 			// Try to cleanup from any previous NUnit run.
35 			Directory.Delete (BaseTempFolder, true);
36 		} catch (Exception) {
37 		}
38 	}
39 
40 	[SetUp]
SetUp()41 	public void SetUp ()
42 	{
43 		int i = 0;
44 		do {
45 			TempFolder = Path.Combine (BaseTempFolder, (++i).ToString());
46 		} while (Directory.Exists (TempFolder));
47 		Directory.CreateDirectory (TempFolder);
48 	}
49 
50 	[TearDown]
TearDown()51 	public void TearDown ()
52 	{
53 		try {
54 			// This throws an exception under MS.NET and Mono on Windows,
55 			// since the directory contains loaded assemblies.
56 			Directory.Delete (TempFolder, true);
57 		} catch (Exception) {
58 		}
59 	}
60 
61 	[Test]
IsDefined_AttributeType_Null()62 	public void IsDefined_AttributeType_Null ()
63 	{
64 		Type t = typeof (ModuleTest);
65 		Module module = t.Module;
66 
67 		try {
68 			module.IsDefined ((Type) null, false);
69 			Assert.Fail ("#1");
70 		} catch (ArgumentNullException ex) {
71 			Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
72 			Assert.IsNull (ex.InnerException, "#3");
73 			Assert.IsNotNull (ex.Message, "#4");
74 			Assert.IsNotNull (ex.ParamName, "#5");
75 			Assert.AreEqual ("attributeType", ex.ParamName, "#6");
76 		}
77 	}
78 
79 	[Test]
GetField_Name_Null()80 	public void GetField_Name_Null ()
81 	{
82 		Type t = typeof (ModuleTest);
83 		Module module = t.Module;
84 
85 		try {
86 			module.GetField (null);
87 			Assert.Fail ("#A1");
88 		} catch (ArgumentNullException ex) {
89 			Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#A2");
90 			Assert.IsNull (ex.InnerException, "#A3");
91 			Assert.IsNotNull (ex.Message, "#A4");
92 			Assert.IsNotNull (ex.ParamName, "#A5");
93 			Assert.AreEqual ("name", ex.ParamName, "#A6");
94 		}
95 
96 		try {
97 			module.GetField (null, 0);
98 			Assert.Fail ("#B1");
99 		} catch (ArgumentNullException ex) {
100 			Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#B2");
101 			Assert.IsNull (ex.InnerException, "#B3");
102 			Assert.IsNotNull (ex.Message, "#B4");
103 			Assert.IsNotNull (ex.ParamName, "#B5");
104 			Assert.AreEqual ("name", ex.ParamName, "#B6");
105 		}
106 	}
107 
108 	// Some of these tests overlap with the tests for ModuleBuilder
109 #if !MONOTOUCH && !FULL_AOT_RUNTIME
110 	[Test]
111 	[Category("NotDotNet")] // path length can cause suprious failures
TestGlobalData()112 	public void TestGlobalData () {
113 
114 		string name = "moduletest-assembly";
115 		string fileName = name + ".dll";
116 
117 		AssemblyName assemblyName = new AssemblyName();
118 		assemblyName.Name = name;
119 
120 		AssemblyBuilder ab
121 			= Thread.GetDomain().DefineDynamicAssembly(
122 				assemblyName, AssemblyBuilderAccess.RunAndSave, TempFolder);
123 
124 		string resfile = Path.Combine (TempFolder, "res");
125 		using (StreamWriter sw = new StreamWriter (resfile)) {
126 			sw.WriteLine ("FOO");
127 		}
128 
129 		ab.AddResourceFile ("res", "res");
130 
131 		ModuleBuilder mb = ab.DefineDynamicModule(fileName, fileName);
132 
133 		mb.DefineInitializedData ("DATA", new byte [100], FieldAttributes.Public);
134 		mb.DefineInitializedData ("DATA2", new byte [100], FieldAttributes.Public);
135 		mb.DefineInitializedData ("DATA3", new byte [99], FieldAttributes.Public);
136 		mb.DefineUninitializedData ("DATA4", 101, FieldAttributes.Public);
137 		mb.DefineInitializedData ("DATA_PRIVATE", new byte [100], 0);
138 		mb.CreateGlobalFunctions ();
139 
140 		ab.Save (fileName);
141 
142 		Assembly assembly = Assembly.LoadFrom (Path.Combine (TempFolder, fileName));
143 
144 		Module module = assembly.GetLoadedModules ()[0];
145 
146 		string[] expectedFieldNames = new string [] {
147 			"DATA", "DATA2", "DATA3", "DATA4"
148 		};
149 		ArrayList fieldNames = new ArrayList ();
150 		foreach (FieldInfo fi in module.GetFields ()) {
151 			fieldNames.Add (fi.Name);
152 		}
153 		AssertArrayEqualsSorted (expectedFieldNames, fieldNames.ToArray (typeof (string)));
154 
155 		Assert.IsNotNull (module.GetField ("DATA"), "#A1");
156 		Assert.IsNotNull (module.GetField ("DATA2"), "#A2");
157 		Assert.IsNotNull (module.GetField ("DATA3"), "#A3");
158 		Assert.IsNotNull (module.GetField ("DATA4"), "#A4");
159 		Assert.IsNull (module.GetField ("DATA_PRIVATE"), "#A5");
160 		Assert.IsNotNull (module.GetField ("DATA_PRIVATE", BindingFlags.NonPublic | BindingFlags.Static), "#A6");
161 
162 		// Check that these methods work correctly on resource modules
163 		Module m2 = assembly.GetModule ("res");
164 		Assert.IsNotNull (m2, "#B1");
165 		Assert.AreEqual (0, m2.GetFields ().Length, "#B2");
166 		Assert.IsNull (m2.GetField ("DATA"), "#B3");
167 		Assert.IsNull (m2.GetField ("DATA", BindingFlags.Public), "#B4");
168 	}
169 #endif
170 
171 	[Test]
ResolveType()172 	public void ResolveType ()
173 	{
174 		Type t = typeof (ModuleTest);
175 		Module module = t.Module;
176 
177 		Assert.AreEqual (t, module.ResolveType (t.MetadataToken), "#1");
178 
179 		/* We currently throw ArgumentException for this one */
180 		try {
181 			module.ResolveType (1234);
182 			Assert.Fail ("#2");
183 		} catch (ArgumentException) {
184 		}
185 
186 		try {
187 			module.ResolveType (t.GetMethod ("ResolveType").MetadataToken);
188 			Assert.Fail ("#3");
189 		} catch (ArgumentException) {
190 		}
191 
192 		try {
193 			module.ResolveType (t.MetadataToken + 10000);
194 			Assert.Fail ("#4");
195 		} catch (ArgumentOutOfRangeException) {
196 		}
197 	}
198 
199 	[Test]
ResolveMethod()200 	public void ResolveMethod ()
201 	{
202 		Type t = typeof (ModuleTest);
203 		Module module = t.Module;
204 
205 		Assert.AreEqual (t.GetMethod ("ResolveMethod"), module.ResolveMethod (t.GetMethod ("ResolveMethod").MetadataToken));
206 
207 		try {
208 			module.ResolveMethod (1234);
209 			Assert.Fail ("1234");
210 		} catch (ArgumentException) {
211 		}
212 
213 		try {
214 			module.ResolveMethod (t.MetadataToken);
215 			Assert.Fail ("MetadataToken");
216 		} catch (ArgumentException) {
217 		}
218 
219 		try {
220 			module.ResolveMethod (t.GetMethod ("ResolveMethod").MetadataToken + 100000);
221 			Assert.Fail ("GetMethod");
222 		} catch (ArgumentOutOfRangeException) {
223 		}
224 	}
225 
226 	public int aField;
227 
228 	[Test]
ResolveField()229 	public void ResolveField ()
230 	{
231 		Type t = typeof (ModuleTest);
232 		Module module = t.Module;
233 
234 		Assert.AreEqual (t.GetField ("aField"), module.ResolveField (t.GetField ("aField").MetadataToken));
235 
236 		try {
237 			module.ResolveField (1234);
238 			Assert.Fail ();
239 		} catch (ArgumentException) {
240 		}
241 
242 		try {
243 			module.ResolveField (t.MetadataToken);
244 			Assert.Fail ();
245 		} catch (ArgumentException) {
246 		}
247 
248 		try {
249 			module.ResolveField (t.GetField ("aField").MetadataToken + 10000);
250 			Assert.Fail ();
251 		} catch (ArgumentOutOfRangeException) {
252 		}
253 	}
254 
255 	[Ignore ("it breaks nunit-console.exe execution under .NET 2.0")]
256 	[Test]
ResolveString()257 	public void ResolveString ()
258 	{
259 		Type t = typeof (ModuleTest);
260 		Module module = t.Module;
261 
262 		for (int i = 1; i < 10000; ++i) {
263 			try {
264 				module.ResolveString (0x70000000 + i);
265 			} catch (Exception) {
266 			}
267 		}
268 
269 		try {
270 			module.ResolveString (1234);
271 			Assert.Fail ();
272 		} catch (ArgumentException) {
273 		}
274 
275 		try {
276 			module.ResolveString (t.MetadataToken);
277 			Assert.Fail ();
278 		} catch (ArgumentException) {
279 		}
280 
281 		try {
282 			module.ResolveString (0x70000000 | 10000);
283 			Assert.Fail ();
284 		} catch (ArgumentOutOfRangeException) {
285 		}
286 	}
287 
288 
289 	[Test]
ResolveMember()290 	public void ResolveMember ()
291 	{
292 		Type t = typeof (ModuleTest);
293 		Module module = t.Module;
294 
295 		Assert.AreEqual (t, module.ResolveMember (t.MetadataToken), "#1");
296 		Assert.AreEqual (t.GetField ("aField"), module.ResolveMember (t.GetField ("aField").MetadataToken), "#2");
297 		Assert.AreEqual (t.GetMethod ("ResolveMember"), module.ResolveMember (t.GetMethod ("ResolveMember").MetadataToken), "#3");
298 
299 		try {
300 			module.ResolveMember (module.MetadataToken);
301 			Assert.Fail ("#4");
302 		} catch (ArgumentException) {
303 		}
304 	}
305 
306 	public class Foo<T>  {
Bar(T t)307 		public void Bar(T t) {}
308 	}
309 
310 	[Test]
ResolveMethodOfGenericClass()311 	public void ResolveMethodOfGenericClass ()
312 	{
313 		Type type = typeof (Foo<>);
314 		Module mod = type.Module;
315 		MethodInfo method = type.GetMethod ("Bar");
316 		MethodBase res = mod.ResolveMethod (method.MetadataToken);
317 		Assert.AreEqual (method, res, "#1");
318 	}
319 
320 	[Test]
FindTypes()321 	public void FindTypes ()
322 	{
323 		Module m = typeof (ModuleTest).Module;
324 
325 		Type[] t;
326 
327 		t = m.FindTypes (Module.FilterTypeName, "FindTypesTest*");
328 		Assert.AreEqual (2, t.Length, "#A1");
329 		Assert.AreEqual ("FindTypesTestFirstClass", t [0].Name, "#A2");
330 		Assert.AreEqual ("FindTypesTestSecondClass", t [1].Name, "#A3");
331 		t = m.FindTypes (Module.FilterTypeNameIgnoreCase, "findtypestest*");
332 		Assert.AreEqual (2, t.Length, "#B1");
333 		Assert.AreEqual ("FindTypesTestFirstClass", t [0].Name, "#B2");
334 		Assert.AreEqual ("FindTypesTestSecondClass", t [1].Name, "#B3");
335 	}
336 
337 	[Test]
338 	[ExpectedException (typeof (ArgumentNullException))]
GetObjectData_Null()339 	public void GetObjectData_Null ()
340 	{
341 		Module m = typeof (ModuleTest).Module;
342 		m.GetObjectData (null, new StreamingContext (StreamingContextStates.All));
343 	}
344 #if !MONOTOUCH && !FULL_AOT_RUNTIME
345 	[Test]
GetTypes()346 	public void GetTypes ()
347 	{
348 		AssemblyName newName = new AssemblyName ();
349 		newName.Name = "ModuleTest";
350 
351 		AssemblyBuilder ab = Thread.GetDomain().DefineDynamicAssembly (newName, AssemblyBuilderAccess.RunAndSave, TempFolder);
352 
353 		ModuleBuilder mb = ab.DefineDynamicModule ("myDynamicModule1", "myDynamicModule" + ".dll", false);
354 
355 		TypeBuilder tb = mb.DefineType ("Foo", TypeAttributes.Public);
356 		tb.CreateType ();
357 
358 		ab.Save ("test_assembly.dll");
359 
360 		Assembly ass = Assembly.LoadFrom (Path.Combine (TempFolder, "test_assembly.dll"));
361 		ArrayList types = new ArrayList ();
362 		// The order of the modules is different between MS.NET and mono
363 		foreach (Module m in ass.GetModules ()) {
364 			Type[] t = m.GetTypes ();
365 			types.AddRange (t);
366 		}
367 		Assert.AreEqual (1, types.Count);
368 		Assert.AreEqual ("Foo", ((Type)(types [0])).Name);
369 	}
370 #endif
371 	class FindTypesTestFirstClass {
372 	}
373 
374 	class FindTypesTestSecondClass {
375 	}
376 
AssertArrayEqualsSorted(Array o1, Array o2)377 	private static void AssertArrayEqualsSorted (Array o1, Array o2) {
378 		Array s1 = (Array)o1.Clone ();
379 		Array s2 = (Array)o2.Clone ();
380 
381 		Array.Sort (s1);
382 		Array.Sort (s2);
383 
384 		Assert.AreEqual (s1.Length, s2.Length);
385 		for (int i = 0; i < s1.Length; ++i)
386 			Assert.AreEqual (s1.GetValue (i), s2.GetValue (i));
387 	}
388 }
389 }
390 
391