xmlconf.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395
  1. using System;
  2. using System.Xml;
  3. using System.IO;
  4. using System.Collections;
  5. using System.ComponentModel;
  6. using System.Reflection;
  7. using System.Text;
  8. namespace MonoTests.stand_alone {
  9. #if NUNIT_SUPPORT
  10. using NUnit.Core;
  11. using NUnit.Framework;
  12. #endif
  13. class AllTests: IDisposable {
  14. #region Command Line Options Handling
  15. class CommandLineOptionAttribute:Attribute{
  16. char _short;
  17. string _long; //FIXME: use long form, too
  18. public CommandLineOptionAttribute (char a_short, string a_long):base() {
  19. _short = a_short;
  20. _long = a_long;
  21. }
  22. public CommandLineOptionAttribute (char a_short):this (a_short, null) {
  23. }
  24. public override string ToString() {
  25. return _short.ToString();
  26. }
  27. public string Long {
  28. get {
  29. return _long;
  30. }
  31. }
  32. }
  33. static void PrintUsage () {
  34. Console.Error.WriteLine("Usage: xmlconf <flags>");
  35. Console.Error.WriteLine("\tFlags:");
  36. foreach (DictionaryEntry de in AllTests.GetOptions())
  37. Console.Error.WriteLine ("\t{0}\t{1}", de.Key, de.Value);
  38. }
  39. public static Hashtable GetOptions() {
  40. Hashtable h = new Hashtable();
  41. foreach (FieldInfo i in typeof (AllTests).GetFields()) {
  42. //FIXME: handle long options, too
  43. string option = "-" + i.GetCustomAttributes(typeof(CommandLineOptionAttribute),
  44. true)[0].ToString();
  45. string descr = (i.GetCustomAttributes(typeof(DescriptionAttribute),
  46. true)[0] as DescriptionAttribute).Description;
  47. h[option] = descr;
  48. }
  49. return h;
  50. }
  51. public bool ParseOptions () {
  52. if (_args == null || _args.Length == 0)
  53. return true;
  54. if(_args[0].Length < 2 || _args[0][0] != '-') {
  55. PrintUsage();
  56. return false;
  57. }
  58. string options = _args[0].Substring(1); //FIXME: handle long options
  59. foreach (FieldInfo i in typeof (AllTests).GetFields (BindingFlags.NonPublic
  60. | BindingFlags.Instance)) {
  61. //FIXME: report if unknown options were passed
  62. object [] attrs = i.GetCustomAttributes(typeof(CommandLineOptionAttribute),true);
  63. if (attrs.Length == 0)
  64. continue;
  65. string option = attrs[0].ToString();
  66. if (options.IndexOf(option) == -1)
  67. continue;
  68. i.SetValue (this, true);
  69. }
  70. return true;
  71. }
  72. #endregion
  73. string [] _args;
  74. #region statistics fields
  75. int totalCount = 0;
  76. int performedCount = 0;
  77. int passedCount = 0;
  78. int failedCount = 0;
  79. int regressionsCount = 0; //failures not listed in knownFailures.lst
  80. int fixedCount = 0; //tested known to fail that passed
  81. #endregion
  82. #region test list fields
  83. ArrayList slowTests = new ArrayList ();
  84. ArrayList igroredTests = new ArrayList ();
  85. ArrayList knownFailures = new ArrayList ();
  86. ArrayList fixmeList = new ArrayList ();
  87. ArrayList netFailures = new ArrayList ();
  88. StreamWriter failedListWriter;
  89. StreamWriter fixedListWriter;
  90. StreamWriter slowNewListWriter;
  91. StreamWriter totalListWriter;
  92. #endregion
  93. #region IDisposable Members
  94. public void Dispose()
  95. {
  96. if (failedListWriter != null)
  97. failedListWriter.Close ();
  98. if (fixedListWriter != null)
  99. fixedListWriter.Close ();
  100. if (slowNewListWriter != null)
  101. slowNewListWriter.Close ();
  102. if (totalListWriter != null)
  103. totalListWriter.Close ();
  104. failedListWriter = null;
  105. fixedListWriter = null;
  106. slowNewListWriter = null;
  107. totalListWriter = null;
  108. }
  109. #endregion
  110. #region command line option fields
  111. [CommandLineOption ('s')]
  112. [Description ("do run slow tests (skipped by default)")]
  113. bool runSlow = false;
  114. [CommandLineOption ('i')]
  115. [Description ("do run tests being ignored by default")]
  116. bool runIgnored = false;
  117. #endregion
  118. static int Main (string[] args)
  119. {
  120. using (AllTests tests = new AllTests (args)) {
  121. if (!tests.Run ())
  122. return 1;
  123. else
  124. return 0;
  125. }
  126. }
  127. #if NUNIT_SUPPORT
  128. TestSuite _suite;
  129. [Suite]
  130. static public TestSuite Suite {
  131. get {
  132. TestSuite suite = new TestSuite ("W3C_xmlconf");
  133. using (AllTests tests = new AllTests (suite)) {
  134. tests.Run ();
  135. }
  136. return suite;
  137. }
  138. }
  139. AllTests (TestSuite suite)
  140. : this () {
  141. _suite = suite;
  142. }
  143. #endif
  144. AllTests (string [] args)
  145. : this () {
  146. _args = args;
  147. }
  148. #region ReadStrings ()
  149. static void ReadStrings (ArrayList array, string filename)
  150. {
  151. if (!File.Exists (filename))
  152. return;
  153. using (StreamReader reader = new StreamReader (filename)) {
  154. foreach (string s_ in reader.ReadToEnd ().Split ("\n".ToCharArray ())) {
  155. string s = s_.Trim ();
  156. if (s.Length > 0)
  157. array.Add (s);
  158. }
  159. }
  160. }
  161. #endregion
  162. private AllTests ()
  163. {
  164. failedListWriter = new StreamWriter ("failed.lst", false);
  165. fixedListWriter = new StreamWriter ("fixed.lst", false);
  166. slowNewListWriter = new StreamWriter ("slow-new.lst", false);
  167. totalListWriter = new StreamWriter ("total.lst", false);
  168. ReadStrings (slowTests, "slow.lst");
  169. ReadStrings (igroredTests, "ignored.lst");
  170. ReadStrings (knownFailures, "knownFailures.lst");
  171. ReadStrings (fixmeList, "fixme.lst");
  172. ReadStrings (netFailures, "net-failed.lst");
  173. }
  174. bool Run ()
  175. {
  176. bool res = true;
  177. if (!ParseOptions ())
  178. return false;
  179. XmlDocument catalog = new XmlDocument ();
  180. catalog.Load ("xmlconf/xmlconf.xml");
  181. foreach (XmlElement test in catalog.SelectNodes ("//TEST")) {
  182. ++totalCount;
  183. string testId = test.GetAttribute ("ID");
  184. if (!runSlow && slowTests.Contains (testId)) {
  185. continue;
  186. }
  187. if (!runIgnored && igroredTests.Contains (testId)) {
  188. continue;
  189. }
  190. DateTime start = DateTime.Now;
  191. if (!PerformTest (test))
  192. res = false;
  193. TimeSpan span = DateTime.Now - start;
  194. if (span.TotalSeconds > 1) {
  195. if (slowTests.Contains (testId))
  196. continue;
  197. slowNewListWriter.WriteLine (testId);
  198. }
  199. }
  200. Console.Error.WriteLine ("\n\n*********");
  201. Console.Error.WriteLine ("Total:{0}", totalCount);
  202. Console.Error.WriteLine ("Performed:{0}", performedCount);
  203. Console.Error.WriteLine ("Passed:{0}", passedCount);
  204. Console.Error.WriteLine ("Failed:{0}", failedCount);
  205. Console.Error.WriteLine ("Regressions:{0}", regressionsCount);
  206. Console.Error.WriteLine ("Fixed:{0}\n", fixedCount);
  207. if (fixedCount > 0)
  208. Console.Error.WriteLine (@"
  209. ATTENTION!
  210. Delete the fixed tests (those listed in fixed.lst) from
  211. knownFailures.lst or fixme.lst, or we might miss
  212. regressions in the future.");
  213. if (regressionsCount > 0)
  214. Console.Error.WriteLine (@"
  215. ERROR!!! New regressions!
  216. If you see this message for the first time, your last changes had
  217. introduced new bugs! Before you commit, consider one of the following:
  218. 1. Find and fix the bugs, so tests will pass again.
  219. 2. Open new bugs in bugzilla and temporily add the tests to fixme.lst
  220. 3. Write to devlist and confirm adding the new tests to knownFailures.lst");
  221. return res;
  222. }
  223. bool PerformTest (XmlElement test)
  224. {
  225. ++performedCount;
  226. string type = test.GetAttribute ("TYPE");
  227. if (type == "error")
  228. return true; //save time
  229. Uri baseUri = new Uri (test.BaseURI);
  230. Uri testUri = new Uri (baseUri, test.GetAttribute ("URI"));
  231. bool validatingPassed;
  232. bool nonValidatingPassed;
  233. try {
  234. XmlTextReader trd = new XmlTextReader (testUri.ToString ());
  235. new XmlDocument ().Load (trd);
  236. nonValidatingPassed = true;
  237. }
  238. catch (Exception) {
  239. nonValidatingPassed = false;
  240. }
  241. try {
  242. XmlTextReader rd = new XmlTextReader (testUri.ToString ());
  243. XmlValidatingReader vrd = new XmlValidatingReader (rd);
  244. new XmlDocument ().Load (vrd);
  245. validatingPassed = true;
  246. }
  247. catch (Exception) {
  248. validatingPassed = false;
  249. }
  250. bool res = isOK (type, nonValidatingPassed, validatingPassed);
  251. return Report (testUri, test, res, nonValidatingPassed, validatingPassed);
  252. }
  253. bool isOK (string type, bool nonValidatingPassed, bool validatingPassed)
  254. {
  255. switch (type) {
  256. case "valid":
  257. return nonValidatingPassed && validatingPassed;
  258. case "invalid":
  259. return nonValidatingPassed && !validatingPassed;
  260. case "not-wf":
  261. return !nonValidatingPassed && !validatingPassed;
  262. case "error":
  263. return true; //readers can optionally accept or reject errors
  264. default:
  265. throw new ArgumentException ("Bad test type", "type");
  266. }
  267. }
  268. bool Report (Uri testUri, XmlElement test, bool isok, bool nonValidatingPassed, bool validatingPassed)
  269. {
  270. string testId = test.GetAttribute ("ID");
  271. #if NUNIT_SUPPORT
  272. if (_suite != null) {
  273. StringBuilder sb = new StringBuilder();
  274. sb.Append (testUri.ToString ());
  275. sb.Append (test.InnerXml);
  276. _suite.Add (new PredefinedTest (testId, isok, sb.ToString ()));
  277. return true;
  278. }
  279. #endif
  280. totalListWriter.Write (testUri.ToString () + "\t");
  281. totalListWriter.Write (testId + "\t");
  282. if (isok) {
  283. ++passedCount;
  284. if (fixmeList.Contains (testId) || knownFailures.Contains (testId)) {
  285. ++fixedCount;
  286. fixedListWriter.WriteLine (testId);
  287. Console.Error.Write ("!");
  288. totalListWriter.WriteLine ("fixed");
  289. return true;
  290. }
  291. if (netFailures.Contains (testId)) {
  292. Console.Error.Write (",");
  293. totalListWriter.WriteLine (",");
  294. return true;
  295. }
  296. Console.Error.Write (".");
  297. totalListWriter.WriteLine (".");
  298. return true;
  299. }
  300. ++failedCount;
  301. if (netFailures.Contains (testId)) {
  302. Console.Error.Write ("K");
  303. totalListWriter.WriteLine ("dot net known failure");
  304. return true;
  305. }
  306. if (knownFailures.Contains (testId)) {
  307. Console.Error.Write ("k");
  308. totalListWriter.WriteLine ("known failure");
  309. return true;
  310. }
  311. if (fixmeList.Contains (testId)) {
  312. Console.Error.Write ("f");
  313. totalListWriter.WriteLine ("fixme");
  314. return true;
  315. }
  316. ++regressionsCount;
  317. Console.Error.Write ("E");
  318. totalListWriter.WriteLine ("regression");
  319. failedListWriter.Write ("*** Test failed:\t{0}\ttype:{1}\tnonValidatingPassed:{2},validatingPassed:{3}\t",
  320. testId, test.GetAttribute ("TYPE"), nonValidatingPassed, validatingPassed);
  321. failedListWriter.WriteLine (test.InnerXml);
  322. return false;
  323. }
  324. }
  325. public class PredefinedTest: NUnit.Core.TestCase {
  326. bool _res;
  327. string _message;
  328. public PredefinedTest (string name, bool res, string message):base (null, name) {
  329. _res = res;
  330. _message = message;
  331. }
  332. public override void Run (TestCaseResult res) {
  333. if (_res)
  334. res.Success ();
  335. else
  336. res.Failure (_message, null);
  337. }
  338. }
  339. }