This should fix #76928. This fix incorporates ideas from a patch
[mono.git] / mcs / class / corlib / Test / System.Reflection.Emit / AssemblyBuilderTest.cs
1 //
2 // AssemblyBuilderTest.cs - NUnit Test Cases for the AssemblyBuilder class
3 //
4 // Zoltan Varga (vargaz@freemail.hu)
5 //
6 // (C) Ximian, Inc.  http://www.ximian.com
7 //
8 //
9
10
11 using System;
12 using System.Globalization;
13 using System.Threading;
14 using System.Reflection;
15 using System.Reflection.Emit;
16 using System.IO;
17 using System.Configuration.Assemblies;
18
19 using NUnit.Framework;
20
21 namespace MonoTests.System.Reflection.Emit
22 {
23
24 [TestFixture]
25 public class AssemblyBuilderTest
26 {       
27         [AttributeUsage (AttributeTargets.Assembly)]
28         public sealed class FooAttribute : Attribute
29         {
30                 public FooAttribute (string arg)
31                 {
32                 }
33
34                 public FooAttribute ()
35                 {
36                 }
37         }
38
39         static int nameIndex = 0;
40
41         static AppDomain domain;
42
43         static AssemblyBuilder ab;
44
45         static ModuleBuilder mb;
46
47         string tempDir = Path.Combine (Path.GetTempPath (), "MonoTests.System.Reflection.Emit.AssemblyBuilderTest");
48
49         [SetUp]
50         protected void SetUp () {
51                 if (Directory.Exists (tempDir))
52                         Directory.Delete (tempDir, true);
53
54                 Directory.CreateDirectory (tempDir);
55
56                 for (int i = 1; i < 3; ++i) {
57                         string resFile = Path.Combine (tempDir, "res" + i + ".txt");
58                         using (StreamWriter sw = new StreamWriter (resFile)) {
59                                 sw.WriteLine ("FOO");
60                         }
61                 }
62
63                 domain = Thread.GetDomain ();
64                 ab = genAssembly ();
65                 mb = ab.DefineDynamicModule ("def_module");
66         }
67
68         [TearDown]
69         protected void TearDown () {
70                 if (Directory.Exists (tempDir))
71                         Directory.Delete (tempDir, true);
72         }               
73
74         private AssemblyName genAssemblyName () {
75                 AssemblyName assemblyName = new AssemblyName();
76                 assemblyName.Name = "MonoTests.System.Reflection.Emit.AssemblyBuilderTest" + (nameIndex ++);
77                 return assemblyName;
78         }
79
80         private AssemblyBuilder genAssembly () {
81                 return domain.DefineDynamicAssembly (genAssemblyName (),
82                                                                                          AssemblyBuilderAccess.RunAndSave,
83                                                                                          tempDir);
84         }
85
86         private MethodInfo genEntryFunction (AssemblyBuilder assembly) {
87                 ModuleBuilder module = assembly.DefineDynamicModule("module1");
88                 TypeBuilder tb = module.DefineType ("A");
89                 MethodBuilder mb = tb.DefineMethod ("A",
90                         MethodAttributes.Static, typeof (void), new Type [0]);
91                 mb.GetILGenerator ().Emit (OpCodes.Ret);
92                 return mb;
93         }
94
95         [ExpectedException (typeof (NotSupportedException))]
96         public void TestCodeBase () {
97                 string codebase = ab.CodeBase;
98         }
99
100         [ExpectedException (typeof (NotSupportedException))]
101         public void TestLocation () {
102                 string location = ab.Location;
103         }
104
105         public void TestEntryPoint () {
106                 Assert.AreEqual (null, ab.EntryPoint, "EntryPoint defaults to null");
107
108                 MethodInfo mi = genEntryFunction (ab);
109                 ab.SetEntryPoint (mi);
110
111                 Assert.AreEqual (mi, ab.EntryPoint, "EntryPoint works");
112         }
113
114         public void TestSetEntryPoint () {
115                 // Check invalid arguments
116                 try {
117                         ab.SetEntryPoint (null);
118                         Assert.Fail ();
119                 }
120                 catch (ArgumentNullException) {
121                 }
122
123                 // Check method from other assembly
124                 try {
125                         ab.SetEntryPoint (typeof (AssemblyBuilderTest).GetMethod ("TestSetEntryPoint"));
126                         Assert.Fail ();
127                 }
128                 catch (InvalidOperationException) {
129                 }
130         }
131
132         public void TestIsDefined () {
133                 CustomAttributeBuilder cab = new CustomAttributeBuilder (typeof (FooAttribute).GetConstructor (new Type [1] {typeof (string)}), new object [1] { "A" });
134                 ab.SetCustomAttribute (cab);
135
136                 Assert.IsTrue (ab.IsDefined (typeof (FooAttribute), false),
137                         "IsDefined(FooAttribute) works");
138                 Assert.IsFalse (ab.IsDefined (typeof (AssemblyVersionAttribute), false),
139                         "!IsDefined(AssemblyVersionAttribute) works");
140         }
141
142         [ExpectedException (typeof (NotSupportedException))]
143         public void TestGetManifestResourceNames () {
144                 ab.GetManifestResourceNames ();
145         }
146
147         [ExpectedException (typeof (NotSupportedException))]
148         public void TestGetManifestResourceInfo () {
149                 ab.GetManifestResourceInfo ("foo");
150         }
151
152         [ExpectedException (typeof (NotSupportedException))]
153         public void TestGetManifestResourceStream1 () {
154                 ab.GetManifestResourceStream ("foo");
155         }
156
157         [ExpectedException (typeof (NotSupportedException))]
158         public void TestGetManifestResourceStream2 () {
159                 ab.GetManifestResourceStream (typeof (int), "foo");
160         }
161
162         [ExpectedException (typeof (NotSupportedException))]
163         public void TestGetFiles1 () {
164                 ab.GetFiles ();
165         }
166
167         [ExpectedException (typeof (NotSupportedException))]
168         public void TestGetFiles2 () {
169                 ab.GetFiles (true);
170         }
171
172         [ExpectedException (typeof (NotSupportedException))]
173         public void TestGetFile () {
174                 ab.GetFile ("foo");
175         }
176
177         [ExpectedException (typeof (NotSupportedException))]
178         public void TestGetExportedTypes () {
179                 ab.GetExportedTypes ();
180         }
181
182         [ExpectedException (typeof (ArgumentNullException))]
183         public void TestGetDynamicModule1 () {
184                 ab.GetDynamicModule (null);
185         }
186
187         [ExpectedException (typeof (ArgumentException))]
188         public void TestGetDynamicModule2 () {
189                 ab.GetDynamicModule ("");
190         }
191
192         public void TestGetDynamicModule3 () {
193                 Assert.IsNull (ab.GetDynamicModule ("FOO2"));
194
195                 ModuleBuilder mb = ab.DefineDynamicModule ("FOO");
196
197                 Assert.AreEqual (mb, ab.GetDynamicModule ("FOO"));
198
199                 Assert.IsNull (ab.GetDynamicModule ("FOO4"));
200         }
201
202 #if NET_1_1
203         public void TestImageRuntimeVersion () {
204                 string version = ab.ImageRuntimeVersion;
205                 Assert.IsTrue (version.Length > 0);
206         }
207 #endif
208
209         [ExpectedException (typeof (ArgumentNullException))]
210         public void TestAddResourceFileNullName () {
211                 ab.AddResourceFile (null, "foo.txt");
212         }
213
214         [ExpectedException (typeof (ArgumentNullException))]
215         public void TestAddResourceFileNullFilename () {
216                 ab.AddResourceFile ("foo", null);
217         }
218
219         [ExpectedException (typeof (ArgumentException))]
220         public void TestAddResourceFileEmptyName () {
221                 ab.AddResourceFile ("", "foo.txt");
222         }
223
224         [ExpectedException (typeof (ArgumentException))]
225         public void TestAddResourceFileEmptyFilename () {
226                 ab.AddResourceFile ("foo", "");
227         }
228
229         [ExpectedException (typeof (FileNotFoundException))]
230         public void TestAddResourceFileNonexistentFile () {
231                 ab.AddResourceFile ("foo", "not-existent.txt");
232         }
233
234         [ExpectedException (typeof (ArgumentException))]
235         public void TestAddResourceFileDuplicateFileName () {
236                 ab.AddResourceFile ("foo", "res1.txt");
237                 ab.AddResourceFile ("foo2", "res1.txt");
238         }
239
240         [ExpectedException (typeof (ArgumentException))]
241         public void TestAddResourceFileDuplicateName () {
242                 ab.AddResourceFile ("foo", "res1.txt");
243                 ab.AddResourceFile ("foo", "res2.txt");
244         }
245
246         [ExpectedException (typeof (ArgumentException))]
247         public void TestAddResourceFileFilenameIncludesPath () {
248                 ab.AddResourceFile ("foo", "/tmp/res1.txt");
249         }
250
251         public void TestAddResourceFile () {
252                 ab.AddResourceFile ("foo", "res2.txt", ResourceAttributes.Public);
253
254                 ab.Save ("TestAddResourceFile.dll");
255
256                 // TODO: Test reading back
257         }
258
259         public void TestDefineResource () {
260                 ab.DefineResource ("foo", "FOO", "foo.txt", ResourceAttributes.Public);
261                 ab.DefineResource ("foo2", "FOO", "foo2.txt");
262
263                 ab.Save ("TestDefineResource.dll");
264         }
265
266         [ExpectedException (typeof (ArgumentNullException))]
267         public void TestDefineDynamicModuleNullName () {
268                 ab.DefineDynamicModule (null, "foo.txt");
269         }
270
271         [ExpectedException (typeof (ArgumentNullException))]
272         public void TestDefineDynamicModuleNullFilename () {
273                 ab.DefineDynamicModule ("foo", null);
274         }
275
276         [ExpectedException (typeof (ArgumentException))]
277         public void TestDefineDynamicModuleEmptyName () {
278                 ab.DefineDynamicModule ("", "foo.txt");
279         }
280
281         [ExpectedException (typeof (ArgumentException))]
282         public void TestDefineDynamicModuleEmptyFilename () {
283                 ab.DefineDynamicModule ("foo", "");
284         }
285
286         [ExpectedException (typeof (ArgumentException))]
287         public void TestDefineDynamicModuleDuplicateFileName () {
288                 ab.DefineDynamicModule ("foo", "res1.txt");
289                 ab.DefineDynamicModule ("foo2", "res1.txt");
290         }
291
292         [ExpectedException (typeof (ArgumentException))]
293         public void TestDefineDynamicModuleDuplicateName () {
294                 ab.DefineDynamicModule ("foo", "res1.txt");
295                 ab.DefineDynamicModule ("foo", "res2.txt");
296         }
297
298         [ExpectedException (typeof (ArgumentException))]
299         public void TestDefineDynamicModuleFilenameIncludesPath () {
300                 ab.DefineDynamicModule ("foo", "/tmp/res1.txt");
301         }
302
303         [ExpectedException (typeof (ArgumentException))]
304         public void TestDefineDynamicModule5 () {
305                 // Filename without extension
306                 ab.DefineDynamicModule ("foo", "foo");
307         }
308
309         /*
310         [ExpectedException (typeof (ArgumentException))]
311         public void TestDefineDynamicModule6 () {
312                 // Name too long
313                 string name = "";
314                 for (int i = 0; i < 259; ++i)
315                         name = name + "A";
316
317                 try {
318                         ab.DefineDynamicModule (name);
319                 }
320                 catch (Exception) {
321                         Assert.Fail ();
322                 }
323
324                 name = name + "A";
325                 // LAMESPEC: According to MSDN, this should throw an ArgumentException
326
327                 ab.DefineDynamicModule (name);
328         }
329         */
330
331         [ExpectedException (typeof (InvalidOperationException))]
332         public void TestDefineDynamicModule7 () {
333                 // Called when assembly was already saved
334                 ab.Save ("TestDefineDynamicModule7.dll");
335                 ab.DefineDynamicModule ("foo", "foo.dll");
336         }
337
338         [ExpectedException (typeof (NotSupportedException))]
339         public void TestDefineDynamicModule8 () {
340                 // Called on an assembly defined with the Run attribute
341                 AssemblyBuilder ab = 
342                         domain.DefineDynamicAssembly (genAssemblyName (),
343                                                                                   AssemblyBuilderAccess.Run,
344                                                                                   tempDir);
345                 ab.DefineDynamicModule ("foo", "foo.dll");
346         }
347
348         public void TestDefineDynamicModule () {
349                 ab.DefineDynamicModule ("foo", "foo.dll");
350                 ab.DefineDynamicModule ("foo2", true);
351                 ab.DefineDynamicModule ("foo3", "foo3.dll");
352                 ab.DefineDynamicModule ("foo4", "foo4.dll", true);
353         }
354
355         [ExpectedException (typeof (ArgumentNullException))]
356         public void TestDefineUnmanagedResource1 () {
357                 // Null argument
358                 ab.DefineUnmanagedResource ((byte[])null);
359         }
360
361         [ExpectedException (typeof (ArgumentNullException))]
362         public void TestDefineUnmanagedResource2 () {
363                 // Null argument
364                 ab.DefineUnmanagedResource ((string)null);
365         }
366
367         [ExpectedException (typeof (ArgumentException))]
368         public void TestDefineUnmanagedResource3 () {
369                 // Empty filename
370                 ab.DefineUnmanagedResource ("");
371         }
372
373         [ExpectedException (typeof (FileNotFoundException))]
374         public void TestDefineUnmanagedResource4 () {
375                 // Nonexistent file
376                 ab.DefineUnmanagedResource ("not-exists.txt");
377         }
378
379         [ExpectedException (typeof (ArgumentNullException))]
380         public void TestSetCustomAttribute1 () {
381                 // Null argument
382                 ab.SetCustomAttribute (null);
383         }
384
385         [ExpectedException (typeof (ArgumentNullException))]
386         public void TestSetCustomAttribute2 () {
387                 // Null constructor
388                 ab.SetCustomAttribute (null, new byte [0]);
389         }
390
391         [ExpectedException (typeof (ArgumentNullException))]
392         public void TestSetCustomAttribute3 () {
393                 // Null blob
394                 ab.SetCustomAttribute (typeof(AssemblyCompanyAttribute).GetConstructor (new Type [] { typeof (String) }), null);
395         }
396
397         public void TestSetCustomAttribute () {
398                 // Test common custom attributes
399
400                 ab.SetCustomAttribute (new CustomAttributeBuilder (typeof (AssemblyVersionAttribute).GetConstructor (new Type [] { typeof (string) }), new object [] { "1.2.3.4"}));
401
402                 ab.SetCustomAttribute (new CustomAttributeBuilder (typeof (AssemblyCultureAttribute).GetConstructor (new Type [] { typeof (string) }), new object [] { "bar"}));
403
404                 ab.SetCustomAttribute (new CustomAttributeBuilder (typeof (AssemblyAlgorithmIdAttribute).GetConstructor (new Type [] { typeof (AssemblyHashAlgorithm) }), new object [] { AssemblyHashAlgorithm.MD5 }));
405
406                 ab.SetCustomAttribute (new CustomAttributeBuilder (typeof (AssemblyFlagsAttribute).GetConstructor (new Type [] { typeof (uint) }), new object [] { (uint)0x0100 }));
407
408                 ab.SetCustomAttribute (new CustomAttributeBuilder (typeof (AssemblyDelaySignAttribute).GetConstructor (new Type [] { typeof (bool) }), new object [] { true }));
409
410                 ab.SetCustomAttribute (typeof (FooAttribute).GetConstructor (new Type [] {}), new byte [0]);
411
412                 ab.Save ("TestSetCustomAttribute.dll");
413
414                 /* We should read back the assembly and check the attributes ... */
415         }
416
417         // strongname generated using "sn -k unit.snk"
418         static byte[] strongName = { 
419                 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 
420                 0x00, 0x04, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x7F, 0x7C, 0xEA, 0x4A, 
421                 0x28, 0x33, 0xD8, 0x3C, 0x86, 0x90, 0x86, 0x91, 0x11, 0xBB, 0x30, 0x0D, 
422                 0x3D, 0x69, 0x04, 0x4C, 0x48, 0xF5, 0x4F, 0xE7, 0x64, 0xA5, 0x82, 0x72, 
423                 0x5A, 0x92, 0xC4, 0x3D, 0xC5, 0x90, 0x93, 0x41, 0xC9, 0x1D, 0x34, 0x16, 
424                 0x72, 0x2B, 0x85, 0xC1, 0xF3, 0x99, 0x62, 0x07, 0x32, 0x98, 0xB7, 0xE4, 
425                 0xFA, 0x75, 0x81, 0x8D, 0x08, 0xB9, 0xFD, 0xDB, 0x00, 0x25, 0x30, 0xC4, 
426                 0x89, 0x13, 0xB6, 0x43, 0xE8, 0xCC, 0xBE, 0x03, 0x2E, 0x1A, 0x6A, 0x4D, 
427                 0x36, 0xB1, 0xEB, 0x49, 0x26, 0x6C, 0xAB, 0xC4, 0x29, 0xD7, 0x8F, 0x25, 
428                 0x11, 0xA4, 0x7C, 0x81, 0x61, 0x97, 0xCB, 0x44, 0x2D, 0x80, 0x49, 0x93, 
429                 0x48, 0xA7, 0xC9, 0xAB, 0xDB, 0xCF, 0xA3, 0x34, 0xCB, 0x6B, 0x86, 0xE0, 
430                 0x4D, 0x27, 0xFC, 0xA7, 0x4F, 0x36, 0xCA, 0x13, 0x42, 0xD3, 0x83, 0xC4, 
431                 0x06, 0x6E, 0x12, 0xE0, 0xA1, 0x3D, 0x9F, 0xA9, 0xEC, 0xD1, 0xC6, 0x08, 
432                 0x1B, 0x3D, 0xF5, 0xDB, 0x4C, 0xD4, 0xF0, 0x2C, 0xAA, 0xFC, 0xBA, 0x18, 
433                 0x6F, 0x48, 0x7E, 0xB9, 0x47, 0x68, 0x2E, 0xF6, 0x1E, 0x67, 0x1C, 0x7E, 
434                 0x0A, 0xCE, 0x10, 0x07, 0xC0, 0x0C, 0xAD, 0x5E, 0xC1, 0x53, 0x70, 0xD5, 
435                 0xE7, 0x25, 0xCA, 0x37, 0x5E, 0x49, 0x59, 0xD0, 0x67, 0x2A, 0xBE, 0x92, 
436                 0x36, 0x86, 0x8A, 0xBF, 0x3E, 0x17, 0x04, 0xFB, 0x1F, 0x46, 0xC8, 0x10, 
437                 0x5C, 0x93, 0x02, 0x43, 0x14, 0x96, 0x6A, 0xD9, 0x87, 0x17, 0x62, 0x7D, 
438                 0x3A, 0x45, 0xBE, 0x35, 0xDE, 0x75, 0x0B, 0x2A, 0xCE, 0x7D, 0xF3, 0x19, 
439                 0x85, 0x4B, 0x0D, 0x6F, 0x8D, 0x15, 0xA3, 0x60, 0x61, 0x28, 0x55, 0x46, 
440                 0xCE, 0x78, 0x31, 0x04, 0x18, 0x3C, 0x56, 0x4A, 0x3F, 0xA4, 0xC9, 0xB1, 
441                 0x41, 0xED, 0x22, 0x80, 0xA1, 0xB3, 0xE2, 0xC7, 0x1B, 0x62, 0x85, 0xE4, 
442                 0x81, 0x39, 0xCB, 0x1F, 0x95, 0xCC, 0x61, 0x61, 0xDF, 0xDE, 0xF3, 0x05, 
443                 0x68, 0xB9, 0x7D, 0x4F, 0xFF, 0xF3, 0xC0, 0x0A, 0x25, 0x62, 0xD9, 0x8A, 
444                 0x8A, 0x9E, 0x99, 0x0B, 0xFB, 0x85, 0x27, 0x8D, 0xF6, 0xD4, 0xE1, 0xB9, 
445                 0xDE, 0xB4, 0x16, 0xBD, 0xDF, 0x6A, 0x25, 0x9C, 0xAC, 0xCD, 0x91, 0xF7, 
446                 0xCB, 0xC1, 0x81, 0x22, 0x0D, 0xF4, 0x7E, 0xEC, 0x0C, 0x84, 0x13, 0x5A, 
447                 0x74, 0x59, 0x3F, 0x3E, 0x61, 0x00, 0xD6, 0xB5, 0x4A, 0xA1, 0x04, 0xB5, 
448                 0xA7, 0x1C, 0x29, 0xD0, 0xE1, 0x11, 0x19, 0xD7, 0x80, 0x5C, 0xEE, 0x08, 
449                 0x15, 0xEB, 0xC9, 0xA8, 0x98, 0xF5, 0xA0, 0xF0, 0x92, 0x2A, 0xB0, 0xD3, 
450                 0xC7, 0x8C, 0x8D, 0xBB, 0x88, 0x96, 0x4F, 0x18, 0xF0, 0x8A, 0xF9, 0x31, 
451                 0x9E, 0x44, 0x94, 0x75, 0x6F, 0x78, 0x04, 0x10, 0xEC, 0xF3, 0xB0, 0xCE, 
452                 0xA0, 0xBE, 0x7B, 0x25, 0xE1, 0xF7, 0x8A, 0xA8, 0xD4, 0x63, 0xC2, 0x65, 
453                 0x47, 0xCC, 0x5C, 0xED, 0x7D, 0x8B, 0x07, 0x4D, 0x76, 0x29, 0x53, 0xAC, 
454                 0x27, 0x8F, 0x5D, 0x78, 0x56, 0xFA, 0x99, 0x45, 0xA2, 0xCC, 0x65, 0xC4, 
455                 0x54, 0x13, 0x9F, 0x38, 0x41, 0x7A, 0x61, 0x0E, 0x0D, 0x34, 0xBC, 0x11, 
456                 0xAF, 0xE2, 0xF1, 0x8B, 0xFA, 0x2B, 0x54, 0x6C, 0xA3, 0x6C, 0x09, 0x1F, 
457                 0x0B, 0x43, 0x9B, 0x07, 0x95, 0x83, 0x3F, 0x97, 0x99, 0x89, 0xF5, 0x51, 
458                 0x41, 0xF6, 0x8E, 0x5D, 0xEF, 0x6D, 0x24, 0x71, 0x41, 0x7A, 0xAF, 0xBE, 
459                 0x81, 0x71, 0xAB, 0x76, 0x2F, 0x1A, 0x5A, 0xBA, 0xF3, 0xA6, 0x65, 0x7A, 
460                 0x80, 0x50, 0xCE, 0x23, 0xC3, 0xC7, 0x53, 0xB0, 0x7C, 0x97, 0x77, 0x27, 
461                 0x70, 0x98, 0xAE, 0xB5, 0x24, 0x66, 0xE1, 0x60, 0x39, 0x41, 0xDA, 0x54, 
462                 0x01, 0x64, 0xFB, 0x10, 0x33, 0xCE, 0x8B, 0xBE, 0x27, 0xD4, 0x21, 0x57, 
463                 0xCC, 0x0F, 0x1A, 0xC1, 0x3D, 0xF3, 0xCC, 0x39, 0xF0, 0x2F, 0xAE, 0xF1, 
464                 0xC0, 0xCD, 0x3B, 0x23, 0x87, 0x49, 0x7E, 0x40, 0x32, 0x6A, 0xD3, 0x96, 
465                 0x4A, 0xE5, 0x5E, 0x6E, 0x26, 0xFD, 0x8A, 0xCF, 0x7E, 0xFC, 0x37, 0xDE, 
466                 0x39, 0x0C, 0x53, 0x81, 0x75, 0x08, 0xAF, 0x6B, 0x39, 0x6C, 0xFB, 0xC9, 
467                 0x79, 0xC0, 0x9B, 0x5F, 0x34, 0x86, 0xB2, 0xDE, 0xC4, 0x19, 0x84, 0x5F, 
468                 0x0E, 0xED, 0x9B, 0xB8, 0xD3, 0x17, 0xDA, 0x78 };
469
470         [Test]
471         public void StrongName_MissingKeyFile_NoDelay () 
472         {
473                 ab.SetCustomAttribute (new CustomAttributeBuilder (typeof (AssemblyKeyFileAttribute).GetConstructor (new Type [] { typeof (string) }), new object [] { "missing.snk" }));
474                 ab.SetCustomAttribute (new CustomAttributeBuilder (typeof (AssemblyDelaySignAttribute).GetConstructor (new Type [] { typeof (bool) }), new object [] { false }));
475                 ab.Save ("StrongName_MissingKeyFile_NoDelay.dll");
476
477                 string filename = Path.Combine (tempDir, "StrongName_MissingKeyFile_NoDelay.dll");
478                 AssemblyName check = AssemblyName.GetAssemblyName (filename);
479                 // no exception is thrown (file not found)
480                 // because it's not AssemblyBuilder.Save job to do the signing :-/
481                 Assert.IsNull (check.GetPublicKeyToken (), "Token");
482         }
483
484         [Test]
485         public void StrongName_KeyFile_Delay () 
486         {
487                 string strongfile = Path.Combine (tempDir, "strongname.snk");
488                 using (FileStream fs = File.OpenWrite (strongfile)) {
489                         fs.Write (strongName, 0, strongName.Length);
490                         fs.Close ();
491                 }
492                 ab.SetCustomAttribute (new CustomAttributeBuilder (typeof (AssemblyKeyFileAttribute).GetConstructor (new Type [] { typeof (string) }), new object [] { strongfile }));
493                 ab.SetCustomAttribute (new CustomAttributeBuilder (typeof (AssemblyDelaySignAttribute).GetConstructor (new Type [] { typeof (bool) }), new object [] { true }));
494                 ab.Save ("StrongName_KeyFile_Delay.dll");
495
496                 string filename = Path.Combine (tempDir, "StrongName_KeyFile_Delay.dll");
497                 AssemblyName check = AssemblyName.GetAssemblyName (filename);
498                 // no public key is inserted into the assembly
499                 // because it's not AssemblyBuilder.Save job to do the signing :-/
500                 Assert.IsNull (check.GetPublicKeyToken (), "Token");
501         }
502
503         [Test]
504         public void StrongName_WithoutAttributes () 
505         {
506                 // this demonstrate that AssemblyKeyFileAttribute (or AssemblyKeyNameAttribute)
507                 // aren't required to sign an assembly.
508                 AssemblyName an = genAssemblyName ();
509                 an.KeyPair = new StrongNameKeyPair (strongName);
510                 AssemblyBuilder ab = domain.DefineDynamicAssembly (an, AssemblyBuilderAccess.RunAndSave, tempDir);
511                 ab.Save ("StrongName_WithoutAttributes.dll");
512
513                 string filename = Path.Combine (tempDir, "StrongName_WithoutAttributes.dll");
514                 AssemblyName check = AssemblyName.GetAssemblyName (filename);
515                 Assert.AreEqual ("0E-EA-7C-E6-5F-35-F2-D8", BitConverter.ToString (check.GetPublicKeyToken ()), "Token");
516         }
517
518         [Test]
519         [ExpectedException (typeof (NotSupportedException))]
520         public void SaveUnfinishedTypes ()
521         {
522                 TypeBuilder typeBuilder = mb.DefineType ("TestType", TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.AnsiClass | TypeAttributes.AutoClass, typeof(object));
523
524                 ab.Save ("def_module");
525         }
526
527         [Test]
528         public void GetModules ()
529         {
530                 Module[] m;
531
532                 m = ab.GetModules ();
533                 Assert.IsTrue (m.Length >= 2);
534
535                 // Test with no modules
536                 AssemblyBuilder ab2 = genAssembly ();
537                 m = ab2.GetModules ();
538         }
539
540         [Test]
541         [Category ("NotWorking")]
542         public void AssemblyName_Culture ()
543         {
544                 AssemblyName assemblyName = new AssemblyName ();
545                 assemblyName.Name = "AssemblyNameTest";
546                 assemblyName.Version = new Version ("1.0.0.0");
547                 assemblyName.CultureInfo = new CultureInfo ("en-US");
548
549                 const string fullName = "AssemblyNameTest, Version=1.0.0.0, Culture=en-US, PublicKeyToken=null";
550                 const string abName = "AssemblyNameTest, Version=1.0.0.0, Culture=en-US";
551
552                 AssertAssemblyName (tempDir, assemblyName, abName, fullName);
553         }
554
555         [Test]
556         public void AssemblyName_PublicKey ()
557         {
558                 AssemblyName assemblyName = new AssemblyName ();
559                 assemblyName.Name = "AssemblyNameTest_PublicKey";
560                 assemblyName.Version = new Version ("1.2.3.4");
561                 assemblyName.KeyPair = new StrongNameKeyPair (strongName);
562
563                 Assert.AreEqual ("AssemblyNameTest_PublicKey, Version=1.2.3.4", assemblyName.FullName, "#1");
564
565                 const string fullName = "AssemblyNameTest_PublicKey, Version=1.2.3.4, Culture=neutral, PublicKeyToken=0eea7ce65f35f2d8";
566
567                 AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly (
568                         assemblyName, AssemblyBuilderAccess.Save, tempDir);
569
570                 AssemblyName abName = ab.GetName ();
571                 Assert.IsNotNull (abName.GetPublicKeyToken (), "#2");
572                 Assert.IsTrue (abName.GetPublicKeyToken ().Length > 0, "#3");
573                 Assert.IsNotNull (abName.GetPublicKey () != null, "#4");
574                 Assert.IsTrue (abName.GetPublicKey ().Length > 0, "#5");
575
576                 ab.Save ("AssemblyNameTest_PublicKey.dll");
577                 AssemblyName bakedName = AssemblyName.GetAssemblyName (Path.Combine(
578                         tempDir, "AssemblyNameTest_PublicKey.dll"));
579
580                 Assert.IsNotNull (bakedName.GetPublicKeyToken (), "#6");
581                 Assert.IsNotNull (bakedName.GetPublicKey (), "#7");
582                 Assert.AreEqual (fullName, bakedName.FullName, "#8");
583         }
584
585         [Test]
586         [Category ("NotWorking")] 
587         public void AssemblyName_MoreCultureInfo ()
588         {
589                 AssemblyName assemblyName = new AssemblyName ();
590                 assemblyName.Name = "AssemblyNameTest_MoreCultureInfo";
591                 assemblyName.Version = new Version ("1.2.3.4");
592                 assemblyName.KeyPair = new StrongNameKeyPair (strongName);
593
594                 Assert.IsNull (assemblyName.CultureInfo, "#1");
595                 Assert.AreEqual ("AssemblyNameTest_MoreCultureInfo, Version=1.2.3.4", assemblyName.FullName, "#2");
596
597                 const string fullName = "AssemblyNameTest_MoreCultureInfo, Version=1.2.3.4, Culture=neutral, PublicKeyToken=0eea7ce65f35f2d8";
598
599                 AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly (
600                         assemblyName, AssemblyBuilderAccess.Save, tempDir);
601
602                 AssemblyName abName = ab.GetName ();
603                 Assert.IsNotNull (abName.CultureInfo != null, "#3");
604 #if NET_2_0
605                 Assert.IsTrue (abName.CultureInfo != CultureInfo.InvariantCulture, "#4");
606                 Assert.AreEqual (CultureInfo.InvariantCulture.LCID, abName.CultureInfo.LCID, "#5");
607                 Assert.AreEqual (fullName, abName.FullName, "#6");
608 #else
609                 Assert.AreEqual (CultureInfo.InvariantCulture, abName.CultureInfo, "#7");
610                 Assert.AreEqual ("AssemblyNameTest_MoreCultureInfo, Version=1.2.3.4, PublicKeyToken=0eea7ce65f35f2d8", abName.FullName, "#8");
611 #endif
612
613                 ab.Save ("AssemblyNameTest_MoreCultureInfo.dll");
614
615                 AssemblyName bakedName = AssemblyName.GetAssemblyName (Path.Combine(
616                         tempDir, "AssemblyNameTest_MoreCultureInfo.dll"));
617
618                 Assert.IsNotNull (bakedName.CultureInfo, "#9");
619
620 #if NET_2_0
621                 Assert.IsTrue (abName.CultureInfo != CultureInfo.InvariantCulture, "#10");
622                 Assert.AreEqual (CultureInfo.InvariantCulture.LCID, abName.CultureInfo.LCID, "#11");
623 #else
624                 Assert.AreEqual (CultureInfo.InvariantCulture, bakedName.CultureInfo, "#12");
625 #endif
626                 Assert.AreEqual (fullName, bakedName.FullName, "#13");
627         }
628
629         [Test]
630         [Category ("NotWorking")]
631         public void AssemblyName_NoVersion ()
632         {
633                 AssemblyName assemblyName = new AssemblyName ();
634                 assemblyName.Name = "AssemblyNameTest";
635
636                 const string fullName = "AssemblyNameTest, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null";
637                 const string abName = "AssemblyNameTest, Version=0.0.0.0";
638
639                 AssertAssemblyName (tempDir, assemblyName, abName, fullName);
640         }
641
642         [Test]
643         [Category ("NotWorking")]
644         public void AssemblyName_Version ()
645         {
646                 AssemblyName assemblyName = new AssemblyName ();
647                 assemblyName.Name = "AssemblyNameTest";
648                 assemblyName.Version = new Version (1, 2, 3, 4);
649
650                 const string fullName = "AssemblyNameTest, Version=1.2.3.4, Culture=neutral, PublicKeyToken=null";
651                 const string abName = "AssemblyNameTest, Version=1.2.3.4";
652
653                 AssertAssemblyName (tempDir, assemblyName, abName, fullName);
654         }
655
656         [Test]
657         public void GetType_IgnoreCase ()
658         {
659                 TypeBuilder tb = mb.DefineType ("Foo.Test2", TypeAttributes.Public, typeof (object));
660
661                 Type t;
662
663                 t = ab.GetType ("foo.Test2", true, true);
664                 Assert.AreEqual ("Test2", t.Name);
665
666                 t = ab.GetType ("foo.test2", true, true);
667                 Assert.AreEqual ("Test2", t.Name);
668
669                 t = ab.GetType ("Foo.test2", true, true);
670                 Assert.AreEqual ("Test2", t.Name);
671         }
672
673         private static void AssertAssemblyName (string tempDir, AssemblyName assemblyName, string abName, string fullName)
674         {
675                 AppDomain currentDomain = AppDomain.CurrentDomain;
676                 AppDomain newDomain = null;
677
678                 try {
679                         AssemblyBuilder ab = currentDomain.DefineDynamicAssembly (
680                                 assemblyName, AssemblyBuilderAccess.Save, tempDir);
681                         ab.Save (assemblyName.Name + ".dll");
682
683 #if NET_2_0
684                         // on .NET 2.0, the full name of the AssemblyBuilder matches the 
685                         // fully qualified assembly name
686                         Assert.AreEqual (fullName, ab.FullName);
687 #else
688                         Assert.AreEqual (abName, ab.FullName);
689 #endif
690
691                         // load assembly in separate domain, so we can clean-up after the 
692                         // test
693                         newDomain = AppDomain.CreateDomain ("test2", currentDomain.Evidence,
694                                 currentDomain.SetupInformation);
695
696                         Helper helper = new Helper (Path.Combine (tempDir, assemblyName.Name + ".dll"),
697                                 fullName);
698                         newDomain.DoCallBack (new CrossAppDomainDelegate (helper.Test));
699                 } finally {
700                         if (newDomain != null) {
701                                 AppDomain.Unload (newDomain);
702                         }
703                 }
704         }
705
706         [Serializable ()]
707         private class Helper
708         {
709                 private readonly string _assemblyPath;
710                 private readonly string _assemblyName;
711
712                 public Helper (string assemblyPath, string assemblyName)
713                 {
714                         _assemblyPath = assemblyPath;
715                         _assemblyName = assemblyName;
716                 }
717                 public void Test ()
718                 {
719                         AssemblyName assemblyName = AssemblyName.GetAssemblyName (_assemblyPath);
720                         Assert.AreEqual (_assemblyName, assemblyName.ToString ());
721                 }
722         }
723 }
724 }
725