2007-10-09 Rodrigo Kumpera <rkumpera@novell.com>
[mono.git] / mono / tests / verifier / AssemblyRunner.cs
1 //
2 // AssemblyRunner.cs
3 //
4 // Author:
5 //   Rodrigo Kumpera (rkumpera@novell.com)
6 //
7 // Copyright (C) 2007 Novell, Inc (http://www.novell.com)
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 using System;
29 using System.IO;
30 using System.Net;
31 using System.Diagnostics;
32 using System.Security;
33 using System.Security.Policy;
34 using System.Security.Permissions;
35 using System.Threading;
36
37
38 namespace AssemblyRunner {
39
40         public class Runner {
41             private static string program = "\"%COMSPEC%\"";
42
43                 static String ExecuteAndFetchStderr (String command) {
44                         ProcessStartInfo psi = new ProcessStartInfo (Environment.ExpandEnvironmentVariables (program), "/c " + command);
45                         psi.CreateNoWindow = true;
46                         psi.UseShellExecute = false;
47                         psi.RedirectStandardError = true;
48
49                     string stderr=null;
50                     Process activeProcess=null;
51
52                         Thread stderrThread = new Thread (new ThreadStart (delegate {
53                                 if (activeProcess != null)
54                                         stderr = activeProcess.StandardError.ReadToEnd ();
55                         }));
56                         activeProcess = Process.Start (psi);
57                         
58                         stderrThread.Start ();
59                 activeProcess.WaitForExit();
60                         stderrThread.Join();
61                         activeProcess.Close ();
62                         return stderr;
63             }
64
65                 static AppDomain NewDomain () {
66                         PolicyStatement statement = new PolicyStatement(new PermissionSet(PermissionState.None),PolicyStatementAttribute.Nothing);
67                         PermissionSet ps = new PermissionSet(PermissionState.None);
68                         ps.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
69                         ps.AddPermission(new SecurityPermission(SecurityPermissionFlag.Assertion));
70                         ps.AddPermission(new SecurityPermission(SecurityPermissionFlag.ControlAppDomain));
71                         ps.AddPermission(new SecurityPermission(SecurityPermissionFlag.ControlDomainPolicy));
72                         ps.AddPermission(new SecurityPermission(SecurityPermissionFlag.ControlEvidence));
73                         ps.AddPermission(new SecurityPermission(SecurityPermissionFlag.ControlPolicy));
74                         ps.AddPermission(new SecurityPermission(SecurityPermissionFlag.ControlPrincipal));
75                         ps.AddPermission(new SecurityPermission(SecurityPermissionFlag.ControlThread));
76                         ps.AddPermission(new SecurityPermission(SecurityPermissionFlag.Infrastructure));
77                         ps.AddPermission(new SecurityPermission(SecurityPermissionFlag.RemotingConfiguration));
78                         ps.AddPermission(new SecurityPermission(SecurityPermissionFlag.SerializationFormatter));
79                         ps.AddPermission(new FileIOPermission(PermissionState.Unrestricted));
80                         ps.AddPermission(new EnvironmentPermission(PermissionState.Unrestricted));
81                         ps.AddPermission(new ReflectionPermission(PermissionState.Unrestricted));
82                         ps.AddPermission(new RegistryPermission(PermissionState.Unrestricted));
83                         ps.AddPermission(new IsolatedStorageFilePermission(PermissionState.Unrestricted));
84                         ps.AddPermission(new EventLogPermission(PermissionState.Unrestricted));
85                         ps.AddPermission(new PerformanceCounterPermission(PermissionState.Unrestricted));
86                         ps.AddPermission(new DnsPermission(PermissionState.Unrestricted));
87                         ps.AddPermission(new UIPermission(PermissionState.Unrestricted));
88                         PolicyStatement statement1 = new PolicyStatement(ps,PolicyStatementAttribute.Exclusive);
89                         CodeGroup group;
90                         group = new UnionCodeGroup(new AllMembershipCondition(),statement);
91                         group.AddChild(new UnionCodeGroup(new ZoneMembershipCondition(SecurityZone.MyComputer),statement1));
92                         PolicyLevel level = PolicyLevel.CreateAppDomainLevel();
93                         level.RootCodeGroup = group;
94
95                         AppDomain domain = AppDomain.CreateDomain ("test");
96                         domain.SetAppDomainPolicy(level);
97                         return domain;
98                 }
99
100                 static void executeTest (String assembly, String path) {
101                         String op = assembly.Substring (0, assembly.IndexOf ("_"));
102                         AppDomain domain = NewDomain ();
103                         try {
104                                 domain.ExecuteAssembly (path);
105                                 if (!op.Equals ("valid"))
106                                         Console.WriteLine ("Test returned valid: "+assembly);
107                         } catch (InvalidProgramException ipe) {
108                                 if (!op.Equals ("invalid"))
109                                         Console.WriteLine ("Test returned invalid: "+assembly);
110                         } catch (FileLoadException ve) {
111                                 if (!op.Equals ("invalid"))
112                                         Console.WriteLine ("Test returned invalid: "+assembly);
113                         } catch (VerificationException ve) {
114                                 RecheckUnverifiableResult (path, assembly, op);
115                         } catch (TypeInitializationException ve) {
116                                 if (ve.InnerException is VerificationException)
117                                         RecheckUnverifiableResult (path, assembly, op);
118                                 else
119                                         Console.WriteLine ("Warning: test thrown exception: "+assembly);
120                         } catch (MissingMemberException ve) {
121                                 if (!op.Equals ("invalid"))
122                                         Console.WriteLine ("Test returned invalid: "+assembly);
123                         } catch (MemberAccessException ve) {
124                                 if (!op.Equals ("unverifiable"))
125                                         Console.WriteLine ("Test returned unverifiable: "+assembly);
126                         } catch (TypeLoadException ve) {
127                                 if (!op.Equals ("unverifiable"))
128                                         Console.WriteLine ("Test returned unverifiable: "+assembly);
129                         } catch (Exception e) {
130                                         Console.WriteLine ("Warning: test thrown exception: "+assembly);
131                         } finally {
132                                 AppDomain.Unload (domain);
133                         }
134                 }
135
136                 /*
137                 This method exists because sometimes a VerificationException is throw for invalid code, so we try to run it as standard-alone a check again.
138                 */
139                 static void RecheckUnverifiableResult (String path, String assembly, String op) {
140                         String stderr = ExecuteAndFetchStderr (path);
141                         bool invalid = stderr.IndexOf ("InvalidProgramException") >= 0 || stderr.IndexOf ("FileLoadException") >= 0;
142
143                         if (invalid) {
144                                 if (!op.Equals ("invalid"))
145                                         Console.WriteLine ("Test returned invalid: "+assembly);
146                         }else if (!op.Equals ("unverifiable"))
147                                 Console.WriteLine ("Test returned unverifiable: "+assembly);
148                 }
149
150                 public static void Main (String[] args) {
151                         String dirName = ".";
152                         if (args.Length > 0)
153                                 dirName = args[0];
154                         DirectoryInfo dir = new DirectoryInfo (dirName);
155                         foreach (FileInfo file in dir.GetFiles ()) {
156                                 try {
157                                 if (file.Name.EndsWith (".exe") && (file.Name.StartsWith ("valid_") || file.Name.StartsWith ("unverifiable_") || file.Name.StartsWith ("invalid_")))
158                                         executeTest (file.Name, file.FullName);
159                                 } catch (Exception e) {
160                                 }
161                         }
162                 }
163         }
164 }