* ModuleBuilderTest.cs: Avoid compiler warning in test for bug #80435.
[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         [TestFixture]
25         public class ModuleBuilderTest
26         {
27                 static string TempFolder = Path.Combine (Path.GetTempPath (), "MT.S.R.E.MBT");
28
29                 [SetUp]
30                 public void SetUp ()
31                 {
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                 {
42                         try {
43                                 // This throws an exception under MS.NET, since the directory contains loaded
44                                 // assemblies.
45                                 Directory.Delete (TempFolder, true);
46                         } catch (Exception) {
47                         }
48                 }
49
50                 [Test]
51                 public void TestIsTransient ()
52                 {
53                         AssemblyName assemblyName = new AssemblyName ();
54                         assemblyName.Name = "foo";
55
56                         AssemblyBuilder ab
57                                 = Thread.GetDomain ().DefineDynamicAssembly (
58                                         assemblyName, AssemblyBuilderAccess.RunAndSave, TempFolder);
59                         ModuleBuilder mb1 = ab.DefineDynamicModule ("foo.dll");
60                         Assert.IsTrue (mb1.IsTransient (), "#1");
61                         ModuleBuilder mb2 = ab.DefineDynamicModule ("foo2.dll", "foo2.dll");
62                         Assert.IsFalse (mb2.IsTransient (), "#2");
63                 }
64
65                 // Some of these tests overlap with the tests for Module
66
67                 [Test]
68                 public void TestGlobalData ()
69                 {
70
71                         AssemblyName assemblyName = new AssemblyName ();
72                         assemblyName.Name = "foo";
73
74                         AssemblyBuilder ab
75                                 = Thread.GetDomain ().DefineDynamicAssembly (
76                                         assemblyName, AssemblyBuilderAccess.RunAndSave, TempFolder);
77
78                         string resfile = Path.Combine (TempFolder, "res");
79                         using (StreamWriter sw = new StreamWriter (resfile)) {
80                                 sw.WriteLine ("FOO");
81                         }
82
83                         ModuleBuilder mb = ab.DefineDynamicModule ("foo.dll", "foo.dll");
84
85                         mb.DefineInitializedData ("DATA", new byte [100], FieldAttributes.Public);
86                         mb.DefineInitializedData ("DATA2", new byte [100], FieldAttributes.Public);
87                         mb.DefineInitializedData ("DATA3", new byte [99], FieldAttributes.Public);
88                         mb.DefineUninitializedData ("DATA4", 101, FieldAttributes.Public);
89                         mb.DefineInitializedData ("DATA_PRIVATE", new byte [100], 0);
90                         mb.CreateGlobalFunctions ();
91
92                         ab.Save ("foo.dll");
93
94                         Assembly assembly = Assembly.LoadFrom (Path.Combine (TempFolder, "foo.dll"));
95
96                         Module module = assembly.GetLoadedModules () [0];
97
98                         string [] expectedFieldNames = new string [] {
99                                 "DATA", "DATA2", "DATA3", "DATA4" };
100                         ArrayList fieldNames = new ArrayList ();
101                         foreach (FieldInfo fi in module.GetFields ()) {
102                                 fieldNames.Add (fi.Name);
103                         }
104                         AssertArrayEqualsSorted (expectedFieldNames, fieldNames.ToArray (typeof (string)));
105
106                         Assert.IsNotNull (module.GetField ("DATA"), "#1");
107                         Assert.IsNotNull (module.GetField ("DATA2"), "#2");
108                         Assert.IsNotNull (module.GetField ("DATA3"), "#3");
109                         Assert.IsNotNull (module.GetField ("DATA4"), "#4");
110                         Assert.IsNull (module.GetField ("DATA_PRIVATE"), "#5");
111                         Assert.IsNotNull (module.GetField ("DATA_PRIVATE", BindingFlags.NonPublic | BindingFlags.Static), "#6");
112                 }
113
114                 [Test]
115                 public void TestGlobalMethods ()
116                 {
117                         AssemblyName an = new AssemblyName ();
118                         an.Name = "TestGlobalMethods";
119                         AssemblyBuilder builder =
120                                 AppDomain.CurrentDomain.DefineDynamicAssembly (an, AssemblyBuilderAccess.Run);
121                         ModuleBuilder module = builder.DefineDynamicModule ("MessageModule");
122                         MethodBuilder method = module.DefinePInvokeMethod ("printf", "libc.so",
123                                                                                                                           MethodAttributes.PinvokeImpl | MethodAttributes.Static | MethodAttributes.Public,
124                                                                                                                           CallingConventions.Standard, typeof (void), new Type [] { typeof (string) }, CallingConvention.Winapi,
125                                                                                                                           CharSet.Auto);
126                         method.SetImplementationFlags (MethodImplAttributes.PreserveSig |
127                                                                                    method.GetMethodImplementationFlags ());
128                         module.CreateGlobalFunctions ();
129
130                         Assert.IsNotNull (module.GetMethod ("printf"));
131                 }
132
133                 [Test]
134                 public void DuplicateSymbolDocument ()
135                 {
136                         AssemblyName assemblyName = new AssemblyName ();
137                         assemblyName.Name = "ModuleBuilderTest.DuplicateSymbolDocument";
138
139                         AssemblyBuilder ab
140                                 = Thread.GetDomain ().DefineDynamicAssembly (
141                                         assemblyName, AssemblyBuilderAccess.RunAndSave, TempFolder);
142
143                         ModuleBuilder mb = ab.DefineDynamicModule ("foo.dll", "foo.dll", true);
144
145                         // Check that it is possible to redefine a symbol document
146                         ISymbolDocumentWriter doc1 =
147                                 mb.DefineDocument ("foo.il", SymDocumentType.Text,
148                                                                   SymLanguageType.ILAssembly, SymLanguageVendor.Microsoft);
149                         ISymbolDocumentWriter doc2 =
150                                 mb.DefineDocument ("foo.il", SymDocumentType.Text,
151                                                                   SymLanguageType.ILAssembly, SymLanguageVendor.Microsoft);
152                 }
153
154                 [Test] // Test case for #80435.
155                 public void GetArrayMethodToStringTest ()
156                 {
157                         AssemblyName name = new AssemblyName ();
158                         name.Name = "a";
159                         AssemblyBuilder assembly = AppDomain.CurrentDomain.DefineDynamicAssembly (name, AssemblyBuilderAccess.RunAndSave);
160
161                         ModuleBuilder module = assembly.DefineDynamicModule ("m", "test.dll");
162
163                         Type [] myArrayClass = new Type [1];
164                         Type [] parameterTypes = { typeof (Array) };
165                         MethodInfo myMethodInfo = module.GetArrayMethod (myArrayClass.GetType (), "Sort", CallingConventions.Standard, null, parameterTypes);
166
167                         string str = myMethodInfo.ToString ();
168                         Assert.IsNotNull (str);
169                         // Don't compare string, since MS returns System.Reflection.Emit.SymbolMethod here 
170                         // (they do not provide an implementation of ToString).
171                 }
172
173                 private static void AssertArrayEqualsSorted (Array o1, Array o2)
174                 {
175                         Array s1 = (Array) o1.Clone ();
176                         Array s2 = (Array) o2.Clone ();
177
178                         Array.Sort (s1);
179                         Array.Sort (s2);
180
181                         Assert.AreEqual (s1.Length, s2.Length, "#1");
182                         for (int i = 0; i < s1.Length; ++i)
183                                 Assert.AreEqual (s1.GetValue (i), s2.GetValue (i), "#2: " + i);
184                 }
185         }
186 }