Tests.py 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  1. #!/usr/bin/env python3
  2. # Contest Management System - http://cms-dev.github.io/
  3. # Copyright © 2012 Bernard Blackham <bernard@largestprime.net>
  4. # Copyright © 2013-2018 Stefano Maggiolo <s.maggiolo@gmail.com>
  5. # Copyright © 2014-2015 Giovanni Mascellani <mascellani@poisson.phc.unipi.it>
  6. # Copyright © 2016 Masaki Hara <ackie.h.gmai@gmail.com>
  7. # Copyright © 2020 Andrey Vihrov <andrey.vihrov@gmail.com>
  8. #
  9. # This program is free software: you can redistribute it and/or modify
  10. # it under the terms of the GNU Affero General Public License as
  11. # published by the Free Software Foundation, either version 3 of the
  12. # License, or (at your option) any later version.
  13. #
  14. # This program is distributed in the hope that it will be useful,
  15. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. # GNU Affero General Public License for more details.
  18. #
  19. # You should have received a copy of the GNU Affero General Public License
  20. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  21. import cmstestsuite.tasks.batch_fileio as batch_fileio
  22. import cmstestsuite.tasks.batch_fileio_managed as batch_fileio_managed
  23. import cmstestsuite.tasks.batch_stdio as batch_stdio
  24. import cmstestsuite.tasks.communication_fifoio_stubbed \
  25. as communication_fifoio_stubbed
  26. import cmstestsuite.tasks.communication_many_fifoio_stubbed \
  27. as communication_many_fifoio_stubbed
  28. import cmstestsuite.tasks.communication_many_stdio_stubbed \
  29. as communication_many_stdio_stubbed
  30. import cmstestsuite.tasks.communication_stdio as communication_stdio
  31. import cmstestsuite.tasks.communication_stdio_stubbed \
  32. as communication_stdio_stubbed
  33. import cmstestsuite.tasks.outputonly as outputonly
  34. import cmstestsuite.tasks.outputonly_comparator as outputonly_comparator
  35. import cmstestsuite.tasks.twosteps as twosteps
  36. import cmstestsuite.tasks.twosteps_comparator as twosteps_comparator
  37. from cmstestsuite.Test import Test, CheckOverallScore, CheckCompilationFail, \
  38. CheckTimeout, CheckTimeoutWall, CheckNonzeroReturn, CheckUserTestEvaluated
  39. LANG_CPP = "C++11 / g++"
  40. LANG_CPP14 = "C++14 / g++"
  41. LANG_CPP17 = "C++17 / g++"
  42. LANG_C = "C11 / gcc"
  43. LANG_HS = "Haskell / ghc"
  44. LANG_JAVA = "Java / JDK"
  45. LANG_PASCAL = "Pascal / fpc"
  46. LANG_PHP = "PHP"
  47. LANG_PYTHON = "Python 2 / CPython"
  48. LANG_PYTHON3 = "Python 3 / CPython"
  49. LANG_RUST = "Rust"
  50. LANG_C_SHARP = "C# / Mono"
  51. ALL_LANGUAGES = (
  52. LANG_CPP, LANG_CPP14, LANG_CPP17, LANG_C, LANG_HS, LANG_JAVA, LANG_PASCAL,
  53. LANG_PHP, LANG_PYTHON, LANG_PYTHON3, LANG_RUST, LANG_C_SHARP
  54. )
  55. NON_INTERPRETED_LANGUAGES = (
  56. LANG_C, LANG_CPP, LANG_CPP14, LANG_CPP17, LANG_PASCAL
  57. )
  58. COMPILED_LANGUAGES = (
  59. LANG_C, LANG_CPP, LANG_CPP14, LANG_CPP17, LANG_PASCAL, LANG_JAVA,
  60. LANG_PYTHON, LANG_PYTHON3, LANG_HS, LANG_RUST, LANG_C_SHARP
  61. )
  62. ALL_TESTS = [
  63. # Correct solutions to batch tasks.
  64. Test('correct-stdio',
  65. task=batch_stdio, filenames=['correct-stdio.%l'],
  66. alt_filenames={
  67. LANG_CPP14: ['correct-stdio-cxx14.%l'],
  68. LANG_CPP17: ['correct-stdio-cxx17.%l'],
  69. },
  70. languages=ALL_LANGUAGES,
  71. checks=[CheckOverallScore(100, 100)]),
  72. Test('correct-freopen',
  73. task=batch_fileio, filenames=['correct-freopen.%l'],
  74. languages=(LANG_C,),
  75. checks=[CheckOverallScore(100, 100)],
  76. user_tests=True,
  77. user_checks=[CheckUserTestEvaluated()]),
  78. Test('correct-stdio-inner-class',
  79. task=batch_stdio, filenames=['correct-stdio-inner-class.%l'],
  80. languages=(LANG_JAVA, LANG_C_SHARP),
  81. checks=[CheckOverallScore(100, 100)]),
  82. Test('correct-fileio',
  83. task=batch_fileio, filenames=['correct-fileio.%l'],
  84. languages=ALL_LANGUAGES,
  85. checks=[CheckOverallScore(100, 100)]),
  86. # Various incorrect solutions to batch tasks.
  87. Test('incorrect-stdio',
  88. task=batch_stdio, filenames=['incorrect-stdio.%l'],
  89. languages=ALL_LANGUAGES,
  90. checks=[CheckOverallScore(0, 100)]),
  91. Test('half-correct-stdio',
  92. task=batch_stdio, filenames=['half-correct-stdio.%l'],
  93. languages=ALL_LANGUAGES,
  94. checks=[CheckOverallScore(50, 100)]),
  95. Test('incorrect-fileio',
  96. task=batch_fileio, filenames=['incorrect-fileio.%l'],
  97. languages=ALL_LANGUAGES,
  98. checks=[CheckOverallScore(0, 100)]),
  99. Test('half-correct-fileio',
  100. task=batch_fileio, filenames=['half-correct-fileio.%l'],
  101. languages=ALL_LANGUAGES,
  102. checks=[CheckOverallScore(50, 100)]),
  103. Test('incorrect-fileio-nooutput',
  104. task=batch_fileio, filenames=['incorrect-fileio-nooutput.%l'],
  105. languages=(LANG_C,),
  106. checks=[CheckOverallScore(0, 100)]),
  107. Test('incorrect-fileio-emptyoutput',
  108. task=batch_fileio, filenames=['incorrect-fileio-emptyoutput.%l'],
  109. languages=(LANG_C,),
  110. checks=[CheckOverallScore(0, 100)]),
  111. Test('incorrect-fileio-with-stdio',
  112. task=batch_fileio, filenames=['incorrect-fileio-with-stdio.%l'],
  113. languages=ALL_LANGUAGES,
  114. checks=[CheckOverallScore(0, 100)]),
  115. # OutputOnly tasks
  116. Test('correct-outputonly',
  117. task=outputonly, filenames=['correct-outputonly-000.txt',
  118. 'correct-outputonly-001.txt'],
  119. languages=[None], checks=[CheckOverallScore(100, 100)]),
  120. Test('incorrect-outputonly',
  121. task=outputonly, filenames=['incorrect-outputonly-000.txt',
  122. 'incorrect-outputonly-001.txt'],
  123. languages=[None], checks=[CheckOverallScore(0, 100)]),
  124. Test('partial-correct-outputonly',
  125. task=outputonly, filenames=['correct-outputonly-000.txt',
  126. 'incorrect-outputonly-001.txt'],
  127. languages=[None], checks=[CheckOverallScore(50, 100)]),
  128. Test('correct-outputonly-comparator',
  129. task=outputonly_comparator,
  130. filenames=['correct-outputonly-000.txt',
  131. 'correct-outputonly-001.txt'],
  132. languages=[None], checks=[CheckOverallScore(100, 100)]),
  133. Test('incorrect-outputonly-comparator',
  134. task=outputonly_comparator,
  135. filenames=['incorrect-outputonly-000.txt',
  136. 'incorrect-outputonly-001.txt'],
  137. languages=[None], checks=[CheckOverallScore(0, 100)]),
  138. Test('partial-correct-outputonly-comparator',
  139. task=outputonly_comparator,
  140. filenames=['correct-outputonly-000.txt',
  141. 'incorrect-outputonly-001.txt'],
  142. languages=[None], checks=[CheckOverallScore(50, 100)]),
  143. # Failed compilation.
  144. Test('compile-fail',
  145. task=batch_fileio, filenames=['compile-fail.%l'],
  146. languages=COMPILED_LANGUAGES,
  147. checks=[CheckCompilationFail()]),
  148. Test('compile-timeout',
  149. task=batch_fileio, filenames=['compile-timeout.%l'],
  150. languages=(LANG_CPP,),
  151. checks=[CheckCompilationFail()]),
  152. # Various timeout conditions.
  153. Test('timeout-cputime',
  154. task=batch_stdio, filenames=['timeout-cputime.%l'],
  155. languages=ALL_LANGUAGES,
  156. checks=[CheckOverallScore(0, 100), CheckTimeout()]),
  157. Test('timeout-pause',
  158. task=batch_stdio, filenames=['timeout-pause.%l'],
  159. languages=(LANG_CPP,),
  160. checks=[CheckOverallScore(0, 100), CheckTimeoutWall()]),
  161. Test('timeout-sleep',
  162. task=batch_stdio, filenames=['timeout-sleep.%l'],
  163. languages=(LANG_CPP,),
  164. checks=[CheckOverallScore(0, 100), CheckTimeout()]),
  165. Test('timeout-sigstop',
  166. task=batch_stdio, filenames=['timeout-sigstop.%l'],
  167. languages=(LANG_CPP,),
  168. checks=[CheckOverallScore(0, 100), CheckTimeout()]),
  169. Test('timeout-select',
  170. task=batch_stdio, filenames=['timeout-select.%l'],
  171. languages=(LANG_CPP,),
  172. checks=[CheckOverallScore(0, 100), CheckTimeout()]),
  173. # Nonzero return status.
  174. Test('nonzero-return-stdio',
  175. task=batch_stdio, filenames=['nonzero-return-stdio.%l'],
  176. languages=ALL_LANGUAGES,
  177. checks=[CheckOverallScore(0, 100), CheckNonzeroReturn()]),
  178. Test('nonzero-return-fileio',
  179. task=batch_fileio, filenames=['nonzero-return-fileio.%l'],
  180. languages=ALL_LANGUAGES,
  181. checks=[CheckOverallScore(0, 100), CheckNonzeroReturn()]),
  182. # Fork
  183. # We can't really check for a specific error, because forking
  184. # doesn't cause an exceptional stop: it just returns -1 to the
  185. # caller; we rely on the fact that the test program is designed to
  186. # produce output only inside the child process
  187. # TODO: since we allow many processes in the sandbox now by default,
  188. # these submission rightfully pass. We need to refactor TestRunner
  189. # to allow different contests for different tests to re-enable them.
  190. # Test('fork',
  191. # task=batch_stdio, filenames=['fork.%l'],
  192. # languages=(LANG_C, LANG_CPP),
  193. # checks=[CheckOverallScore(0, 100)]),
  194. # OOM problems.
  195. Test('oom-static',
  196. task=batch_stdio, filenames=['oom-static.%l'],
  197. languages=NON_INTERPRETED_LANGUAGES,
  198. checks=[CheckOverallScore(0, 100)]),
  199. Test('oom-heap',
  200. task=batch_stdio, filenames=['oom-heap.%l'],
  201. languages=ALL_LANGUAGES,
  202. checks=[CheckOverallScore(0, 100)]),
  203. # Tasks with graders. PHP is not yet supported.
  204. Test('managed-correct',
  205. task=batch_fileio_managed, filenames=['managed-correct.%l'],
  206. languages=(LANG_C, LANG_CPP, LANG_PASCAL, LANG_PYTHON3, LANG_JAVA,
  207. LANG_C_SHARP),
  208. checks=[CheckOverallScore(100, 100)],
  209. user_tests=True, user_managers=['grader.%l'],
  210. user_checks=[CheckUserTestEvaluated()]),
  211. Test('managed-incorrect',
  212. task=batch_fileio_managed, filenames=['managed-incorrect.%l'],
  213. languages=(LANG_C, LANG_CPP, LANG_PASCAL, LANG_PYTHON3, LANG_JAVA,
  214. LANG_C_SHARP),
  215. checks=[CheckOverallScore(0, 100)]),
  216. # Communication tasks. PHP is not yet supported.
  217. Test('communication-fifoio-correct',
  218. task=communication_fifoio_stubbed,
  219. filenames=['communication-stubbed-correct.%l'],
  220. languages=(LANG_C, LANG_CPP, LANG_PASCAL, LANG_PYTHON3, LANG_JAVA),
  221. checks=[CheckOverallScore(100, 100)]),
  222. Test('communication-fifoio-incorrect',
  223. task=communication_fifoio_stubbed,
  224. filenames=['communication-stubbed-incorrect.%l'],
  225. languages=(LANG_C, LANG_CPP, LANG_PASCAL, LANG_PYTHON3, LANG_JAVA),
  226. checks=[CheckOverallScore(0, 100)]),
  227. Test('communication-stdio-correct',
  228. task=communication_stdio_stubbed,
  229. filenames=['communication-stubbed-correct.%l'],
  230. languages=(LANG_C, LANG_CPP, LANG_PASCAL, LANG_PYTHON3, LANG_JAVA),
  231. checks=[CheckOverallScore(100, 100)]),
  232. Test('communication-stdio-incorrect',
  233. task=communication_stdio_stubbed,
  234. filenames=['communication-stubbed-incorrect.%l'],
  235. languages=(LANG_C, LANG_CPP, LANG_PASCAL, LANG_PYTHON3, LANG_JAVA),
  236. checks=[CheckOverallScore(0, 100)]),
  237. Test('communication-stdio-unstubbed-correct',
  238. task=communication_stdio,
  239. filenames=['communication-stdio-correct.%l'],
  240. languages=(LANG_C, LANG_CPP, LANG_PASCAL, LANG_PYTHON3, LANG_JAVA),
  241. checks=[CheckOverallScore(100, 100)]),
  242. Test('communication-stdio-unstubbed-incorrect',
  243. task=communication_stdio,
  244. filenames=['communication-stdio-incorrect.%l'],
  245. languages=(LANG_C, LANG_CPP, LANG_PASCAL, LANG_PYTHON3, LANG_JAVA),
  246. checks=[CheckOverallScore(0, 100)]),
  247. # Communication tasks with two processes.
  248. Test('communication-many-fifoio-correct',
  249. task=communication_many_fifoio_stubbed,
  250. filenames=['communication-many-correct-user1.%l',
  251. 'communication-many-correct-user2.%l'],
  252. languages=(LANG_C, LANG_CPP, LANG_PASCAL, LANG_PYTHON3, LANG_JAVA),
  253. checks=[CheckOverallScore(100, 100)]),
  254. Test('communication-many-fifoio-incorrect',
  255. task=communication_many_fifoio_stubbed,
  256. filenames=['communication-many-incorrect-user1.%l',
  257. 'communication-many-incorrect-user2.%l'],
  258. languages=(LANG_C, LANG_CPP, LANG_PASCAL, LANG_PYTHON3, LANG_JAVA),
  259. checks=[CheckOverallScore(0, 100)]),
  260. Test('communication-many-stdio-correct',
  261. task=communication_many_stdio_stubbed,
  262. filenames=['communication-many-correct-user1.%l',
  263. 'communication-many-correct-user2.%l'],
  264. languages=(LANG_C, LANG_CPP, LANG_PASCAL, LANG_PYTHON3, LANG_JAVA),
  265. checks=[CheckOverallScore(100, 100)]),
  266. Test('communication-many-stdio-incorrect',
  267. task=communication_many_stdio_stubbed,
  268. filenames=['communication-many-incorrect-user1.%l',
  269. 'communication-many-incorrect-user2.%l'],
  270. languages=(LANG_C, LANG_CPP, LANG_PASCAL, LANG_PYTHON3, LANG_JAVA),
  271. checks=[CheckOverallScore(0, 100)]),
  272. # TwoSteps
  273. Test('twosteps-correct',
  274. task=twosteps, filenames=["twosteps-correct-first.%l",
  275. "twosteps-correct-second.%l"],
  276. languages=(LANG_C, ),
  277. checks=[CheckOverallScore(100, 100)]),
  278. Test('twosteps-half-correct',
  279. task=twosteps, filenames=["twosteps-half-correct-first.%l",
  280. "twosteps-correct-second.%l"],
  281. languages=(LANG_C,),
  282. checks=[CheckOverallScore(50, 100)]),
  283. Test('twosteps-incorrect',
  284. task=twosteps, filenames=["twosteps-incorrect-first.%l",
  285. "twosteps-correct-second.%l"],
  286. languages=(LANG_C,),
  287. checks=[CheckOverallScore(0, 100)]),
  288. Test('twosteps-comparator-correct',
  289. task=twosteps_comparator, filenames=["twosteps-correct-first.%l",
  290. "twosteps-correct-second.%l"],
  291. languages=(LANG_C,),
  292. checks=[CheckOverallScore(100, 100)]),
  293. Test('twosteps-comparator-half-correct',
  294. task=twosteps_comparator, filenames=["twosteps-half-correct-first.%l",
  295. "twosteps-correct-second.%l"],
  296. languages=(LANG_C,),
  297. checks=[CheckOverallScore(50, 100)]),
  298. Test('twosteps-comparator-incorrect',
  299. task=twosteps_comparator, filenames=["twosteps-incorrect-first.%l",
  300. "twosteps-correct-second.%l"],
  301. languages=(LANG_C,),
  302. checks=[CheckOverallScore(0, 100)]),
  303. # Writing to files not allowed.
  304. # Inability to write to a file does not throw a specific error,
  305. # just returns a NULL file handler to the caller. So we rely on
  306. # the test program to write the correct result only if the
  307. # returned handler is valid.
  308. Test('write-forbidden-fileio',
  309. task=batch_fileio, filenames=['write-forbidden-fileio.%l'],
  310. languages=(LANG_C,),
  311. checks=[CheckOverallScore(0, 100)]),
  312. Test('write-forbidden-stdio',
  313. task=batch_stdio, filenames=['write-forbidden-stdio.%l'],
  314. languages=(LANG_C,),
  315. checks=[CheckOverallScore(0, 100)]),
  316. Test('write-forbidden-managed',
  317. task=batch_fileio_managed, filenames=['write-forbidden-managed.%l'],
  318. languages=(LANG_C,),
  319. checks=[CheckOverallScore(0, 100)]),
  320. Test('write-forbidden-communication',
  321. task=communication_fifoio_stubbed,
  322. filenames=['write-forbidden-communication.%l'],
  323. languages=(LANG_C,),
  324. checks=[CheckOverallScore(0, 100)]),
  325. # This tests complete successfully only if it is unable to execute
  326. # output.txt.
  327. Test('executing-output',
  328. task=batch_fileio, filenames=['executing-output.%l'],
  329. languages=(LANG_C,),
  330. checks=[CheckOverallScore(100, 100)]),
  331. # Rewrite input in the solution.
  332. Test('rewrite-input',
  333. task=batch_fileio_managed, filenames=['rewrite-input.%l'],
  334. languages=(LANG_C,),
  335. checks=[CheckOverallScore(0, 100)]),
  336. Test('delete-write-input',
  337. task=batch_fileio_managed, filenames=['delete-write-input.%l'],
  338. languages=(LANG_C,),
  339. checks=[CheckOverallScore(0, 100)]),
  340. # Write a huge file
  341. Test('write-big-fileio',
  342. task=batch_fileio, filenames=['write-big-fileio.%l'],
  343. languages=(LANG_C,),
  344. checks=[CheckOverallScore(0, 100)]),
  345. ]