PageRenderTime 60ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/tool/gecop/src/eiffel_test_case.e

http://github.com/gobo-eiffel/gobo
Specman e | 1187 lines | 1010 code | 75 blank | 102 comment | 60 complexity | 77bd6ada17dd9a526d9297abfa6cd609 MD5 | raw file
  1. note
  2. description:
  3. "Eiffel standard test cases"
  4. copyright: "Copyright (c) 2002-2021, Eric Bezault and others"
  5. license: "MIT License"
  6. date: "$Date$"
  7. revision: "$Revision$"
  8. class EIFFEL_TEST_CASE
  9. inherit
  10. TS_TEST_CASE
  11. redefine
  12. make_default,
  13. set_up
  14. end
  15. KL_SHARED_FILE_SYSTEM
  16. export {NONE} all end
  17. KL_SHARED_EXECUTION_ENVIRONMENT
  18. export {NONE} all end
  19. create
  20. make,
  21. make_default
  22. feature {NONE} -- Initialization
  23. make (a_program_dirname, a_test_dirname: STRING)
  24. -- Create a new test case with program `a_program_dirname'
  25. -- to be compiled and run in `a_test_dirname'.
  26. require
  27. a_program_dirname_not_void: a_program_dirname /= Void
  28. a_program_dirname_not_empty: not a_program_dirname.is_empty
  29. a_test_dirname_not_void: a_test_dirname /= Void
  30. a_test_dirname_not_empty: not a_test_dirname.is_empty
  31. do
  32. make_default
  33. program_dirname := a_program_dirname
  34. testrun_dirname := a_test_dirname
  35. ensure
  36. program_dirname_set: program_dirname = a_program_dirname
  37. testrun_dirname_set: testrun_dirname = a_test_dirname
  38. end
  39. make_default
  40. -- <Precursor>
  41. do
  42. program_dirname := default_testrun_dirname
  43. testrun_dirname := default_testrun_dirname
  44. precursor
  45. end
  46. feature -- Test
  47. compile_and_test (a_tested_eiffel_tool: STRING)
  48. -- Compile and test with `a_tested_eiffel_tool'.
  49. require
  50. a_tested_eiffel_tool_not_void: a_tested_eiffel_tool /= Void
  51. do
  52. if a_tested_eiffel_tool.same_string ("ise") then
  53. compile_and_test_ise
  54. elseif a_tested_eiffel_tool.same_string ("ise_debug") then
  55. variables.set_value ("debug", "true")
  56. compile_and_test_ise
  57. elseif a_tested_eiffel_tool.same_string ("ise_dotnet") then
  58. variables.set_value ("GOBO_DOTNET", "true")
  59. compile_and_test_ise
  60. elseif a_tested_eiffel_tool.same_string ("ise_dotnet_debug") then
  61. variables.set_value ("GOBO_DOTNET", "true")
  62. variables.set_value ("debug", "true")
  63. compile_and_test_ise
  64. elseif a_tested_eiffel_tool.same_string ("ge") then
  65. compile_and_test_gec
  66. elseif a_tested_eiffel_tool.same_string ("ge_debug") then
  67. variables.set_value ("debug", "true")
  68. compile_and_test_gec
  69. elseif a_tested_eiffel_tool.same_string ("ge_lint") then
  70. compile_and_test_gelint
  71. elseif a_tested_eiffel_tool.same_string ("gec") then
  72. compile_and_test_gec
  73. elseif a_tested_eiffel_tool.same_string ("gelint") then
  74. compile_and_test_gelint
  75. else
  76. assert ("unknown eiffel tool: " + a_tested_eiffel_tool, False)
  77. end
  78. end
  79. feature -- Test Gobo Eiffel Compiler
  80. compile_and_test_gec
  81. -- Compile and test with gec.
  82. local
  83. a_debug: STRING
  84. a_geant_filename: STRING
  85. l_directory: KL_DIRECTORY
  86. l_executable: STRING
  87. do
  88. if variables.has ("debug") then
  89. a_debug := "debug_"
  90. else
  91. a_debug := ""
  92. end
  93. if variables.has ("executable") then
  94. l_executable := " -D%"GEC_EXECUTABLE=" + variables.value ("executable") + "%""
  95. else
  96. l_executable := ""
  97. end
  98. a_geant_filename := geant_filename
  99. -- Compile program.
  100. execute_shell ("geant -b %"" + a_geant_filename + "%"" + l_executable + " -Dgelint_option=true compile_" + a_debug + "ge" + output1_log)
  101. concat_output1 (agent filter_output_gec)
  102. -- Execute program.
  103. if file_system.file_exists (file_system.pathname (testrun_dirname, program_exe)) then
  104. execute_shell (program_exe + output2_log)
  105. concat_output2
  106. end
  107. -- Clean.
  108. execute_shell ("geant -b %"" + a_geant_filename + "%" clobber" + output3_log)
  109. concat_output3
  110. -- Test.
  111. create l_directory.make (program_dirname)
  112. if l_directory.there_exists (agent output_recognized (?, l_directory, passed_filename_regexp ("gec?"), output_log_filename)) then
  113. assert ("test_passed", True)
  114. elseif l_directory.there_exists (agent output_recognized (?, l_directory, failed_filename_regexp ("gec?"), output_log_filename)) then
  115. assert ("test_failed", False)
  116. else
  117. assert_known_test_result ("unknown_test_result", False, output_log_filename)
  118. end
  119. end
  120. feature {NONE} -- Test Gobo Eiffel Compiler
  121. filter_output_gec (an_input_filename, an_output_filename: STRING)
  122. -- Filter text from file `an_input_filename' and append it to the end of file `an_output_filename'.
  123. require
  124. an_input_filename_not_void: an_input_filename /= Void
  125. an_output_filename_not_void: an_output_filename /= Void
  126. local
  127. out_file: KL_TEXT_OUTPUT_FILE
  128. in_file: KL_TEXT_INPUT_FILE
  129. a_line: STRING
  130. a_pattern1, a_pattern2, a_pattern3, a_pattern4: STRING
  131. a_regexp1, a_regexp2, a_regexp3, a_regexp4: RX_PCRE_REGULAR_EXPRESSION
  132. l_empty_line: BOOLEAN
  133. l_first_line: BOOLEAN
  134. do
  135. -- Compile regexps.
  136. a_pattern1 := "BUILD FAILED!"
  137. create a_regexp1.make
  138. a_regexp1.compile (a_pattern1)
  139. assert ("cannot compile regexp '" + a_pattern1 + "'", a_regexp1.is_compiled)
  140. a_regexp1.optimize
  141. a_pattern2 := "aa[0-9]+\.c"
  142. create a_regexp2.make
  143. a_regexp2.compile (a_pattern2)
  144. assert ("cannot compile regexp '" + a_pattern2 + "'", a_regexp2.is_compiled)
  145. a_regexp2.optimize
  146. a_pattern3 := "(Degree -?[0-9]+|Total Time): [ 0-9:./]*"
  147. create a_regexp3.make
  148. a_regexp3.compile (a_pattern3)
  149. assert ("cannot compile regexp '" + a_pattern3 + "'", a_regexp3.is_compiled)
  150. a_regexp3.optimize
  151. a_pattern4 := "(line [0-9]+ column [0-9]+ in )([^\\/]*[\\/])*([a-z][a-z0-9_]*\.e)"
  152. create a_regexp4.make
  153. a_regexp4.compile (a_pattern4)
  154. assert ("cannot compile regexp '" + a_pattern4 + "'", a_regexp4.is_compiled)
  155. a_regexp4.optimize
  156. -- Copy files.
  157. create out_file.make (an_output_filename)
  158. out_file.open_append
  159. if out_file.is_open_write then
  160. create in_file.make (an_input_filename)
  161. in_file.open_read
  162. if in_file.is_open_read then
  163. from
  164. in_file.read_line
  165. l_first_line := True
  166. until
  167. in_file.end_of_file
  168. loop
  169. a_line := in_file.last_string
  170. if l_first_line and then a_line.starts_with ({UC_UTF8_ROUTINES}.utf8_bom) then
  171. a_line := a_line.tail (a_line.count - {UC_UTF8_ROUTINES}.utf8_bom.count)
  172. end
  173. if a_line.is_empty then
  174. l_empty_line := True
  175. elseif a_regexp1.recognizes (a_line) then
  176. -- Skip this line and the previous empty line.
  177. l_empty_line := False
  178. elseif a_regexp2.recognizes (a_line) then
  179. -- Skip this line and the previous empty line.
  180. l_empty_line := False
  181. elseif a_regexp3.recognizes (a_line) then
  182. -- Skip this line and the previous empty line.
  183. l_empty_line := False
  184. else
  185. if l_empty_line then
  186. out_file.put_new_line
  187. l_empty_line := False
  188. end
  189. if a_regexp4.recognizes (a_line) then
  190. out_file.put_line (a_regexp4.captured_substring (1) + a_regexp4.captured_substring (3))
  191. else
  192. out_file.put_line (a_line)
  193. end
  194. end
  195. a_regexp1.wipe_out
  196. a_regexp2.wipe_out
  197. a_regexp3.wipe_out
  198. a_regexp4.wipe_out
  199. in_file.read_line
  200. l_first_line := False
  201. end
  202. in_file.close
  203. if l_empty_line then
  204. out_file.put_new_line
  205. l_empty_line := False
  206. end
  207. else
  208. assert ("cannot open file '" + an_input_filename + "'", False)
  209. end
  210. out_file.close
  211. else
  212. assert ("cannot open file '" + an_output_filename + "'", False)
  213. end
  214. end
  215. feature -- Test gelint
  216. compile_and_test_gelint
  217. -- Compile and test with gelint.
  218. local
  219. a_debug: STRING
  220. l_directory: KL_DIRECTORY
  221. l_executable: STRING
  222. do
  223. if variables.has ("debug") then
  224. a_debug := "debug_"
  225. else
  226. a_debug := ""
  227. end
  228. if variables.has ("executable") then
  229. l_executable := variables.value ("executable")
  230. else
  231. l_executable := "gelint"
  232. end
  233. execute_shell (l_executable + " --variable=GOBO_EIFFEL=ge --flat %"" + ecf_filename + "%"" + output1_log)
  234. concat_output1 (agent filter_output_gelint)
  235. -- Test.
  236. create l_directory.make (program_dirname)
  237. if l_directory.there_exists (agent output_recognized (?, l_directory, passed_filename_regexp ("(gelint|gec?)"), output_log_filename)) then
  238. assert ("test_passed", True)
  239. elseif l_directory.there_exists (agent output_recognized (?, l_directory, failed_filename_regexp ("(gelint|gec?)"), output_log_filename)) then
  240. assert ("test_failed", False)
  241. else
  242. assert_known_test_result ("unknown_test_result", False, output_log_filename)
  243. end
  244. end
  245. feature {NONE} -- Test gelint
  246. filter_output_gelint (an_input_filename, an_output_filename: STRING)
  247. -- Filter text from file `an_input_filename' and append it to the end of file `an_output_filename'.
  248. require
  249. an_input_filename_not_void: an_input_filename /= Void
  250. an_output_filename_not_void: an_output_filename /= Void
  251. local
  252. out_file: KL_TEXT_OUTPUT_FILE
  253. in_file: KL_TEXT_INPUT_FILE
  254. a_line: STRING
  255. a_pattern1, a_pattern2, a_pattern3: STRING
  256. a_regexp1, a_regexp2, a_regexp3: RX_PCRE_REGULAR_EXPRESSION
  257. l_empty_line: BOOLEAN
  258. l_first_line: BOOLEAN
  259. do
  260. -- Compile regexps.
  261. a_pattern1 := "BUILD FAILED!"
  262. create a_regexp1.make
  263. a_regexp1.compile (a_pattern1)
  264. assert ("cannot compile regexp '" + a_pattern1 + "'", a_regexp1.is_compiled)
  265. a_regexp1.optimize
  266. a_pattern2 := "(Degree -?[0-9]+|Total Time): [ 0-9:./]*"
  267. create a_regexp2.make
  268. a_regexp2.compile (a_pattern2)
  269. assert ("cannot compile regexp '" + a_pattern2 + "'", a_regexp2.is_compiled)
  270. a_regexp2.optimize
  271. a_pattern3 := "(line [0-9]+ column [0-9]+ in )([^\\/]*[\\/])*([a-z][a-z0-9_]*\.e)"
  272. create a_regexp3.make
  273. a_regexp3.compile (a_pattern3)
  274. assert ("cannot compile regexp '" + a_pattern3 + "'", a_regexp3.is_compiled)
  275. a_regexp3.optimize
  276. -- Copy files.
  277. create out_file.make (an_output_filename)
  278. out_file.open_append
  279. if out_file.is_open_write then
  280. create in_file.make (an_input_filename)
  281. in_file.open_read
  282. if in_file.is_open_read then
  283. from
  284. in_file.read_line
  285. l_first_line := True
  286. until
  287. in_file.end_of_file
  288. loop
  289. a_line := in_file.last_string
  290. if l_first_line and then a_line.starts_with ({UC_UTF8_ROUTINES}.utf8_bom) then
  291. a_line := a_line.tail (a_line.count - {UC_UTF8_ROUTINES}.utf8_bom.count)
  292. end
  293. if a_line.is_empty then
  294. l_empty_line := True
  295. elseif a_regexp1.recognizes (a_line) then
  296. -- Skip this line and the previous empty line.
  297. l_empty_line := False
  298. elseif a_regexp2.recognizes (a_line) then
  299. -- Skip this line and the previous empty line.
  300. l_empty_line := False
  301. else
  302. if l_empty_line then
  303. out_file.put_new_line
  304. l_empty_line := False
  305. end
  306. if a_regexp3.recognizes (a_line) then
  307. out_file.put_line (a_regexp3.captured_substring (1) + a_regexp3.captured_substring (3))
  308. else
  309. out_file.put_line (a_line)
  310. end
  311. end
  312. a_regexp1.wipe_out
  313. a_regexp2.wipe_out
  314. a_regexp3.wipe_out
  315. in_file.read_line
  316. l_first_line := False
  317. end
  318. in_file.close
  319. if l_empty_line then
  320. out_file.put_new_line
  321. l_empty_line := False
  322. end
  323. else
  324. assert ("cannot open file '" + an_input_filename + "'", False)
  325. end
  326. out_file.close
  327. else
  328. assert ("cannot open file '" + an_output_filename + "'", False)
  329. end
  330. end
  331. feature -- Test ISE Eiffel
  332. compile_and_test_ise
  333. -- Compile and test with ISE Eiffel.
  334. local
  335. a_debug: STRING
  336. l_dotnet: STRING
  337. a_geant_filename: STRING
  338. l_directory: KL_DIRECTORY
  339. l_executable: STRING
  340. do
  341. if variables.has ("debug") then
  342. a_debug := "debug_"
  343. else
  344. a_debug := ""
  345. end
  346. if variables.has ("executable") then
  347. l_executable := " -D%"EC_EXECUTABLE=" + variables.value ("executable") + "%""
  348. else
  349. -- Use 'ecb' by default to run the validation suite.
  350. -- It runs faster. The generated EIFGEN is not compatible with 'ec',
  351. -- but this is not a problem here since we remove the EIFGEN at the
  352. -- end of this test.
  353. l_executable := " -DEC_EXECUTABLE=ecb"
  354. end
  355. if variables.has ("GOBO_DOTNET") or attached Execution_environment.variable_value ("GOBO_DOTNET") as l_variable and then not l_variable.is_empty then
  356. l_dotnet := " -DGOBO_DOTNET=true"
  357. else
  358. l_dotnet := ""
  359. end
  360. a_geant_filename := geant_filename
  361. -- Compile program.
  362. execute_shell ("geant -b %"" + a_geant_filename + "%"" + l_executable + l_dotnet + " compile_" + a_debug + "ise" + output1_log)
  363. concat_output1 (agent filter_output_ise)
  364. -- Execute program.
  365. if file_system.file_exists (file_system.pathname (testrun_dirname, program_exe)) then
  366. execute_shell (program_exe + output2_log)
  367. concat_output2
  368. end
  369. -- Clean.
  370. execute_shell ("geant -b %"" + a_geant_filename + "%" clobber" + output3_log)
  371. concat_output3
  372. -- Test.
  373. create l_directory.make (program_dirname)
  374. if l_directory.there_exists (agent output_recognized (?, l_directory, passed_filename_regexp ("ise"), output_log_filename)) then
  375. assert ("test_passed", True)
  376. elseif l_directory.there_exists (agent output_recognized (?, l_directory, failed_filename_regexp ("ise"), output_log_filename)) then
  377. assert ("test_failed", False)
  378. else
  379. assert_known_test_result ("unknown_test_result", False, output_log_filename)
  380. end
  381. end
  382. feature {NONE} -- Test ISE Eiffel
  383. filter_output_ise (an_input_filename, an_output_filename: STRING)
  384. -- Filter text from file `an_input_filename' and append it to the end of file `an_output_filename'.
  385. require
  386. an_input_filename_not_void: an_input_filename /= Void
  387. an_output_filename_not_void: an_output_filename /= Void
  388. local
  389. out_file: KL_TEXT_OUTPUT_FILE
  390. in_file: KL_TEXT_INPUT_FILE
  391. a_line: STRING
  392. a_pattern1, a_pattern2, a_pattern3, a_pattern4, a_pattern5, a_pattern6, a_pattern7, a_pattern8, a_pattern9, a_pattern10: STRING
  393. a_regexp1, a_regexp2, a_regexp3, a_regexp4, a_regexp5, a_regexp6, a_regexp7, a_regexp8, a_regexp9, a_regexp10: RX_PCRE_REGULAR_EXPRESSION
  394. l_empty_line: BOOLEAN
  395. l_first_line: BOOLEAN
  396. do
  397. -- Compile regexps.
  398. a_pattern1 := "BUILD FAILED!"
  399. create a_regexp1.make
  400. a_regexp1.compile (a_pattern1)
  401. assert ("cannot compile regexp '" + a_pattern1 + "'", a_regexp1.is_compiled)
  402. a_regexp1.optimize
  403. a_pattern2 := "(\[ *[0-9]+%% - *[0-9]+\] (Degree -?[0-9]+|Generating Auxiliary Files))|(Features done: [0-9]+\sFeatures to go: [0-9]+)|(Degree 6: Examining System)|(Degree 5: Parsing Classes)|(Degree 4: Analyzing Inheritance)|(Degree 3: Checking Types)|(Degree 2: Generating Byte Code)|(Degree -1: Generating Code)|(Degree -2: Constructing Polymorphic Table)|(Degree -3: Generating Optimized Code)"
  404. create a_regexp2.make
  405. a_regexp2.compile (a_pattern2)
  406. assert ("cannot compile regexp '" + a_pattern2 + "'", a_regexp2.is_compiled)
  407. a_regexp2.optimize
  408. a_pattern3 := "(Eiffel Compilation Manager)|(Freezing System Changes)|(System Recompiled\.)|(C compilation completed)|(Preparing C compilation.*\.\.\.)|(Removing Dead Code)|(Removing Unused Code)|(\s*\(version .*\))|(Version .*)|(\s*1 file\(s\) copied\.)"
  409. create a_regexp3.make
  410. a_regexp3.compile (a_pattern3)
  411. assert ("cannot compile regexp '" + a_pattern3 + "'", a_regexp3.is_compiled)
  412. a_regexp3.optimize
  413. a_pattern4 := "[a-zA-Z0-9_]+\.c"
  414. create a_regexp4.make
  415. a_regexp4.compile (a_pattern4)
  416. assert ("cannot compile regexp '" + a_pattern4 + "'", a_regexp4.is_compiled)
  417. a_regexp4.optimize
  418. a_pattern5 := "Batch/Stop mode: saving new configuration format as"
  419. create a_regexp5.make
  420. a_regexp5.compile (a_pattern5)
  421. assert ("cannot compile regexp '" + a_pattern5 + "'", a_regexp5.is_compiled)
  422. a_regexp5.optimize
  423. a_pattern6 := "(Eiffel C/C\+\+ Compilation Tool - Version:)|(Copyright Eiffel Software)|(Microsoft \(R\) Incremental Linker Version)|(Microsoft \(R\) Windows \(R\) Resource Compiler Version)|(Copyright \(C\) Microsoft Corporation)|(You must now run \%"finish_freezing(\.exe)?\%" in:)|(EIFGENs[\\/]aa[\\/][WF]_code)"
  424. create a_regexp6.make
  425. a_regexp6.compile (a_pattern6)
  426. assert ("cannot compile regexp '" + a_pattern6 + "'", a_regexp6.is_compiled)
  427. a_regexp6.optimize
  428. a_pattern7 := "(-STACK:5000000)|(-NODEFAULTLIB:libc)|(-SUBSYSTEM:CONSOLE)|(-OUT:aa\.exe)|(e1\\emain\.obj)|(E1\\estructure\.h)|(wkbench\.lib)|(finalized\.lib)|(USER32\.lib)|(WSOCK32\.lib)|(WSOCK32\.dll)|(ADVAPI32\.lib)|(GDI32\.lib)|(SHELL32\.lib)|(MSIMG32\.lib)|(COMDLG32\.lib)|(UUID\.lib)|(OLE32\.lib)|(OLEAUT32\.lib)|(COMCTL32\.lib)|(MPR\.LIB)|(aa\.res)|(E[0-9]+\\[A-Za-z0-9_]+\.obj)|(E[0-9]+\\[A-Za-z0-9_]+\.lib)|(C[0-9]+\\Cobj[0-9]+\.lib)"
  429. create a_regexp7.make
  430. a_regexp7.compile (a_pattern7)
  431. assert ("cannot compile regexp '" + a_pattern7 + "'", a_regexp7.is_compiled)
  432. a_regexp7.optimize
  433. a_pattern8 := "WARNING: Option '[^']+' was found in neither CONFIG\.EIF nor registry\."
  434. create a_regexp8.make
  435. a_regexp8.compile (a_pattern8)
  436. assert ("cannot compile regexp '" + a_pattern8 + "'", a_regexp8.is_compiled)
  437. a_regexp8.optimize
  438. a_pattern9 := "<[0-9A-F]{16}>(.*)"
  439. create a_regexp9.make
  440. a_regexp9.compile (a_pattern9)
  441. assert ("cannot compile regexp '" + a_pattern9 + "'", a_regexp9.is_compiled)
  442. a_regexp9.optimize
  443. a_pattern10 := "(.*([^-]|[^-]-)) @[0-9]+ *"
  444. create a_regexp10.make
  445. a_regexp10.compile (a_pattern10)
  446. assert ("cannot compile regexp '" + a_pattern10 + "'", a_regexp10.is_compiled)
  447. a_regexp10.optimize
  448. -- Copy files.
  449. create out_file.make (an_output_filename)
  450. out_file.open_append
  451. if out_file.is_open_write then
  452. create in_file.make (an_input_filename)
  453. in_file.open_read
  454. if in_file.is_open_read then
  455. from
  456. in_file.read_line
  457. l_first_line := True
  458. until
  459. in_file.end_of_file
  460. loop
  461. a_line := in_file.last_string
  462. if l_first_line and then a_line.starts_with ({UC_UTF8_ROUTINES}.utf8_bom) then
  463. a_line := a_line.tail (a_line.count - {UC_UTF8_ROUTINES}.utf8_bom.count)
  464. end
  465. if a_line.is_empty then
  466. l_empty_line := True
  467. elseif a_regexp1.recognizes (a_line) then
  468. -- Skip this line and the previous empty line.
  469. l_empty_line := False
  470. elseif a_regexp2.matches (a_line) then
  471. -- Skip this line and the previous empty line.
  472. l_empty_line := False
  473. elseif a_regexp3.recognizes (a_line) then
  474. -- Skip this line and the previous empty line.
  475. l_empty_line := False
  476. elseif a_regexp4.recognizes (a_line) then
  477. -- Skip this line and the previous empty line.
  478. l_empty_line := False
  479. elseif a_regexp5.matches (a_line) then
  480. -- Skip this line and the previous empty line.
  481. l_empty_line := False
  482. elseif a_regexp6.matches (a_line) then
  483. -- Skip this line and the previous empty line.
  484. l_empty_line := False
  485. elseif a_regexp7.matches (a_line) then
  486. -- Skip this line and the previous empty line.
  487. l_empty_line := False
  488. elseif a_regexp8.matches (a_line) then
  489. -- Skip this line and the previous empty line.
  490. l_empty_line := False
  491. else
  492. if l_empty_line then
  493. out_file.put_new_line
  494. l_empty_line := False
  495. end
  496. if a_regexp9.recognizes (a_line) then
  497. -- These are object addresses in exception traces.
  498. out_file.put_string ("<XXXXXXXXXXXXXXXX>")
  499. out_file.put_line (a_regexp9.captured_substring (1))
  500. elseif a_regexp10.recognizes (a_line) then
  501. -- These are breakpoint positions in exception traces.
  502. out_file.put_string (a_regexp10.captured_substring (1))
  503. out_file.put_line (" @N")
  504. else
  505. out_file.put_line (a_line)
  506. end
  507. end
  508. a_regexp1.wipe_out
  509. a_regexp2.wipe_out
  510. a_regexp3.wipe_out
  511. a_regexp4.wipe_out
  512. a_regexp5.wipe_out
  513. a_regexp6.wipe_out
  514. a_regexp7.wipe_out
  515. a_regexp8.wipe_out
  516. a_regexp9.wipe_out
  517. a_regexp10.wipe_out
  518. in_file.read_line
  519. l_first_line := False
  520. end
  521. in_file.close
  522. if l_empty_line then
  523. out_file.put_new_line
  524. l_empty_line := False
  525. end
  526. else
  527. assert ("cannot open file '" + an_input_filename + "'", False)
  528. end
  529. out_file.close
  530. else
  531. assert ("cannot open file '" + an_output_filename + "'", False)
  532. end
  533. end
  534. concat_output1_ise
  535. -- Concat the logs of the compilation to 'output.log'.
  536. local
  537. out_file: KL_TEXT_OUTPUT_FILE
  538. in_file: KL_TEXT_INPUT_FILE
  539. in_filename: STRING
  540. a_line: STRING
  541. a_pattern1, a_pattern2, a_pattern3: STRING
  542. a_regexp1, a_regexp2, a_regexp3: RX_PCRE_REGULAR_EXPRESSION
  543. done: BOOLEAN
  544. has_empty_line: BOOLEAN
  545. l_first_line: BOOLEAN
  546. do
  547. -- Compile regexps.
  548. a_pattern1 := "BUILD FAILED!"
  549. create a_regexp1.make
  550. a_regexp1.compile (a_pattern1)
  551. assert ("cannot compile regexp '" + a_pattern1 + "'", a_regexp1.is_compiled)
  552. a_regexp1.optimize
  553. a_pattern2 := "\(version .*\)"
  554. create a_regexp2.make
  555. a_regexp2.compile (a_pattern2)
  556. assert ("cannot compile regexp '" + a_pattern2 + "'", a_regexp2.is_compiled)
  557. a_regexp2.optimize
  558. a_pattern3 := "\[ *[0-9]+%% - *[0-9]+\] Degree [0-9]+"
  559. create a_regexp3.make
  560. a_regexp3.compile (a_pattern3)
  561. assert ("cannot compile regexp '" + a_pattern3 + "'", a_regexp3.is_compiled)
  562. a_regexp3.optimize
  563. -- Copy files.
  564. create out_file.make (output_log_filename)
  565. out_file.open_write
  566. if out_file.is_open_write then
  567. from
  568. in_filename := output1_log_filename
  569. until
  570. in_filename = Void
  571. loop
  572. create in_file.make (in_filename)
  573. in_file.open_read
  574. if in_file.is_open_read then
  575. from
  576. done := False
  577. in_file.read_line
  578. l_first_line := True
  579. until
  580. done or
  581. in_file.end_of_file
  582. loop
  583. a_line := in_file.last_string
  584. if l_first_line and then a_line.starts_with ({UC_UTF8_ROUTINES}.utf8_bom) then
  585. a_line := a_line.tail (a_line.count - {UC_UTF8_ROUTINES}.utf8_bom.count)
  586. end
  587. if a_regexp1.recognizes (a_line) then
  588. done := True
  589. elseif a_regexp2.matches (a_line) then
  590. -- Skip it.
  591. in_file.read_line
  592. elseif a_regexp3.matches (a_line) then
  593. -- Skip it.
  594. in_file.read_line
  595. elseif a_line.count = 0 then
  596. has_empty_line := True
  597. in_file.read_line
  598. else
  599. if has_empty_line then
  600. out_file.put_new_line
  601. has_empty_line := False
  602. end
  603. out_file.put_line (a_line)
  604. in_file.read_line
  605. end
  606. l_first_line := False
  607. end
  608. if has_empty_line then
  609. if not done then
  610. out_file.put_new_line
  611. end
  612. has_empty_line := False
  613. end
  614. in_file.close
  615. else
  616. out_file.close
  617. assert ("cannot open file '" + in_filename + "'", False)
  618. end
  619. if in_filename = output1_log_filename then
  620. in_filename := error1_log_filename
  621. else
  622. in_filename := Void
  623. end
  624. end
  625. out_file.close
  626. else
  627. assert ("cannot open file '" + output_log_filename + "'", False)
  628. end
  629. end
  630. feature -- Execution
  631. set_up
  632. -- Setup for a test.
  633. local
  634. a_testdir: STRING
  635. do
  636. if attached set_up_mutex as l_mutex then
  637. l_mutex.lock
  638. end
  639. a_testdir := testrun_dirname
  640. file_system.recursive_create_directory (a_testdir)
  641. assert (a_testdir + "_exists", file_system.directory_exists (a_testdir))
  642. if attached set_up_mutex as l_mutex then
  643. l_mutex.unlock
  644. end
  645. end
  646. feature -- Multi-threading
  647. set_up_mutex: detachable MUTEX
  648. -- Mutex to create directories in `set_up'
  649. set_set_up_mutex (a_mutex: like set_up_mutex)
  650. -- Set `set_up_mutex' to `a_mutex'.
  651. do
  652. set_up_mutex := a_mutex
  653. ensure
  654. set_up_mutex_set: set_up_mutex = a_mutex
  655. end
  656. feature {NONE} -- Directory and file names
  657. program_name: STRING
  658. -- Program name
  659. once
  660. Result := "aa"
  661. ensure
  662. program_name_not_void: Result /= Void
  663. program_name_not_empty: Result.count > 0
  664. end
  665. program_dirname: STRING
  666. -- Name of program source directory
  667. program_exe: STRING
  668. -- Name of program executable file
  669. do
  670. Result := file_system.pathname (file_system.relative_current_directory, program_name + file_system.exe_extension)
  671. ensure
  672. program_exe_not_void: Result /= Void
  673. program_exe_not_empty: Result.count > 0
  674. end
  675. geant_filename: STRING
  676. -- Name of geant build file used for compilation
  677. do
  678. Result := file_system.pathname (program_dirname, "build.eant")
  679. ensure
  680. geant_filename_not_void: Result /= Void
  681. geant_filename_not_empty: Result.count > 0
  682. end
  683. ecf_filename: STRING
  684. -- Name of ECF file used for compilation
  685. do
  686. Result := file_system.pathname (program_dirname, "system.ecf")
  687. ensure
  688. ecf_filename_not_void: Result /= Void
  689. ecf_filename_not_empty: Result.count > 0
  690. end
  691. testrun_dirname: STRING
  692. -- Name of temporary directory where to run the test
  693. feature {NONE} -- Assertions
  694. assert_known_test_result (a_tag: STRING; a_is_known: BOOLEAN; a_output_filename: STRING)
  695. -- Assert that the test result is known.
  696. -- `a_is_known' is True when the test result is known.
  697. -- `a_output_filename' is the name of the file containing the output of the test.
  698. require
  699. a_tag_not_void: a_tag /= Void
  700. a_output_filename_not_void: a_output_filename /= Void
  701. local
  702. l_file: KL_TEXT_INPUT_FILE
  703. l_output: STRING
  704. do
  705. assertions.add_assertion
  706. if not a_is_known then
  707. create l_output.make (512)
  708. l_output.append_string (a_tag)
  709. l_output.append_string ("%Ntest output:%N----%N")
  710. create l_file.make (a_output_filename)
  711. l_file.open_read
  712. if l_file.is_open_read then
  713. from
  714. l_file.read_line
  715. until
  716. l_file.end_of_file
  717. loop
  718. l_output.append_string (l_file.last_string)
  719. l_output.append_character ('%N')
  720. l_file.read_line
  721. end
  722. l_file.close
  723. else
  724. l_output.append_string ("Cannot read test output file '")
  725. l_output.append_string (a_output_filename)
  726. l_output.append_string ("%'%N")
  727. end
  728. l_output.append_string ("----")
  729. logger.report_failure (a_tag, l_output)
  730. assertions.report_error (l_output)
  731. else
  732. logger.report_success (a_tag)
  733. end
  734. end
  735. feature {NONE} -- Output logs
  736. output_log_filename: STRING
  737. -- Test output log filename
  738. do
  739. Result := file_system.pathname (testrun_dirname, "output.log")
  740. ensure
  741. output_log_filename_not_void: Result /= Void
  742. output_log_filename_not_empty: Result.count > 0
  743. end
  744. output1_log_basename: STRING = "output1.log"
  745. -- Compilation output log basename
  746. output1_log_filename: STRING
  747. -- Compilation output log filename
  748. do
  749. Result := file_system.pathname (testrun_dirname, output1_log_basename)
  750. ensure
  751. output1_log_filename_not_void: Result /= Void
  752. output1_log_filename_not_empty: Result.count > 0
  753. end
  754. error1_log_basename: STRING = "error1.log"
  755. -- Compilation error log basename
  756. error1_log_filename: STRING
  757. -- Compilation error log filename
  758. do
  759. Result := file_system.pathname (testrun_dirname, error1_log_basename)
  760. ensure
  761. error1_log_filename_not_void: Result /= Void
  762. error1_log_filename_not_empty: Result.count > 0
  763. end
  764. output1_log: STRING
  765. -- Where and how to redirect compilation output logs
  766. once
  767. Result := " > " + output1_log_basename + " 2> " + error1_log_basename
  768. ensure
  769. output1_log_not_void: Result /= Void
  770. output1_log_not_empty: Result.count > 0
  771. end
  772. output2_log_basename: STRING = "output2.log"
  773. -- Execution output log basename
  774. output2_log_filename: STRING
  775. -- Execution output log filename
  776. do
  777. Result := file_system.pathname (testrun_dirname, output2_log_basename)
  778. ensure
  779. output2_log_filename_not_void: Result /= Void
  780. output2_log_filename_not_empty: Result.count > 0
  781. end
  782. error2_log_basename: STRING = "error2.log"
  783. -- Execution error log basename
  784. error2_log_filename: STRING
  785. -- Execution error log filename
  786. do
  787. Result := file_system.pathname (testrun_dirname, error2_log_basename)
  788. ensure
  789. error2_log_filename_not_void: Result /= Void
  790. error2_log_filename_not_empty: Result.count > 0
  791. end
  792. output2_log: STRING
  793. -- Where and how to redirect execution output logs
  794. once
  795. Result := " > " + output2_log_basename + " 2> " + error2_log_basename
  796. ensure
  797. output2_log_not_void: Result /= Void
  798. output2_log_not_empty: Result.count > 0
  799. end
  800. output3_log_basename: STRING = "output3.log"
  801. -- Cleaning output log basename
  802. output3_log_filename: STRING
  803. -- Cleaning output log filename
  804. do
  805. Result := file_system.pathname (testrun_dirname, output3_log_basename)
  806. ensure
  807. output3_log_filename_not_void: Result /= Void
  808. output3_log_filename_not_empty: Result.count > 0
  809. end
  810. error3_log_basename: STRING = "error3.log"
  811. -- Cleaning error log basename
  812. error3_log_filename: STRING
  813. -- Cleaning error log filename
  814. do
  815. Result := file_system.pathname (testrun_dirname, error3_log_basename)
  816. ensure
  817. error3_log_filename_not_void: Result /= Void
  818. error3_log_filename_not_empty: Result.count > 0
  819. end
  820. output3_log: STRING
  821. -- Where and how to redirect cleaning output logs
  822. once
  823. Result := " > " + output3_log_basename + " 2> " + error3_log_basename
  824. ensure
  825. output3_log_not_void: Result /= Void
  826. output3_log_not_empty: Result.count > 0
  827. end
  828. concat_output1 (a_filter: PROCEDURE [TUPLE [STRING, STRING]])
  829. -- Concat the logs of the compilation to 'output.log'.
  830. require
  831. a_filter_not_void: a_filter /= Void
  832. do
  833. file_system.delete_file (output_log_filename)
  834. a_filter.call ([output1_log_filename, output_log_filename])
  835. a_filter.call ([error1_log_filename, output_log_filename])
  836. end
  837. concat_output2
  838. -- Concat the logs of the execution to 'output.log'.
  839. local
  840. out_file: KL_TEXT_OUTPUT_FILE
  841. in_file: KL_TEXT_INPUT_FILE
  842. a_line: STRING
  843. a_pattern1, a_pattern2: STRING
  844. a_regexp1, a_regexp2: RX_PCRE_REGULAR_EXPRESSION
  845. l_input_filename: STRING
  846. l_output2_log_filename: STRING
  847. l_first_line: BOOLEAN
  848. do
  849. -- Compile regexps.
  850. a_pattern1 := "<[0-9A-F]{16}>(.*)"
  851. create a_regexp1.make
  852. a_regexp1.compile (a_pattern1)
  853. assert ("cannot compile regexp '" + a_pattern1 + "'", a_regexp1.is_compiled)
  854. a_regexp1.optimize
  855. a_pattern2 := "(.*([^-]|[^-]-)) @[0-9]+ *"
  856. create a_regexp2.make
  857. a_regexp2.compile (a_pattern2)
  858. assert ("cannot compile regexp '" + a_pattern2 + "'", a_regexp2.is_compiled)
  859. a_regexp2.optimize
  860. -- Copy files.
  861. create out_file.make (output_log_filename)
  862. out_file.open_append
  863. if out_file.is_open_write then
  864. from
  865. l_output2_log_filename := output2_log_filename
  866. l_input_filename := l_output2_log_filename
  867. until
  868. l_input_filename = Void
  869. loop
  870. create in_file.make (l_input_filename)
  871. in_file.open_read
  872. if in_file.is_open_read then
  873. from
  874. in_file.read_line
  875. l_first_line := True
  876. until
  877. in_file.end_of_file
  878. loop
  879. a_line := in_file.last_string
  880. if l_first_line and then a_line.starts_with ({UC_UTF8_ROUTINES}.utf8_bom) then
  881. a_line := a_line.tail (a_line.count - {UC_UTF8_ROUTINES}.utf8_bom.count)
  882. end
  883. if a_regexp1.recognizes (a_line) then
  884. -- These are object addresses in exception traces.
  885. out_file.put_string ("<XXXXXXXXXXXXXXXX>")
  886. out_file.put_line (a_regexp1.captured_substring (1))
  887. elseif a_regexp2.recognizes (a_line) then
  888. -- These are breakpoint positions in exception traces.
  889. out_file.put_string (a_regexp2.captured_substring (1))
  890. out_file.put_line (" @N")
  891. else
  892. out_file.put_line (a_line)
  893. end
  894. a_regexp1.wipe_out
  895. a_regexp2.wipe_out
  896. in_file.read_line
  897. l_first_line := False
  898. end
  899. in_file.close
  900. else
  901. assert ("cannot open file '" + l_input_filename + "'", False)
  902. end
  903. if l_input_filename = l_output2_log_filename then
  904. l_input_filename := error2_log_filename
  905. else
  906. l_input_filename := Void
  907. end
  908. end
  909. out_file.close
  910. else
  911. assert ("cannot open file '" + output_log_filename + "'", False)
  912. end
  913. end
  914. concat_output3
  915. -- Concat the logs of the cleaning to 'output.log'.
  916. local
  917. out_file: KL_TEXT_OUTPUT_FILE
  918. in_file: KL_TEXT_INPUT_FILE
  919. a_line: STRING
  920. l_input_filename: STRING
  921. l_output3_log_filename: STRING
  922. l_first_line: BOOLEAN
  923. do
  924. -- Copy files.
  925. create out_file.make (output_log_filename)
  926. out_file.open_append
  927. if out_file.is_open_write then
  928. from
  929. l_output3_log_filename := output3_log_filename
  930. l_input_filename := l_output3_log_filename
  931. until
  932. l_input_filename = Void
  933. loop
  934. create in_file.make (l_input_filename)
  935. in_file.open_read
  936. if in_file.is_open_read then
  937. from
  938. in_file.read_line
  939. l_first_line := True
  940. until
  941. in_file.end_of_file
  942. loop
  943. a_line := in_file.last_string
  944. if l_first_line and then a_line.starts_with ({UC_UTF8_ROUTINES}.utf8_bom) then
  945. a_line := a_line.tail (a_line.count - {UC_UTF8_ROUTINES}.utf8_bom.count)
  946. end
  947. out_file.put_line (a_line)
  948. in_file.read_line
  949. l_first_line := False
  950. end
  951. in_file.close
  952. else
  953. assert ("cannot open file '" + l_input_filename + "'", False)
  954. end
  955. if l_input_filename = l_output3_log_filename then
  956. l_input_filename := error3_log_filename
  957. else
  958. l_input_filename := Void
  959. end
  960. end
  961. out_file.close
  962. else
  963. assert ("cannot open file '" + output_log_filename + "'", False)
  964. end
  965. end
  966. output_recognized (a_filename1: STRING; a_directory1: KL_DIRECTORY; a_regexp1: RX_REGULAR_EXPRESSION; a_filename2: STRING): BOOLEAN
  967. -- Is `a_filename1' of the form expected by `a_regexp1' in `a_directory1',
  968. -- and then is there no difference between the contents of files named
  969. -- `a_filename1' and `a_filename2' (after the environment variables in
  970. -- file `a_filename1' have been expanded)?
  971. require
  972. a_filename1_not_void: a_filename1 /= Void
  973. a_filename1_not_empty: a_filename1.count > 0
  974. a_directory1_not_void: a_directory1 /= Void
  975. a_regexp1_not_void: a_regexp1 /= Void
  976. a_regexp1_compied: a_regexp1.is_compiled
  977. a_filename2_not_void: a_filename2 /= Void
  978. a_filename2_not_empty: a_filename2.count > 0
  979. local
  980. l_full_filename1: STRING
  981. l_file1, l_file2: KI_TEXT_INPUT_FILE
  982. done: BOOLEAN
  983. l_pattern2: STRING
  984. l_regexp2: RX_PCRE_REGULAR_EXPRESSION
  985. l_first_line: BOOLEAN
  986. do
  987. if a_regexp1.recognizes (a_filename1) then
  988. -- Compile regexp.
  989. l_pattern2 := "^Parse error in "
  990. create l_regexp2.make
  991. l_regexp2.compile (l_pattern2)
  992. assert ("cannot compile regexp '" + l_pattern2 + "'", l_regexp2.is_compiled)
  993. l_regexp2.optimize
  994. l_full_filename1 := file_system.pathname (a_directory1.name, a_filename1)
  995. l_file1 := file_system.new_input_file (l_full_filename1)
  996. l_file1.open_read
  997. if l_file1.is_open_read then
  998. l_file2 := file_system.new_input_file (a_filename2)
  999. l_file2.open_read
  1000. if l_file2.is_open_read then
  1001. Result := True
  1002. from
  1003. l_first_line := True
  1004. until
  1005. done
  1006. loop
  1007. l_file1.read_line
  1008. l_file2.read_line
  1009. if l_file1.end_of_file then
  1010. if not l_file2.end_of_file then
  1011. Result := False
  1012. end
  1013. l_file1.close
  1014. l_file2.close
  1015. done := True
  1016. elseif l_file2.end_of_file then
  1017. Result := False
  1018. l_file1.close
  1019. l_file2.close
  1020. done := True
  1021. elseif l_file1.last_string.same_string (l_file2.last_string) then
  1022. -- OK
  1023. elseif l_first_line and then l_file1.last_string.same_string ({UC_UTF8_ROUTINES}.utf8_bom + l_file2.last_string) then
  1024. -- OK
  1025. elseif l_first_line and then l_file2.last_string.same_string ({UC_UTF8_ROUTINES}.utf8_bom + l_file1.last_string) then
  1026. -- OK
  1027. elseif Execution_environment.interpreted_string (l_file1.last_string).same_string (l_file2.last_string) then
  1028. -- OK
  1029. elseif
  1030. l_regexp2.matches (l_file2.last_string) and then
  1031. (l_file1.last_string.as_lower.same_string (l_file2.last_string.as_lower) or
  1032. Execution_environment.interpreted_string (l_file1.last_string).as_lower.same_string (l_file2.last_string.as_lower))
  1033. then
  1034. -- OK
  1035. else
  1036. Result := False
  1037. l_file1.close
  1038. l_file2.close
  1039. done := True
  1040. end
  1041. l_first_line := False
  1042. end
  1043. else
  1044. l_file1.close
  1045. Result := False
  1046. end
  1047. else
  1048. Result := False
  1049. end
  1050. end
  1051. end
  1052. feature {NONE} -- Execution
  1053. execute_shell (a_shell_command: STRING)
  1054. -- Execute `a_shell_command'.
  1055. require
  1056. a_shell_command_not_void: a_shell_command /= Void
  1057. a_shell_command_not_empty: a_shell_command.count > 0
  1058. local
  1059. l_command: DP_SHELL_COMMAND
  1060. l_command_name: STRING
  1061. do
  1062. l_command_name := a_shell_command.twin
  1063. l_command_name.replace_substring_all ("\", "\\")
  1064. l_command_name.replace_substring_all ("%"", "\%"")
  1065. l_command_name := "geant -b %"" + execution_buildname + "%" -Dexecutable=%"" + l_command_name + "%" -Ddirectory=%"" + testrun_dirname + "%" execute"
  1066. create l_command.make (l_command_name)
  1067. l_command.execute
  1068. end
  1069. execution_buildname: STRING
  1070. -- Name of geant build file used for execution
  1071. do
  1072. Result := file_system.nested_pathname (Execution_environment.interpreted_string ("${GOBO}"), <<"library", "common", "config", "execute.eant">>)
  1073. ensure
  1074. execution_buildname_not_void: Result /= Void
  1075. execution_buildname_not_empty: Result.count > 0
  1076. end
  1077. feature {NONE} -- Regular expressions
  1078. passed_filename_regexp (a_file_extension: STRING): RX_PCRE_REGULAR_EXPRESSION
  1079. -- Regular expression corresponding to names of files containing possible passed output logs
  1080. -- `a_file_extension' is the expected file extension, without the leading dot.
  1081. require
  1082. a_file_extension_not_void: a_file_extension /= Void
  1083. a_file_extension_not_empty: not a_file_extension.is_empty
  1084. do
  1085. create Result.make
  1086. Result.compile (".*passed.*\." + a_file_extension)
  1087. ensure
  1088. passed_filename_regexp_not_void: Result /= Void
  1089. passed_filename_regexp_compiled: Result.is_compiled
  1090. end
  1091. failed_filename_regexp (a_file_extension: STRING): RX_PCRE_REGULAR_EXPRESSION
  1092. -- Regular expression corresponding to names of files containing possible failed output logs;
  1093. -- `a_file_extension' is the expected file extension, without the leading dot.
  1094. require
  1095. a_file_extension_not_void: a_file_extension /= Void
  1096. a_file_extension_not_empty: not a_file_extension.is_empty
  1097. do
  1098. create Result.make
  1099. Result.compile (".*failed.*\." + a_file_extension)
  1100. ensure
  1101. failed_filename_regexp_not_void: Result /= Void
  1102. failed_filename_regexp_compiled: Result.is_compiled
  1103. end
  1104. feature {NONE} -- Constants
  1105. default_testrun_dirname: STRING = "test1"
  1106. -- Default value for `testrun_dirname'
  1107. invariant
  1108. program_dirname_not_void: program_dirname /= Void
  1109. program_dirname_not_empty: not program_dirname.is_empty
  1110. testrun_dirname_not_void: testrun_dirname /= Void
  1111. testrun_dirname_not_empty: not testrun_dirname.is_empty
  1112. end