X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Ftests%2Ftest-runner.cs;h=53b4e9283575422f08b828cdd4a4cab271a91341;hb=aefc06ddf682848e3a6a4e0a534f443b335a6167;hp=95011edf2c9c2d6d200ad577696870a5813372f0;hpb=6b139f4c98eb90bfb7e1285933fc682dae541cad;p=mono.git diff --git a/mono/tests/test-runner.cs b/mono/tests/test-runner.cs index 95011edf2c9..53b4e928357 100644 --- a/mono/tests/test-runner.cs +++ b/mono/tests/test-runner.cs @@ -15,8 +15,12 @@ using System.Diagnostics; using System.Collections.Generic; using System.Globalization; using System.Xml; +using System.Text; using System.Text.RegularExpressions; + +#if !MOBILE_STATIC using Mono.Unix.Native; +#endif // // This is a simple test runner with support for parallel execution @@ -26,11 +30,12 @@ public class TestRunner { const string TEST_TIME_FORMAT = "mm\\:ss\\.fff"; const string ENV_TIMEOUT = "TEST_DRIVER_TIMEOUT_SEC"; + const string MONO_PATH = "MONO_PATH"; class ProcessData { public string test; - public StreamWriter stdout, stderr; - public string stdoutFile, stderrFile; + public StringBuilder stdout, stderr; + public string stdoutName, stderrName; } class TestInfo { @@ -42,15 +47,19 @@ public class TestRunner int concurrency = 1; int timeout = 2 * 60; // in seconds int expectedExitCode = 0; + bool verbose = false; string testsuiteName = null; string inputFile = null; - // FIXME: Add support for runtime arguments + env variables - string disabled_tests = null; string runtime = "mono"; + string config = null; + string mono_path = null; var opt_sets = new List (); + string aot_run_flags = null; + string aot_build_flags = null; + // Process options int i = 0; while (i < args.Length) { @@ -86,6 +95,13 @@ public class TestRunner } runtime = args [i + 1]; i += 2; + } else if (args [i] == "--config") { + if (i + 1 >= args.Length) { + Console.WriteLine ("Missing argument to --config command line option."); + return 1; + } + config = args [i + 1]; + i += 2; } else if (args [i] == "--opt-sets") { if (i + 1 >= args.Length) { Console.WriteLine ("Missing argument to --opt-sets command line option."); @@ -115,6 +131,38 @@ public class TestRunner } inputFile = args [i + 1]; i += 2; + } else if (args [i] == "--runtime") { + if (i + 1 >= args.Length) { + Console.WriteLine ("Missing argument to --runtime command line option."); + return 1; + } + runtime = args [i + 1]; + i += 2; + } else if (args [i] == "--mono-path") { + if (i + 1 >= args.Length) { + Console.WriteLine ("Missing argument to --mono-path command line option."); + return 1; + } + mono_path = args [i + 1].Substring(0, args [i + 1].Length); + + i += 2; + } else if (args [i] == "--aot-run-flags") { + if (i + 1 >= args.Length) { + Console.WriteLine ("Missing argument to --aot-run-flags command line option."); + return 1; + } + aot_run_flags = args [i + 1].Substring(0, args [i + 1].Length); + i += 2; + } else if (args [i] == "--aot-build-flags") { + if (i + 1 >= args.Length) { + Console.WriteLine ("Missing argument to --aot-build-flags command line option."); + return 1; + } + aot_build_flags = args [i + 1].Substring(0, args [i + 1].Length); + i += 2; + } else if (args [i] == "--verbose") { + verbose = true; + i ++; } else { Console.WriteLine ("Unknown command line option: '" + args [i] + "'."); return 1; @@ -173,6 +221,65 @@ public class TestRunner output_width = Math.Min (120, ti.test.Length); } + if (aot_build_flags != null) { + Console.WriteLine("AOT compiling tests"); + + object aot_monitor = new object (); + var aot_queue = new Queue (tests); + + List build_threads = new List (concurrency); + + for (int j = 0; j < concurrency; ++j) { + Thread thread = new Thread (() => { + while (true) { + String test_name; + + lock (aot_monitor) { + if (aot_queue.Count == 0) + break; + test_name = aot_queue.Dequeue (); + } + + string test_bitcode_output = test_name + "_bitcode_tmp"; + string test_bitcode_arg = ",temp-path=" + test_bitcode_output; + string aot_args = aot_build_flags + test_bitcode_arg + " " + test_name; + + Directory.CreateDirectory(test_bitcode_output); + + ProcessStartInfo job = new ProcessStartInfo (runtime, aot_args); + job.UseShellExecute = false; + job.EnvironmentVariables[ENV_TIMEOUT] = timeout.ToString(); + job.EnvironmentVariables[MONO_PATH] = mono_path; + Process compiler = new Process (); + compiler.StartInfo = job; + + compiler.Start (); + + if (!compiler.WaitForExit (timeout * 1000)) { + try { + compiler.Kill (); + } catch { + } + throw new Exception(String.Format("Timeout AOT compiling tests, output in {0}", test_bitcode_output)); + } else if (compiler.ExitCode != 0) { + throw new Exception(String.Format("Error AOT compiling tests, output in {0}", test_bitcode_output)); + } else { + Directory.Delete (test_bitcode_output, true); + } + } + }); + + thread.Start (); + + build_threads.Add (thread); + } + + for (int j = 0; j < build_threads.Count; ++j) + build_threads [j].Join (); + + Console.WriteLine("Done compiling"); + } + List threads = new List (concurrency); DateTime test_start_time = DateTime.UtcNow; @@ -193,19 +300,35 @@ public class TestRunner string test = ti.test; string opt_set = ti.opt_set; - output.Write (String.Format ("{{0,-{0}}} ", output_width), test); + if (verbose) { + output.Write (String.Format ("{{0,-{0}}} ", output_width), test); + } else { + Console.Write ("."); + } + + string test_invoke; + + if (aot_run_flags != null) + test_invoke = aot_run_flags + " " + test; + else + test_invoke = test; /* Spawn a new process */ string process_args; if (opt_set == null) - process_args = test; + process_args = test_invoke; else - process_args = "-O=" + opt_set + " " + test; + process_args = "-O=" + opt_set + " " + test_invoke; + ProcessStartInfo info = new ProcessStartInfo (runtime, process_args); info.UseShellExecute = false; info.RedirectStandardOutput = true; info.RedirectStandardError = true; info.EnvironmentVariables[ENV_TIMEOUT] = timeout.ToString(); + if (config != null) + info.EnvironmentVariables["MONO_CONFIG"] = config; + if (mono_path != null) + info.EnvironmentVariables[MONO_PATH] = mono_path; Process p = new Process (); p.StartInfo = info; @@ -216,27 +339,21 @@ public class TestRunner if (opt_set != null) log_prefix = "." + opt_set.Replace ("-", "no").Replace (",", "_"); - data.stdoutFile = test + log_prefix + ".stdout"; - data.stdout = new StreamWriter (new FileStream (data.stdoutFile, FileMode.Create)); + data.stdoutName = test + log_prefix + ".stdout"; + data.stdout = new StringBuilder (); - data.stderrFile = test + log_prefix + ".stderr"; - data.stderr = new StreamWriter (new FileStream (data.stderrFile, FileMode.Create)); + data.stderrName = test + log_prefix + ".stderr"; + data.stderr = new StringBuilder (); p.OutputDataReceived += delegate (object sender, DataReceivedEventArgs e) { if (e.Data != null) { - data.stdout.WriteLine (e.Data); - } else { - data.stdout.Flush (); - data.stdout.Close (); + data.stdout.AppendLine (e.Data); } }; p.ErrorDataReceived += delegate (object sender, DataReceivedEventArgs e) { if (e.Data != null) { - data.stderr.WriteLine (e.Data); - } else { - data.stderr.Flush (); - data.stderr.Close (); + data.stderr.AppendLine (e.Data); } }; @@ -252,14 +369,18 @@ public class TestRunner timedout.Add (data); } +#if !MOBILE_STATIC // Force the process to print a thread dump try { Syscall.kill (p.Id, Signum.SIGQUIT); Thread.Sleep (1000); } catch { } +#endif - output.Write ("timed out"); + if (verbose) { + output.Write ($"timed out ({timeout}s)"); + } try { p.Kill (); @@ -272,7 +393,8 @@ public class TestRunner failed.Add (data); } - output.Write ("failed, time: {0}, exit code: {1}", (end - start).ToString (TEST_TIME_FORMAT), p.ExitCode); + if (verbose) + output.Write ("failed, time: {0}, exit code: {1}", (end - start).ToString (TEST_TIME_FORMAT), p.ExitCode); } else { var end = DateTime.UtcNow; @@ -280,13 +402,15 @@ public class TestRunner passed.Add (data); } - output.Write ("passed, time: {0}", (end - start).ToString (TEST_TIME_FORMAT)); + if (verbose) + output.Write ("passed, time: {0}", (end - start).ToString (TEST_TIME_FORMAT)); } p.Close (); lock (monitor) { - Console.WriteLine (output.ToString ()); + if (verbose) + Console.WriteLine (output.ToString ()); } } }); @@ -308,7 +432,9 @@ public class TestRunner XmlWriterSettings xmlWriterSettings = new XmlWriterSettings (); xmlWriterSettings.NewLineOnAttributes = true; xmlWriterSettings.Indent = true; - using (XmlWriter writer = XmlWriter.Create (String.Format ("TestResult-{0}.xml", testsuiteName), xmlWriterSettings)) { + + string xmlPath = String.Format ("TestResult-{0}.xml", testsuiteName); + using (XmlWriter writer = XmlWriter.Create (xmlPath, xmlWriterSettings)) { // writer.WriteStartDocument (); // @@ -383,10 +509,10 @@ public class TestRunner writer.WriteAttributeString ("asserts", "1"); writer.WriteStartElement ("failure"); writer.WriteStartElement ("message"); - writer.WriteCData (DumpPseudoTrace (pd.stdoutFile)); + writer.WriteCData (FilterInvalidXmlChars (pd.stdout.ToString ())); writer.WriteEndElement (); writer.WriteStartElement ("stack-trace"); - writer.WriteCData (DumpPseudoTrace (pd.stderrFile)); + writer.WriteCData (FilterInvalidXmlChars (pd.stderr.ToString ())); writer.WriteEndElement (); writer.WriteEndElement (); writer.WriteEndElement (); @@ -402,10 +528,10 @@ public class TestRunner writer.WriteAttributeString ("asserts", "1"); writer.WriteStartElement ("failure"); writer.WriteStartElement ("message"); - writer.WriteCData (DumpPseudoTrace (pd.stdoutFile)); + writer.WriteCData (FilterInvalidXmlChars (pd.stdout.ToString ())); writer.WriteEndElement (); writer.WriteStartElement ("stack-trace"); - writer.WriteCData (DumpPseudoTrace (pd.stderrFile)); + writer.WriteCData (FilterInvalidXmlChars (pd.stderr.ToString ())); writer.WriteEndElement (); writer.WriteEndElement (); writer.WriteEndElement (); @@ -425,14 +551,29 @@ public class TestRunner // writer.WriteEndElement (); writer.WriteEndDocument (); + + string babysitterXmlList = Environment.GetEnvironmentVariable("MONO_BABYSITTER_NUNIT_XML_LIST_FILE"); + if (!String.IsNullOrEmpty(babysitterXmlList)) { + try { + string fullXmlPath = Path.GetFullPath(xmlPath); + File.AppendAllText(babysitterXmlList, fullXmlPath + Environment.NewLine); + } catch (Exception e) { + Console.WriteLine("Attempted to record XML path to file {0} but failed.", babysitterXmlList); + } + } } - 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); - Console.WriteLine ("{0,4} test(s) timed out", ntimedout); + if (verbose) { + 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); + Console.WriteLine ("{0,4} test(s) timed out", ntimedout); + } else { + Console.WriteLine (); + Console.WriteLine (String.Format ("{0} test(s) passed, {1} test(s) did not pass.", npassed, nfailed)); + } if (nfailed > 0) { Console.WriteLine (); @@ -440,8 +581,8 @@ public class TestRunner foreach (ProcessData pd in failed) { Console.WriteLine (); Console.WriteLine (pd.test); - DumpFile (pd.stdoutFile); - DumpFile (pd.stderrFile); + DumpFile (pd.stdoutName, pd.stdout.ToString ()); + DumpFile (pd.stderrName, pd.stderr.ToString ()); } } @@ -451,27 +592,18 @@ public class TestRunner foreach (ProcessData pd in timedout) { Console.WriteLine (); Console.WriteLine (pd.test); - DumpFile (pd.stdoutFile); - DumpFile (pd.stderrFile); + DumpFile (pd.stdoutName, pd.stdout.ToString ()); + DumpFile (pd.stderrName, pd.stderr.ToString ()); } } return (ntimedout == 0 && nfailed == 0) ? 0 : 1; } - static void DumpFile (string filename) { - if (File.Exists (filename)) { - Console.WriteLine ("=============== {0} ===============", filename); - Console.WriteLine (File.ReadAllText (filename)); - Console.WriteLine ("=============== EOF ==============="); - } - } - - static string DumpPseudoTrace (string filename) { - if (File.Exists (filename)) - return FilterInvalidXmlChars (File.ReadAllText (filename)); - else - return string.Empty; + static void DumpFile (string filename, string text) { + Console.WriteLine ("=============== {0} ===============", filename); + Console.WriteLine (text); + Console.WriteLine ("=============== EOF ==============="); } static string FilterInvalidXmlChars (string text) {