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