Merge pull request #4248 from Unity-Technologies/boehm-gc-alloc-fixed
[mono.git] / mcs / class / corlib / Test / System.Reflection / AssemblyTest.cs
1 //
2 // System.Reflection.Assembly Test Cases
3 //
4 // Authors:
5 //      Gonzalo Paniagua Javier (gonzalo@ximian.com)
6 //      Philippe Lavoie (philippe.lavoie@cactus.ca)
7 //      Sebastien Pouliot (sebastien@ximian.com)
8 //      Aleksey Kliger (aleksey@xamarin.com)
9 //
10 // (c) 2003 Ximian, Inc. (http://www.ximian.com)
11 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
12 // Copyright (C) 2015 Xamarin, Inc. (http://www.xamarin.com)
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
21 // 
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
24 // 
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 //
33
34 using NUnit.Framework;
35 using System;
36 using System.Configuration.Assemblies;
37 using System.Globalization;
38 using System.IO;
39 using System.Reflection;
40 #if !MONOTOUCH && !FULL_AOT_RUNTIME
41 using System.Reflection.Emit;
42 #endif
43 using System.Threading;
44 using System.Runtime.Serialization;
45 using System.Runtime.CompilerServices;
46 using System.Security;
47 using System.Linq;
48 using System.Resources;
49
50 // Used by GetType_TypeForwarder_Nested ()
51 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Globalization.CultureInfo))]
52
53 namespace MonoTests.System.Reflection
54 {
55         [TestFixture]
56         public class AssemblyTest
57         {
58                 static string BaseTempFolder = Path.Combine (Path.GetTempPath (),
59                         "MonoTests.System.Reflection.AssemblyTest");
60                 static string TempFolder;
61
62                 [TestFixtureSetUp]
63                 public void FixtureSetUp ()
64                 {
65                         try {
66                                 // Try to cleanup from any previous NUnit run.
67                                 Directory.Delete (BaseTempFolder, true);
68                         } catch (Exception) {
69                         }
70                 }
71
72                 [SetUp]
73                 public void SetUp ()
74                 {
75                         int i = 0;
76                         do {
77                                 TempFolder = Path.Combine (BaseTempFolder, (++i).ToString());
78                         } while (Directory.Exists (TempFolder));
79                         Directory.CreateDirectory (TempFolder);
80                 }
81
82                 [TearDown]
83                 public void TearDown ()
84                 {
85                         try {
86                                 // This throws an exception under MS.NET and Mono on Windows,
87                                 // since the directory contains loaded assemblies.
88                                 Directory.Delete (TempFolder, true);
89                         } catch (Exception) {
90                         }
91                 }
92
93                 [Test] 
94                 public void CreateInstance() 
95                 {
96                         Type type = typeof (AssemblyTest);
97                         Object obj = type.Assembly.CreateInstance ("MonoTests.System.Reflection.AssemblyTest");
98                         Assert.IsNotNull (obj, "#01");
99                         Assert.AreEqual (GetType (), obj.GetType (), "#02");
100                 }
101
102                 [Test] 
103                 public void CreateInvalidInstance() 
104                 {
105                         Type type = typeof (AssemblyTest);
106                         Object obj = type.Assembly.CreateInstance("NunitTests.ThisTypeDoesNotExist");
107                         Assert.IsNull (obj, "#03");
108                 }
109
110                 [Test] // bug #49114
111                 [ExpectedException (typeof (ArgumentException))]
112                 public void GetType_TypeName_Invalid () 
113                 {
114                         typeof (int).Assembly.GetType ("&blabla", true, true);
115                 }
116
117                 [Test] // bug #17571
118                 [ExpectedException (typeof (ArgumentException))]
119                 public void GetType_Invalid_RefPtr () {
120                         typeof (int).Assembly.GetType ("System.Int32&*", true, true);
121                 }
122
123                 [Test]
124                 [ExpectedException (typeof (ArgumentException))]
125                 public void GetType_Invalid_RefArray () {
126                         typeof (int).Assembly.GetType ("System.Int32&[]", true, true);
127                 }
128
129                 [Test]
130                 [ExpectedException (typeof (ArgumentException))]
131                 public void GetType_Invalid_RefGeneric () {
132                         typeof (int).Assembly.GetType ("System.Tuple`1&[System.Int32]", true, true);
133                 }
134
135                 [Test]
136                 [ExpectedException (typeof (ArgumentException))]
137                 public void GetType_Invalid_PtrGeneric () {
138                         typeof (int).Assembly.GetType ("System.Tuple`1*[System.Int32]", true, true);
139                 }
140
141                 [Test]
142                 public void GetType_ComposeModifiers () {
143                         var a = typeof(int).Assembly;
144
145                         var e1 = typeof (Int32).MakePointerType().MakeByRefType();
146                         var t1 = a.GetType ("System.Int32*&", true, true);
147                         Assert.AreEqual (e1, t1, "#1");
148
149                         var e2 = typeof (Int32).MakeArrayType(2).MakeByRefType();
150                         var t2 = a.GetType ("System.Int32[,]&", true, true);
151                         Assert.AreEqual (e2, t2, "#2");
152
153                         var e3 = typeof (Int32).MakePointerType().MakeArrayType();
154                         var t3 = a.GetType ("System.Int32*[]", true, true);
155                         Assert.AreEqual (e3, t3, "#3");
156
157                         var e4 = typeof (Int32).MakeArrayType().MakePointerType().MakePointerType().MakeArrayType().MakePointerType().MakeByRefType();
158                         var t4 = a.GetType ("System.Int32[]**[]*&", true, true);
159                         Assert.AreEqual (e4, t4, "#4");
160                                 
161                 }
162                 
163                 [Test] // bug #334203
164                 public void GetType_TypeName_AssemblyName ()
165                 {
166                         Assembly a = typeof (int).Assembly;
167                         string typeName = typeof (string).AssemblyQualifiedName;
168                         try {
169                                 a.GetType (typeName, true, false);
170                                 Assert.Fail ("#A1");
171                         } catch (ArgumentException ex) {
172                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#A2");
173                                 Assert.IsNull (ex.InnerException, "#A3");
174                                 Assert.IsNotNull (ex.Message, "#A4");
175                                 Assert.IsNull (ex.ParamName, "#A5");
176                         }
177
178                         Type type = a.GetType (typeName, false);
179                         Assert.IsNull (type, "#B1");
180                         type = a.GetType (typeName, false, true);
181                         Assert.IsNull (type, "#B2");
182                 }
183
184                 [Test]
185                 public void GetType_TypeForwarder_Nested () {
186                         // System.Globalization is a PCL assembly
187                         Type t = typeof (AssemblyTest).Assembly.GetType ("System.Globalization.CultureInfo/Data");
188                         Assert.IsNotNull (t);
189                         Assert.AreEqual ("System.Globalization.CultureInfo+Data", t.FullName);
190                 }
191
192                 [Test]
193                 public void GetEntryAssembly ()
194                 {
195                         // note: only available in default appdomain
196                         // http://weblogs.asp.net/asanto/archive/2003/09/08/26710.aspx
197                         // Not sure we should emulate this behavior.
198 #if __WATCHOS__
199                         Assert.IsNull (Assembly.GetEntryAssembly (), "GetEntryAssembly");
200                         Assert.IsTrue (AppDomain.CurrentDomain.IsDefaultAppDomain (), "!default appdomain");
201 #elif !MONODROID
202                         string fname = AppDomain.CurrentDomain.FriendlyName;
203                         if (fname.EndsWith (".dll")) { // nunit-console
204                                 Assert.IsNull (Assembly.GetEntryAssembly (), "GetEntryAssembly");
205                                 Assert.IsFalse (AppDomain.CurrentDomain.IsDefaultAppDomain (), "!default appdomain");
206                         } else { // gnunit
207                                 Assert.IsNotNull (Assembly.GetEntryAssembly (), "GetEntryAssembly");
208                                 Assert.IsTrue (AppDomain.CurrentDomain.IsDefaultAppDomain (), "!default appdomain");
209                         }
210 #else
211                         Assert.IsNull (Assembly.GetEntryAssembly (), "GetEntryAssembly");
212                         Assert.IsTrue (AppDomain.CurrentDomain.IsDefaultAppDomain (), "!default appdomain");
213 #endif
214                 }
215
216 #if !MONOTOUCH && !FULL_AOT_RUNTIME // Reflection.Emit is not supported.
217                 [Test]
218                 [Category("AndroidNotWorking")] // Missing Mono.CompilerServices.SymbolWriter
219                 public void GetModules_MissingFile ()
220                 {
221                         AssemblyName newName = new AssemblyName ();
222                         newName.Name = "AssemblyTest";
223
224                         AssemblyBuilder ab = Thread.GetDomain().DefineDynamicAssembly (newName, AssemblyBuilderAccess.RunAndSave, TempFolder);
225
226                         ModuleBuilder mb = ab.DefineDynamicModule ("myDynamicModule1", "myDynamicModule.dll", true);
227
228                         ab.Save ("test_assembly.dll");
229
230                         File.Delete (Path.Combine (TempFolder, "myDynamicModule.dll"));
231
232                         Assembly ass = Assembly.LoadFrom (Path.Combine (TempFolder, "test_assembly.dll"));
233                         try {
234                                 ass.GetModules ();
235                                 Assert.Fail ();
236                         } catch (FileNotFoundException ex) {
237                                 Assert.AreEqual ("myDynamicModule.dll", ex.FileName);
238                         }
239                 }
240 #endif
241
242                 [Category ("NotWorking")]
243                 [Test]
244                 public void Corlib () 
245                 {
246                         Assembly corlib = typeof (int).Assembly;
247                         Assert.IsTrue (corlib.CodeBase.EndsWith ("mscorlib.dll"), "CodeBase");
248                         Assert.IsNull (corlib.EntryPoint, "EntryPoint");
249                         Assert.IsTrue (corlib.EscapedCodeBase.EndsWith ("mscorlib.dll"), "EscapedCodeBase");
250                         Assert.IsNotNull (corlib.Evidence, "Evidence");
251                         Assert.IsTrue (corlib.Location.EndsWith ("mscorlib.dll"), "Location");
252
253                         // corlib doesn't reference anything
254                         Assert.AreEqual (0, corlib.GetReferencedAssemblies ().Length, "GetReferencedAssemblies");
255                         Assert.AreEqual ("mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", corlib.FullName, "FullName");
256                         // not really "true" but it's even more trusted so...
257                         Assert.IsTrue (corlib.GlobalAssemblyCache, "GlobalAssemblyCache");
258                         Assert.AreEqual (0, corlib.HostContext, "HostContext");
259                         Assert.AreEqual ("v2.0.50727", corlib.ImageRuntimeVersion, "ImageRuntimeVersion");
260                         Assert.IsFalse (corlib.ReflectionOnly, "ReflectionOnly");
261                         Assert.AreEqual (0x1, corlib.ManifestModule.MetadataToken);
262                 }
263
264                 [Test]
265                 public void Corlib_test ()
266                 {
267                         Assembly corlib_test = Assembly.GetExecutingAssembly ();
268 #if MONODROID || FULL_AOT_DESKTOP || __WATCHOS__
269                         Assert.IsNull (corlib_test.EntryPoint, "EntryPoint");
270                         Assert.IsNull (corlib_test.Evidence, "Evidence");
271 #elif MOBILE
272                         Assert.IsNotNull (corlib_test.EntryPoint, "EntryPoint");
273                         Assert.IsNull (corlib_test.Evidence, "Evidence");
274 #else
275                         Assert.IsNull (corlib_test.EntryPoint, "EntryPoint");
276                         Assert.IsNotNull (corlib_test.Evidence, "Evidence");
277 #endif
278                         Assert.IsFalse (corlib_test.GlobalAssemblyCache, "GlobalAssemblyCache");
279
280                         Assert.IsTrue (corlib_test.GetReferencedAssemblies ().Length > 0, "GetReferencedAssemblies");
281                         Assert.AreEqual (0, corlib_test.HostContext, "HostContext");
282                         Assert.AreEqual ("v4.0.30319", corlib_test.ImageRuntimeVersion, "ImageRuntimeVersion");
283
284                         Assert.IsNotNull (corlib_test.ManifestModule, "ManifestModule");
285                         Assert.IsFalse (corlib_test.ReflectionOnly, "ReflectionOnly");
286                 }
287
288                 [Test]
289                 public void GetAssembly ()
290                 {
291                         Assert.IsTrue (Assembly.GetAssembly (typeof (int)).FullName.StartsWith ("mscorlib"), "GetAssembly(int)");
292                         Assert.AreEqual (this.GetType ().Assembly.FullName, Assembly.GetAssembly (this.GetType ()).FullName, "GetAssembly(this)");
293                 }
294
295                 [Test]
296                 public void GetFile_Null ()
297                 {
298                         try {
299                                 Assembly.GetExecutingAssembly ().GetFile (null);
300                                 Assert.Fail ("#1");
301                         } catch (ArgumentNullException ex) {
302                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
303                                 Assert.IsNull (ex.InnerException, "#3");
304                                 Assert.IsNotNull (ex.Message, "#4");
305                                 Assert.IsNull (ex.ParamName, "#5");
306                         }
307                 }
308
309                 [Test]
310                 public void GetFile_Empty ()
311                 {
312                         try {
313                                 Assembly.GetExecutingAssembly ().GetFile (
314                                         String.Empty);
315                                 Assert.Fail ("#1");
316                         } catch (ArgumentException ex) {
317                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
318                                 Assert.IsNull (ex.InnerException, "#3");
319                                 Assert.IsNotNull (ex.Message, "#4");
320                                 Assert.IsNull (ex.ParamName, "#5");
321                         }
322                 }
323
324                 [Test]
325                 [Category ("AndroidNotWorking")] // Assemblies in Xamarin.Android cannot be accessed as FileStream
326                 public void GetFiles_False ()
327                 {
328                         Assembly corlib = typeof (int).Assembly;
329                         FileStream[] fss = corlib.GetFiles ();
330                         Assert.AreEqual (fss.Length, corlib.GetFiles (false).Length, "corlib.GetFiles (false)");
331
332                         Assembly corlib_test = Assembly.GetExecutingAssembly ();
333                         fss = corlib_test.GetFiles ();
334                         Assert.AreEqual (fss.Length, corlib_test.GetFiles (false).Length, "test.GetFiles (false)");
335                 }
336
337                 [Test]
338                 [Category ("AndroidNotWorking")] // Assemblies in Xamarin.Android cannot be accessed as FileStream
339                 public void GetFiles_True ()
340                 {
341                         Assembly corlib = typeof (int).Assembly;
342                         FileStream[] fss = corlib.GetFiles ();
343                         Assert.IsTrue (fss.Length <= corlib.GetFiles (true).Length, "corlib.GetFiles (true)");
344
345                         Assembly corlib_test = Assembly.GetExecutingAssembly ();
346                         fss = corlib_test.GetFiles ();
347                         Assert.IsTrue (fss.Length <= corlib_test.GetFiles (true).Length, "test.GetFiles (true)");
348                 }
349
350                 [Test]
351                 public void GetManifestResourceStream_Name_Empty ()
352                 {
353                         Assembly corlib = typeof (int).Assembly;
354
355                         try {
356                                 corlib.GetManifestResourceStream (string.Empty);
357                                 Assert.Fail ("#A1");
358                         } catch (ArgumentException ex) {
359                                 // String cannot have zero length
360                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#A2");
361                                 Assert.IsNull (ex.InnerException, "#A3");
362                                 Assert.IsNotNull (ex.Message, "#A4");
363                         }
364
365                         corlib.GetManifestResourceStream (typeof (int), string.Empty);
366
367                         try {
368                                 corlib.GetManifestResourceStream ((Type) null, string.Empty);
369                                 Assert.Fail ("#B1");
370                         } catch (ArgumentException ex) {
371                                 // String cannot have zero length
372                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#B2");
373                                 Assert.IsNull (ex.InnerException, "#B3");
374                                 Assert.IsNotNull (ex.Message, "#B4");
375                         }
376                 }
377
378                 [Test]
379                 public void GetManifestResourceStream_Name_Null ()
380                 {
381                         Assembly corlib = typeof (int).Assembly;
382
383                         try {
384                                 corlib.GetManifestResourceStream ((string) null);
385                                 Assert.Fail ("#A1");
386                         } catch (ArgumentNullException ex) {
387                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#A2");
388                                 Assert.IsNull (ex.InnerException, "#A3");
389                                 Assert.IsNotNull (ex.Message, "#A4");
390                         }
391
392                         corlib.GetManifestResourceStream (typeof (int), (string) null);
393
394                         try {
395                                 corlib.GetManifestResourceStream ((Type) null, (string) null);
396                                 Assert.Fail ("#B1");
397                         } catch (ArgumentNullException ex) {
398                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#B2");
399                                 Assert.IsNull (ex.InnerException, "#B3");
400                                 Assert.IsNotNull (ex.Message, "#B4");
401                                 Assert.IsNotNull (ex.ParamName, "#B5");
402                                 Assert.AreEqual ("type", ex.ParamName, "#B6");
403                         }
404                 }
405
406                 [Test]
407                 public void IsDefined_AttributeType_Null ()
408                 {
409                         Assembly corlib = typeof (int).Assembly;
410
411                         try {
412                                 corlib.IsDefined ((Type) null, false);
413                                 Assert.Fail ("#1");
414                         } catch (ArgumentNullException ex) {
415                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
416                                 Assert.IsNull (ex.InnerException, "#3");
417                                 Assert.IsNotNull (ex.Message, "#4");
418                                 Assert.IsNotNull (ex.ParamName, "#5");
419                                 Assert.AreEqual ("attributeType", ex.ParamName, "#6");
420                         }
421                 }
422
423                 [Test] // bug #78517
424                 public void LoadFrom_Empty_Assembly ()
425                 {
426                         string tempFile = Path.Combine (TempFolder, Path.GetRandomFileName ());
427                         File.CreateText (tempFile).Close ();
428
429                         try {
430                                 Assembly.LoadFrom (tempFile);
431                                 Assert.Fail ("#1");
432                         } catch (BadImageFormatException ex) {
433                                 Assert.IsNull (ex.InnerException, "#2");
434                         }
435                 }
436
437                 [Test] // bug #78517
438                 public void LoadFrom_Invalid_Assembly ()
439                 {
440                         string tempFile = Path.Combine (TempFolder, Path.GetRandomFileName ());
441                         using (StreamWriter sw = File.CreateText (tempFile)) {
442                                 sw.WriteLine ("foo");
443                                 sw.Close ();
444                         }
445
446                         try {
447                                 Assembly.LoadFrom (tempFile);
448                                 Assert.Fail ("#1");
449                         } catch (BadImageFormatException ex) {
450                                 Assert.IsNull (ex.InnerException, "#2");
451                         }
452                 }
453
454                 [Test]
455                 public void LoadFrom_NonExisting_Assembly ()
456                 {
457                         string tempFile = Path.Combine (TempFolder, Path.GetRandomFileName ());
458
459                         try {
460                                 Assembly.LoadFrom (tempFile);
461                                 Assert.Fail ("#1");
462                         } catch (FileNotFoundException ex) {
463                                 Assert.IsNull (ex.InnerException, "#2");
464                         }
465                 }
466
467                 [Test]
468                 public void LoadWithPartialName ()
469                 {
470 // FIXME?
471 // So the problem here is that if we load an assembly
472 // in a fully aot mode and then cannot load the
473 // dylib, we will assert. This test is incompatible
474 // with the semantics of aot'ed assembly loading, as
475 // aot may assert when loading. This assumes that it's
476 // safe to greedly load everything.
477 #if FULL_AOT_DESKTOP
478                         string [] names = { "testing_aot_full_corlib_test", "winaot_corlib_test" };
479 #else
480                         string [] names = { "corlib_test_net_1_1", "corlib_test_net_2_0", "corlib_test_net_4_0", "corlib_test_net_4_5", "net_4_x_corlib_test", "corlib_plattest", "mscorlibtests", "BclTests" };
481 #endif
482
483                         foreach (string s in names)
484                                 if (Assembly.LoadWithPartialName (s) != null)
485                                         return;
486                         Assert.Fail ("Was not able to load any corlib test");
487                 }
488
489                 [Test]
490                 public void GetObjectData_Info_Null ()
491                 {
492                         Assembly corlib = typeof (int).Assembly;
493                         try {
494                                 corlib.GetObjectData (null, new StreamingContext (
495                                         StreamingContextStates.All));
496                                 Assert.Fail ("#1");
497                         } catch (ArgumentNullException ex) {
498                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
499                                 Assert.IsNull (ex.InnerException, "#3");
500                                 Assert.IsNotNull (ex.Message, "#4");
501                                 Assert.IsNotNull (ex.ParamName, "#5");
502                                 Assert.AreEqual ("info", ex.ParamName, "#6");
503                         }
504                 }
505
506                 [Test]
507                 public void GetReferencedAssemblies ()
508                 {
509                         Assembly corlib_test = Assembly.GetExecutingAssembly ();
510                         AssemblyName[] names = corlib_test.GetReferencedAssemblies ();
511                         foreach (AssemblyName an in names) {
512                                 Assert.IsNull (an.CodeBase, "CodeBase");
513                                 Assert.IsNotNull (an.CultureInfo, "CultureInfo");
514                                 Assert.IsNull (an.EscapedCodeBase, "EscapedCodeBase");
515                                 Assert.AreEqual (AssemblyNameFlags.None, an.Flags, "Flags");
516                                 Assert.IsNotNull (an.FullName, "FullName");
517                                 Assert.AreEqual (AssemblyHashAlgorithm.SHA1, an.HashAlgorithm, "HashAlgorithm");
518                                 Assert.IsNull (an.KeyPair, "KeyPair");
519                                 Assert.IsNotNull (an.Name, "Name");
520                                 Assert.IsNotNull (an.Version, "Version");
521                                 Assert.AreEqual (AssemblyVersionCompatibility.SameMachine, 
522                                         an.VersionCompatibility, "VersionCompatibility");
523                         }
524                 }
525
526 #if !MONOTOUCH && !FULL_AOT_RUNTIME // Reflection.Emit is not supported.
527                 [Test]
528                 public void Location_Empty() {
529                         string assemblyFileName = Path.Combine (
530                                 TempFolder, "AssemblyLocation.dll");
531
532                         AssemblyName assemblyName = new AssemblyName ();
533                         assemblyName.Name = "AssemblyLocation";
534
535                         AssemblyBuilder ab = AppDomain.CurrentDomain
536                                 .DefineDynamicAssembly (assemblyName,
537                                 AssemblyBuilderAccess.Save,
538                                 TempFolder,
539                                 AppDomain.CurrentDomain.Evidence);
540                         ab.Save (Path.GetFileName (assemblyFileName));
541
542                         using (FileStream fs = File.OpenRead (assemblyFileName)) {
543                                 byte[] buffer = new byte[fs.Length];
544                                 fs.Read (buffer, 0, buffer.Length);
545                                 Assembly assembly = Assembly.Load (buffer);
546                                 Assert.AreEqual (string.Empty, assembly.Location);
547                                 fs.Close ();
548                         }
549                 }
550
551                 [Test]
552                 public void SateliteAssemblyForInMemoryAssembly ()
553                 {
554                         string assemblyFileName = Path.Combine (
555                                 TempFolder, "AssemblyLocation1.dll");
556
557                         AssemblyName assemblyName = new AssemblyName ();
558                         assemblyName.Name = "AssemblyLocation1";
559
560                         AssemblyBuilder ab = AppDomain.CurrentDomain
561                                 .DefineDynamicAssembly (assemblyName,
562                                         AssemblyBuilderAccess.Save,
563                                         TempFolder);
564
565                         ModuleBuilder moduleBuilder = ab.DefineDynamicModule (assemblyName.Name, assemblyName.Name + ".dll");
566                         TypeBuilder typeBuilder = moduleBuilder.DefineType ("Program", TypeAttributes.Public);
567
568                         MethodBuilder methodBuilder = typeBuilder.DefineMethod ("TestCall", MethodAttributes.Public | MethodAttributes.Static, typeof(void), Type.EmptyTypes);
569                         ILGenerator gen = methodBuilder.GetILGenerator ();
570
571                         //
572                         //      var resourceManager = new ResourceManager (typeof (Program));
573                         //      resourceManager.GetString ("test");
574                         //
575                         gen.Emit (OpCodes.Ldtoken, typeBuilder);
576                         gen.Emit (OpCodes.Call, typeof(Type).GetMethod ("GetTypeFromHandle"));
577                         gen.Emit (OpCodes.Newobj, typeof(ResourceManager).GetConstructor (new Type[] { typeof(Type) }));
578                         gen.Emit (OpCodes.Ldstr, "test");
579                         gen.Emit (OpCodes.Callvirt, typeof(ResourceManager).GetMethod ("GetString", new Type[] { typeof(string) }));
580                         gen.Emit (OpCodes.Pop);
581                         gen.Emit (OpCodes.Ret);
582
583                         typeBuilder.CreateType ();
584
585                         ab.Save (Path.GetFileName (assemblyFileName));
586
587                         using (FileStream fs = File.OpenRead (assemblyFileName)) {
588                                 byte[] buffer = new byte[fs.Length];
589                                 fs.Read (buffer, 0, buffer.Length);
590                                 Assembly assembly = Assembly.Load (buffer);
591
592                                 var mm = assembly.GetType ("Program").GetMethod ("TestCall");
593                                 try {
594                                         mm.Invoke (null, null);
595                                         Assert.Fail ();
596                                 } catch (TargetInvocationException e) {
597                                         Assert.IsTrue (e.InnerException is MissingManifestResourceException);
598                                 }
599
600                                 fs.Close ();
601                         }
602                 }
603
604                 [Test]
605                 [Category ("NotWorking")]
606                 public void bug78464 ()
607                 {
608                         string assemblyFileName = Path.Combine (
609                                 TempFolder, "bug78464.dll");
610
611                         // execute test in separate appdomain to allow assembly to be unloaded
612                         AppDomain testDomain = CreateTestDomain (AppDomain.CurrentDomain.BaseDirectory, false);
613                         CrossDomainTester crossDomainTester = CreateCrossDomainTester (testDomain);
614                         try {
615                                 crossDomainTester.bug78464 (assemblyFileName);
616                         } finally {
617                                 AppDomain.Unload (testDomain);
618                         }
619                 }
620
621                 [Test]
622                 [Category("MobileNotWorking")]
623                 public void bug78465 ()
624                 {
625                         string assemblyFileName = Path.Combine (
626                                 TempFolder, "bug78465.dll");
627
628                         AssemblyName assemblyName = new AssemblyName ();
629                         assemblyName.Name = "bug78465";
630
631                         AssemblyBuilder ab = AppDomain.CurrentDomain
632                                 .DefineDynamicAssembly (assemblyName,
633                                 AssemblyBuilderAccess.Save,
634                                 Path.GetDirectoryName (assemblyFileName),
635                                 AppDomain.CurrentDomain.Evidence);
636                         ab.Save (Path.GetFileName (assemblyFileName));
637
638                         using (FileStream fs = File.OpenRead (assemblyFileName)) {
639                                 byte[] buffer = new byte[fs.Length];
640                                 fs.Read (buffer, 0, buffer.Length);
641                                 Assembly assembly = Assembly.Load (buffer);
642                                 Assert.AreEqual (string.Empty, assembly.Location, "#1");
643                                 fs.Close ();
644                         }
645
646                         AppDomain testDomain = CreateTestDomain (AppDomain.CurrentDomain.BaseDirectory, false);
647                         CrossDomainTester crossDomainTester = CreateCrossDomainTester (testDomain);
648                         try {
649                                 crossDomainTester.bug78465 (assemblyFileName);
650                         } finally {
651                                 AppDomain.Unload (testDomain);
652                         }
653                 }
654
655                 [Test]
656                 [Category("MobileNotWorking")]
657                 public void bug78468 ()
658                 {
659                         string assemblyFileNameA = Path.Combine (TempFolder,
660                                 "bug78468a.dll");
661                         string resourceFileName = Path.Combine (TempFolder,
662                                 "readme.txt");
663
664                         using (StreamWriter sw = File.CreateText (resourceFileName)) {
665                                 sw.WriteLine ("FOO");
666                                 sw.Close ();
667                         }
668
669                         AssemblyName assemblyName = new AssemblyName ();
670                         assemblyName.Name = "bug78468a";
671
672                         AssemblyBuilder ab = AppDomain.CurrentDomain
673                                 .DefineDynamicAssembly (assemblyName,
674                                 AssemblyBuilderAccess.Save,
675                                 TempFolder,
676                                 AppDomain.CurrentDomain.Evidence);
677                         ab.AddResourceFile ("read", "readme.txt");
678                         ab.Save (Path.GetFileName (assemblyFileNameA));
679
680                         Assembly assembly;
681
682                         using (FileStream fs = File.OpenRead (assemblyFileNameA)) {
683                                 byte[] buffer = new byte[fs.Length];
684                                 fs.Read (buffer, 0, buffer.Length);
685                                 assembly = Assembly.Load (buffer);
686                                 fs.Close ();
687                         }
688
689                         Assert.AreEqual (string.Empty, assembly.Location, "#A1");
690                         string[] resNames = assembly.GetManifestResourceNames ();
691                         Assert.IsNotNull (resNames, "#A2");
692                         Assert.AreEqual (1, resNames.Length, "#A3");
693                         Assert.AreEqual ("read", resNames[0], "#A4");
694                         ManifestResourceInfo resInfo = assembly.GetManifestResourceInfo ("read");
695                         Assert.IsNotNull (resInfo, "#A5");
696                         Assert.AreEqual ("readme.txt", resInfo.FileName, "#A6");
697                         Assert.IsNull (resInfo.ReferencedAssembly, "#A7");
698                         Assert.AreEqual ((ResourceLocation) 0, resInfo.ResourceLocation, "#A8");
699                         try {
700                                 assembly.GetManifestResourceStream ("read");
701                                 Assert.Fail ("#A9");
702                         } catch (FileNotFoundException) {
703                         }
704                         try {
705                                 assembly.GetFile ("readme.txt");
706                                 Assert.Fail ("#A10");
707                         } catch (FileNotFoundException) {
708                         }
709
710                         string assemblyFileNameB = Path.Combine (TempFolder,
711                                 "bug78468b.dll");
712
713                         AppDomain testDomain = CreateTestDomain (AppDomain.CurrentDomain.BaseDirectory, false);
714                         CrossDomainTester crossDomainTester = CreateCrossDomainTester (testDomain);
715                         try {
716                                 crossDomainTester.bug78468 (assemblyFileNameB);
717                         } finally {
718                                 AppDomain.Unload (testDomain);
719                         }
720                 }
721
722                 [Test]
723                 [Category ("NotWorking")]
724                 public void ReflectionOnlyLoad ()
725                 {
726                         Assembly assembly = Assembly.ReflectionOnlyLoad (typeof (AssemblyTest).Assembly.FullName);
727                         
728                         Assert.IsNotNull (assembly);
729                         Assert.IsTrue (assembly.ReflectionOnly);
730                 }
731
732                 [Test]
733                 [Category ("AndroidNotWorking")] // Assemblies in Xamarin.Android cannot be directly as files
734                 public void ReflectionOnlyLoadFrom ()
735                 {
736                         string loc = typeof (AssemblyTest).Assembly.Location;
737                         string filename = Path.GetFileName (loc);
738                         Assembly assembly = Assembly.ReflectionOnlyLoadFrom (filename);
739
740                         Assert.IsNotNull (assembly);
741                         Assert.IsTrue (assembly.ReflectionOnly);
742                 }
743
744                 [Test]
745                 [ExpectedException (typeof (ArgumentException))]
746                 public void CreateInstanceOnRefOnly ()
747                 {
748                         Assembly assembly = Assembly.ReflectionOnlyLoad (typeof (AssemblyTest).Assembly.FullName);
749                         assembly.CreateInstance ("MonoTests.System.Reflection.AssemblyTest");
750                 }
751
752                 [Test]
753                 [Category ("NotWorking")] // patch for bug #79720 must be committed first
754                 public void Load_Culture ()
755                 {
756                         string tempDir = TempFolder;
757                         string cultureTempDir = Path.Combine (tempDir, "nl-BE");
758                         if (!Directory.Exists (cultureTempDir))
759                                 Directory.CreateDirectory (cultureTempDir);
760                         cultureTempDir = Path.Combine (tempDir, "en-US");
761                         if (!Directory.Exists (cultureTempDir))
762                                 Directory.CreateDirectory (cultureTempDir);
763
764
765                         AppDomain ad = CreateTestDomain (tempDir, true);
766                         try {
767                                 CrossDomainTester cdt = CreateCrossDomainTester (ad);
768
769                                 // PART A
770
771                                 AssemblyName aname = new AssemblyName ();
772                                 aname.Name = "culturea";
773                                 cdt.GenerateAssembly (aname, Path.Combine (tempDir, "culturea.dll"));
774
775                                 aname = new AssemblyName ();
776                                 aname.Name = "culturea";
777                                 Assert.IsTrue (cdt.AssertLoad(aname), "#A1");
778
779                                 aname = new AssemblyName ();
780                                 aname.Name = "culturea";
781                                 aname.CultureInfo = new CultureInfo ("nl-BE");
782                                 Assert.IsTrue (cdt.AssertFileNotFoundException (aname), "#A2");
783
784                                 aname = new AssemblyName ();
785                                 aname.Name = "culturea";
786                                 aname.CultureInfo = CultureInfo.InvariantCulture;
787                                 Assert.IsTrue (cdt.AssertLoad(aname), "#A3");
788
789                                 // PART B
790
791                                 aname = new AssemblyName ();
792                                 aname.Name = "cultureb";
793                                 aname.CultureInfo = new CultureInfo ("nl-BE");
794                                 cdt.GenerateAssembly (aname, Path.Combine (tempDir, "cultureb.dll"));
795
796                                 aname = new AssemblyName ();
797                                 aname.Name = "cultureb";
798                                 aname.CultureInfo = new CultureInfo ("nl-BE");
799                                 Assert.IsTrue (cdt.AssertFileNotFoundException (aname), "#B1");
800
801                                 aname = new AssemblyName ();
802                                 aname.Name = "cultureb";
803                                 Assert.IsTrue (cdt.AssertLoad (aname), "#B2");
804
805                                 aname = new AssemblyName ();
806                                 aname.Name = "cultureb";
807                                 aname.CultureInfo = new CultureInfo ("en-US");
808                                 Assert.IsTrue (cdt.AssertFileNotFoundException (aname), "#B3");
809
810                                 // PART C
811
812                                 aname = new AssemblyName ();
813                                 aname.Name = "culturec";
814                                 aname.CultureInfo = new CultureInfo ("nl-BE");
815                                 cdt.GenerateAssembly (aname, Path.Combine (tempDir, "nl-BE/culturec.dll"));
816
817                                 aname = new AssemblyName ();
818                                 aname.Name = "culturec";
819                                 aname.CultureInfo = new CultureInfo ("nl-BE");
820                                 Assert.IsTrue (cdt.AssertLoad (aname), "#C1");
821
822                                 aname = new AssemblyName ();
823                                 aname.Name = "culturec";
824                                 Assert.IsTrue (cdt.AssertFileNotFoundException (aname), "#C2");
825
826                                 aname = new AssemblyName ();
827                                 aname.Name = "culturec";
828                                 aname.CultureInfo = CultureInfo.InvariantCulture;
829                                 Assert.IsTrue (cdt.AssertFileNotFoundException (aname), "#C3");
830
831                                 // PART D
832
833                                 aname = new AssemblyName ();
834                                 aname.Name = "cultured";
835                                 aname.CultureInfo = new CultureInfo ("nl-BE");
836                                 cdt.GenerateAssembly (aname, Path.Combine (tempDir, "en-US/cultured.dll"));
837
838                                 aname = new AssemblyName ();
839                                 aname.Name = "cultured";
840                                 aname.CultureInfo = new CultureInfo ("nl-BE");
841                                 Assert.IsTrue (cdt.AssertFileNotFoundException (aname), "#D1");
842
843                                 aname = new AssemblyName ();
844                                 aname.Name = "cultured";
845                                 Assert.IsTrue (cdt.AssertFileNotFoundException (aname), "#D2");
846
847                                 aname = new AssemblyName ();
848                                 aname.Name = "cultured";
849                                 aname.CultureInfo = CultureInfo.InvariantCulture;
850                                 Assert.IsTrue (cdt.AssertFileNotFoundException (aname), "#D3");
851                         } finally {
852                                 AppDomain.Unload (ad);
853                         }
854                 }
855
856                 [Test] // bug #79712
857                 [Category ("NotWorking")] // in non-default domain, MS throws FileNotFoundException
858                 public void Load_Culture_Mismatch ()
859                 {
860                         string tempDir = TempFolder;
861                         string cultureTempDir = Path.Combine (tempDir, "en-US");
862                         if (!Directory.Exists (cultureTempDir))
863                                 Directory.CreateDirectory (cultureTempDir);
864
865                         AppDomain ad = CreateTestDomain (tempDir, true);
866                         try {
867                                 CrossDomainTester cdt = CreateCrossDomainTester (ad);
868
869                                 // PART A
870
871                                 AssemblyName aname = new AssemblyName ();
872                                 aname.Name = "bug79712a";
873                                 aname.CultureInfo = new CultureInfo ("nl-BE");
874                                 cdt.GenerateAssembly (aname, Path.Combine (tempDir, "bug79712a.dll"));
875
876                                 aname = new AssemblyName ();
877                                 aname.Name = "bug79712a";
878                                 aname.CultureInfo = CultureInfo.InvariantCulture;
879                                 Assert.IsTrue (cdt.AssertFileNotFoundException (aname), "#A1");
880
881                                 // PART B
882
883                                 aname = new AssemblyName ();
884                                 aname.Name = "bug79712b";
885                                 aname.CultureInfo = new CultureInfo ("nl-BE");
886                                 cdt.GenerateAssembly (aname, Path.Combine (tempDir, "en-US/bug79712b.dll"));
887
888                                 aname = new AssemblyName ();
889                                 aname.Name = "bug79712b";
890                                 aname.CultureInfo = new CultureInfo ("en-US");
891                                 Assert.IsTrue (cdt.AssertFileNotFoundException (aname), "#B1");
892                         } finally {
893                                 AppDomain.Unload (ad);
894                         }
895                 }
896
897
898                 [Test] // bug #79715
899                 [Category("MobileNotWorking")]
900                 public void Load_PartialVersion ()
901                 {
902                         string tempDir = TempFolder;
903
904                         AppDomain ad = CreateTestDomain (tempDir, true);
905                         try {
906                                 CrossDomainTester cdt = CreateCrossDomainTester (ad);
907
908                                 AssemblyName aname = new AssemblyName ();
909                                 aname.Name = "bug79715";
910                                 aname.Version = new Version (1, 2, 3, 4);
911                                 cdt.GenerateAssembly (aname, Path.Combine (tempDir, "bug79715.dll"));
912
913                                 aname = new AssemblyName ();
914                                 aname.Name = "bug79715";
915                                 aname.Version = new Version (1, 2);
916                                 Assert.IsTrue (cdt.AssertLoad (aname), "#A1");
917                                 Assert.IsTrue (cdt.AssertLoad (aname.FullName), "#A2");
918
919                                 aname = new AssemblyName ();
920                                 aname.Name = "bug79715";
921                                 aname.Version = new Version (1, 2, 3);
922                                 Assert.IsTrue (cdt.AssertLoad (aname), "#B1");
923                                 Assert.IsTrue (cdt.AssertLoad (aname.FullName), "#B2");
924
925                                 aname = new AssemblyName ();
926                                 aname.Name = "bug79715";
927                                 aname.Version = new Version (1, 2, 3, 4);
928                                 Assert.IsTrue (cdt.AssertLoad (aname), "#C1");
929                                 Assert.IsTrue (cdt.AssertLoad (aname.FullName), "#C2");
930                         } finally {
931                                 AppDomain.Unload (ad);
932                         }
933                 }
934
935                 private static AppDomain CreateTestDomain (string baseDirectory, bool assemblyResolver)
936                 {
937                         AppDomainSetup setup = new AppDomainSetup ();
938                         setup.ApplicationBase = baseDirectory;
939                         setup.ApplicationName = "testdomain";
940
941                         AppDomain ad = AppDomain.CreateDomain ("testdomain", 
942                                 AppDomain.CurrentDomain.Evidence, setup);
943
944                         if (assemblyResolver) {
945                                 Assembly ea = Assembly.GetExecutingAssembly ();
946                                 ad.CreateInstanceFrom (ea.CodeBase,
947                                         typeof (AssemblyResolveHandler).FullName,
948                                         false,
949                                         BindingFlags.Public | BindingFlags.Instance,
950                                         null,
951                                         new object [] { ea.Location, ea.FullName },
952                                         CultureInfo.InvariantCulture,
953                                         null,
954                                         null);
955                         }
956
957                         return ad;
958                 }
959
960                 private static CrossDomainTester CreateCrossDomainTester (AppDomain domain)
961                 {
962                         Type testerType = typeof (CrossDomainTester);
963                         return (CrossDomainTester) domain.CreateInstanceAndUnwrap (
964                                 testerType.Assembly.FullName, testerType.FullName, false,
965                                 BindingFlags.Public | BindingFlags.Instance, null, new object[0],
966                                 CultureInfo.InvariantCulture, new object[0], null);
967                 }
968
969                 private class CrossDomainTester : MarshalByRefObject
970                 {
971                         public void GenerateAssembly (AssemblyName aname, string path)
972                         {
973                                 AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly (
974                                         aname, AssemblyBuilderAccess.Save, Path.GetDirectoryName (path));
975                                 ab.Save (Path.GetFileName (path));
976                         }
977
978                         public void Load (AssemblyName assemblyRef)
979                         {
980                                 Assembly.Load (assemblyRef);
981                         }
982
983                         public void LoadFrom (string assemblyFile)
984                         {
985                                 Assembly.LoadFrom (assemblyFile);
986                         }
987
988                         public bool AssertLoad (AssemblyName assemblyRef)
989                         {
990                                 try {
991                                         Assembly.Load (assemblyRef);
992                                         return true;
993                                 } catch {
994                                         return false;
995                                 }
996                         }
997
998                         public bool AssertLoad (string assemblyString)
999                         {
1000                                 try {
1001                                         Assembly.Load (assemblyString);
1002                                         return true;
1003                                 } catch {
1004                                         return false;
1005                                 }
1006                         }
1007
1008                         public bool AssertFileLoadException (AssemblyName assemblyRef)
1009                         {
1010                                 try {
1011                                         Assembly.Load (assemblyRef);
1012                                         return false;
1013                                 } catch (FileLoadException) {
1014                                         return true;
1015                                 }
1016                         }
1017
1018                         public bool AssertFileNotFoundException (AssemblyName assemblyRef)
1019                         {
1020                                 try {
1021                                         Assembly.Load (assemblyRef);
1022                                         return false;
1023                                 } catch (FileNotFoundException) {
1024                                         return true;
1025                                 }
1026                         }
1027
1028                         public void bug78464 (string assemblyFileName)
1029                         {
1030                                 AssemblyName assemblyName = new AssemblyName ();
1031                                 assemblyName.Name = "bug78464";
1032
1033                                 AssemblyBuilder ab = AppDomain.CurrentDomain
1034                                         .DefineDynamicAssembly (assemblyName,
1035                                         AssemblyBuilderAccess.Save,
1036                                         Path.GetDirectoryName (assemblyFileName),
1037                                         AppDomain.CurrentDomain.Evidence);
1038                                 ab.Save (Path.GetFileName (assemblyFileName));
1039
1040                                 Assembly assembly;
1041
1042                                 using (FileStream fs = File.OpenRead (assemblyFileName)) {
1043                                         byte[] buffer = new byte[fs.Length];
1044                                         fs.Read (buffer, 0, buffer.Length);
1045                                         assembly = Assembly.Load (buffer);
1046                                         fs.Close ();
1047                                 }
1048
1049                                 Assert.AreEqual (string.Empty, assembly.Location, "#1");
1050
1051                                 assembly = Assembly.LoadFrom (assemblyFileName, AppDomain.CurrentDomain.Evidence);
1052                                 Assert.IsFalse (assembly.Location == string.Empty, "#2");
1053                                 Assert.AreEqual (Path.GetFileName (assemblyFileName), Path.GetFileName(assembly.Location), "#3");
1054                                 // note: we cannot check if directory names match, as MS.NET seems to 
1055                                 // convert directory part of assembly location to lowercase
1056                                 Assert.IsFalse (Path.GetDirectoryName(assembly.Location) == string.Empty, "#4");
1057                         }
1058
1059                         public void bug78465 (string assemblyFileName)
1060                         {
1061                                 Assembly assembly = Assembly.LoadFrom (assemblyFileName, AppDomain.CurrentDomain.Evidence);
1062                                 Assert.IsFalse (assembly.Location == string.Empty, "#2");
1063                                 Assert.AreEqual (Path.GetFileName (assemblyFileName), Path.GetFileName (assembly.Location), "#3");
1064                                 // note: we cannot check if directory names match, as MS.NET seems to 
1065                                 // convert directory part of assembly location to lowercase
1066                                 Assert.IsFalse (Path.GetDirectoryName (assembly.Location) == string.Empty, "#4");
1067                         }
1068
1069                         public void bug78468 (string assemblyFileName)
1070                         {
1071                                 AssemblyName assemblyName = new AssemblyName ();
1072                                 assemblyName.Name = "bug78468b";
1073
1074                                 AssemblyBuilder ab = AppDomain.CurrentDomain
1075                                         .DefineDynamicAssembly (assemblyName,
1076                                         AssemblyBuilderAccess.Save,
1077                                         Path.GetDirectoryName (assemblyFileName),
1078                                         AppDomain.CurrentDomain.Evidence);
1079                                 ab.AddResourceFile ("read", "readme.txt");
1080                                 ab.Save (Path.GetFileName (assemblyFileName));
1081
1082                                 Assembly assembly = Assembly.LoadFrom (assemblyFileName, AppDomain.CurrentDomain.Evidence);
1083                                 Assert.IsTrue (assembly.Location != string.Empty, "#B1");
1084                                 string[] resNames = assembly.GetManifestResourceNames ();
1085                                 Assert.IsNotNull (resNames, "#B2");
1086                                 Assert.AreEqual (1, resNames.Length, "#B3");
1087                                 Assert.AreEqual ("read", resNames[0], "#B4");
1088                                 ManifestResourceInfo resInfo = assembly.GetManifestResourceInfo ("read");
1089                                 Assert.IsNotNull (resInfo, "#B5");
1090                                 Assert.AreEqual ("readme.txt", resInfo.FileName, "#B6");
1091                                 Assert.IsNull (resInfo.ReferencedAssembly, "#B7");
1092                                 Assert.AreEqual ((ResourceLocation) 0, resInfo.ResourceLocation, "#B8");
1093                                 Stream s = assembly.GetManifestResourceStream ("read");
1094                                 Assert.IsNotNull (s, "#B9");
1095                                 s.Close ();
1096                                 s = assembly.GetFile ("readme.txt");
1097                                 Assert.IsNotNull (s, "#B10");
1098                                 s.Close ();
1099                         }
1100                 }
1101
1102                 [Test]
1103                 public void bug79872 ()
1104                 {
1105                         string outdir = TempFolder;
1106
1107                         AssemblyName an = new AssemblyName ();
1108                         an.Name = "bug79872";
1109                         AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly (an, AssemblyBuilderAccess.Save, outdir);
1110                         string dllname = "bug79872.dll";
1111                         ModuleBuilder mb1 = ab.DefineDynamicModule ("bug79872", dllname);
1112                         string netmodule = "bug79872.netmodule";
1113                         ModuleBuilder mb2 = ab.DefineDynamicModule (netmodule, netmodule);
1114                         TypeBuilder a1 = mb2.DefineType ("A");
1115                         a1.CreateType ();
1116                         ab.Save (dllname);
1117
1118                         bool ok = true;
1119                         try {
1120                                 Assembly.LoadFrom (Path.Combine (outdir, dllname));
1121                         } catch {
1122                                 ok = false;
1123                         }
1124                         Assert.IsTrue (ok, "Should load a .NET metadata file with an assembly manifest");
1125
1126                         ok = false;
1127                         try {
1128                                 Assembly.LoadFrom (Path.Combine (outdir, netmodule));
1129                         } catch (BadImageFormatException) {
1130                                 ok = true; // mono and .net 2.0 throw this
1131                         } catch (FileLoadException) {
1132                                 ok = true; // .net 1.1 throws this
1133                         } catch {
1134                                 // swallow the rest
1135                         }
1136                         Assert.IsTrue (ok, "Complain on loading a .NET metadata file without an assembly manifest");
1137                 }
1138 #endif
1139
1140                 [Test]
1141                 public void ManifestModule ()
1142                 {
1143                         Assembly assembly = typeof (int).Assembly;
1144                         Module module = assembly.ManifestModule;
1145                         Assert.IsNotNull (module, "#1");
1146
1147                         Assert.AreEqual ("MonoModule", module.GetType ().Name, "#2");
1148
1149 #if !MONOTOUCH && !FULL_AOT_RUNTIME
1150                         Assert.AreEqual ("mscorlib.dll", module.Name, "#3");
1151 #endif
1152                         Assert.IsFalse (module.IsResource (), "#4");
1153                         Assert.IsTrue (assembly.GetModules ().Length > 0, "#5");
1154                         Assert.AreSame (module, assembly.GetModules () [0], "#6");
1155                         Assert.AreSame (module, assembly.ManifestModule, "#7");
1156                 }
1157
1158
1159                 [Serializable ()]
1160                 private class AssemblyResolveHandler
1161                 {
1162                         public AssemblyResolveHandler (string assemblyFile, string assemblyName)
1163                         {
1164                                 _assemblyFile = assemblyFile;
1165                                 _assemblyName = assemblyName;
1166
1167                                 AppDomain.CurrentDomain.AssemblyResolve +=
1168                                         new ResolveEventHandler (ResolveAssembly);
1169                         }
1170
1171                         private Assembly ResolveAssembly (Object sender, ResolveEventArgs args)
1172                         {
1173                                 if (args.Name == _assemblyName)
1174                                         return Assembly.LoadFrom (_assemblyFile);
1175
1176                                 return null;
1177                         }
1178
1179                         private readonly string _assemblyFile;
1180                         private readonly string _assemblyName;
1181                 }
1182
1183                 protected internal class Bug328812_NestedFamORAssem { };
1184
1185                 [Test]
1186                 public void bug328812 ()
1187                 {
1188                         Assembly corlib_test = Assembly.GetExecutingAssembly ();
1189                         Assert.IsNull (corlib_test.GetType ("Bug328812_NestedFamORAssem"));
1190                         // Just a sanity check, in case the above passed for some other reason
1191                         Assert.IsNotNull (corlib_test.GetType ("MonoTests.System.Reflection.AssemblyTest+Bug328812_NestedFamORAssem"));
1192                 }
1193                 
1194                 [Test]
1195                 public void GetCustomAttributes_AttributeType_Null ()
1196                 {
1197                         Assembly a = typeof (int).Assembly;
1198                         try {
1199                                 a.GetCustomAttributes (null, false);
1200                                 Assert.Fail ("#1");
1201                         } catch (ArgumentNullException ex) {
1202                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
1203                                 Assert.IsNull (ex.InnerException, "#3");
1204                                 Assert.IsNotNull (ex.Message, "#4");
1205                                 Assert.IsNotNull (ex.ParamName, "#5");
1206                                 Assert.AreEqual ("attributeType", ex.ParamName, "#6");
1207                         }
1208                 }
1209
1210                 [Test]
1211                 public void GetTypeWithEmptyStringShouldThrow ()
1212                 {
1213                         try {
1214                                 typeof (string).Assembly.GetType ("");
1215                                 Assert.Fail ("#1");
1216                         } catch (ArgumentException) {}
1217                 }
1218
1219                 class GetCallingAssemblyCallee {
1220                         static int _dummy;
1221
1222                         static void sideEffect () {
1223                                 _dummy++;
1224                         }
1225
1226                         // GetCallingAssembly may see an unpredictable
1227                         // view of the stack if it's called in tail
1228                         // position, or if its caller or the caller's
1229                         // caller is inlined.  So we put in a side
1230                         // effect to get out of tail position, and we
1231                         // tag the methods NoInlining to discourage
1232                         // the inliner.
1233                         [MethodImplAttribute (MethodImplOptions.NoInlining)]
1234                         public static Assembly Leaf () {
1235                                 var a = Assembly.GetCallingAssembly ();
1236                                 sideEffect();
1237                                 return a;
1238                         }
1239
1240                         [MethodImplAttribute (MethodImplOptions.NoInlining)]
1241                         public static Assembly DirectCall () {
1242                                 var a = Leaf();
1243                                 sideEffect();
1244                                 return a;
1245                         }
1246
1247                         [MethodImplAttribute (MethodImplOptions.NoInlining)]
1248                         public static Assembly InvokeCall () {
1249                                 var ty = typeof (GetCallingAssemblyCallee);
1250                                 var mi = ty.GetMethod("Leaf");
1251                                 var o = mi.Invoke(null, null);
1252                                 sideEffect();
1253                                 return (Assembly)o;
1254                         }
1255                 }
1256
1257                 [Test]
1258                 public void GetCallingAssembly_Direct() {
1259                         var a = GetCallingAssemblyCallee.DirectCall ();
1260                         Assert.IsNotNull (a);
1261
1262                         Assert.AreEqual (GetType().Assembly, a);
1263                 }
1264
1265                 [Test]
1266                 public void GetCallingAssembly_SkipsReflection () {
1267                         // check that the calling assembly is this
1268                         // one, not mscorlib (aka, the reflection
1269                         // API).
1270                         var a = GetCallingAssemblyCallee.InvokeCall ();
1271                         Assert.IsNotNull (a);
1272
1273                         var invokeAssembly =
1274                                 typeof (MethodInfo).Assembly;
1275                         Assert.AreNotEqual (invokeAssembly, a);
1276
1277                         Assert.AreEqual (GetType().Assembly, a);
1278                 }
1279
1280                 [Test]
1281                 public void DefinedTypes_Equality ()
1282                 {
1283                         var x1 = Assembly.GetExecutingAssembly ().DefinedTypes.Where (l => l.FullName == "MonoTests.System.Reflection.TestDefinedTypes").Single ();
1284                         var x2 = Assembly.GetExecutingAssembly ().GetTypes ().Where (l => l.FullName == "MonoTests.System.Reflection.TestDefinedTypes").Single ();
1285
1286                         Assert.AreSame (x1, x2, "#1");
1287                 }
1288
1289                 class MyAssembly : Assembly { }
1290
1291                 [Test]
1292                 public void CustomAssemblyImplThrows ()
1293                 {
1294                         var ma = new MyAssembly();
1295                         try {
1296                                 ma.GetName ();
1297                                 Assert.Fail ("must throw");
1298                         } catch (NotImplementedException){
1299                         }
1300                 }
1301         }
1302
1303         public class TestDefinedTypes
1304         {
1305         }
1306 }