FoxTest.Mod 8.2 KB

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