First set of licensing changes
[mono.git] / mono / tests / test-runner.cs
index 4fc99c1fd1a728ba50fefde724c780065a756a9b..80a294566dfec3e5f4357d1c142976badb608f22 100644 (file)
@@ -6,24 +6,7 @@
 //
 // Copyright (C) 2008 Novell, Inc (http://www.novell.com)
 //
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
 //
 using System;
 using System.IO;
@@ -40,6 +23,9 @@ using System.Text.RegularExpressions;
 
 public class TestRunner
 {
+       const string TEST_TIME_FORMAT = "mm\\:ss\\.fff";
+       const string ENV_TIMEOUT = "TEST_DRIVER_TIMEOUT_SEC";
+
        class ProcessData {
                public string test;
                public StreamWriter stdout, stderr;
@@ -56,8 +42,7 @@ public class TestRunner
                int timeout = 2 * 60; // in seconds
                int expectedExitCode = 0;
                string testsuiteName = null;
-
-               DateTime test_start_time = DateTime.UtcNow;
+               string inputFile = null;
 
                // FIXME: Add support for runtime arguments + env variables
 
@@ -122,6 +107,13 @@ public class TestRunner
                                        }
                                        testsuiteName = args [i + 1];
                                        i += 2;
+                               } else if (args [i] == "--input-file") {
+                                       if (i + 1 >= args.Length) {
+                                               Console.WriteLine ("Missing argument to --input-file command line option.");
+                                               return 1;
+                                       }
+                                       inputFile = args [i + 1];
+                                       i += 2;
                                } else {
                                        Console.WriteLine ("Unknown command line option: '" + args [i] + "'.");
                                        return 1;
@@ -143,11 +135,16 @@ public class TestRunner
                                disabled [test] = test;
                }
 
-               // The remaining arguments are the tests
                var tests = new List<string> ();
-               for (int j = i; j < args.Length; ++j)
-                       if (!disabled.ContainsKey (args [j]))
-                               tests.Add (args [j]);
+
+               if (!String.IsNullOrEmpty (inputFile)) {
+                       tests.AddRange (File.ReadAllLines (inputFile));
+               } else {
+                       // The remaining arguments are the tests
+                       for (int j = i; j < args.Length; ++j)
+                               if (!disabled.ContainsKey (args [j]))
+                                       tests.Add (args [j]);
+               }
 
                var passed = new List<ProcessData> ();
                var failed = new List<ProcessData> ();
@@ -155,8 +152,7 @@ public class TestRunner
 
                object monitor = new object ();
 
-               if (concurrency != 1)
-                       Console.WriteLine ("Running tests: ");
+               Console.WriteLine ("Running tests: ");
 
                var test_info = new Queue<TestInfo> ();
                if (opt_sets.Count == 0) {
@@ -167,10 +163,19 @@ public class TestRunner
                                foreach (string s in tests)
                                        test_info.Enqueue (new TestInfo { test = s, opt_set = opt });
                        }
-               }               
+               }
+
+               /* compute the max length of test names, to have an optimal output width */
+               int output_width = -1;
+               foreach (TestInfo ti in test_info) {
+                       if (ti.test.Length > output_width)
+                               output_width = Math.Min (120, ti.test.Length);
+               }
 
                List<Thread> threads = new List<Thread> (concurrency);
 
+               DateTime test_start_time = DateTime.UtcNow;
+
                for (int j = 0; j < concurrency; ++j) {
                        Thread thread = new Thread (() => {
                                while (true) {
@@ -182,11 +187,12 @@ public class TestRunner
                                                ti = test_info.Dequeue ();
                                        }
 
+                                       var output = new StringWriter ();
+
                                        string test = ti.test;
                                        string opt_set = ti.opt_set;
 
-                                       if (concurrency == 1)
-                                               Console.Write ("Testing " + test + "... ");
+                                       output.Write (String.Format ("{{0,-{0}}} ", output_width), test);
 
                                        /* Spawn a new process */
                                        string process_args;
@@ -198,6 +204,7 @@ public class TestRunner
                                        info.UseShellExecute = false;
                                        info.RedirectStandardOutput = true;
                                        info.RedirectStandardError = true;
+                                       info.EnvironmentVariables[ENV_TIMEOUT] = timeout.ToString();
                                        Process p = new Process ();
                                        p.StartInfo = info;
 
@@ -232,6 +239,8 @@ public class TestRunner
                                                }
                                        };
 
+                                       var start = DateTime.UtcNow;
+
                                        p.Start ();
 
                                        p.BeginOutputReadLine ();
@@ -242,33 +251,32 @@ public class TestRunner
                                                        timedout.Add (data);
                                                }
 
-                                               if (concurrency == 1)
-                                                       Console.WriteLine ("timed out.");
-                                               else
-                                                       Console.Write (".");
+                                               output.Write ("timed out");
 
                                                p.Kill ();
                                        } else if (p.ExitCode != expectedExitCode) {
+                                               var end = DateTime.UtcNow;
+
                                                lock (monitor) {
                                                        failed.Add (data);
                                                }
 
-                                               if (concurrency == 1)
-                                                       Console.WriteLine ("failed.");
-                                               else
-                                                       Console.Write (".");
+                                               output.Write ("failed, time: {0}, exit code: {1}", (end - start).ToString (TEST_TIME_FORMAT), p.ExitCode);
                                        } else {
+                                               var end = DateTime.UtcNow;
+
                                                lock (monitor) {
                                                        passed.Add (data);
                                                }
 
-                                               if (concurrency == 1)
-                                                       Console.WriteLine ("passed.");
-                                               else
-                                                       Console.Write (".");
+                                               output.Write ("passed, time: {0}", (end - start).ToString (TEST_TIME_FORMAT));
                                        }
 
                                        p.Close ();
+
+                                       lock (monitor) {
+                                               Console.WriteLine (output.ToString ());
+                                       }
                                }
                        });
 
@@ -280,15 +288,16 @@ public class TestRunner
                for (int j = 0; j < threads.Count; ++j)
                        threads [j].Join ();
 
+               TimeSpan test_time = DateTime.UtcNow - test_start_time;
+
                int npassed = passed.Count;
                int nfailed = failed.Count;
                int ntimedout = timedout.Count;
 
-               TimeSpan test_time = DateTime.UtcNow - test_start_time;
                XmlWriterSettings xmlWriterSettings = new XmlWriterSettings ();
                xmlWriterSettings.NewLineOnAttributes = true;
                xmlWriterSettings.Indent = true;
-               using (XmlWriter writer = XmlWriter.Create (String.Format ("TestResults_{0}.xml", testsuiteName), xmlWriterSettings)) {
+               using (XmlWriter writer = XmlWriter.Create (String.Format ("TestResult-{0}.xml", testsuiteName), xmlWriterSettings)) {
                        // <?xml version="1.0" encoding="utf-8" standalone="no"?>
                        writer.WriteStartDocument ();
                        // <!--This file represents the results of running a test suite-->
@@ -407,6 +416,8 @@ public class TestRunner
                        writer.WriteEndDocument ();
                }
 
+               Console.WriteLine ();
+               Console.WriteLine ("Time: {0}", test_time.ToString (TEST_TIME_FORMAT));
                Console.WriteLine ();
                Console.WriteLine ("{0,4} test(s) passed", npassed);
                Console.WriteLine ("{0,4} test(s) failed", nfailed);