FoxTest.Mod 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. MODULE FoxTest; (** AUTHOR "fof"; PURPOSE "Fox tester"; *)
  2. (* (c) fof ETH Zürich, 2008 *)
  3. IMPORT Basic := FoxBasic, TestSuite, Diagnostics, Streams, Commands, Shell, Options, Files, Strings, Versioning, CompilerInterface, Texts, TextUtilities, Modules;
  4. TYPE
  5. Command = ARRAY 256 OF CHAR;
  6. Tester = OBJECT (TestSuite.Tester)
  7. VAR
  8. log: Streams.Writer;
  9. fileLog: Streams.Writer;
  10. mayTrap: BOOLEAN;
  11. command, prolog, epilog: Command;
  12. fileName: Files.FileName;
  13. PROCEDURE &InitTester (log, logFileWriter: Streams.Writer; diagnostics: Diagnostics.Diagnostics; mayTrap: BOOLEAN; CONST prolog, command, epilog: Command; CONST fileName: ARRAY OF CHAR);
  14. BEGIN
  15. Init (diagnostics); SELF.log := log; SELF.mayTrap := mayTrap; SELF.fileLog := logFileWriter;
  16. COPY(prolog, SELF.prolog);
  17. COPY(epilog, SELF.epilog);
  18. COPY(command, SELF.command);
  19. COPY(fileName, SELF.fileName);
  20. END InitTester;
  21. PROCEDURE Handle (r: Streams.Reader; position: LONGINT; CONST name: ARRAY OF CHAR; type: TestSuite.TestType): INTEGER;
  22. VAR result: INTEGER; msg: ARRAY 128 OF CHAR; res: LONGINT; f: Files.File; w: Files.Writer; ch: CHAR;
  23. BEGIN
  24. result := TestSuite.Failure;
  25. IF log # NIL THEN log.String ("testing: "); log.String (name); log.String("@"); log.Int(position,0); log.Ln; log.Update; END;
  26. (* prepare tester input as a file for all test cases *)
  27. f := Files.New(fileName);
  28. NEW(w,f,0);
  29. WHILE r.Available() > 0 DO
  30. r.Char(ch); w.Char(ch)
  31. END;
  32. w.Update;
  33. Files.Register(f);
  34. res := Commands.Ok;
  35. IF prolog # "" THEN
  36. Commands.Call(prolog, {Commands.Wait}, res, msg);
  37. IF (res # Commands.Ok) & (log # NIL) THEN
  38. log.String("prolog failed: "); log.String(msg); log.Ln;
  39. END;
  40. END;
  41. IF (command # "") & (res = Commands.Ok) THEN
  42. Commands.Call(command, {Commands.Wait}, res, msg);
  43. IF res = Commands.Ok THEN
  44. result := TestSuite.Positive
  45. ELSIF (res < 3500) & (res >= 3440) THEN (* loader error *)
  46. result := TestSuite.Failure
  47. ELSIF ~mayTrap & (res = Commands.CommandTrapped) THEN (* command error, trap *)
  48. result := TestSuite.Failure
  49. ELSE
  50. result := TestSuite.Negative
  51. END;
  52. IF (result # type) & (log # NIL) THEN
  53. log.String (msg); log.Ln;
  54. END;
  55. ELSIF (command # "") THEN result := TestSuite.Failure
  56. END;
  57. IF epilog # "" THEN
  58. Commands.Call(epilog, {Commands.Wait}, res, msg);
  59. END;
  60. IF fileLog # NIL THEN
  61. IF result = type THEN
  62. fileLog.String("success: ")
  63. ELSE
  64. fileLog.String("failure: ")
  65. END;
  66. fileLog.String(name); fileLog.Ln;
  67. END;
  68. FINALLY
  69. RETURN result;
  70. END Handle;
  71. END Tester;
  72. PROCEDURE GetOptions(): Options.Options;
  73. VAR options: Options.Options;
  74. BEGIN
  75. NEW(options);
  76. options.Add("p","prolog", Options.String);
  77. options.Add("e","epilog", Options.String);
  78. options.Add("c","command", Options.String);
  79. options.Add("v","verbose",Options.Flag);
  80. options.Add("t","mayTrap",Options.Flag);
  81. options.Add("f","fileName",Options.String);
  82. options.Add("l","logFile",Options.String);
  83. options.Add("r","result",Options.String);
  84. RETURN options
  85. END GetOptions;
  86. PROCEDURE DriveTest (options: Options.Options; diagnostics: Diagnostics.Diagnostics; reader: Streams.Reader; error, writer: Streams.Writer);
  87. VAR
  88. tester: Tester; prolog, epilog, command: Command;
  89. verbose, mayTrap: BOOLEAN; report: TestSuite.StreamReport; fileName, logFileName: Files.FileName; logFileWriter, log:Streams.Writer;
  90. testname, resultname: Files.FileName;
  91. baseOptions: Options.Options; ch: CHAR; string: ARRAY 256 OF CHAR; stringReader: Streams.StringReader;
  92. BEGIN
  93. reader.SetPos(0);
  94. WHILE reader.Available() >0 DO
  95. reader.SkipWhitespace;
  96. reader.Char(ch);
  97. IF (ch = "#") THEN
  98. IF reader.GetString(string) & Strings.StartsWith("options",0,string) THEN
  99. reader.Ln(string);
  100. NEW(stringReader, LEN(string));
  101. stringReader.Set(string);
  102. baseOptions := GetOptions();
  103. IF baseOptions.Parse(stringReader, error) THEN
  104. Options.Merge(options, baseOptions);
  105. END;
  106. ELSE
  107. reader.SkipLn()
  108. END;
  109. ELSE
  110. reader.SkipLn()
  111. END;
  112. END;
  113. IF ~options.GetString("p", prolog) THEN prolog := "" END;
  114. IF ~options.GetString("c", command) THEN command := "" END;
  115. IF ~options.GetString("e", epilog) THEN epilog := "" END;
  116. IF ~options.GetString("f", fileName) THEN fileName := "TesterInput.txt" END;
  117. mayTrap := options.GetFlag("t");
  118. verbose := options.GetFlag("verbose");
  119. IF options.GetString("l",logFileName) THEN
  120. logFileWriter := Versioning.NewLogWriter(logFileName, "Test",testname);
  121. logFileWriter.Ln;
  122. logFileWriter.String("prolog= "); logFileWriter.String(prolog); logFileWriter.Ln;
  123. logFileWriter.String("command= "); logFileWriter.String(command); logFileWriter.Ln;
  124. logFileWriter.Ln;
  125. END;
  126. IF ~options.GetString("r",resultname) THEN resultname := "" END;
  127. IF verbose THEN log := writer ELSE log := NIL END;
  128. NEW (tester, log, logFileWriter, diagnostics, mayTrap, prolog, command, epilog, fileName);
  129. NEW (report, writer);
  130. reader.SetPos(0);
  131. TestSuite.DriveByReader(reader, error, resultname, tester);
  132. tester.Print (report);
  133. IF logFileWriter # NIL THEN
  134. NEW(report, logFileWriter);
  135. tester.Print(report);
  136. logFileWriter.Update;
  137. writer.String("testing logged in "); writer.String(logFileName); writer.Ln;
  138. END;
  139. writer.Update;
  140. END DriveTest;
  141. PROCEDURE Compile* (context: Commands.Context);
  142. VAR writer: Streams.Writer; options: Options.Options;diagnostics: Diagnostics.StreamDiagnostics; testname: Files.FileName; test: Files.File;
  143. reader: Files.Reader;
  144. BEGIN
  145. IF (context.caller # NIL) & (context.caller IS Shell.Shell) THEN
  146. writer := context.out
  147. ELSE
  148. writer := Basic.GetDebugWriter("Oberon Compiler Test Results")
  149. END;
  150. options := GetOptions();
  151. IF options.Parse(context.arg, context.error) THEN
  152. NEW (diagnostics, writer);
  153. IF context.arg.GetString (testname) THEN
  154. test := Files.Old (testname);
  155. IF test = NIL THEN
  156. context.error.String ("Failed to open test file "); context.error.String (testname); context.error.Ln;
  157. RETURN;
  158. END;
  159. ELSE
  160. context.result := Commands.CommandParseError;
  161. END;
  162. Files.OpenReader(reader, test, 0);
  163. DriveTest (options, diagnostics, reader, context.error, writer);
  164. END;
  165. END Compile;
  166. PROCEDURE GetTextReader(text: Texts.Text): Streams.Reader;
  167. VAR
  168. buffer : POINTER TO ARRAY OF CHAR;
  169. length: LONGINT; reader: Streams.StringReader;
  170. BEGIN
  171. ASSERT((text # NIL));
  172. text.AcquireRead;
  173. length := text.GetLength();
  174. text.ReleaseRead;
  175. IF length = 0 THEN length := 1 END;
  176. NEW(buffer, length);
  177. TextUtilities.TextToStr(text, buffer^);
  178. (* prepare the reader *)
  179. NEW(reader, LEN(buffer)); reader.SetRaw(buffer^, 0, LEN(buffer));
  180. RETURN reader
  181. END GetTextReader;
  182. PROCEDURE RunTests(
  183. text : Texts.Text;
  184. CONST source: ARRAY OF CHAR;
  185. pos: LONGINT; (* ignore *)
  186. CONST pc,opt: ARRAY OF CHAR;
  187. log: Streams.Writer; diagnostics : Diagnostics.Diagnostics; VAR error: BOOLEAN);
  188. VAR
  189. reader: Streams.Reader;
  190. options: Options.Options;
  191. optionReader: Streams.StringReader;
  192. BEGIN
  193. ASSERT((text # NIL) & (diagnostics # NIL));
  194. reader := GetTextReader(text);
  195. options := GetOptions();
  196. NEW(optionReader, LEN(opt));
  197. optionReader.Set(opt);
  198. IF options.Parse(optionReader, log) THEN
  199. DriveTest (options, diagnostics, reader, log, log);
  200. END;
  201. END RunTests;
  202. PROCEDURE Cleanup;
  203. BEGIN
  204. CompilerInterface.Unregister("TestTool");
  205. END Cleanup;
  206. BEGIN
  207. CompilerInterface.Register("TestTool", "Run test cases against Fox compiler", "Test", RunTests);
  208. Modules.InstallTermHandler(Cleanup);
  209. END FoxTest.
  210. SystemTools.Free FoxTest TestSuite Versioning ~
  211. FoxTest.Compile Oberon.Execution.Test Oberon.Execution.AMD64TestDiff ~
  212. FoxTest.Compile Oberon.Compilation.Test Oberon.Compilation.AMD64TestDiff ~
  213. FoxTest.Compile MathVectors.Test MathVectors.Test.Diff ~
  214. FoxTest.Compile
  215. --verbose
  216. --fileName="TesterInput.Mod"
  217. --prolog="Compiler.Compile TesterInput.Mod"
  218. --command="SystemTools.Free Test Dummy B A;SystemTools.Load Test"
  219. --logFile="FoxExecutionTest.Log"
  220. MathVectors.Test MathVectors.Test.Diff ~