58dc1a551a09a21df5561698d7ea70b4a2be15b6
[mono.git] / mcs / tools / linker / Tests / Mono.Linker.Tests / AbstractLinkingTestFixture.cs
1 //
2 // AbstractLinkingTestFixture.cs
3 //
4 // Author:
5 //   Jb Evain (jbevain@gmail.com)
6 //
7 // (C) 2006 Jb Evain
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29 using System.IO;
30 using Mono.Cecil;
31 using Mono.Linker.Steps;
32 using NUnit.Framework;
33
34 namespace Mono.Linker.Tests {
35
36         public abstract class AbstractLinkingTestFixture : AbstractTestFixture {
37
38                 [SetUp]
39                 public override void SetUp ()
40                 {
41                         base.SetUp ();
42
43                         TestCasesRoot = "Linker";
44                 }
45
46                 [TearDown]
47                 public override void TearDown ()
48                 {
49                         base.TearDown ();
50
51                         string output = GetOutputPath ();
52                         if (Directory.Exists (output))
53                                 Directory.Delete (output, true);
54                 }
55
56                 protected override Pipeline GetPipeline ()
57                 {
58                         Pipeline p = new Pipeline ();
59                         p.AppendStep (new LoadReferencesStep ());
60                         p.AppendStep (new BlacklistStep ());
61                         p.AppendStep (new TypeMapStep ());
62                         p.AppendStep (new MarkStep ());
63                         p.AppendStep (new SweepStep ());
64                         p.AppendStep (new CleanStep ());
65                         p.AppendStep (new OutputStep ());
66                         return p;
67                 }
68
69                 protected override void RunTest (string testCase)
70                 {
71                         base.RunTest (testCase);
72
73                         Prepare ();
74                 }
75
76                 void Prepare ()
77                 {
78                         Context = GetContext ();
79                         string output = GetOutputPath ();
80                         if (Directory.Exists (output))
81                                 Directory.Delete (output, true);
82                         Directory.CreateDirectory (output);
83                 }
84
85                 protected override void Run ()
86                 {
87                         base.Run ();
88                         Compare ();
89                 }
90
91                 void Compare ()
92                 {
93                         foreach (AssemblyDefinition assembly in Context.GetAssemblies ()) {
94                                 if (Annotations.GetAction (assembly) != AssemblyAction.Link)
95                                         continue;
96
97                                 string fileName = GetAssemblyFileName (assembly);
98
99                                 CompareAssemblies (
100                                         AssemblyFactory.GetAssembly (
101                                                 Path.Combine (GetTestCasePath (), fileName)),
102                                         AssemblyFactory.GetAssembly (
103                                                 Path.Combine (GetOutputPath (), fileName)));
104                         }
105                 }
106
107                 static void CompareAssemblies (AssemblyDefinition original, AssemblyDefinition linked)
108                 {
109                         foreach (TypeDefinition originalType in original.MainModule.Types) {
110                                 TypeDefinition linkedType = linked.MainModule.Types [originalType.FullName];
111                                 if (NotLinked (originalType)) {
112                                         Assert.IsNull (linkedType, string.Format ("Type `{0}' should not have been linked", originalType));
113                                         continue;
114                                 }
115
116                                 Assert.IsNotNull (linkedType, string.Format ("Type `{0}' should have been linked", originalType));
117                                 CompareTypes (originalType, linkedType);
118                         }
119                 }
120
121                 static void CompareTypes (TypeDefinition type, TypeDefinition linkedType)
122                 {
123                         foreach (FieldDefinition originalField in type.Fields) {
124                                 FieldDefinition linkedField = linkedType.Fields.GetField (originalField.Name);// TODO: also get with the type!
125                                 if (NotLinked (originalField)) {
126                                         Assert.IsNull (linkedField, string.Format ("Field `{0}' should not have been linked", originalField));
127                                         continue;
128                                 }
129
130                                 Assert.IsNotNull (linkedField, string.Format ("Field `{0}' should have been linked", originalField));
131                         }
132
133                         foreach (MethodDefinition originalCtor in type.Constructors) {
134                                 MethodDefinition linkedCtor = linkedType.Constructors.GetConstructor (originalCtor.IsStatic, originalCtor.Parameters);
135                                 if (NotLinked (originalCtor)) {
136                                         Assert.IsNull (linkedCtor, string.Format ("Constructor `{0}' should not have been linked", originalCtor));
137                                         continue;
138                                 }
139
140                                 Assert.IsNotNull (linkedCtor, string.Format ("Constructor `{0}' should have been linked", originalCtor));
141                         }
142
143                         foreach (MethodDefinition originalMethod in type.Methods) {
144                                 MethodDefinition linkedMethod = linkedType.Methods.GetMethod (originalMethod.Name, originalMethod.Parameters);
145                                 if (NotLinked (originalMethod)) {
146                                         Assert.IsNull (linkedMethod, string.Format ("Method `{0}' should not have been linked", originalMethod));
147                                         continue;
148                                 }
149
150                                 Assert.IsNotNull (linkedMethod, string.Format ("Method `{0}' should have been linked", originalMethod));
151                         }
152                 }
153
154                 static bool NotLinked(ICustomAttributeProvider provider)
155                 {
156                         foreach (CustomAttribute ca in provider.CustomAttributes)
157                                 if (ca.Constructor.DeclaringType.Name == "NotLinkedAttribute")
158                                         return true;
159
160                         return false;
161                 }
162         }
163 }