New test.
[mono.git] / mcs / class / corlib / Test / System.Reflection.Emit / ModuleBuilderTest.cs
1 //
2 // ModuleBuilderTest - NUnit Test Cases for the ModuleBuilder 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.Threading;
13 using System.Reflection;
14 using System.Reflection.Emit;
15 using System.IO;
16 using System.Collections;
17 using System.Diagnostics.SymbolStore;
18 using System.Runtime.InteropServices;
19
20 using NUnit.Framework;
21
22 namespace MonoTests.System.Reflection.Emit
23 {
24
25 [TestFixture]
26 public class ModuleBuilderTest : Assertion
27 {       
28         static string TempFolder = Path.Combine (Path.GetTempPath (), "MT.S.R.E.MBT");
29
30         [SetUp]
31         public void SetUp () {
32                 Random AutoRand = new Random ( );
33                 string TempPath = TempFolder;
34                 while (Directory.Exists (TempFolder))
35                         TempFolder = Path.Combine (TempPath, AutoRand.Next ().ToString());
36                 Directory.CreateDirectory (TempFolder);
37         }               
38
39         [TearDown]
40         public void TearDown () {
41                 try {
42                         // This throws an exception under MS.NET, since the directory contains loaded
43                         // assemblies.
44                         Directory.Delete (TempFolder, true);
45                 }
46                 catch (Exception) {
47                 }
48         }
49
50         [Test]
51         public void TestIsTransient () {
52                 AssemblyName assemblyName = new AssemblyName();
53                 assemblyName.Name = "foo";
54
55                 AssemblyBuilder ab
56                         = Thread.GetDomain().DefineDynamicAssembly(
57                                 assemblyName, AssemblyBuilderAccess.RunAndSave, TempFolder);            
58                 ModuleBuilder mb1 = ab.DefineDynamicModule ("foo.dll");
59                 AssertEquals (true, mb1.IsTransient ());
60                 ModuleBuilder mb2 = ab.DefineDynamicModule ("foo2.dll", "foo2.dll");
61                 AssertEquals (false, mb2.IsTransient ());
62         }
63
64         // Some of these tests overlap with the tests for Module
65
66         [Test]
67         public void TestGlobalData () {
68
69                 AssemblyName assemblyName = new AssemblyName();
70                 assemblyName.Name = "foo";
71
72                 AssemblyBuilder ab
73                         = Thread.GetDomain().DefineDynamicAssembly(
74                                 assemblyName, AssemblyBuilderAccess.RunAndSave, TempFolder);
75
76                 string resfile = Path.Combine (TempFolder, "res");
77                 using (StreamWriter sw = new StreamWriter (resfile)) {
78                         sw.WriteLine ("FOO");
79                 }
80
81                 ModuleBuilder mb = ab.DefineDynamicModule("foo.dll", "foo.dll");
82
83                 mb.DefineInitializedData ("DATA", new byte [100], FieldAttributes.Public);
84                 mb.DefineInitializedData ("DATA2", new byte [100], FieldAttributes.Public);
85                 mb.DefineInitializedData ("DATA3", new byte [99], FieldAttributes.Public);
86                 mb.DefineUninitializedData ("DATA4", 101, FieldAttributes.Public);
87                 mb.DefineInitializedData ("DATA_PRIVATE", new byte [100], 0);
88                 mb.CreateGlobalFunctions ();
89
90                 ab.Save ("foo.dll");
91
92                 Assembly assembly = Assembly.LoadFrom (Path.Combine (TempFolder, "foo.dll"));
93
94                 Module module = assembly.GetLoadedModules ()[0];
95
96                 string[] expectedFieldNames = new string [] {
97                         "DATA", "DATA2", "DATA3", "DATA4"
98                 };
99                 ArrayList fieldNames = new ArrayList ();
100                 foreach (FieldInfo fi in module.GetFields ()) {
101                         fieldNames.Add (fi.Name);
102                 }
103                 AssertArrayEqualsSorted (expectedFieldNames, fieldNames.ToArray (typeof (string)));
104
105                 AssertEquals (module.GetField ("DATA") != null, true);
106                 AssertEquals (module.GetField ("DATA2") != null, true);
107                 AssertEquals (module.GetField ("DATA3") != null, true);
108                 AssertEquals (module.GetField ("DATA4") != null, true);
109                 AssertEquals (module.GetField ("DATA_PRIVATE"), null);
110                 AssertEquals (module.GetField ("DATA_PRIVATE", BindingFlags.NonPublic | BindingFlags.Static) != null, true);
111         }
112
113         [Test]
114         public void TestGlobalMethods () {
115                 AssemblyName an = new AssemblyName();
116                 an.Name = "TestGlobalMethods";
117                 AssemblyBuilder builder = 
118                         AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run);
119                 ModuleBuilder module = builder.DefineDynamicModule("MessageModule");
120                 MethodBuilder method = module.DefinePInvokeMethod("printf", "libc.so",
121                                                                                                                   MethodAttributes.PinvokeImpl | MethodAttributes.Static | MethodAttributes.Public, 
122                                                                                                                   CallingConventions.Standard, typeof(void), new Type[]{typeof(string)}, CallingConvention.Winapi, 
123                                                                                                                   CharSet.Auto);
124                 method.SetImplementationFlags (MethodImplAttributes.PreserveSig | 
125                                                                            method.GetMethodImplementationFlags());
126                 module.CreateGlobalFunctions();
127
128                 Assert (module.GetMethod ("printf") != null);
129         }
130
131         [Test]
132         public void DuplicateSymbolDocument () {
133                 AssemblyName assemblyName = new AssemblyName();
134                 assemblyName.Name = "ModuleBuilderTest.DuplicateSymbolDocument";
135
136                 AssemblyBuilder ab
137                         = Thread.GetDomain().DefineDynamicAssembly(
138                                 assemblyName, AssemblyBuilderAccess.RunAndSave, TempFolder);
139
140                 ModuleBuilder mb = ab.DefineDynamicModule("foo.dll", "foo.dll", true);
141
142                 // Check that it is possible to redefine a symbol document
143                 ISymbolDocumentWriter doc1 =
144                         mb.DefineDocument("foo.il", SymDocumentType.Text,
145                                                           SymLanguageType.ILAssembly,SymLanguageVendor.Microsoft);
146                 ISymbolDocumentWriter doc2 =
147                         mb.DefineDocument("foo.il", SymDocumentType.Text,
148                                                           SymLanguageType.ILAssembly,SymLanguageVendor.Microsoft);
149         }
150         
151     private static void AssertArrayEqualsSorted (Array o1, Array o2) {
152                 Array s1 = (Array)o1.Clone ();
153                 Array s2 = (Array)o2.Clone ();
154
155                 Array.Sort (s1);
156                 Array.Sort (s2);
157
158                 AssertEquals (s1.Length, s2.Length);
159                 for (int i = 0; i < s1.Length; ++i)
160                         AssertEquals (s1.GetValue (i), s2.GetValue (i));
161         }
162 }
163 }
164